#clojure logs

2009-09-05

01:50hiredman~sandbox
01:50clojurebotsandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html
03:45mathiasI am trying to start swank separately to be able to connect to it from a separate emacs instance. I am able to start the swank server and even connect to it from emacs but I never get a lime buffer up. I can send things for evaluation from a normal emacs buffer but how do I get the REPL?
03:45mathiasI start clojure like this: java -cp clojure/clojure.jar:swank-clojure clojure.lang.Repl
03:46mathiasI then do: (require 'swank.swank)...
03:46mathiasand lastly: (swank.swank/start-server "/tmp/slime02" :port 4005 :encoding "utf-8")
03:50hiredmanclojurebot: how can you start swank seperately and connect to it from emacs?
03:50clojurebotwith style and grace
03:51hiredman(sorry)
03:53mathiashiredman: ?
03:54hiredmannot an emacser, so I don't know anything about swank
03:55mathiashiredman: ah
04:48tomojaw he left
05:38octecan i refresh a package loaded with the use-method?
05:54LauJensen(use :reload-all ns)
05:56LauJensen@ octe
07:12octeLauJensen: thanks
07:14LauJensennp
10:34slyrus_rhickey: who was the author of the database book you mentioned near the end of the blip.tv talk? Andres Rieter? I think I'm spelling that wrong.
11:41winterstreamI've been poking around clojure-contrib to see how test-is should be used. One thing I can't figure out is how to define a variable that can be used by all tests in a given namespace - that is, I only want to do the work of setting up the variable once.
11:41winterstreamDoes anyone know how to do this?
11:46Chousukehmm
11:47Chousukethere's the custom test hook, and fixtures.
11:51winterstreamChousuke: Thanks for the tip. I think I'm just going to take a shortcut now. I want to load a fairly large XML file for my tests, but I think I'll trim it down and include it as a string in my file.
11:51kirasi've been reading through "Programming Clojure" and i have a question about one of the examples. i'm sure it's really simple, but i'm new to clojure/lisp and somewhat confused. is it ok to show code here or is there a pastebin site that people generally use?
11:52LauJensen~paste
11:52clojurebotlisppaste8, url
11:52lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
11:52LauJensenGo go go :)
11:52kirasty :)
11:53Chousukewinterstream: you could also just use a function that loads it once and caches the result
11:54winterstreamChousuke: That would actually be the best way; I should learn how to memoize in Clojure anyway :).
11:54Chousukehm
11:55Chousuke(doc memoize)
11:55clojurebot"([f]); Returns a memoized version of a referentially transparent function. The memoized version of the function keeps a cache of the mapping from arguments to results and, when calls with the same arguments are repeated often, has higher performance at the expense of higher memory use."
11:55winterstreamSo now I can be even lazier :). Thanks.
11:55Chousukedunno if that works for functions with no arguments though :/
11:56winterstreamIf not, I'll just hack it by adding an unused parameter :)
11:56kirashttp://paste.lisp.org/display/86614
11:57kirasmy question has to do with line 3. in the book, it says "On line 3, the zero-argument body returns the concatenation of the basis values [0 1] and then calls the two-argument body to calculate the rest of the values."
11:58LauJensenSo whats the question?
11:59Chousukehm, the wording of the book is a bit weird.
11:59kirasso... does concat return values multiple times? or does it calculate the value once and then return it?
11:59kirasdid i phrase that ok?
11:59Chousukeconcat just concatenates two sequences
12:00Chousuke(lazy-seq-fibo 0 1) call produces a lazy sequence, so concat concatenates [0 1] with that sequence
12:00LauJensen,(concat [1 2] [3 4])
12:00clojurebot(1 2 3 4)
12:00LauJensenclojurebot: compute!
12:00clojurebotPardon?
12:01kirasok. the way the book put it, it seemed like it was saying that concat returned (0 1) first, then called (lazy-seq-fibo 0 1)
12:02kirasat least, that's how it seemed to me
12:02Chousukewell, the (lazy-seq-fibo 0 1) gets evaluated when it's passed to concat.
12:02Chousukebut the result of it is a lazy sequence, so no *items* of the sequence are actually produced
12:03kiraswell, i think i understand the lazy sequence part
12:03Chousukeand since concat is lazy too, no additional items will get computed until you have consumed the first two (the [0 1]) from the resulting sequence.
12:04kirasi was mostly confused about how arguments to concat were evaluated
12:04kirasoh
12:04kiraslol
12:04kirasi think i'm confused again...
12:04Chousukearguments to functions are always evaluated.
12:04kirasok
12:05Chousukebut the thing is, when evaluated, (lazy-seq-fibo 0 1) produces a lazy sequence, and unless you actually try to access items from the sequence (which concat won't do until it's needed), then no items will be computed
12:06kirasok... so basically, if it wasn't lazy, it would produce the whole set of fibonacci numbers?
12:06Chousukeyes.
12:06kirasok
12:07LauJensenkiras: I dont know if you already got this, but if not this might help: http://paste.lisp.org/display/86614#1
12:08kiraslaujensen: ty, i'll look at that
12:12kirasLauJensen: i understand your example. at the moment, i think i'm ok with the recursion that i've seen, just the lazy sequence part is something i don't remember coming across before.
12:12LauJensenJust the simplest for of dispatching on argument count
12:12LauJensenAlright
12:12kirasty
12:13LauJensenBut you understand now?
12:14kiraswell... sort of... i guess to really understand, i might have to look at how lazy-seq actually works with take and similar functions
12:17LauJensen,(doc lazy-seq)
12:17LauJensenYou can use that in your emacs repl when new functions come up
12:17clojurebot"([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls."
12:18Chousukehmm
12:18Chousuke,(lazy-seq 5)
12:18clojurebotDon't know how to create ISeq from: Integer
12:18kirasty, i was actually reading that just now lol
12:18Chousukeah, right.
12:27kirasso a lazy-seq is "a Seqable object that will invoke the body only the first time seq is called..."
12:27kiras?
12:28LauJensenYes sir
12:28kirasso is it actually a sequence or does it just implement the ISeq interface? if that makes any sense?
12:30Chousuke,(ancestors (lazy-seq [1 2]))
12:30clojurebotnil
12:30Chousukehuh.
12:30Chousuke,(ancestors (class (lazy-seq [1 2])))
12:30clojurebot#{java.lang.Iterable clojure.lang.ISeq java.util.Collection clojure.lang.Seqable java.util.List clojure.lang.IMeta java.lang.Object clojure.lang.IObj clojure.lang.Obj clojure.lang.Sequential :clojure.contrib.generic/any clojure.lang.IPersistentCollection}
12:30LauJensenAs I understood it in plain english, its a sequence of items where each expression is calculated when you eval it. Ex (take 5 (iterate inc 1)) will return (1 2 3 4 5), the next item is 6, but its not calculated, and 1-5 is cached for future calls.
12:31Chousuketake itself produces a lazy seq though
12:31Chousukeat least, IIRC :)
12:32LauJensentrue
12:32Chousuke,(take 2 (take 5 (iterate (fn [x] (do (println x) (inc x))))))
12:32clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$iterate
12:32Chousukeoops
12:32Chousuke,(take 2 (take 5 (iterate (fn [x] (do (println x) (inc x))) 1)))
12:32LauJensenYou forgot the offset
12:32clojurebot(1 2)
12:33Chousukeweird, nothing printed :P
12:33LauJensenits in the inferior lisp buffer :)
12:36kiraswhen you say "1-5 is cached for future calls" how long are those values cached?
12:38Chousukekiras: until they're no longer referenced.
12:39Chousukeand they're referenced as long as you hold on to the head of a sequence that contains them.
12:39kirasChousuke: so if they aren't stored in a variable or the such, they would be calculated again, right?
12:39Chousukewell
12:40Chousukeif you do (let [x (iterate inc 1)] [(take 5 x) (take 10 x)]) then on the first take call, the values get calculated, but for the second the cached ones would be used for the first 5 and then again calculated
12:41kirasthat makes sense
12:41LauJensenkiras: but short answer is yes
12:42Chousukethe caching is why you don't want to do (def fibos (lazy-fibo))
12:42kirashehe
12:42Chousukebecause then if you did (take 10000 fibos) then it'd hold on to the 10000 fibos until the program ends (or until fibos is redef'd)
12:43kirasright
12:43Chousukeaccidentally holding on to the head of lazy sequences is the main cause of out of memory errors in programs btw :)
12:43kiraslol
12:44Chousukeit's sometimes difficult to see if you're holding a reference to something or not.
12:44kirasi was wondering if that was a very common mistake or not
12:44LauJensenkiras: Chousuke does it all the time
12:44Chousukeespecially because the clojure compiler currently does not nullify references after last use.
12:44Chousukeonly at tail calls
12:48kirasi never really thought about that. do you mean that, if you were to do (def fibos (lazy-fibo)) and store a lot of numbers in there, used them once and then never used them again, it might be possible for the compiler to know the fibos was never going to be used again and set it to null?
12:48Chousukenah, not that.
12:48ChousukeI meant local references
12:49LauJensenkiras: As it is now, that reference would be kept until program termination
12:50Chousukeeg. (fn [x] (let [foo (do-something (drop 100000 x))] "the reference to x still exists here even though it's not needed")
12:51Chousukeif the compiler were smarted it could figure out x is not used after the do-something call and nullify the reference, but currently it doesn't do that.
12:51kirasLauJensen: seems like it would. i thought maybe Chousuke meant that someday the compiler might be able to tell and set it to null. would think that would be very difficult to do though.
12:51Chousukesmarter*
12:52kirasChousuke: i see...
12:52kirasinteresting
12:55Chousuketo get around that you need to do (fn [x] (letfn [(work [y] (let [foo (do-something y)] "no ref to x here"))] (work (drop 100000 x))))
12:56Chousukebecause the (work ...) call is at the tail position the compiler knows x can't be referenced after the call and nullifies the reference
12:56Chousukeof course, the example is rather silly like that, but imagine that the strings returned were something more complex (possibly utilising foo, but not x)
12:57LauJensenkiras: With dynamic code (macros) I think its near impossible.
12:59kirasso do lazy sequences keep track of references to themselves and the parts of the sequence each reference is holding onto (pointing to?)? then when a variable that is using part of the sequence is deleted, the lazy sequence drops that part of the sequence from its cache? or is that handled outside the lazy sequence somehow?
13:00Chousukekiras: the lazy sequence is like a linked list. it's made of smaller subsequences. :)
13:01Chousukekiras: and each subsequence just caches its own value after it's computed.
13:01Chousukethe head of each subsequence that is.
13:02tomojso if you're holding the head, the entire sequence computed so far is not gcable?
13:02Chousukeyes.
13:02Chousukebecause there's a reference from the head to the second item, from the second item to the third, etc. until the last actually computed item
13:03Chousukethis might be oversimplified though, because you can have seqs that are just "views" to something that already exists fully in memory, like a vector.
15:01fpshello, could someone give me a hint on how to use the clj-record library? http://github.com/duelinmarkers/clj-record/tree/master/
15:03fpsI already compiled it, but I cannot find a jar to add to the classpath
15:09Bercilakfor those of you using emacs clojure-mode, have you had any success using the clojure-update command?
15:10BercilakI'm running into an error where it tries to run ant in the wrong directory, and I think it's a bug in clojure-mode.
15:11cschreinerI get an error with Git
15:11cschreinerbut I've had no success using the clojure-update command
15:12Bercilakout of curiosity, what's the error?
15:15cschreinerjust that Git cannot be found
15:16cschreinerI just left it, and continued with what I was doing before
15:16cschreinerthere are a couple of things that don't work right in emacs, but I'll manage
15:18cschreinerlike; code-completion, java-lookup, some problems with elisp formatting from swank etc
15:19cschreinerespecially when doing (println "whatever") statements
15:20Bercilakhmm. I'm still in the process of switching to emacs from textmate, so I'm useless for those...
15:20cschreinererror in process filter: slime-dispatch-event: Elisp destructure-case failed: (:write-string "Whatever")
15:21cschreineryeah, textmate, never seen much of that since going back to emacs
15:22cschreinerI tend to spend more time browsing elisp code than actually clojouring
15:23cschreinerI still need to understand the big picture though (re. emacs)
15:27LauJensenFor those of you who are interested I'm launching a blog which pivots on Clojure but from a business relevant angle. You'll find it at http://bestinclass.wordpress.com
15:27cschreinersure :-)
15:31Bercilaktextmate is very approachable and snippets are simple to understand and damn useful
15:31Bercilakslime is so worth the switch though, and eventually I'll get the hang of emacs
15:31clojurebotslime is icky
15:31Bercilakheh
15:31LauJensen~forget slime
15:31clojurebotI forgot slime
15:31Chousukein the end emacs is more powerful than any other editor
15:31Chousukeit just requires some effort :/
15:32cschreinerI messed with the ergoemacs keybindings, but I returned to a blank slate
15:32BercilakI always knew that I was going to switch to emacs or vim someday, so recently I set up a linux dev box and I've been doing all my work on that
15:32cschreinerbetter to build the system bit by bit with functionality I am really going to use
15:33cschreineron another hand, the original keybindings are really hard on my old hands
15:33Bercilakergoemacs looked interesting, it's nice to hear from someone who tried it out
15:33Chousukemaybe you just need a better keyboard :/
15:33cschreinermaybe
15:34cschreinerI need an original symbolics thing
15:34Bercilakhehe. I type in dvorak which makes a lot of these layouts kind of infuriating. They make sense in qwerty but not dvorak
15:34ChousukeI get by with caps lock as meta and cmd as control but still I think a better keyboard would help a lot :P
15:34cschreinerWell, I have three different apple keyboards here, and all of them makes my hand ache
15:35cschreinerI need to think more about typing less
15:35Bercilakmaybe it's blasphemy, but I might switch to using vimpulse/viper for basic text movement and manipulation
15:35Bercilakelisp is where it's at for configuration though
15:35cschreinercare to share?
15:36cschreinervimpulse, is that a vim thing?
15:36Chousukeviper.el is a vi implementation for emacs.
15:36Chousukeand vimpulse adds some vim things missing from viper.
15:36ChousukeI used viper but it didn't play well with paredit so now I'm trying to get used to emacs controls
15:37cschreinerany torough docs/intros?
15:37cschreinerI think the incremental search is the most important thing, and sexp navigation of course
15:37Chousukeparedit is awesome.
15:38cschreinerso few modifiers, so many modes
15:39ChousukeI don't even do much besides some barfing and slurping and sexp-killing with paredit but it's still an enlightening experience.
15:39BercilakI just googled it... the paredit koolaid looks delicious.
15:40ChousukeI suppose if I learned to use the sexp navigation commands properly I would be one step closer to lisper nirvana
15:41cschreinerexamining the pareditcheatsheet now http://www.emacswiki.org/emacs/PareditCheatsheet
15:43Chousukeone of the more common operations I do with paredit is deleting a let, and it's really very easy :/
15:44Chousukeor the reverse, wrapping some code in a let.
15:45cschreinerworking with a non-us keyboard layout, everthing is fucked from the beginning
15:45cschreinerthe intention of the original layout does not count
15:46cschreineror, is non-existant
15:47ChousukeI find it usable on a Finnish layout.
15:47Chousukethough I think if I got used to a US one it would be better
15:47cschreinerSuomi?
15:47Chousukeit's not like I need ä ör ö when coding :/
15:47Chousukeyeah. :P
15:48cschreinerI would never have guessed it
15:48cschreinerNorway here
15:52cschreinerbarfage and slurpage seems reasonable enough, never touched paredit- before
15:53cschreinerguess I've loaded it, but not bound any of the functions
16:21quidnunccgrand: Is it possible to select a node whose child satisfies some predicate in enlive? I'm trying to do (select foo [[:font (has [:a (attr-contains :href "blah")])]]) but it doesn't seem to be working (the selector on the child works on its own.
17:19cgrandquidnunc: (select foo [[:font (has [[:a (attr-contains :href "blah")]])]])
17:20cgrand'has takes a whole selector not a single selector-step
17:23quidnunccgrand: Thanks.
17:26quidnunccgrand: There is no way to get a parent of a node once I from the value returned by select right?
17:27cgrandnot by select itself
17:30cgrandlook at zip-select: something like (zip-select (map xml/xml-zip nodes) [your selector here]) -- where xml is net.cgrand.xml
17:30quidnunccgrand: One last question. Is it possible to use zip-filter.xml functions on the nodes returned by select?
17:32quidnunccgrand: I wasn't clear about the difference between zip-select and select. What does zip-select do differently than select?
17:32cgrandzip-filter.xml may barf on xml comments (other than whitespace handling it's the main difference between clojure.xml and net.cgrand.xml)
17:34cgrand'select returns nodes, 'zip-select returns locs (zips) to these nodes... and you can get the parent of a loc
17:35cgrandonce you have a loc you can freely use clojure.zip or zip-filters
17:37quidnuncThanks cgrand.
17:37cgrandwelcome
17:41cgrandquidnunc: bedtime for me
18:11cemerickholy crap, I just grokked what subseq is all about
18:12cemerickI had never read the docs -- thought it was over Indexed colls!
18:35cemerickit'd be great to see PTM become extensible (so as to support building stuff like interval trees on top of it, etc)
18:44emacsenWhy doesn't this do what I expect (knowing I clearly misunderstand): (reduce merge [{:a 10} {:b 20} {:c 30}])
18:45Chousuke,(reduce merge [{:a 10} {:b 20} {:c 30}])
18:45clojurebot{:c 30, :b 20, :a 10}
18:46Chousukeisn't that what you want it to do?
18:46emacsenI didn't get that... let me try again
18:46Chousukethough you could also do (apply merge ...)
18:46Chousukewhich probably internally uses reduce :)
18:46Chousukebut might not!
18:46emacsenlol, okay this was a slime problem with my display
18:46Chousuke~def merge
18:46emacsenI was like "I must be going crazy... this should work"
18:47Chousukehm, merge could be changed to use transients I suppose
18:48emacsenChouske, okay here's a harder one... given another vector in mynode's content, this is invalid:
18:48emacsen(map #({(:k (:attrs %)) (:v (:attrs %))}) (:content mynode))
18:48emacsenI've tried that function on a single argument and it works, and (:content mynode) gives me back a persistent vector
18:49Chousuke#() is not fn
18:49Chousuke#({}) means calling {} with no parameters
18:49ChousukeI assume you meant to return the map
18:49emacsenisn't #() a macro for (fn ..)
18:49Chousukeno
18:49Chousuke#(foo) = (fn [] (foo))
18:50emacsenoh good point
18:50emacsenright... okay this all makes more sense
18:50hiredman> ((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)
18:50clojurebotAny = 1
18:50hiredman:D
18:50Chousukewhat.
18:51ChousukeClojurebot does Scala now?
18:51Chousukewhat blasphemy is this.
18:51emacsenoh that's scala?
18:51hiredmanyep
18:52hiredmanvia the simplyscala online repl
20:42AWizzArdAnyone awake who knows well about snapshots in Clojure? When I made a snapshot of a ref, and then the ref is mutated, will it use copy on write, as in forks?
20:46hiredmanuh
20:46hiredmanwhat?
20:48AWizzArdwhen we make a snapshot of a map and have another thread changing the map, will then Clojure have to copy everything from the root to that leaf that gets mutated?
20:48hiredmanmutating a ref is just assigning it a new value, te copy-onwrite or not depends on what the value is
20:48AWizzArdimagine a fork.. when the parent or child mutates data then the os will first copy the page, because everything is marked as read-only
20:49hiredmanthat has nothing to do with refs
20:49AWizzArdbut mutating something in a tree may require to copy data from the root to that mutated leaf
20:50hiredmanrefs do not care, and don't know anything about what they wrap
20:50hiredmanand copy on write, etc, is the responsibility of the object wrapped by the ref
20:50AWizzArdi snapshot a ref (i call deref on it) and have a long running function that works on the object
20:51hiredmansure
20:51AWizzArdand now another thread mutates this object..
20:51hiredmanthen you are screwed
20:51AWizzArdthen COW is happening under the hood?
20:51hiredmanthat is not how refs work
20:51hiredmanthe value a ref holds should never mutate
20:51AWizzArdthe ref is already forgotten after a snapshotted/derefd
20:51hiredmanthe ref can mutate and point to different values
20:52AWizzArdyes, let's forget the ref
20:52hiredmanwe cannot just forget the ref
20:53hiredmanif you wrap a mutable object like stringbuilder in a ref, the ref is useless
20:53AWizzArdyes
20:53AWizzArdbut say it is a clojure map
20:53AWizzArdwe call (foo @our-map)
20:53hiredmanok, clojure maps are implemented using structural sharing
20:54AWizzArdand while foo is running some other function bar mutates our-map
20:54hiredmanaand Immutable
20:54hiredmanAWizzArd: you cannot
20:54hiredmanImmutable
20:54AWizzArdour-map sits in a ref
20:55hiredmandoesn't matter
20:55AWizzArdand as you said, the structure is shared
20:55AWizzArdso, it seems to us that we are working on a completely new object, while under the hood the same thing is mutated
20:55hiredmanno!
20:55AWizzArdif our-map is 600 mb in size, then not each time those 600mb need to be copied
20:55hiredmanno!
20:55hiredmanit is a new object
20:56hiredmanit just contains a pointer to another object that it shares some structure with
20:56hiredmanno mutation
20:56AWizzArdI know, they are not identical
20:56Chouseronly the parts that are identical are shared
20:57AWizzArdwhen we call (foo @our-map) then at those point foo sees an immutable map, and all threads can see the same thing
20:57AWizzArdsimilar to a fork
20:57Chouserthe COW, if you want to think of it that way, happens the moment you do (assoc ...), regardless of whether a ref is involved or not.
20:57AWizzArdyes
20:57hiredman,(let [a '(1 2 3) b (cons 4 a)] [a b]) ;shared structure, no mutation
20:57clojurebot[(1 2 3) (4 1 2 3)]
20:57AWizzArdthis is what i want to know
20:57AWizzArddoes a COW happen, and how efficient will it be
20:58AWizzArdsome other thread runs the function bar which is doing transactions and alters our-map
20:58hiredmanAWizzArd: it happens everytime you cons, conj, assoc, etc
20:59hiredmanAWizzArd: you cannot alter the map
20:59hiredman*cannot*
20:59ChouserAWizzArd: http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/
20:59hiredmanyou can create a new map that shares structure with the old map, and place the new map into the ref
20:59AWizzArdyes
20:59hiredmanbut that in no way effects our-map
21:00AWizzArdChouser: thanks for the link
21:00AWizzArdyes hiredman I know, but I want to know how efficient it will be under the hood
21:00AWizzArdconsing is no problem
21:00AWizzArdbut changes in the middle might be
21:01hiredman,(time (reduce conj [] (range 10000)))
21:01clojurebot[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 13
21:01clojurebot"Elapsed time: 10.073 msecs"
21:01ChouserAWizzArd: changes on the end and in the middle are handled identically (for both vectors and maps)
21:01clojurebotfor is not used enough
21:03hiredmanAWizzArd: I recomend you read http://clojure.org/refs and http://clojure.org/state
21:04AWizzArdthose pages don't explain much of how structure sharing is done
21:04hiredmancorrect, I am more concerned with you understanding of refs
21:04AWizzArdthat is no problem at all
21:05hiredman
21:05AWizzArdonly that i was not talking about them, and fortunately Chouser understood this and gave me an interesting link
21:06mabesany vimclojure users here? When I try to run ant in the plugin dir the build fails:
21:06hiredmanare you following the directions in the readme?
21:06mabeshttp://pastie.org/607372
21:07mabeshiredman: I was following a screen cast.. I'll double check the readme to see if something has been updated
21:08hiredmanyou need to follow the build instructions for contrib
21:08mabesit is as if it can't find my clojure-contrib.jar but I defined it in the local.properites
21:08mabeshiredman: ok.. so I just don't run "ant"?
21:09hiredmanmabes: run ant and check for a "Warning ..." and follow the instructions
21:09mabeshiredman: k, thanks for the help
21:10AWizzArdChouser: when there is a big map and in a snapshot we have the k/v pair [:a 100] and some other thread dissocs it, then the snapshot still sees it. Will that operation require very much work under the hood, or is that still very efficient?
21:18ChouserAWizzArd: that has nothing to do with threads or refs. 'dissoc' will do what it does
21:19hiredman,(time (let [v (vec (range 1e6))] (nil? (reduce #(assoc % %2 (* %2 3)) v v))))
21:19clojurebot"Elapsed time: 2788.926 msecs"
21:20hiredman1e6 new vectors
21:22AWizzArdI will definitly need to look into that. It seems interesting to see how dissoc can remove elements in such a way that no snapshots will see it.
21:22AWizzArdOki, thanks you two and good night
21:22hiredmanNo!
21:23hiredmandissoc doesn't effect any "snapshots"
21:23hiredmanthe snapsots are immutable!
21:23AWizzArdexactly
21:23AWizzArdthey won't see the change
21:23AWizzArdbut when the structure is shared then some copying must happen, so that the snapshot is not a full copy but still can see the dissoc'd element
21:24AWizzArdn8 n8
21:24Chouseryes, clojure's persistent structures are amazing.
22:04emacsenn8?
22:04emacsenoh, night
22:29emacsenhey technomancy
22:30emacsentechnomancy, how mature is your http abtraction library?
22:39technomancyemacsen: in terms of age/usage, not very
22:39technomancyI wrote it in three days and haven't touched it yet
22:39technomancyI've got like three patches contributed that I've been sitting on.</shame>
22:40emacsenI don't need any http library yet but soon will
22:40emacsenand looking for something other than the java one, because I don't know Java, I find it distracting to go back and forth between documentation and programming styles
22:41emacsenunless Clojure comes with another one that I've missed
22:44technomancythe java one certainly requires a lot of ceremony
22:45technomancyemacsen: there's one in contrib too; uses agents
22:45emacsenthat's a lot of overkill for what I'm doing
22:47technomancyif you're working with a restful API then I'd recommend the "resourcefully" namespace in clojure-http-client
23:05nathanmarzany monad masters around?
23:38emacsentechnomancy, I am indeed working with a restul api
23:53prospero_how do I reset the state of the repl?
23:58hiredmanwhat state?