#clojure logs

2010-09-18

00:01technomancyah; nice, it just joins it with the line above
00:01technomancyI didn't get that far
00:28joegallotehcnomancy: I'm in your code, making changes.
00:29joegalloCrap, typo. Anyway.
00:29joegallotechnomancy: I'm making good progress on your side, I'll send a pull request or something soon.
00:29joegalloRight now I'm dealing with a bizarre emacs error.
00:47laurusHow difficult is it to make a theme for JFreeChart?
00:52joegallotechnomancy: Pushed.
00:53joegalloStill some bugs, but I got around the one I was dealing with.
00:56scottjlaurus: no clue. there don't appear to be many, even outside of incanter. maybe modding the incanter ones would be easy?
00:57technomancyjoegallo: sweet; thanks
00:57technomancyjust added you to the repo so you can push directly for future changes
00:58laurusscottj, well, I took a look at charts.clj, but it's hard to figure out what would need to be changed, so I thought I'd ask here to see if anyone else had taken a look at that
00:58laurusI'm surprised someone hasn't made a simple theme with a white background, etc.
01:06bhenryjoegallo: technomancy http://gist.github.com/585375
01:08joegallobhenry: :(
01:08joegalloBleh, I haven't been testing for that.
01:08bhenryyeah i was wondering if it was strange for me to use the namespaces that way.
01:09joegalloI dunno, I haven't seen it before, but that's neither here nor there.
01:09joegalloIf clojure supports it, then I think this should, too.
01:10bhenryagreed. works great in my latest project, but i don't have any of those multiple namespaces from the same project dealies.
01:15bhenryjoegallo: don't feel too bad. it was wonky before your push too.
01:20technomancyI dunno; I read a thread on a future possible overhaul of the ns form and it sounds like the nesting like that may be deprecated in the future
01:21technomancyit'd be nice to support, but I think there's a lot of other low-hanging fruit to tackle first
01:21technomancylike removing unused imports maybe
01:22bhenrytechnomancy: would the removing unused imports be it's own function? sometimes i throw some in knowing i will need them later.
01:23bhenryi wouldn't mind it say right before pushing to production, but if it was part of some bigger function i'd hate to lose important stuff
01:23technomancyit would be its own function, yeah
01:23technomancyand it would be paired with a function that could check for imports that are needed but absent and search the classpath for them
01:24bhenrycool. i'll have to find those plans for the ns form.
01:24amalloyeveryone: what's the project y'all are working on?
01:24bhenryoh that's a good one.
01:25technomancyamalloy: talking about Durendal now: http://github.com/technomancy/durendal
01:26technomancybhenry: http://groups.google.com/group/clojure/browse_thread/thread/dbcfb0dc6699ec41/e8165da1ceebba9d?#e8165da1ceebba9d
01:26technomancyalso http://www.assembla.com/spaces/clojure/tickets/272-load-ns-require-use-overhaul
01:26amalloytechnomancy: that's no fair. i'm not done learning all the other emacs features yet. can you hold off a decade or so?
01:27technomancynobody learns all the emacs features
01:28amalloythat's why i want a decade
01:28amalloy(it's a sort of irony, see)
01:28laurusI wonder when someone will write a Clojure version of Emacs :P
01:28amalloylaurus: never, i imagine
01:29laurusWho knows? :)
01:29amalloywell, knock yourself out
01:29laurusamalloy, haha, no thanks!
01:29laurus;)
01:29laurusHence why you said "never" :P
01:32amalloyyep
01:33amalloywell, that and there's no compelling reason to do so. if there were a reason, it might happen
01:34laurusRight :)
01:36laurusGood night everyone :)
01:38amalloytechnomancy: you don't have to escape . inside of [character classes]. you also ought to be able to replace the whole class with something like \S*
01:39joegalloMmmm... I have commit that fixes that stuff.
01:39joegalloI think.
01:39joegalloPushed.
01:40amalloyi was referring to line 163 (169 after your push)
01:40amalloythe \\ can go away as it's meaningless here, or you can (probably, untested) replace the whole [...] with \S
01:41joegalloOh, gotcha, I'm not in that stuff at the moment, but maybe technomancy is. I've messed with font lock stuff before, and I know it's way too late for me to hope to get it right.
01:41joegalloSo I'm going to leave that alone. ;)
01:42amalloyjoegallo: sure. i haven't messed with emacs at all, but i have a pretty strong regex background
01:42clojurebotemacs is best configured for Clojure with instructions at http://technomancy.us/126
01:43amalloyclojurebot: thanks, but who asked you?
01:43clojurebotTitim gan éirí ort.
01:51seangroveHey all, I can't seem to get lein swank to work properly
01:51seangroveWhenever I evaluate my (ns statement, it trips up
01:52seangroveI realize that's vague, but I'm not really sure where to look
01:55amalloysame code work copy/pasted in lein repl?
01:59amalloyseangrove: ^, and also how are you loading the code into slime? C-c C-k is how i usually start
02:06seangroveamalloy: C-x C-e on the (ns statement
02:06seangroveC-c C-k would be smarter
02:07amalloyseangrove: if i don't start with a C-c C-k things mysteriously break. C-x C-e works better after that, usually
02:08seangroveamalloy: That looks much better, thank you
02:08bhenrywhen doing C-x C-e down the file, you'll often forget one of your forms and that's why things will break.
02:08bhenryi use C-x C-l and load the whole thing at once.
02:11amalloybhenry: C-c C-k does that too
02:12bhenryC-c C-k compiles. loads it after?
02:13technomancyload/compile is a distinction slime inherits from common lisp
02:13technomancyit has no meaning in clojure
02:13amalloythat's what i thought
02:14bhenryoooh cool. well i should start using C-c C-k then so i don't have to push enter after.
02:26seangroveHmm, seems like compojure doesn't have serve-file anymore...
02:26clojurebotcompojure is http://github.com/weavejester/compojure/tree/master
02:28amalloyclojurebot: why are you suddenly volunteering information nobody wants today?
02:28clojurebotwhat should I do today, it is the weekend and all
03:32joegalloPushed durendal again, pretty much finished the sort-ns stuff, except for the crazy-fun ns example that bhenry sent.
03:32joegalloAnd I'm going to sleep. Goodnight, clojure!
03:39jjido(fn) does not take doc?
03:44amalloyit's an anonymous function. how would you get at the doc for it?
03:45jjidoIn my case it is a struct function
03:47jjidothe function is saved in a structure
03:48amalloyyou can do something like (def x (with-meta (fn [a] a) {:doc "test"}))
03:49jjidook
03:49amalloythat's not perfect though
03:49amalloyie, (doc x) won't work. but at least you can see the docs with (:doc (meta myfn))
03:55jjidodefn is a macro isn't it? What does it do for the doc?
03:58amalloyi've been looking
03:59amalloycan't really tell. try macroexpanding it; it looks like the docstring vanishes
04:00amalloyor i guess it...tacks the metadata onto the name at macroexpansion time, so that once it's expanded the string is hidding inside of (meta myfunc) already
04:02jjido,(defn myfunc "myfunc doc" [] 1) (meta myfunc)
04:02clojurebotDENIED
04:02jjidoanyway it is not in (meta myfunc)
04:07flintf_Hey, does anyone happen to know if someone has translated the SICP examples to Clojure?
04:08flintf_it's not hard to look at them and "imagine" them into Clojure, but it'd be nice if someone had already done to work
04:09flintf_hah, actually...apparently there's a whole website devoted to the idea...nvm
04:35coldheadso it turns out its a bad idea to evaluate (iterate inc 0) at the repl
04:35coldheadi learned this the hard way
04:39fliebelmorning
04:40seangrove,({:a "34"} {:b 3241})
04:40clojurebotnil
04:40jjidoseangrove: {...} is a function
04:41seangroveTrying to merge those two maps
04:41seangrove,(merge {:a "34"} {:b 3241})
04:41clojurebot{:b 3241, :a "34"}
04:41seangroveYup, that did it
04:41seangroveNot sure what I did differently
04:42jkkramercoldhead: (set! *print-length* 103)
04:42seangrove,(merge (for [key (keys {:a "34" :b 3241})] {key (key {:a "34" :b 3241})}))
04:42clojurebot({:a "34"} {:b 3241})
04:42seangrove,(for [key (keys {:a "34" :b 3241})] {key (key {:a "34" :b 3241})})
04:42clojurebot({:a "34"} {:b 3241})
04:42seangroveWeird :P
04:43coldheadthanks jkkramer
04:45amalloyseangrove: why is that weird? you're taking each key from the map, and inserting it into the new map with whatever value it had in the old one
04:47amalloy,(zipmap ((juxt vals keys) {:a 34 :b 3241}))
04:47clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$zipmap
04:47amalloy,(apply zipmap ((juxt vals keys) {:a 34 :b 3241}))
04:47clojurebot{3241 :b, 34 :a}
04:47amalloyseangrove: ^^ this one's more fun
04:50seangroveHaha
04:50seangroveBut why are they two separate maps instead of one, even with the merge?
04:51amalloyoh, i see. sorry, missed that
04:51amalloy,(into {} (for [key (keys {:a "34" :b 3241})] {key (key {:a "34" :b 3241})}))
04:51clojurebot{:a "34", :b 3241}
04:52amalloyseangrove: tada!
04:52tomojyou would've needed to apply the merge
04:52seangroveHaha
04:52seangroveNice :)
04:52amalloyit's amazing the things that suddenly turn easy when i remember that juxt exists
04:53amalloyit's like map, but rotated ninety degrees
04:58seangroveWhat would be the equivalent of scheme's member? in clojure?
04:59seangrove(member? 'a '(a b c d)) => #t
04:59Chousukeyou can use the java .contains method I think
04:59Chousuke,(.contains '(a b c d) 'a)
04:59clojurebottrue
04:59seangroveOh, nice
05:00Chousukeit doesn't exist as a clojure function because it's slow :)
05:01seangroveThanks :)
05:04amalloy,(some #('a) '(a b c d))
05:04clojurebotjava.lang.IllegalArgumentException: Wrong number of args (1) passed to: sandbox$eval7126$fn
05:05amalloy,(some #{'a} '(a b c d))
05:05clojurebota
05:05amalloy,(some #{'a} '(b c d))
05:05clojurebotnil
05:05amalloyseangrove: ^^
05:11amalloyhere i'm using the singleton set a as a predicate. but (some) takes any predicate, eg
05:11amalloy,(some even? [1 7 4 9 8])
05:11clojurebottrue
05:25amalloyto go along with some there are also every? and not-any? not-any seems kinda silly to me - isn't it just (complement some)?
05:26amalloybut anyway, way past bedtime to me. have a good weekend, folks
05:27amalloy,(source not-any?)
05:27clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
05:27amalloyanyway not-any is written as (comp not some), fyi
07:40fliebelWhat do you guys usually do for static files in a Ring app? I tried Ring's wrap-file, which is not very configurable and even considers index.img123.jpg an index file. Then I tried using Jetty directly using :cofigurator, which gave me a 403 on the web root.
08:37BahmanHi all!
08:37neotykMorning Bahman
08:38BahmanMorning neotyk.
08:42fliebelneotyk: You posted the uncle bob video the other day, right? Where you by any chance at the Amsterdam Clojurians the week before?
08:43neotykfliebel: Hi, I'm here every meetup, we host it
08:44fliebelneotyk: I'm Pepijn, I was there as well. :) I think someone must have mentioned your IRC name there.
08:45neotykfliebel: Hubert here, I go by that nick everywhere
09:15notsonerdysunnyHello everybody, I am not sure if the question really belongs here .. but I am asking since it is part of clojure-contrib... http://clojuredocs.org/v/436 what exactly are self-recursive-sets?
09:27fliebelIs there something like filter that splits the result into 2 seqs based on pred?
09:28@rhickey,(doc split-with)
09:28clojurebot"([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]"
09:30fliebelrhickey: Sorry, I mean… put all the ones that qualify in one seq and the others in the other. But the relation is the same as take-while => split-with, only with filter.
09:30@rhickeyah
09:31fliebelSo I could use not= for the one and = for the other, but I was just wondering if it exists.
09:33fliebelThe clojure.core ns is really shallow and wide if you ask me, not easy to find things. Much better the way contrib/java/python are structured.
09:33@rhickeyfliebel: not sure there's anything better than filter and remove for that
09:33fliebelrhickey: Thanks :) I'll use them.
09:34neotykrhickey: Hi, do you think this could make to c.core? http://groups.google.com/group/clojure-dev/browse_thread/thread/bbf34a823f3081d6#
09:35MayDaniel_fliebel: clojure.contrib.seq-utils/separate?
09:36fliebelMayDaniel_: Yay!
09:36@rhickeyneotyk: not with that implementation
09:37neotykrhickey: I would also like to post a ticket with patch to assemba http://groups.google.com/group/clojure-dev/browse_thread/thread/cb6c2a9fe9b20b55#
09:37@rhickeyneotyk: have you sent in a CA?
09:37neotykrhickey: there have been few commits after that, but how do I make it nice so it could come to core?
09:37neotykrhickey: yes
09:38@rhickeyneotyk: Ok, I see you in the list
09:41neotykrhickey: thanks
09:41@rhickeyneotyk: you can't use metadata for that. Also, this is something that has been asked for for futures and delays, so a common API would make sense. Unfortunately, it doesn't make sense for all refs, so needs some care in design
09:42fliebelsplit-with is lazy, right? I'm splitting a line-seq with it, and returning the parts in a lazy-cat, so the first can be accessed without reading adn parsing the second part.
09:42neotykrhickey: why metadata is no go for it?
09:43@rhickeyneotyk: that kind of use of metadata is a hack
09:44neotykok
09:45neotykI will try to find more info about futures and delays in context of check ability
10:19fliebelCan someone explain me briefly how classloaders work in Clojure? I'm loading files form the classpath by using the class of an fn in the same dir, but I'm havin circular imports now. When I use a local fn, I'm somehow unable to find the file. What to do?
10:36fliebelWhat is the difference between DynamicClassLoader and AppClassLoader? The one half of my app seems to be loaded with the one, while the other half uses the other.
10:37fliebelThis prevents parts of my app of getting resources from the cp.
10:48fliebelWell, turns out I can use the dynamic one myself directly to solve the problem. Got to run now. Later
11:04slyrusif anyone's interested in fnparse (or cheminformatics for that matter) I've started blogging my experiences with using fnparse for parsing SMILES strings: http://slyrus.github.com/2010/09/17/parsing-smiles-with-fnparse.html
11:06BahmanWhat's the URL for build.clojure.org index file (maven)?
11:08BahmanGood news...clojure.org is now accessible here with no need to proxy software.
12:05jonasen,(keyword "")
12:05clojurebot:
12:05jonasen^^ is that ok behaviour?
12:07notsonerdysunny->(keyword "")
12:07sexpbot⟹ :
12:07notsonerdysunny,(keyword "")
12:07clojurebotnotsonerdysunny: No entiendo
12:08leafw_is there such thing as a cumulative map?
12:08mrBlissthere is a cumulative reduce called reductions
12:09leafw_I'v ebeen using cumulative map logic for a qwhile now. If the map itself was cummulative, it would be easier...
12:09leafw_aha
12:09leafw_,(doc reductions)
12:09clojurebot"([f coll] [f init coll]); Returns a lazy seq of the intermediate values of the reduction (as per reduce) of coll by f, starting with init."
12:09leafw_that is not clear to me--what does it mean?
12:09Chousukejonasen: no, but it's currently considered an user error
12:09Chousukea*
12:10mrBliss,(reductions + (range 1 10))
12:10clojurebot(1 3 6 10 15 21 28 36 45)
12:10leafw_I see
12:10leafw_but applied to a list of k/v pairs, where some keys are duplicated, will not concat the corresponding vs
12:11mrBlissleafw_: what exactly are you trying to do?
12:11jonasenChousuke: ok, thanks
12:12leafw_I'd like a map that, when assoc, it adds the element wrapped in a set. If the key is already there, conj to that set.
12:12mrBliss,(merge-with conj {:a 1, :b 2} {:a 3})
12:12clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection
12:12mrBliss,(merge-with conj {:a [1], :b [2]} {:a [3]})
12:12clojurebot{:a [1 [3]], :b [2]}
12:13leafw_cool!
12:13mrBlissstill not right ^^ but you get the point
12:13leafw_merge-with may work :)
12:16leafw_just reduced 4 lines of code to "apply merge-with union"
12:16leafw_fantastic :)
12:23leafw_the beauty of chosing the right functions is that the code gets shorter, clearer to read, more explicit as to what it does, and has less points where errors can sneak in. Ah, clojure!
12:44leafw_any advice on debugging monads?
12:45leafw_I find the stack trace doesn't show much, points to the "domonad" line and not within the domonad declaration.
12:56sproustIs there a non-lazy version of map? or should I use (doall (map ...) )
12:56leafw_doall
12:57raekor dorur
12:57raek*dorun
12:57sproustThx.
12:57leafw_,(doc dorun)
12:57clojurebot"([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil."
12:57raek,(doc doseq)
12:57clojurebot"([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."
12:57raekI most often use doseq in that case
12:57sproustI actually need map, but I assign my result to a thread-local binding, so I need to force it.
12:58raekah, then doall looks like the right thing
12:58sproustIt's one of those recursive parsers that accumulates state; better modeled with some state that gets appended to.
12:58sproustLearning more and more about clojure, it seems like there should be a convention for lazy vs. non-lazy variants, e.g. map and map*
12:59sproustPython has the same problem, map vs. imap
12:59leafw_sproust: assume all is lazy
12:59sproustI know, but the non-lazy variants do exist.
12:59sproustWell, some of tehm.
12:59sproustAlso, a similar situation occurs with application, some functions that take a sequence, and some that take varargs, which are otherwise identical.
13:00Vinzenthi. how can I create regexp from string var?
13:01sproustre-pattern
13:01sproust,(re-pattern "(.*)")
13:01clojurebot#"(.*)"
13:01sproust,(re-pattern (format "%%%ds" 2))
13:01clojurebot#"%2s"
13:03VinzentThank you!
13:07leafw_what is the best way to filter a map? I.e. remove some entries, but returning a map? filter returns a sequence that needs (into {} (filter ...))
13:09ohpauleezleafw_: As far as debugging domonad...
13:09ohpauleezYou can just macroexpand it
13:09ohpauleezwhich may make things a little clearer
13:10leafw_ohpauleez: not when there is too much recursion--been there
13:10leafw_hum. I could execute the macroexpanded version
13:10ohpauleezright
13:10leafw_thanks
13:11ohpauleeznp, see if it helps, and I'll ping you if I think of something else
13:15raekleafw_: (into {} (filter (fn [[k v]] ...) m)) ; one way of doing it
13:16leafw_raek: that's how I do it. I was wondering if there is an easier way, like a filter-map or so
13:16raekor, you can use dissoc, if you know which keys you want to remove in advance
13:16Raynesraek: What arrow did you use for trattern?
13:17raekRaynes: "U+21D2 RIGHTWARDS DOUBLE ARROW"
13:18raekand "U+21CF RIGHTWARDS DOUBLE ARROW WITH STROKE" for exceptions
13:18RaynesHrm. Never saw that onew.
13:18Raynesone*
13:19raekit's in the Arrows unicode block
13:19leafw_raek: no, the fn must peek into the value
13:19leafw_it's ok, it's not terrible
15:17alpheusHalfway through _The Joy of Clojure_, and the book really is teaching me new ways to think about programming. I liked the other two I read first, but I'm kind of glad I saved this one for last.
15:19alpheus(the other two Clojure books, if that wasn't clear)
15:33nexhow can I make a struct passing the keys in a list?
15:33mrBliss(apply (partial struct struct-name) [key1 key2...]) is what I do
15:33amalloystruct-map, or apply, depending what you mean
15:37nexwell im parsing a csv, and i want to make a struct-map of all the rows, i have each row in a '( ) and wanted to pass those lists directly to make each of the structs in the struct-map
15:38nex(im testing apply, thank you guys very much)
15:38LauJensennex: perhaps you should check out clojure-csv on github, its quite good
15:48chouserLauJensen: PM, in case you missed it.
16:09arohner,(let [a|b 42] (println a|b))
16:09clojurebot42
16:09arohneris | (pipe) guaranteed to be valid character in symbols?
16:09arohnersimilarly for &
16:10chouserI don't think so.
16:10amalloyi think & is, at least, isn't it?
16:10mrBlissI quote: "Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, and ? (other characters will be allowed eventually)"
16:11mrBlissI could be that & and | will be used for something else later
16:11hiredmanthat list doesn't include < and >, which are used in clojure.core
16:12hiredman< > also look great in Mensch
16:12mrBlisshiredman: I copied it from http://clojure.org/reader#The%20Reader--Reader%20forms
16:12hiredmanI am well aware where it is from
16:13mrBlissthe docs should be updated then
16:14arohnerI'm doing a lot of bayesian statistics, so it'd be nice to write P-a|b. it'd be nice if I could do P(x,y), but I'll settle for P-x&y
16:15hiredmanP′xy
16:15LauJensenarohner: if it ever changes you can fix your code with sed
16:15arohnerLauJensen: true
16:18hiredman,(let [x 1 x′ (inc x)] x′)
16:18clojurebot2
16:19amalloyit's my understanding that collections do fast equality checks by computing their hash at construction time, but i can't find where this is happening in the source. can anyone point me in the right direction?
16:21hiredmanamalloy: I don't think they do it at construction time, they calculate it if asked and then cache it
16:22hiredmanbut I've never looked
16:24arohneramalloy: search for "hashCode" in the java source
16:24arohnerhiredman is right, it's lazy & cached
16:27amalloyhiredman: thanks, i see they're caching the hashcodes now. but where are they getting used? it looks like the equiv/equals methods in eg ASeq and PersistentList just iterate over their elements every time
16:28LauJensenyea I dont recall seeing equiv check the hash, just size, type and then elements
16:29amalloyoh duh. cause seqs can be infinite, so hash would never finish
16:30arohneramalloy: yeah, but = on two infinite seqs would never finish either
16:30arohnerinteresting. That means you can't use an infinite list as a key in a map
16:31amalloyarohner: but (= (range) []) can finish, which it couldn't if you hashed (range) first
16:31arohneramalloy: good point
16:31arohnernote to self. Don't try (.size (range))
16:32amalloy,(let [x (range) m {x 10}] (m x))
16:32clojurebotExecution Timed Out
16:32amalloyaww, really? i thought it could use identical?
16:32arohneramalloy: maps use hash codes
16:33arohnersets too
16:33LauJensen,({(range) 5} (range))
16:33amalloyyeah, i guess they would have to
16:33LauJensen-> ({(range) 5} (range))
16:33clojurebotExecution Timed Out
16:33sexpbotExecution Timed Out!
16:34amalloy,(= (range) [])
16:34clojurebotfalse
16:34amalloywhew. would hate to be wrong about that too
16:35hiredmanin that case you can just do a type check to shirt circuit equality
16:35hiredmanalthough vectors and lists can be equal to each other
16:35hiredmanlists are seqs but seqs are not lists
16:36hiredmanand range produces a seq
16:37amalloyyeah, the type check can't be allowed there
16:37amalloy,(= (range 0 1) [0])
16:37clojurebottrue
16:38LauJensenbut am I correct in stating that the above check will fail in the master branch now?
16:40amalloyLauJensen: i don't know, but i hope not. i thought seqable objects with the same contents were supposed to compare as equal
16:40LauJensenI think the equiv branch changed that
16:41RaynesHeh. Ran out of heap space.
16:45LauJensenRaynes: The bot died?
16:45RaynesLauJensen: I have some pretty tight JVM options in place that I've been trying out. This is the first time I've ever run out of heap space with them. :p
16:46hiredmanamalloy: that is not true
16:46hiredmansequable objects with the same contents do not compare as equal
16:46hiredman,(= (seq {:a :b}) {:a :b})
16:46clojurebotfalse
16:47amalloyhiredman: good point
16:47arohner,(= [1 2 3] (list 1 2 3))
16:47clojurebottrue
16:48arohner,(= {:a :b} {:a :b})
16:48clojurebottrue
16:48arohner,(class (seq {:a :b}))
16:48clojurebotclojure.lang.PersistentArrayMap$Seq
16:49arohner(= (array-map :a :b) (hash-map :a :b))
16:49arohner,(= (array-map :a :b) (hash-map :a :b))
16:49clojurebottrue
16:50arohner,(= [1 2 3] #{1 2 3})
16:50clojurebotfalse
17:21_Vi"Function must be free of side effects because of it can be called multiple times". Does it mean Undefined Behaviour if it has them (for example, if it writes a log message to file) or it just warns you that your side effects may occur more than once?
17:23dnolen_Vi: the later
17:26acts_asQuestion: Are there any posts (or whatever) that talk about some interesting applications for Clojure? IE, cases where it solves a given problem exceedingly well? Or cases where it's less ideal? Sorry, that's a crappy question. I'm really liking Clojure, and I'm just wanting to absorb some opinions/blah before I really start digging in.
17:27acts_asMay or may not be the best way to learn a language, but they usually give me things that I look out for in the language
17:29LauJensenacts_as: I do a lot of different stuff with Clojure on my blog at bestinclass.dk
17:31LauJensenIf you want an example of what Clojure does exceedlingly well, see the Scala Vs Clojure Concurrency post. If you want something its less ideal for, see the Fluid Dynamics post
17:41arohnerman, I wish ints could hold metadata. I really want "typed ints"
17:42arohnerI have two vectors of entirely different objects, and I typically look up values in the vectors. I'd really like to be able to put a type on the ints used to look up items in the vectors, so I don't accidentally use the wrong int to lookup in a vector
17:44raeksomething like SML's datatypes would be interesting. maybe this can be achieved with [:type-tag value] or records, though
17:44amalloy_arohner: why not just use a value,type pair of some kind? map, vector, whatever
17:45arohneramalloy_: I need to use vectors of primitives, for speed reasons
17:46amalloymetadata would slow things down too
17:47amalloyyou could hack something up, like use negative numbers for one of the vectors
17:47amalloythen if you use the wrong int, you'll get an ArrayIndexOutOfBoundsException
17:47arohneramalloy: If we had real escape analysis, the metadata check could be an assert that can be compiled out
17:48_ViIs there a table somewhere that shows similarities and differences between usual variable, ref, atom, agent and other such things (if any)?
17:49arohner_Vi: yes, there's a table. I don't remember where
17:49amalloy_Vi: i know there's one in the joy of clojure. might be one in labrepl, maybe?
17:49_Viarohner, May be all (doc ...) pages about these function should link to it?
17:50_Vi(Looking up what "labrepl" is)
17:56_Vihttp://stackoverflow.com/questions/1028318/clojure-mutable-storage-types "Disclaimer: All of this information is informal and potentially wrong. Do not use this post for gaining an understanding of how Clojure works." Is it really wrong somewhere?
17:58arohner_Vi: vars don't always contain a root binding
17:58arohner(def x) is legal
17:59arohnerhere, x doesn't contain a root binding
18:08arohnerhrm. attempting to eval symbols containing the pipe character completely hoses SLIME
18:13_ViWhat doc page for "atom" does not mention "deref", "swap!" and "compare-and-set!"?
18:16_ViAtom vs Ref vs Agent. "swap!" vs "alter" vs "send". Is there a mnemonic not to confuse them?
18:17amalloyatoms swap a value for another atomically; refs get altered in transactions; you send agents instructions
18:17amalloy_Vi: ^^ best i can do
18:17_ViBut to an atom you also "send" a function.
18:18kumarshantanudoes anyone know if Clojars push works now with Windows?
18:18amalloytry thinking of swap! like apply, with an implicit first argument. then you're not sending atoms functions, you're calling functions on them
18:35arohner,(contains? #{Double/NaN} Double/NaN)
18:35clojurebottrue
18:35arohnerwhat's up with that?
18:37acts_asCtrl+C seems to nuke cake. Is there a shortcut to tell cake to "stop that" sans the seppuku?
18:37arohnernevermind. on the equiv branch, that returns false
18:39acts_asoh wait, cake persists in some deity layer of my computer. blessed am i, for the preservation of my defn is eternal
18:39_ViHave I understood atoms correctly? http://vi-server.org/vi/code/atoms.clj can print "Async" sometimes. Can somebody on SMP system try it?
18:45arohner_Vi: it's a bad idea to use emperical tests on concurrency
18:46_Viarohner, How to really watch that asynchronousity? (BTW does that print "Async" for yours?)
18:47_Viarohner, (For me it doesn't print anything, but I have uniprocessor system that can't do real concurrency here).
18:47arohner_Vi: I'm pretty sure that won't print async
18:47arohner_Vi: why do you think it would?
18:48_Viarohner, Because of main thread can see assignments to a1 and a2 in any order (not in order background thread swap!s them).
18:49_Vi(if a1 and a2 are not close enough in memory to cache them and consider as one unit)
18:49amalloy_Vi: that code is not threadsafe. i don't understand how it's supposed to work
18:50arohnerthere's only one background thread. Those swaps happen 1) atomically and 2) deterministically
18:50_Viamalloy, It is supposed to demonstrate that unsafety.
18:50amalloyas an aside, why (loop [] (let [stuff]))? (loop [stuff]) is equivalent
18:51arohneroh, nevermind
18:51arohneryes, you can read a1 and a2 out of order
18:52arohnerbut it's the reading that causes bugs here. If you replaced the atoms with refs, and then read inside a transaction, you wouldn't see async
18:52_Viarohner, It swaps both a1 and a2. Unlike agents (as I understood from documentation), atoms are not safe when you use multiple of them and expect state-of-both-atoms-considered-as-the-whole consistent.
18:52amalloy_Vi: on my 4-core work computer it prints Async after about ten seconds
18:52arohner_Vi: right. I didn't pay attention to the reads
18:53_Viarohner, Yes, when I see "async" messages I want to change atoms to 1. agents, 2. refs and see that it fixes things.
18:53arohneryou should see async on agents as well, for the same reason
18:53amalloy_Vi: no, atoms are fine for this task, if you use them differently
18:54_Viamalloy, OK. It works for you. ("works" means demonstrates pitfall of naive using atoms on concrete example).
18:54amalloy(def a (atom [0 0])) (future (swap! a #(map inc %)) (recur))
18:55_Viarohner, On agents? Why? Documentation says that agents are synchronised.
18:55amalloygives you an atom of two integers, increasing forever, and always the same
18:55arohner_Vi: where do you see that? Agent values are updated from a threadpool
18:55_Viamalloy, Of course "(swap! a #(map inc %))" will work, as there is only one atom.
18:56amalloy_awayyes. i'm just saying, switching to refs is often overkill; just use your atoms properly to fix the async issues
18:56arohner,(doc send)
18:56clojurebot"([a f & args]); Dispatch an action to an agent. Returns the agent immediately. Subsequently, in a thread from a thread pool, the state of the agent will be set to the value of: (apply action-fn state-of-agent args)"
18:57arohner_Vi: in your example replacing atoms for agents, you still have the unsynchronized read problem
18:57_Viarohner, (Thinking about difference between agents and atoms then)
18:58amalloy_awayarohner is right. the writes are syncronous, but the reads are no more guaranteed than atoms
18:58arohnerusing agents, the writes aren't synchronus
18:59_Viamalloy_away, (thinking how an example that prints "async!" for agents, but stops doing it for atoms can look)
19:00_ViHow the code that naively misuse agents might look? (where atoms are actually needed)
19:16_Viamalloy, Can you please run this: http://vi-server.org/vi/code/agents.clj Expected: "agent" should drop to 0 once, but "atom" should be 1 or 2 indefinitely.
19:17_Viarohner, Is it a good demo for agent vs atom difference?
19:17amalloy,(let [a (agent 0)] (send a #(do (Thread/sleep 1000) inc %)) @a
19:17clojurebotEOF while reading
19:17amalloy,(let [a (agent 0)] (send a #(do (Thread/sleep 1000) inc %)) @a)
19:17clojurebotjava.lang.Exception: No such namespace: Thread
19:17amalloyclojurebot: whatever. _Vi: that will demonstrate misusing agents
19:17clojurebotamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
19:20_Viamalloy, What's wrong with "(send a #(do (Thread/sleep 1000) inc %)) @a" If should print either 0 or 1.
19:20_Vi*It should print
19:20amalloyyes, it should print either. expecting it to always print 1 would be a misuse of agents
19:21_Viamalloy, Atom will also print either 0 or 1.
19:21amalloybet you a dollar?
19:21amalloyor maybe you're right
19:21_Viamalloy, Because of "@a" is a read. And reads are not synchorinsed both for atoms and agents.
19:21amalloyright
19:22_Viamalloy, Please run that code and report if it works. Works means "agent=0 atom=1".
19:22_Viamalloy, The code does the same thing for atom and agent, but they should diverge because of their "atomness" and "agentness".
19:23amalloywon't they just diverge because of read timing?
19:23amalloyneither one seems to be getting to zero, btw
19:24_Viamalloy, Try waiting a bit more. If neither will drop to 0 the more complex racy test is probably needed.
19:24amalloyand i don't see why they would. the agents are queueing up their actions and then using swap! internally just like the atoms are
19:24arohner_Vi: again, emperical tests of concurrency are not sound
19:24_Viarohner, When they signal failure, they sound.
19:25amalloyarohner: they can't prove something is thread safe, but they can prove something isn't thread safe
19:25_Viarohner, Like that test with reading.
19:25arohner_Vi: the agent should never hit 0, because the swaps are deterministic
19:25arohnererr, the atom should never hit 0
19:25_Viamalloy, "the agents are queueing up their actions and then using swap! internally just like the atoms are" So what's real difference?
19:27arohner_Vi: the agent executions happen in a threadpool, async
19:27amalloythe difference is when you call (send) it returns right away. (swap!) blocks until the write succeeds
19:27_Viarohner, Yes. Atom is more synchronised than agent and should "win" this.
19:27arohnerwhat does win mean?
19:27_Viarohner, Means retain consistent value (1 or 2). 0 means that some function is called out-of-order and a signal of failure.
19:28_Viarohner, If that assignments are executed out-of-order for agent, it should drop to 0.
19:28amalloy_Vi: still no zeros. pretty sure there never will be
19:28arohnerright. an agent has a queue of actions to dispatch
19:28_Viamalloy, Why never be? Why is agent weaker than atom then?
19:28amalloyit's not. who said it was? they're just suited for different tasks
19:29amalloy(do (send agent fn) (await agent)) is identical to (swap! atom fn)
19:30amalloyagents give you the ability to keep doing other stuff while they work, without getting out of sync
19:30arohneramalloy: careful. agents actions are not deterministic when receiving actions from multiple threads
19:31arohnereach agent has a queue of actions. Those actions will be executed *in the order received*, in a thread pool
19:31amalloyarohner: atoms are just as nondeterministic across threads
19:31_Vi(thinking of simplest example that would signal synchronisation failure because of misusing agent instead of atom)
19:32amalloyoh, but you mean that you can still get out of sync. yes, agents aren't magic
19:35arohner_Vi: you've read http://clojure.org/agents and http://clojure.org/atoms, right?
19:36_ViYes. (Doesn't mean I've understood completely them)
19:37arohner_Vi: reading the source also helps
19:37arohneranyways, I have to run. Hope you find your answers
19:38_Viarohner, I think building an example that diverge only because of differences between agents and atoms can help even more.
19:44amalloy_Vi: the difference will be timing
19:47_Viamalloy, Also I it is said that sending to a agent from a transaction will not be duplicated (unlike swapping! an atom).
19:48amalloymaybe so. i don't remember
19:48amalloy_Vi: http://malloys.org/~akm/tmp.clj
19:54_Viamalloy, Thanks for the example. So the most differences are on the "caller" side.
19:54amalloyyes. swap! blocks and send doesn't
19:56_ViSo, is it true that agents are more heavyweight than atoms and refs are more heavyweight that agents?
19:56amalloyprobably. not really my area of interest so i dunno
19:57raekatoms could be seen as lightweight refs, at least
19:57raekagents and refs are heavy in different ways, I guess
19:57amalloyraek: yeah, that's what i think too
20:01raekalso, yes. sends within transactions are held until the transaction succeeds
20:01raekthis also holds for sends within agent functions
20:02raekthere is the release-pending-sends function for getting around this, if one need it
20:03amalloy_Vi: btw if you want to do more agent/atom comparisons i've modified the above link to be an easy template function
20:06_Vi"what who stall" What? Who?
20:07amalloysee the doseq
20:07amalloywho/what get bound to ag/send and then at/swap!
20:08_ViI know. Just occasional phrase in the source.
20:09amalloyheh, yeah, it does look kinda funny
20:09_ViIt is the same as before, but shorter.
20:09amalloyyes
20:09amalloyno retyping stuff
20:09amalloyso if you want to test some different behavior set just write it in once
20:09amalloyanyway, off to do some errands
20:23Raynesivey: ohai
20:23iveyRaynes: howdy
20:42kutkuhello.
20:42kutkuI am experienceing some problems when running code in closure:
20:42kutkuerror: java.io.FileNotFoundException: Could not locate examples/introduction__init.class or examples/introduction.clj on classpath: (NO_SOURCE_FILE:0)
20:42kutkuwhat have I done wrong?
20:44raekkutku: how did you start clojure?
20:45kutkutried two ways:
20:45kutku java -cp '/usr/share/java/clojure.jar:/usr/share/java/clojure-contrib.jar' clojure.main
20:45kutkuand :
20:45kutkuexport PATH=/home/admin/.cljr/bin:$PATH; cljr repl
20:45raekyou need to have the example code on the classpath too
20:46raekit is not a part of clojure
20:46kutkuhow do I do that?
20:46amalloykutku: your command line could be shorter, too: PATH=/home/admin/.cljr/bin:$PATH cljr repl
20:47kutkuoh ya that worked too :)
20:47kutkuI am fairly new at this.im really just a web developer
20:48amalloyno worries. most of the unix tools (bash, emacs, etc) have so many features you'll never know them all
20:48raekjava -cp '/usr/share/java/clojure.jar:/usr/share/java/clojure-contrib.jar:programming-clojure/' clojure.main
20:48raekkutku: where programming-clojure/ is the directory containing the examples directory
20:48kutkustupid question: how can I know my programming-clojure examples dir? I can use locate "keyword" but what would be the keyword?
20:49raekkutku: have you downloaded the examples?
20:49kutkuno
20:49coldheadah
20:49coldhead:)
20:49raekhttp://github.com/stuarthalloway/programming-clojure
20:49kutkui want to access the fib series
20:49raekit even comes with a start script
20:50kutkuwhere should I look?
20:50kutkuor should I get all the files?
20:51raekhttp://github.com/stuarthalloway/programming-clojure/raw/master/examples/introduction.clj
20:51raekthere's the file for examples.introduction
20:51kutkuthanks !!
20:51raekkutku: are you following the book or hacking on your own?
20:52kutkuboth.
20:52raekkutku: you can add the examples to cljr's classpath with "cljr add-classpath path/to/programming-clojure/"
20:53kutkui did that
20:53raekthen you will always have that available when you start clojure with cljr
20:53kutkucan I do the same with contrib?
20:54raekI think contrib is included by default in cljr
20:54kutkuim still getting the same error msg.
20:54raekhave you downloaded all the files or just introduction.clj?
20:54kutkuhttp://pastebin.com/5gWKuaUY
20:54kutkujust introduction.clj
20:55raekah, no. you don't add the clj file to the classpath. sorry for not explaining
20:55kutkusorry
20:55kutkuit makes sense now
20:55raekthe namespace is "example.introduction" so clojure will look for examples/introduction.clj on the classpath
20:55kutkuI add the entire programming-clojure dir ofc
20:56raekusually, you don't have to do this kind of stuff manuall
20:56kutkuthen why am I doing it?
20:56kutkuoh shit du e svensk ju!
20:56kutkuhhe :)
20:57raekkutku: #clojure.se :-)
22:13laurusSo I found that someone, vshender, has created a library called clojure-gnuplot: http://bitbucket.org/vshender/clojure-gnuplot
22:13laurusMy question is, how hard would it be to create such a thing for Python with similar syntax, so that matplotlib graphs could be generated from within Clojure with a Clojure-like syntax?
22:16technomancylaurus: you mean an alternative output backend?
22:16laurusYes I think so
22:16laurusThe example I'm referring to is here: http://bitbucket.org/vshender/clojure-gnuplot/src/bcff38db8260/README
22:16technomancyI think that really depends a lot more on the differences between gnuplot and matplotlib than having anything to do with Clojure
22:17laurusWell, my question is, I don't know how the Python "should" look in Clojure :P
22:17laurusI mean, the gnuplot syntax translates somewhat naturally
22:18laurusAnd it only took him 86 lines to make it work
22:18laurusI've only read 4 and a half chapters of _Practical Clojure_ so I don't know enough Clojure yet to tell how hard this would be.
22:22technomancyif you're just generating trees then it should be pretty natural; depends on python syntax you need
22:22laurustechnomancy, the problem is that matplotlib uses objects for its plotting
22:23laurusFor example, http://matplotlib.sourceforge.net/examples/api/histogram_demo.html
22:23laurusSo I have no idea how one would translate that to Clojure syntax