#clojure logs

2009-10-12

04:27LauJensenMorning gents
04:53AWizzArdHi the Lau.
04:57adityoTotally n00b question..in clojure how will i comapre two strings? eg. "Clojure" and "clojure"?
04:59hoeck,(= "Clojure" "Clojure")
04:59clojurebottrue
04:59AWizzArdadityo: http://java.sun.com/javase/6/docs/api/java/lang/String.html#equalsIgnoreCase%28java.lang.String%29
05:00AWizzArd,(.equalsIgnoreCase "cloJURE" "CLOjure")
05:00clojurebottrue
05:00hoeckthose were lower and uppercase C's in "clojure"?
05:01adityoyeah i dont want to Ignore case?
05:02hoeckadityo: then use =
05:03adityookie..is it equivalent to java equals
05:04hoeckadityo: yes, = uses equals under the hood
05:07hoeckadityo: stated in the doc of =, try: (doc =)
05:08adityohoeck: yes i did check it out, thanks :)
05:15triyoI have a string that contains 2 forms "(print (+ 2 1) (print (- 2 1))". The read function seems to be able to read the forms from the Reader however it seems to only grab the first form. Am I missing some iteration spec to get the next form from my string reader?
05:16ambientyou're parentheses are unequal
05:16ambient*your
05:16triyoSorry typo in this message
05:20hoecktriyo: are you using the read-string function?
05:20triyo,(-> "(print (+ 2 1)) (print (- 2 1))" java.io.StringReader. java.io.PushbackReader. read)
05:20clojurebot(print (+ 2 1))
05:20triyoUsing read
05:20triyoAs above
05:20hoecktriyo: read only reads one object at a time
05:21hoeckto read in the whole string, either wrap it into a seq by using iterate
05:22triyoOk I'll try that
05:22hoeckor wrap the string in parens using (str "[" your-string "]") and read that
05:22Chousukedon't forget that read-string exists :)
05:23hoeck,(read-string "first second")
05:23clojurebotfirst
05:23hoeck,(read-string (str "[" "first second" "]"))
05:23clojurebot[first second]
05:26triyoThx hoeck, that'll work for me.
07:12ambientanyone know of the fate of Counterclockwise (clojure eclipse plugin)?
07:12ambientwhere would i get the latest, seems that it only supports clojure 1.0.0 and i need to use a newer platform
07:12ambient~ccw
07:12clojurebotccw is http://github.com/laurentpetit/ccw
07:15ambientnot sure who maintains it and is it even actively developed
07:18rsynnottisn't there another eclipse plugin?
07:21ambientclojure-dev was the original, but it was renamed to counterclockwise
07:31cgrandambient: Laurent Petit (lpetit here) is actually the main developer
07:45AWizzArdI have one agent A and many threads which do (send A foo). foo must not threadsafe. The queue of A helps to serialize my requests. Each thread does the (send A...) and then (await A), to get the result. But now the question is how I can (deref A) so that I will get the result which was produce for the current thread.
07:45AWizzArdWhat I currently do is (let [x (atom nil)] ... (send A foo x) (await A) and have foo writing its result to x, and then I can work with @x.
07:46AWizzArdfoo must not threadsafe ==> foo is not threadsafe
07:47AWizzArdcgrand: is there something like await which also returns the result of the agent?
07:50cgrandAWizzArd: clojure 1.0 or 1.1?
07:50AWizzArda fresh master
07:50AWizzArdso, 1.1 i would say
07:51AWizzArdmy *clojure-version* ==> {:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}
07:51cgrandgood! you can use a promise instead of an atom, thus you'll don't have to await, just @my-promise (it will block)
07:52cgrandor get rid of agents and use futures with you own executor
07:52AWizzArdah okay, never heard of promises before.. is there already a doc page set up?
07:52cgrandI dunno
07:52AWizzArdis the promise the replacement for the agent or the atom or their combination?
07:53cgrandpromises are simple: (def p (promise)) to create, (deliver p value) to set, @p to block and get
07:54cgranddo you _really_ need to proces the returned value on the same thread that dispacthed the action to the agent?
07:55AWizzArdIt is a thread which jetty/compojure opens and which handles the request.
07:55cgrandok
07:55AWizzArdMy processing function may run in parallel, and i want the result in the same thread, so i can generate a response.
07:56AWizzArdThe await makes sure that the thread will wait for the (send ..) which I did just one line above, right? I can not accidently await that A returns from a different thread?
07:57cgrandawait awaits that actions dispatched from the current thread are executed
07:58AWizzArdok good
07:58AWizzArdand btw, what is the advantage of a promise over an atom?
07:58cgrandatom+await ~= promise (in your use case)
07:58cgrandno explicit await
07:58AWizzArdwell, I have a agent+atom+await
07:59cgrandagent+atom+await ~= agent+promise :-)
07:59AWizzArdokay good, I will test that - sounds good
08:00cgrand(let [x (atom nil)] ... (send A foo x) (await A) (do-something @x)) becomes (let [x (promise)] ... (send A foo x) (do-something @x))
08:02AWizzArdyes, I am doing this now, thanks for this tip
08:02AWizzArddidn't know this promise thing
08:05adityohow to convert a string to a number for eg. "2" to 2
08:06eevar2(Integer/parseInt "2")
08:07adityohey thanks eevar2
10:09octehas anyone used clojure-install to set up slime/swank/clojure recently?
10:09octeit seems it sets up the swank-clojure-jar-path variable, but the latest swank-clojure doesn't use it anymore..
10:28ambientis git integration in emacs ok+
10:28ambientor would it be better to use it from command line
10:29ambient(ok this was perhaps too off-topic)
10:30liwpambient: AFAIK there is no git integration in emacs out of the box
10:30liwpambient: there is magit, which apparently works ok, but I haven't tried it myself
10:30noidihttp://zagadka.vm.bytemark.co.uk/magit/
10:31liwpnoidi: have you used it?
10:31noidiI only installed it a few days ago so can't really comment on it yet
10:32froogthere's a good magit introduction video here: http://www.vimeo.com/2871241
10:32liwpI've never used SCM tools from emacs. Some people seem to love the VC-mode integration though. AFAICT it works on a per file basis which seems a bit weird to me, i.e. my commits tend to span more than one file and I'd like those changes to show up as a single commit
10:32liwpbut I've probably misunderstood something...
10:34ambienti'd rather use mercurial but git seems to be de facto standard for open source devs, and gaining momentum a lot faster :/
10:36RaynesGit is the chit.
11:02durka42anybody know why there is no clojure package for debian lenny?
11:04LauJensendurka42, debian :P
11:04durka42i suppose clojure is not considered "stable"
11:15ambientthe same code works from command line "java clojure.main gears.clj" but not from emacs using C-c C-k :(
11:16ambient"could not locate penumbra/opengl__init.class or..."
11:16LauJensenambient, which OS are you on?
11:16ambientvista
11:16LauJensenaha... and you say you're having problems.... :)
11:17ambienti dont have much choice in the matter
11:17LauJensenIs it still the LIBRARY_PATH tripping you up ?
11:17ambienti have no such thing defined in my env vars
11:18LauJensenwe can talk in priv if u need help
11:28chouserhuh, I didn't know this... http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
11:28octei have a vector containing vectors with 2 elements in each one.. i want to create a hash-map from this
11:28octei'm not even sure where to start
11:29chouserocte: (apply into {} your-vector)
11:29chouserwait
11:29chouser,(into {} [[1 2] [3 4] [5 6]])
11:29clojurebot{1 2, 3 4, 5 6}
11:29chouserthere you go -- no apply
11:30octecool, now i'm just wondering what the , does :)
11:30dreishchouser: Not that I'm endorsing double-checked locking, but the first objection they raise doesn't apply if all fields are final.
11:30noidichouser, cool! :)
11:31dreishYou can never see a "pre-initialized" value of a final field.
11:31noidiI ended up with: (into {} (map #(apply hash-map %) [[:foo 1] [:bar 2]]))
11:31noidiplenty of clojure idioms to learn :P
11:31chouserocte: , is whitespace in clojure -- , in IRC tells clojurebot to do it.
11:31octeoh..
11:31octei thought it meant something special
11:31chouserjust here
11:31chouser,(+ 1 2)
11:31clojurebot3
11:33noidi,(conj {} [[:foo :bar] [:baz :blah]])
11:33clojurebot{[:foo :bar] [:baz :blah]}
11:33noidiwow, I didn't know that conj is so flexible
11:33noidi,(conj {} [:foo :bar])
11:33clojurebot{:foo :bar}
11:33noidieh, it wasn't :)
11:34chousernoidi: you understand your first example made a vector key?
11:34noidiyeah, i see it now
11:34chouser,(apply conj {} [[:foo :bar] [:baz :blah]])
11:34clojurebot{:baz :blah, :foo :bar}
11:34chouserbut don't do that. Use into.
11:36chouserThis surprises me a bit:
11:36chouser,(conj {} {:a 1, :b 2} {:c 3, :d 4})
11:36clojurebot{:d 4, :c 3, :b 2, :a 1}
11:38octehttp://pastebin.ca/1615642 <- so this is a good way to do what i want? (parse line with fields seperated by ":" and their key/value seperated by "=" and turn it into a map)
11:38froog,(into {} [[1 2] [3 4] [5 6]])
11:38clojurebot{1 2, 3 4, 5 6}
11:39froogwhat version is clojurebot running?
11:39froogI get: {5 6, 3 4, 1 2}
11:40chouserfroog: map order isn't generally guaranteed, so it shouldn't matter to you which you get. I happen to get the same as clojurebot on latest master.
11:42chouserocte: yep, looks good. you might want to take advantage of #() and the more modern (.method obj arg) interop form
11:43chouserdreish: as it mentions, though, there are more and more reasons it doesn't work. for example is the pointer assignment atomic?
11:43durka42is pastebin.ca dead or is it just me?
11:44dreishLike I said, I'm not claiming double-checked locking is okay.
11:44froogchouser: that makes sense. Still, would've expected the output to have been the same
11:44octechouser: thanks
11:45chouserfroog: yeah, I'm surprised by your output. what version are *you* running? :-)
11:45octe#().. more magic ungoogable symbols ;) (found the docs on clojure.org though)
11:45froogchouser: "1.0.0--SNAPSHOT"
11:45froog,(clojure-version)
11:45clojurebot"1.1.0-alpha-SNAPSHOT"
11:47chouserocte: and even more: ->> can be used here (though not sure if it's better than without it)
11:47chouserthat's not even on clojure.org yet. :-/
11:48chouser,(let [line "version=123:foo=bar:something=moo"] (->> (.split line ":") (map #(vec (.split % "="))) (into {})))
11:48clojurebot{"version" "123", "foo" "bar", "something" "moo"}
11:56froogis 1.1.0 going to be a bugfix release?
11:57morphlinghi, is there a way to get the argument count of a #(...)-created function?
11:58morphlingI found (count (first ((meta #'foo) :arglists))), but that does not seem work on anonymous functions created by #() or (fn)
12:00technomancycgrand: party time!
12:02cgrandmorphling: no, you can't get the argcount of a function. What are you trying to do?
12:03djorkI'm using Aquamacs and it seems like clojure-install from clojure-mode fails to "stick"
12:03djorknot sure why
12:03technomancydjork: did you follow the note at the end of the install process?
12:03djorkI think so
12:03djork(can't remember)
12:04morphlingcgrand: I'm trying to print a truth table for a boolean function, it would be nice you did not have to specify the argcount explicitly
12:05chouserfroog: depends on what you mean I guess -- lots of new features coming.
12:06chousermorphling: you can introspect on the invoke methods of the class created, but it's definitely a hack
12:08cgrandother hack: try to call the function and catch the exception when you call with an unsupported argcount
12:08djorktechnomancy: yup, I missed it :)
12:08djorkthat was easy
12:09djork<3 swank-clojure and clojure-mode... now that it works every time :D
12:10morphlingI actually thought of the latter but it's not worth the hacks
12:10noidi,(doc partial)
12:10clojurebot"([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more]); Takes a function f and fewer than the normal arguments to f, and returns a fn that takes a variable number of additional args. When called, the returned function calls f with args + additional args."
12:10noidimorphling, maybe that could work for you?
12:11noidi,((partial str "foo") "bar" "baz")
12:11clojurebot"foobarbaz"
12:12noidioops, i didn't even understand the question properly
12:12noidimaybe i'll just shut up and call it a day :)
12:25technomancydjork: most of the problems people have are missing that notice... I think I might automate the process of adding it to your config.
12:25djorkit should just be on a separate line, like the "run M-x slime" line
13:03froog,(into {} [[:a 1] [:b 2] [:a 43]])
13:03clojurebot{:a 43, :b 2}
13:37raekhow do I do the dissoc counterpart to assoc-in ?
13:38raeknevermind, found clojure.contrib.core/dissoc-in
13:42ambientso, did anyone at any point complete the translation of Minilight (ray tracing engine) to Clojure?
13:42ambientthere seem to have been several attempts
13:44djorkhmm, it appears that Clojure is not suited to serving up dumb cgi scripts :)
13:45djork(s/Clojure/Java)
13:47drewrnot if you'd like to exceed >1 req/s
13:57funkenblattyeah... wouldn't that have to restart the jvm process every time?
14:04drewrfunkenblatt: yep
14:06chouseryou at *least* need fastcgi or equiv, and it's hard to find a context where that's a better fit than jetty or some other servlet container.
14:07LauJensenfunkenblatt, if your only problem is start/stopping the JVM, just use Nailgun
14:07funkenblattheh... not MY problem per se
14:07funkenblattbut i'll keep that in mind
14:07drewrdo you guys know if there is a fs-backed version of LinkedBlockingQueue?
14:08drewrthinking about writing one, but not sure if it's solving the right problem
14:09drewrI need somewhere to stash data while I process it, but I don't want the heap to fill up
14:09licoresse...
14:11chouserdrewr: seems pretty reasonable. I think several message-passing libs provide disk buffering
14:11chouserexcept I'm probably using all the wrong terminology because I still don't know anything about them. :-)
14:11drewryeah, looks like jms et al have similar func
14:12drewrwanted something lighter weight than that, but it's not a trivial solution
14:24raekI am amazed how simple it is to make a simple event-driven system!
14:24raekhttp://gist.github.com/208575
14:25technomancydrewr: rabbitmq is great at that.
14:25raekclojure is the only language I've been using where my code actually shrinks in size the more I work on it
14:25Chousukeheh
14:25raeknow: begin coding on irc bot
14:25Chousukehack on Clojurebot :P
14:26technomancyclojurebot's nontrivial to set up and hack on. =\
14:26chouserraek: that's pretty tidy. I love how all of the code (except the example usage) could be used as-is on any reference type, not just an agent.
14:28djork"how simple it is to make a simple ..."
14:28djorkit always is :)
14:28chouserraek: depending on how you intend to use it, you might also consider multimethods instead.
14:28djorknow make a complex one :P
14:29raekchouser: in what way?
14:29raekI want to be able to have multiple event handlers
14:30drewrtechnomancy: yeah, we're already using that in our infrastructure, although I wanted to solve this problem inside one jvm
14:31drewrraek: clot has the beginnings of what you want
14:31hiredmantechnomancy: :(
14:32hiredmanclojurebot: be simpler
14:32clojurebotIt's greek to me.
14:32technomancyhiredman: well, at the time I tried it, fnparse was totally nonfunctional.
14:32hiredmanyeah
14:33technomancyprobably has improved since then
14:33hiredmanI have had thought perhaps hitching clojurebot's star to fnparse's wagon was not the wisest move
14:33technomancystill though, until you get the deps situation improved, recommending it for a newbie to hack on is questionable
14:33hiredmanyes
14:38chouserraek: ah, good point -- multimethods are probably not a good fit then.
14:43adityocan anybody provide an example of using sort-by with an comparator?
14:46adityoping
14:46Chousukehm
14:47Chousuke,(sort-by count > [[1] [1 2] [1 2 3]])
14:47clojurebot([1 2 3] [1 2] [1])
14:47Chousukelike this?
14:48adityoyeah, sort-by by default returns in an ascending order
14:49Chousukethe docstring is pretty clear
14:50LauJensenSpeaking of clear, is there some work being put into those backtraces?
14:50adityoyep, it is
15:53ambienthow do i know after which operations i can still use the function lazily?
15:53ambientfor example, does into-array break the laziness?
15:54chouserinto-array is greedy
15:54chouserI think everything lazy says it is.
15:55ambienteg. range doesn't say it is lazy, nor does map
15:59Chousuke,(doc map)
15:59clojurebot"([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls]); Returns a lazy sequence consisting of the result of applying f to the set of first items of each coll, followed by applying f to the set of second items in each coll, until any one of the colls is exhausted. Any remaining items in other colls are ignored. Function f should accept number-of-colls arguments."
15:59ambienti can define oscillators as infinite sequences :))
15:59Chousukethird word. :P
15:59ambienthmm, ok i see
16:08hiredmanif the sequence interface allows it to be lazy, it is
16:08ambient(audiochan-play source (into-array Byte/TYPE (take (msec-samples 500) (sin-osc 440.0)))) this works
16:10ambienti'll see if i can do the whole synth framework lazily
16:10ambientIIR filters might be a PITA thou
16:13funkenblattthere's a recursive sequence thing in clojure-contrib
16:13funkenblattthat'll do IIR filters
16:13ambientsweet
16:16adityohow do i remove all nil's in '(1 nil 3 nil 6 nil nil)
16:17funkenblatt,(filter identity '(1 nil 3 nil 6 nil nil))
16:17clojurebot(1 3 6)
16:17adityo.(doc identity)
16:17Chousukeidentity does nothing :)
16:17adityo,(doc identity)
16:17clojurebot"([x]); Returns its argument."
16:18Chousukea better way would be (remove nil? ...)
16:20adityothanks :Chousuke :funkenblatt
16:26arohnerChouser: I asked this question the other day, but I don't think you were around
16:27arohnerin Clojurescript, how do you determine whether a form is a javascript memeber access vs. function call?
16:27arohneri.e. (. foo bar) turns into "foo.bar()" or "foo.bar"?
16:28Chousukeis clojurescript actually functional? :/
16:30raek,(into {} '([:a 1] nil [:b 1] nil))
16:30clojurebot{:a 1, :b 1}
16:34arohnerChousuke: sort of
16:34arohnerI'm asking because I'm trying to figure out how to handle it in scriptjure
16:34arohnerand javascript cares about the difference between foo.bar and foo.bar()
16:35Chousukedoes it have static fields like java though?
16:35arohnerwhat do you mean by static?
16:36ChousukeI mean, if javascript doesn't need it, maybe you could use the Foo/bar notation to differentiate
16:36arohneryeah, but so far scriptjure's semantics are largely the same as clojure's
16:37arohnerFoo/bar in clojure can be a variable access or a function call
16:37arohnerwhich it can do because it can know the type of bar
16:38arohnerif I want to do that, I have to add a check in the generated code
16:38Chousukehmmh :/
16:39Chousukethe conceptually valid choice would be to require users to write ((.foo bar) args) but that's not very neat
16:39arohnerright
16:43arohnerthe other thing that's interesting is that in javascript, foo.bar could be a function, so you could want to return the function. you can't do that in Clojure, so that's something else I have to worry about
16:45Chousukehm
16:46lpetit,*clojure-version*
16:46clojurebot{:interim true, :major 1, :minor 1, :incremental 0, :qualifier "alpha"}
16:46ChousukeI really can't think of any other way than restricting (.foo bar) to be field access only
17:49itistodayis it possible to create lexical closure with 'with-local-vars'?
17:49itistodayi.e., I'm trying to see if it's possible to avoid using atoms to create a counter-generator. no practical reason, just an exercise
17:49itistodaythis is what i have so far:
17:49itistoday(defn new-counter [] (with-local-vars [a 0] (fn [] (var-set a (inc @a)))))
17:49itistodayand it doesn't work
17:51itistodayyes, i know that code is probably in terrible form ;-)
17:56ambientis there a way to polymorphically handle sequences and numbers (floats, integers, etc..)? like (* 10.0 (repeat 5.0))
17:57ambientvectors and matrices wouldbe gravy
18:05morphlingambient: (map (partial * 10.0) (repeat 5.0)) ?
18:05ambientthe point is that i dont want to use map
18:06ambientbecause im using map on every damn line :/
18:06ambientif * / + - would be polymorphic, my code size would dramatically lessen
18:06morphlingah
18:06ambientand all basic functions that work on one numeric input
18:06ambientlike sin, cos etc
18:07ambientperhaps i should write equivalent macroes that just wrap all numbers to (repeat foo)
18:10ambientsimple frequency modulation looks like this: (take 15000 (sin-osc (map + (repeat 440.0) (sin-osc (repeat 100.0)))
18:11ambientwhen it could be (sin-osc (+ 440.0 (sin-osc 100.0)))
18:16itistodayis it possible to create lexical closure with 'with-local-vars'?
18:17itistodayi.e., I'm trying to see if it's possible to avoid using atoms to create a counter-generator. no practical reason, just an exercise
18:17itistodaythis is what i have so far:
18:17itistoday(defn new-counter [] (with-local-vars [a 0] (fn [] (var-set a (inc @a)))))
18:17itistodayit doesn't work though (java.lang.IllegalStateException: Var null/null is unbound.). Yes, I also know that it's probably in bad for, but i was just wondering if it was possible
18:18itistodayit could be thread-safe though if the function were only used in a single thread :-)
18:19Licenser_itistoday: everyting is thread safe when only used in a single thread :P
18:20itistodayLicenser_: indeed, and that's kinda an interesting point, because Clojure doesn't seem to offer optimizations for that case...
18:20Licenser_I know, but it
18:20Licenser_I know, but it's a tradeoff for the fact that we get thread safety for most of everything for no extra work ;)
18:22itistodayit would be cool though if you could bind a function, or an "instance" of a function to a specific thread. that would be a neat optimization, and a sort-of "best of both worlds" approach i think
18:22itistodaybut i have a feeling that the mindset of clojure is "we don't want you shooting yourself in the foot accidentally"...
18:23itistodayit might be possible to ensure thread-safety though. sortof how you can't use set! except in (binding ..)
18:23technomancyyou can use alter-var-root outside of binding, but it's almost always the Wrong Thing to Do.
18:24itistodaytechnomancy: thanks, didn't know of that function
18:24itistodaywhy then are there atoms?
18:24danlarkinunless you're using with-alter-var-root!!!
18:25itistodaythat's another thing i'm having difficulty understanding, is the point of atoms
18:25itistodayor perhaps the point of vars.
18:25itistoday(i.e. use atoms everywhere instead of vars)
18:27gbji love with-alter-var-root!!
18:27danlarkingbj: you would!
18:27itistodaywhat is the reasoning to have atoms and vars as opposed to just one of them?
18:28danlarkinitistoday: vars are threadlocal
18:28itistodaydanlarkin: what about vars bound to the root?
18:28itistodaywith def?
18:29itistodayare they threadlocal?
18:29kib2Hi; is there any way to repeat a string a given times ?
18:30itistodayquiet day?
18:31danlarkinwell it's more nuanced than vars just being threadlocal
18:31itistodaykib2: (repeat 4 "foo") ?
18:31danlarkinbindings are thread local
18:31itistodaysure, bindings are threadlocal, but does that make vars threadlocal? i don't think they are
18:32kib2itistoday: so simple! I was looking for java solutions! thanks.
18:32itistodayand as technomancy pointed out, you have alter-var-root
18:32itistodaywhich seems very similar to set!
18:32itistodayrhickey: taskete! save me!
18:33technomancydude.
18:33technomancyno offense, but I think Rich has more important things to do than explain this to you.
18:33danlarkin+1
18:33itistodaytechnomancy: probably, couldn't hurt to ask though?
18:34itistodayif he didn't want to be bugged would he be on this channel?
18:34itistoday:-)
18:35chouservars are what namespaces intern
18:35danlarkinevery time rich answers a question in IRC he's not accepting technomancy's patches :)
18:35chouserhehe
18:36itistodaychouser: i guess i'm asking, why have vars and atoms? why not just have one of them? and aren't symbols interned, not vars?
18:37chouseritistoday: symbols are not interned
18:38itistodaychouser: i'm reading through clojure.org/vars and i don't quite get it
18:38chouseritistoday: a namespace holds a bunch of named vars because that provides useful semantics for named globals with optional thread-local dynamic scope
18:39chouseratoms provide no thread-local or dynamic scope, but use fast CAS to make changes to the value they store.
18:40itistodaychouser: and they are also not named...?
18:40itistodayand by that meaning they are not "interned"?
18:40chouserthat's true, though the fact that vars know their own name (if any) may be more of an implementation detail.
18:41octeis there a repository for clojurebot's code?
18:41itistodaychouser: i suppose being more anonymous does give them a unique use
18:42itistodaychouser: and the fact that vars, unlike atoms, can be used with 'with-local-vars'
18:42chouseritistoday: interned I think in this case means that there is a single place for each named var -- if you do (def foo) two different times in the same namespace, there will still be only the one var
18:42chouserwith-local-vars is how you can create anonymous vars -- an *extremely* rarely used feature afaik
18:43itistodayahhhh, so both atoms and vars can be anonymous
18:43itistodaybut vars... unlike atoms, can be "non-anonymous"... eh...
18:43itistodaymy head hurts
18:43itistodayi guess the main thing is that atoms are always global
18:43itistodayor rather, always "shared data" CAS stuff
18:44itistodayand vars are less likely to be mutated
18:44itistodayand can be local
18:44itistodaychouser: get-var/set-var do not use CAS, correct?
18:44chouseritistoday: correct -- I believe they use a lock on the var
18:45itistodaya lock??
18:45technomancyitistoday: clojure existed for quite some time without atoms... if you're just getting started it would probably be easier to just ignore them and focus on refs and functional code first.
18:45chouser,(.sym (var *print-length*))
18:45clojurebot*print-length*
18:45chouser,(with-local-vars [x 5] (.sym x))
18:45clojurebotnil
18:45itistodayneat
18:45itistodaychouser: are you sure they use a lock?
18:45chouseritistoday: so there is a named vs. an anonymous var
18:45itistodaywhy would they use a lock?
18:46chouseritistoday: just for you, I'll check.
18:47danlarkinitistoday: clojure itself has lots of locks. The point is that it has them so you don't have to
18:47itistodaychouser: sorry, you don't need to trouble yourself for me
18:47itistodaychouser: but if you do i'm thankful!
18:47danlarkinwell let me rephrase that... not "lots of locks", but it uses locking
18:47chouseritistoday: var-set is thread local, so there are no locks or anything there.
18:48itistodaychouser: that's what i thought, which is why i was shocked when you said it
18:48chouseritistoday: alter-var-root is a sychronized function, so it's essentially a lock.
18:48itistodaychouser: that's also good to know... although i think someone said it was CAS
18:48chouseratom is CAS
18:49chouserif it helps, here's how I think of them...
18:49chouservars are how you build up the global definition of your program, but using them to store functions and configuration type values in namespaces.
18:50chouseron rare occasions it's useful to give a particular var a thread-local binding, perhaps to tweak the definition of a function or adjust one of those config values
18:51chouserthey can be used in other ways, but it's hardly ever a good idea
18:51chouserI would not recommend storing any of your applications actual state in a var, for example.
18:52chouseratoms on the other hand are the very simplest way to store application data
18:52itistodayinstead store it in an atom? or a ref?
18:52chouserright, or an agent
18:52itistodaygotcha
18:53ambientanyone know how i could make this into an actual infinite sequence? http://paste.pocoo.org/show/144606/
18:53ambientseems that (iterate inc 0.0) can't be infinite
18:53ambientat least performance wise
18:53chouseralthough both atoms and vars overlap in a subset of their technical feature support, I've never had any trouble choosing between the two for any particular purpose.
18:54itistodaychouser: thanks, that helps a bit
18:55chouserambient: few things have infinite performance
18:55chouser:-)
18:55chousersorry, I guess I don't know what you're asking.
18:55ambientwhat i meant that eventually it will jump into bignums and the program will DIE
18:55chouserah
18:55itistodaychouser: the other day Chousuke helped me with a function i was trying to write, here it is: (defn new-counter [] (let [a (atom 0)] (fn [] (swap! a inc))))
18:56ambientbecause oscillators are by definition looping inside a defined waveform, im just trying to find out how to do an infinite stream of sin oscillator
18:56ambientwhich can be modulated by frequency
18:56itistodaychouser: (defn c (new-counter)) (c) => 1 (c) => 2, etc. Is there a way to do that instead with with-local-vars or is that not possible?
18:56itistodaychouser: i.e. i tried this and it failed: (defn new-counter [] (with-local-vars [a 0] (fn [] (var-set a (inc @a)))))
18:57chouseritistoday: right, vars aren't for that.
18:57ambientperhaps i should give up this stream based approach and just start managing global state :|
18:57chouserambient: wait wait
18:57chouser:-)
18:57itistodaychouser: k, thanks!
18:58chouserambient: could you use bignum for all of them?
18:59ambienti'd rather not use bignum anywhere, because afaik it kills performance
19:00ambienthere's the full app. im not sure my approach is the right one http://paste.pocoo.org/show/144608/
19:00chouserwell, at some point your float is going be out of precision such that adding 1 to it wouldn't produce any different number if it were still a float.
19:00chouserwhat would you like it to do at that point?
19:01ambienti just want to loop between 0 and PI * 2
19:01ambientbut twisting my brain around how to do that with streams, especially with phase and frequency modulation is just too much
19:02itistodayambient: what does the function (or macro) 'do' do? i couldn't find it in the api
19:02itistoday(looking at your paste)
19:03ambientit does, sequentially
19:03ambient:p
19:03itistoday,(doc do)
19:03clojurebotPardon?
19:03itistodaywhy isn't it in the API?
19:03chouseritistoday: do is a special operator, like if
19:04itistodaychouser: ah, ok. hopefully i'll stumble upon an explanation on the clojure site
19:05itistodayfound it: http://clojure.org/special_forms
19:05chouseritistoday: http://clojure.org/special_forms#do
19:05chouser:-)
19:05itistodayhehe :-)
19:05itistodayit's like prgn?
19:05itistoday(or 'begin' in other languages)
19:05chouserambient: do you need to be able to change the frequency during the course of the oscillation?
19:05ambientchouser yes
19:07itistodayambient: sorry to bother, but if 'do' is like begin/prgn, why do you use it in audiochan-close/audiochan-play? doesn't defn allow you to not use it?
19:07ambientitistoday yes, probably
19:07itistodayambient: ah k, just wondering, guess it's a matter of style
19:08ambientnah, it's completely redundant
19:08itistodayi wasn't going to say it ;-)
19:08ambientyou're not clearly finnish
19:08itistoday:)
19:14ambienti think there's no going around it, oscillator has to have state
19:14chouserambient: how will state help?
19:14ambientit will define at which point the oscillation is
19:14ambientwhich can then be phase modulated, and checked against limits
19:14chouserambient: personally, I'd try bignum first since it's so easy. if the performance is unacceptiable, then take another look.
19:17ambientwith state i can just do new_phase = (old_phase++)%256 in some old arcaic language, which keeps the oscillation inside 0..255
19:17ambientoops ++old_phase
19:18ambientimmutability has corrupted my mind. it's phase = (++phase) % 256 of course
19:18chouserah, that kind of "state" isn't so bad -- you can still use that to produce a lazy seq and therefore remain purely functional.
19:19ambienthmm i dont know how
19:19chouserseq-utils/reductions is one way to produce a lazy seq where each new value depends on the previous value.
19:19ambientbecause i have to modulate the phase delta
19:19ambientok i'll check that out
19:19chouserbut in this case it's probably easiest to use the lazy-seq macro directly
19:20chouserI hope lazy sequences themselves aren't too slow for your application.
19:20ambientyeah, we'll see
19:21itistodaywhat happened to lazy-cons?
19:21chouseritistoday: gone the way of all dinosaurs
19:21funkenblattsleeping with the garbage collected fishes
19:21itistodayis lazy-seq its replacement?
19:21chouserambient: have you used lazy-seq directly?
19:21ambienti think once, a month ago
19:22ambient:p
19:22chouseritistoday: http://clojure.org/lazy ...except what is future there is now past
19:22itistodaychouser: thanks
19:23chouserambient: one technique would be to write your function as a infinitely recursive loop
19:23ambientyeah i was thinking about that too
19:23chouser(defn foo [i] (prn i) (foo (inc i)))
19:24chouser...that prints your new values.
19:24chouserthen you can transform that into a lazy seq
19:24chouser(defn foo [i] (lazy-seq (cons i (foo (inc i))))))))) ; lost track of parens
19:25itistodayambient: is your code somewhere? i'd love to see the finished version when it's ready
19:25itistodayambient: just tried, sounded cool
19:26ambientwell all the synth code is in the paste
19:26itistodayambient: just wondering if you had it up, i.e. github or something like that
19:27ambientits on bitbucket but i'd rather not yet publish it anywhere
19:27itistodaymmk
19:31chouserAudio Device Unavailable ...my java audio setup must be completely broken and I just hadn't noticed before.
19:31ambientthere might be some type hints missing
19:31ambienti stopped debugging when mine started working
20:08octei've been reading up on concurrency-stuff in clojure and i'm kind of understanding how to deal with concurrent access to data objects, but what about sharing non-data non-threadsafe objects, like an OutputStream?
20:12chouserwell, you've got to be careful. :-/ Often one nice way to handle an output stream use an agent to control access to it, so threads can send-off write functions to it.
20:14octeok, i was thinking about agents but i wasn't sure that it "fit"
20:14octei'll try it
20:16itistodayin http://clojure.org/lazy, why does he say use 'rest' instead of 'next' here: (lazy-cons (f (first coll)) (map f (rest coll)))))
20:17itistodayall that's said is "if consuming another seq, use rest instead of next", no clear explanation given
20:18itistodayerr, rather, i copied the wrong code (from the old way)
20:18itistodaythis is the one i'm referring to: http://paste.pocoo.org/show/144619/
20:18itistoday(copied from "The new way")
20:20rhickey_itistoday: using next would make it eager by one
20:20chousernext never returns an empty collection, but nil instead. This can be handy, but it means the next step of the lazy seq is forced so sometimes it's inappropriate
20:22itistodaydoes not compute
20:22itistodaysorry :-(
20:23itistodayi'm trying to understand this in terms of cons
20:23itistodayor rather... one sec
20:23rhickey_itistoday: it's not about the cons, but the args to cons, you'd be forcing the second arg (if it was lazy) by using next
20:24rhickey_(next x ) === (seq (rest x))
20:25itistodaydo i understand correctly...
20:25itistodayrest returns a delay
20:25itistodayand next does not?
20:25itistodayor rather, next forces the delay returned by rest?
20:26octechouser: i guess another alternative is to use something like a shared threadsafe queue object?
20:26octethat something reads off and sends off on the OutputStream..
20:26chouserocte: yes, that can work well. a BlockingQueue perhaps.
20:31chouseritistoday: a delay is something else specific. but if x is (cons a (lazy-seq ...)) then (rest x) doesn't force the lazy-seq while (next x) does.
20:33itistodaychouser: thanks, i think that helps a bit
20:33itistodayi'm playing around with the repl, hopefully that'll help clear up my confusion
20:33itistodayi think the problem is that i'm thinking in terms of streams
20:33itistodaywhat does lazy-seq do?
20:34itistodaynm.. reading the docs...
20:35itistoday,(doc first)
20:35clojurebot"([coll]); Returns the first item in the collection. Calls seq on its argument. If coll is nil, returns nil."
20:35itistoday,(doc next)
20:35clojurebot"([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."
20:36itistoday,(doc rest)
20:36clojurebot"([coll]); Returns a possibly empty seq of the items after the first. Calls seq on its argument."
20:37itistoday,(doc seq)
20:37clojurebot"([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable."
20:38ambienthow do i generate infinite seq of random numbers? (take 10 (repeat (rand))) print out just one number for each run
20:39chouserrepeatedly
20:39funkenblatt,(take 5 (map rand (repeat 1)))
20:39clojurebot(0.7265724927209442 0.3998850009265046 0.008882990808162017 0.1862657057261602 0.2660922579606133)
20:40funkenblattthere's probably a better way than that, but that's what came immediately to mind
20:41ambient(take 10 (repeatedly rand)) seems to work :)
20:41itistoday,(take 10 (repeatedly rand))
20:41clojurebot(0.7418891709881609 0.5002349453871904 0.6923304956080272 0.23683099175381928 0.6196438692623625 0.5261268340502978 0.4262760865021553 0.1628545274801868 0.8089272143742726 0.9269205296576724)
20:41funkenblattoh standard libraries
20:42funkenblattcoming from scheme i'm totally used to not having any
20:43itistoday(defn rand-seq [] (lazy-seq (cons (rand) (rand-seq))))
20:43itistodaythat works too
20:45ambienti'm wondering if i can keep a short ring-buffer inside a lazy-sequence
20:45tomojitistoday: that's exactly what repeatedly does :)
20:45ambientloop/recur can be used to maintain some sort of state but dont know if it works with lazy-seq
20:46chouseryou want something other that 'cycle' I guess?
20:46itistodaychouser: check this out:
20:46itistoday,(rest (cons 1 (lazy-seq (println "foo"))))
20:46clojurebot()
20:46itistoday,(next (cons 1 (lazy-seq (println "foo"))))
20:46clojurebotfoo
20:46chouserring-buffer sounds mutable -- not a good idea for a lazy seq
20:47itistodayillustrating your point right?
20:47itistoday,(seq (rest (cons 1 (lazy-seq (println "foo")))))
20:47clojurebotfoo
20:47ambientchouser perhaps ring-buffer is not the right term, values that depend on the previous values
20:47ambientand roll-around depending on conditions
20:47chouserambient: yeah, you can do that with lazy-seq
20:47hiredmanyou can implement a ring buffer with a vector and an index to the currect position in the vector
20:48hiredmanall very immutable
20:48itistodaychouser: so, clojure isn't helping me here
20:48itistodaychouser: i see that that happens, but i still don't know why
20:48itistodayi guess i'm trying to figure out how 'seq' forces it
20:49itistodayas well as, what is returned by this: (rest (cons 1 (lazy-seq (println "foo"))))
20:49steigerwhy can't multimethods have '?' in their name? i always get: don't know how to create ISeq from: Character
20:51hiredmaneh?
20:51hiredmanpastebin
20:51itistodaytomoj: gotcha: (defn rep [f] (lazy-seq (cons (f) (rep f))))
20:52steigerhmm, seems it has nothnig to do with '?'
20:53tomojitistoday: yup, that is exactly the source of repeatedly
20:53steigerhiredman: http://paste.lisp.org/display/88563
20:54itistodayi won't wrack my head about this a anymore
20:54itistodayi blame the documentation
20:55itistodaywill just take hichey's word on it
20:55rhickey_,(doc lazy-seq)
20:55clojurebot"([& 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."
20:56itistodayrhickey_: "i guess i'm trying to figure out how 'seq' forces it", and "what is returned by this: (rest (cons 1 (lazy-seq (println "foo"))))" ?
20:57rhickey_how seq forces it? you can read the source
20:57rhickey_what does how matter for understanding the use?
20:57itistodaygood point
20:57hiredmansteiger: and the exception?
20:58rhickey_LazySeq.java has the gory details
20:58steigerhiredman: Exception in thread "main" java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Character (graphutilsNew.clj:9)
20:58itistodayrhickey_: thanks
20:58steigersorry, forgot to paste it to pastebin
20:59hiredmanhuh
20:59hiredmanoh
20:59hiredmandefmethod's don't take docstrings
20:59steigeroh
20:59steigeryeah
20:59steigerjust noticed that
21:00steigerthat's odd, it feels very natural to put docstrings in defmethods
21:01hiredmanhow would you read the docstring?
21:01clojurebotwith style and grace
21:01hiredman~botsnack
21:01clojurebotthanks; that was delicious. (nom nom nom)
21:01itistodayhow would you read the docstring?
21:02itistodaydamn bot
21:02steigerhiredman: how would i read? using (doc) ?
21:02hiredmansteiger: but how would you pick out the particular method's docstring?
21:03itistodayhow would you ______? => "with style and grace" chance of 5%?
21:03steigeroh. i see the dilema, hiredman
21:03hiredman~literal [?] how
21:03clojurebot1
21:03hiredman~literal [1] how
21:03clojurebotIt's greek to me.
21:03hiredman~literal [0] how
21:03clojurebot<reply>with style and grace
21:04itistodayneato
21:04hiredmanand clojurebot has a 1/100 chance of treating any line not addressed to it as addressed to it
21:04itistodayah, thanks, good to know
21:04steigermaybe it should print all avaliable docstrings, i don't know. anyway, eliminating the possibility of having a docstring doesn't feel right
21:04itistodaywhy not put it in the defmulti?
21:05steigerdefmulti supports it, right?
21:05itistodayi've no idea
21:05steigeritistoday: yeah, that's what i thought
21:05steigerit supports it
21:05itistoday:)
21:05steigerhm. weird.
21:05steigerok, i'll put it in the defmulti
21:05hiredmanyou have to use the whole #^{:doc "foo bar"} stuff, if I recall
21:06steigerhiredman: it compiled nicely with the friendly syntax
21:07steigeri.e, after defmulti and the name
21:32steigerwhat's the cleanest way to check if a vector contains an item?
21:33tomoj,(.contains ["foo" "bar" "baz"] "bar")
21:33clojurebottrue
21:33steigerthankyou tomoj
21:33tomojof course it's slow
21:33hiredmaneh?
21:34hiredmanright
21:34steigeri see
21:34steigermaybe i should use hashmaps.
21:35hiredmanwell, key looks up would be fast, but not value lookups
21:36steigeri gotta think.
21:36tomojkey lookups in this case are really just checking whether the vector is at least that long, right?
21:36tomoj,(contains ["foo" "bar" "baz"] 2)
21:36clojurebotjava.lang.Exception: Unable to resolve symbol: contains in this context
21:37tomoj,(contains? ["foo" "bar" "baz"] 2)
21:37clojurebottrue
21:39arohner,(some #{:foo} [:bar :foo :baz])
21:39clojurebot:foo
21:39arohner,(some #{:bogus} [:bar :foo :baz])
21:39clojurebotnil
21:39arohnerof course, that's a linear scan
21:39arohnerif you want sublinear, use a map
21:39tomojor a set, no?
21:40arohnertomoj: yes
22:12ambient,(take 10 (rec-cat fibs [0 1] (map + fibs (rest fibs))))
22:12clojurebot(0 1 1 2 3 5 8 13 21 34)
22:14tomojis that new? I don't have it
22:14ambientclojure.contrib.seq-utils
22:15tomojah
22:15tomojsweet
23:41durka42can clojureql do persistent connections?
23:52tomojdurka42: not yet, I believe
23:52tomojbtw, coi
23:52durka42coi lojbo
23:53tomojthere's some discussion about it on the lighthouse
23:54tomoji mi gleki lonu lo lojbo cu pilno la klojur
23:54durka42ie la klojur cu logji
23:56tomojui ji'a melbi