#clojure logs

2009-07-30

00:11JomyootAnyone uses BBEDIT?
00:32mebaran151any hack to assign metadata to a java object
00:32mebaran151it would be extremely convenient in this one case
02:23Fossi1freakin damn lazyness
02:23Fossi1it got me *again*
02:23RaynesFossi1: In order to beat the lazy, you must first, think like the lazy.
02:24RaynesKick your feet up, grab a remote and a cup of coffee and put your hands behind your head for an hour or too. Once you have done this, you will be ready.
02:25_mstwhen someone asks you to do something, just immediately say "Yep, done". Then when they actually want to see the work start madly scrabbling...
02:25_mstpeople will respect you for it :)
02:26Fossi1hell, i can think lazy ;D
02:27Fossi1normally it's called procrastination though
02:30albino_mst: I like that advice
02:30Fossi1lisppaste8: url
02:30lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
02:31lisppaste8Fossi pasted "ref trouble" at http://paste.lisp.org/display/84421
02:32Fossi1when i call this, i get [ref{} ()] back, then when i run *1 on the repl again, ref suddently has a value
02:34hiredmanare you sure you want commute there?
02:34Fossi1could be ref-set, i don't care what color it is, if i have 2 such events
02:35Fossi1just why does the ref change after the dosync is done?
02:35Fossi1because everything around it is lazy?
02:35Fossi1do i need to doall the map?
02:35hiredmanyeah
02:36hiredmanyou might just put (vec left-events) in the returned pair
02:38Fossi1ok, i'll try
02:45Fossi1ok, didn't help much with my error, i'll have a look later
02:45Fossi1off to more professional clojure ventures ;)
02:45Fossi1bbl
03:32lbjTop of the morning gents
03:44AWizzArdHi lbj
03:49lbjAny interesting new developers in Clojureland lately? (disregarding new new entirely)
03:50lbjhehe, developers = developments
03:52Chousukewell, the new forkjoin stuff looks promising, and "batch mode"
03:52lbjWhat are they?
03:54lbj@ Chousuke
03:54Chousukehttp://paste.lisp.org/display/84027 <- automatically parallelised vector operations and http://paste.lisp.org/display/84027 (no timing data there though) :/
03:55ChousukeI wonder which branch the batch stuff was in.
03:56lbjInteresting - Does vec then determine wether or not the task at hand is suited for paralization ?
03:56Chousukevec does nothing different. it's pvreduce and pvmap that do the parallelisation
03:58Chousukerhickey says he has a quad core machine, so the results are rather impressive.
03:58lbjIndeed
03:58ChousukeI have a dual core and wasn't able to get 2x improvement :/ I suspect my memory is a bottleneck
03:58lbjBut if you replace vec with pvreduce, what would the answer to my question be?
03:59Chousukepvreduce always divides the work I think
03:59lbjThere's a certain threshold before which paralization would only slow the process down with scheduling. If this is automated it has to be aware of that somehow
04:00Chousukethe batch mode stuff is also interesting; it allows you to get a local "mutable" version of a collection for cases when you know you will be doing lots of modifications in one go and don't need the intermediates.
04:00Chousukelbj: it's not that far automated :)
04:01Chousukeregular reduce and map will remain (the pv* stuff is not lazy anyway)
04:05Chousukelbj: There's also the chunked seqs branch, but you may have already heard of that :)
04:06lbjThat I'm familiar with
04:18Chousukelbj: I hope this doesn't explode your ERC
04:18lbjThanks friend - I actually got one of those cool Jaunty notifications :)
04:19lbjNow I just need to work out the hook for private msgs, seems thats handled differently
04:26blbrown_winmorning
04:26lbjMorning :)
04:37blbrown_winI wish I got paid for the work I did outside of work
04:38hiredmanheh
04:39RaynesI wish I got paid for the work that hiredman does outside of work...
04:39blbrown_winnice
04:39blbrown_winme too
06:00angermanI have two vecotrs, the first one consists of bools and has exactly one set to true. The second one has values.
06:00angermannow I want to get the value that corresponds to the true item
06:01angermanany ideas?
06:01angerman,(let x [true false false] y ["a" "b" "c"] (for [x x y y :when x] [x]))
06:01clojurebotjava.lang.IllegalArgumentException: let requires a vector for its binding
06:07jdz,(mapcat (fn [x y] (when x (list y))) '[true false false] '["a" "b" "c"])
06:07clojurebot("a")
06:07angerman,(:true (zipmap [:true :false :false] ["a" "b" "c"])
06:07clojurebotEOF while reading
06:07angerman,(:true (zipmap [:true :false :false] ["a" "b" "c"]))
06:07clojurebot"a"
06:07angermandoes not feel right :/
06:08lbjangerman: Why are you using a vector?
06:08angermanlbj: ?
06:09hiredman,((comp second first (partial filter first) (partial map vector)) '[true false false] '["a""b" "c"])
06:09clojurebot"a"
06:10lbjangerman: It sounded like a job for a map, but anyway, merge the two, maybe applying partition 2
06:10hiredman,(zipmap '[true false false] '["a" "b" "c"])
06:10clojurebot{false "c", true "a"}
06:10hiredman,((zipmap '[true false false] '["a" "b" "c"]) true)
06:10clojurebot"a"
06:10hiredmanI think I win
06:10angermanhiredman: ahh, right
06:10angermanhiredman: :) I tried (true (zipmap ...)) and that didn't work
08:45lbj...
10:51dysingermoing!
10:53cgranddysinger: shhh everybody is asleep
11:26Drakesonhow would you find the element in a list that has the maximum value of a function of the element? (reduce max (map f coll)) only gives you the maximum value, not the one that maximizes f.
11:28stuartsierraI think there's a contrib fn that does that
11:28rhickey,(doc max-key)
11:28clojurebot"([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest."
11:29Drakesonthanks :)
13:09rhickeynew new branch is up
13:10stuartsierracool
13:10rhickeystill work in progress, but can create new instances - all method need full type hints (missing hint means Object)
13:11rhickeywill eventually try to match superclasses' sigs
13:11rhickeydoes accept non-interface superclass with no-arg ctor
13:12rhickeyprimitives can flow in and out
13:12rhickeyno indirection on method calls
13:13rhickey(new [super? interfaces*] thisname? {:flags :here}? (methodname [args] body)*)
13:14stuartsierra"thisname" is a class name?
13:14rhickeyhints are metadata on method and arg names
13:14rhickeystuartsierra: no, the name of this object, usually this
13:14stuartsierraah, ok
13:16rhickey(defn foo []
13:16rhickey (let [y (int 17)]
13:16rhickey (new [Object clojure.lang.Seqable] this {:foo :bar}
13:16rhickey (#^String toString [] "foo")
13:16rhickey (#^int hashCode [] 42)
13:16rhickey (#^int baz [#^int x] (+ x y))
13:16rhickey (#^clojure.lang.ISeq seq [] (seq ["woo hoo"])))))
13:17Chousukeare the flags purely for the compiler or can you access them somehow?
13:18rhickeyChousuke: flags go in bitbucket right now
13:18Chousukeheh.
13:20stuartsierraSo this returns an instance of a new dynamically-generated class, which is not a proxy, correct?
13:20rhickeyright
13:20rhickeyshould be much faster than proxy
13:20stuartsierraGotcha.
13:20stuartsierraAnd it is not intended to replace gen-class for statically-named classes?
13:20rhickeynot right now
13:20stuartsierraok
13:20duck1123will this replace proxy, then?
13:21rhickeyduck1123: most usage will move to this, but not removing proxy
13:21rhickeyproxy does support some dynamic fiddling which this won't
13:22rhickeynot much used afaik
13:22stuartsierraRight, this "new" creates a class which cannot be changed, correct?
13:22rhickeyright
13:22stuartsierraI didn't realize proxies could be changed.
13:22rhickeybut the enclosing 'factory' fn can, since no one depends on the name of the generated class
13:23rhickey,(doc update-proxy)
13:23clojurebot"([proxy mappings]); Takes a proxy instance and a map of strings (which must correspond to methods of the proxy superclass/superinterfaces) to fns (which must take arguments matching the corresponding method, plus an additional (explicit) first arg corresponding to this, and updates (via assoc) the proxy's fn map. nil can be passed instead of a fn, in which case the corresponding method will revert to the default behavior
13:25stuartsierraWow, never saw that before. Can't think I'd use it much; I'd rather call a normal fn and rebind that.
13:25Chouserrhickey: so cool. Are the return type hints required for some reason?
13:25rhickeystill todo - figure out signatures from superclasses, prevent additional overloads of superclass methods (overrides only, local helper methods must have unique names), volatile declarations, non-reflective calls to this...
13:26Chouserah
13:26rhickeystuartsierra: the advantage of that is it updates existing instance
13:26stuartsierraCool, like prototype classes.
13:27rhickeystuartsierra: well, it's per instance
13:27stuartsierraAh, like Ruby's instance methods, then. :)
13:27Chouserupdate-proxy is per instance, delegating do a var and redef or binding that would be per class, and newnew won't do either.
13:27rhickeylike I said, I don't know if anyone uses it
13:28Chouserto a var
13:28rhickeynew new will be what most people imagine proxy is
13:28lbjGood evening gents
13:29rhickeyanyway, what's up there should be usable, and needs a good workout
13:29stuartsierraSame usage pattern as an anonymous inner class in Java, right?
13:30rhickeystuartsierra: sort of, more emphasis on the lexical binding, less on nested class scope
13:30stuartsierraok
13:30rhickeybut supports multiple supers, unlike aic
13:30stuartsierraright, forgot that detail
13:31rhickeyno local member not from lexical scope, i.e. no explicit fields, field inits, class init...
13:32rhickeywill support volatile declaration making for mutable local in 'this' only
13:32rhickeyI would like a good name for these things other than "kind of like an anonymous inner class" though
13:32rhickey:)
13:33rhickeylexical objects?
13:33duck1123so does "old" new still work the same way, or will usage of it need to be changed?
13:34duck1123not that I ever use new, I always do (Object.)
13:34rhickey,(macroexpand-1 '(Object.))
13:34clojurebot(new Object)
13:35lbjThe questions still good :)
13:35rhickey(new classname ...) works as ever, does something different only when it sees vector as first arg
13:36Chouserlexical object isn't bad. I was thinking Clojure object would work.
13:36rhickeyChouser: I want to avoid Band-Aid/Kleenex syndrome
13:36lbjOk, sounds good
13:37Chouserother languages have lexical objects, but it doesn't seem like there's a whole lot of agreement on what they actually are.
13:37duck1123I knew that (Object.) expanded to (new Object) but presumably if the way to call (new Object) changed, the macro expansion would be changed to the new format
13:37stuartsierra"temporary-class object"?
13:37rhickeyChouser: right, completely different meanings
13:37stuartsierra"generated object"?
13:37y-combinatorHello. What is the best way to comnvert lazy seq to vector?
13:37Chousery-combinator: vec
13:38stuartsierra"anonymous instance"?
13:38Chouseryou actually get both a class and an object
13:39rhickeyplease try replacing a proxy or two with new new, admittedly the required hints make it a bit of a pain right now
13:39stuartsierra"generated class instance"?
13:39rhickeyChouser: right, that's the problem
13:39Chouserooh, sure, I have proxy all over the place. hmm, where to start...
13:40Chouserhm. need ctor args
13:40lbj~proxy
13:40clojurebotproxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.
13:41lbjTo me proxy was downright unuseable, because it could extend far enough
13:47Chouser'read' requires a PushbackReader; PushbackReader requires an arg for its ctor; have to keep using proxy here I guess.
13:55ChouserSecond attempt, this time extending sun.misc.Signal:
13:55ChouserException in thread "SIGINT handler" java.lang.AbstractMethodError: clojure.contrib.repl_utils$eval__335$start_handling_break$obj__339.handle(Lsun/misc/Signal;)V
13:57Chouser(new [sun.misc.SignalHandler] this (#^Void handle [sig] (prn :got-it) nil))
13:59ChousukeVoid? not void?
14:00Chouser,#^Void []
14:00clojurebot[]
14:00Chouser,#^void []
14:00clojurebotjava.lang.Exception: Unable to resolve symbol: void in this context
14:00Chousukehmm
14:00Chousuke,(str Void/TYPE)
14:00clojurebot"void"
14:01stuartsierra(.getName (.getParent Void))
14:01stuartsierra,(.getName (.getParent Void))
14:01clojurebotjava.lang.IllegalArgumentException: No matching field found: getParent for class java.lang.Class
14:06rhickey#^void in new new
14:08Chouserhm. same error though.
14:08Chouser(.handle (new [sun.misc.SignalHandler] this (#^void handle [sig] nil)) nil)
14:08stuartsierrado you need to type-hint sig?
14:09rhickeyChouser: sig is an Object?
14:09Chouseryes
14:09Chouser(.handle (new [sun.misc.SignalHandler] this (#^void handle [sig] nil)) (sun.misc.Signal. "INT"))
14:09rhickeythere's no default method for methods yo udon't define
14:10rhickeyif they get called you'll get AbstractMethodError
14:10Chouser(.handle (proxy [sun.misc.SignalHandler] [] (handle [sig] nil)) (sun.misc.Signal. "INT")) ;works fine
14:10Chouserrhickey: ok, good to know. sun.misc.SignalHandler has only the one instance method
14:12rhickeyChouser: sig is Signal, no?
14:12rhickey#^Signal sig
14:12Chouseryes, sun.misc.Signal
14:12rhickeythen it's not Object
14:12Chouseroh, sorry. I thought you meant non-primitive
14:13rhickeysorry I said an Object before, the sig is not Object
14:13Chouserah, so I do have to hint the arg
14:13rhickeyright now you have to specify exact signatures, I'm not looking at superclasses at all
14:13Chouserok
14:13rhickeyit won't end up being this hard, sorry
14:14Chouserok! works perfectly.
14:15Chouserso proxy will continue to be useful for when you need to extend classes that require args in their ctors?
14:16rhickeyChouser: I need to see when/why people are doing that. Deriving from concrete classes is always a questionable design, java.io a perfect example of how bad it can get
14:17Chouserok
14:17Chouserin this case (repl-utils/get-source) I only need it because core/read needs a PushbackReader
14:18Chousukehmm
14:18Chousukeare there any OO languages that allow only interface inheritance?
14:18rhickeyBut looking at the difference between new new and anonymous inner classes is instructive, all that implicit complexity we become inured to
14:19rhickeyChouser: It's a real pain that there aren't interfaces for java.io
14:19rhickeybut when does it stop?
14:20Chousukeis java.nio better in this regard? :/
14:20rhickeyeven the no-arg concrete ctors are insidious
14:22ChouserDoes java.nio have anything line-based?
14:24Chouseroh, I guess that's not what 'read' cares about. It wants an unread() method.
14:25stuartsierraWhat's the alternative to no-arg ctors? Factories?
14:26rhickeystuartsierra: it's actually more about concrete derivation than the ctors
14:26stuartsierraright, ok
14:27ChouserI guess clojure could define an interface with unread(), and by default use a custom class that extends PushbackReader. That would allow me to use newnew to implement a different class that 'read' would be happy with.
14:27ChousukeIClojureReader? :P
14:27rhickeyChouser: it could, yes
14:27rhickeyIMTiredOfJavaIo
14:28Chousuke:)
14:28Chouserwith all that, repl-utils could abandon proxy
14:28ChousukeProbably it would help with clojure-in-clojure as well?
14:28stuartsierraI remember when I was trying to write c.c.fnmap, I discovered I couldn't derive from PersistantHashMap. Maybe I wasn't supposed to.
14:29rhickeystuartsierra: no, there are interfaces + abstract bases
14:29hiredmanclojurebot: a man of means by no means is <reply>da da king of the road
14:29clojurebotAlles klar
14:30Chousukeif you define the clojure reader in terms of Clojure interfaces, it would be more portable across hosts too, I guess.
14:30rhickeyI'd love for a different solution than abstract bases, but they don't have (most of) the problems of concrete derivation
14:31rhickeyand I can make it so all of mine have no-arg ctors. The other set of very valuable ones, for j.u.collections, also have no-arg ctors
14:34Chouseroh, so 'this' is not required, but if not given you have no way to refer to the current instance.
14:34clojurebotthis is not a bug
14:35Chouserno indeed
14:35rhickeyright, it can get as small as: (str (new [] (#^String toString [] "foo")))
14:35rhickeyand once I get the superclass stuff in, lose the type hint
14:35hiredmanooo
14:36stuartsierrathat's nice, that will be really useful.
14:36stuartsierraYou could really do prototype-style objects then, right? Just define a "constructor" function that calls newnew.
14:37stuartsierraWell, I guess you can't change the definition of existing objects, but everything else.
14:37hiredmanstuartsierra: I doubt that
14:37Chouseryou can do even closer to that now with proxy, I'd think
14:37hiredmanseems like new has to be a compile time operation
14:38rhickeystuartsierra: it's more a rendition of known good practice - factory fns hiding implementation class details, programming to interfaces only
14:38hiredmanwhich makes it hard to monkey with at runtime
14:39stuartsierraBut you could gen-class a superclass if you need static names or mutable definitions, right?
14:39stuartsierrae.g., (gen-class "x.y.z") ... then later (new [x.y.z] ...)
14:40hiredmangen-interface :P
14:40Chouserexactly
14:40stuartsierracool!
14:40Chouserproxy already gives you a whole lot of this
14:41stuartsierraTrue.
14:41rhickeystuartsierra: right gen-class will do all of that. I'm still thinking about both stable anonymous names (for serialization) and AOT-only static names, but the best code will gen-interface + new new, possibly + gen-static which will make Java-friendly static-member-only classes
14:41ChouserMmmm.. I want gen-static.
14:41stuartsierraNice.
14:41kotarakwhat I don't like about proxy, is that it's saves its .class file in a common place for different namespaces. This makes packaging a nightmare. :(
14:42ChouserI have a gen-class with a whole lot of #^{:static true}
14:43rhickeypeople make such a righteous mess of OO, but if you only ever have immutable instances of anonymous classes manipulated via interfaces, life is good
14:43rhickeyso I'm trying to encourage that
14:44rhickeyand most of Clojure's Java is that way, except the few places where I need to define constructs to manage mutation or laziness
14:44stuartsierraGreat idea. A pity it breaks down as soon as you need to do I/O. :)
14:44hiredmanjava.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (fnparse.clj:1)
14:44Chouserkotarak: interesting. would you want a classpath entry per namespace, and somehow tell proxy that?
14:44hiredman:(
14:44kotarakchouser: just a sec
14:46rhickeystuartsierra: I think Chouser has a good idea replacing PushbackREader in Clojure's interfaces. HAving a concrete class in a signature is always a bad sign. But the drawback is that PushbackReader itself won't implement our interface, people will always have to implement our thingy, which is also bad, but not as bad
14:46rhickeyand supports implementing the interface via composition, which is good
14:47ChouserI suppose 'read' could still accept PushbackReader as well
14:47stuartsierraI suppose it's trivial to wrap java.io.PushbackReader (or whatever) in clojure.lang.BetterReader.
14:47rhickeyas soon as there is an interface you can compose
14:48rhickeyand with new new implement macros like def-this-on-that
14:48stuartsierraRight, I was just thinking about some kind of "thin proxy" that would delegate from an interface to a concrete class with matching methods.
14:48rhickeyand automate all the forwarding associated with composition
14:49Chousukewhat methods does the clojure reader need? just read and unread?
14:51ChouserChousuke: I think that's right.
14:52Drakesonliebke: a suggestion re incanter, could you please remove dependencies from lib/ and put them in cloud.github, as compojure does? thanks :)
14:56hiredmanoooh
14:57hiredmannew-new works in clojurebot's sandbox
14:57rhickey,(str (new [] (#^String toString [] "foo")))
14:57clojurebot"foo"
14:57rhickeycool
14:58rhickeylet the AbstractMethodErrors ensue
14:59hiredman,((new [clojure.lang.IFn] (#^Integer invoke [#^Integer x #^Integer y] (+ x y))) 1 2)
14:59clojurebotjava.lang.VerifyError: (class: sandbox$eval$obj__1939, method: invoke signature: (Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Integer;) Wrong return type in function
14:59hiredman:|
14:59rhickeyuse #^int etc
14:59hiredmanoh
14:59hiredman,((new [clojure.lang.IFn] (#^int invoke [#^int x #^int y] (+ x y))) 1 2)
14:59clojurebotjava.lang.AbstractMethodError: sandbox$eval$obj__1945.invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
15:00hiredmanah
15:00hiredmandoesn't match
15:00hiredmanI see
15:00rhickey,((new [clojure.lang.AFn] (invoke [x y] (+ x y))) 1 2)
15:00clojurebot3
15:01Chousukehmm
15:01hiredman,(import '(clojure.lang IDref AFn IFn))
15:01clojurebotjava.lang.ClassNotFoundException: clojure.lang.IDref
15:01hiredman,(import '(clojure.lang IDeref AFn IFn))
15:01clojurebotclojure.lang.IFn
15:01rhickeyI came up with a plan for supporting long and double args and returns in IFn earlier this week, but there are only so many hours in a week
15:01rhickeyIDeref
15:01hiredmanExcellent
15:02hiredman~rhickey
15:02clojurebotis_rhickey_is_a_minor_god? is yes
15:02Chousukefunky predicate
15:02Chousuke:P
15:03gjohnsonhowdy rich. I'm wondering about pcalls in clojure.core
15:03rhickeygjohnson: hi
15:04gjohnsonAt first glance, I would have imagined it was part of jsr166y.
15:04gjohnsonbut apparently not. so I'm guessing you're doing some magic with threadpools or somesuch?
15:04hiredmanrhickey: so new-new methods aren't backed my fns?
15:04rhickeygjohnson: it's just piggybacking on the agent thread pool
15:05gjohnsonok, that was my guess.
15:05rhickeyhiredman: no, pedal to the metal methods
15:05rhickeygjohnson: there is work going on in the par branch to leverage jsr166y, including a fjtask macro
15:05hiredmando they have a frame to recur to?
15:05rhickeyreturns something that can be forked and joined
15:06rhickeyhiredman: yes, should do
15:06gjohnsonhmm...so will that ultimately give pcalls a dependency on jsr166y and move it out of core?
15:06hiredmanI guess I could have just tried that out :P
15:07rhickeygjohnson: I haven't decided on tying the two together, so probably some new features for fj
15:07gjohnsonI had built a little tool for splitting my work over multiple processors back in January or so, but some of it was guesswork because I don't know the formula you're using to calculate the size of the fixed thread pool.
15:07stuartsierranumber of cores reported by the runtime
15:07gjohnson,(defn distribute-load-over-processors
15:07gjohnson [action-fn arg-seq]
15:07gjohnson (let [num-processors (.availableProcessors (Runtime/getRuntime))
15:07gjohnson agents (map agent (replicate (* *agents-per-processor* num-processors) ()))]
15:07gjohnson (println "Sending Tasks to" (count agents) "Agents...")
15:07clojurebotEOF while reading
15:07gjohnson (dorun (map #(send %1 action-fn %2) (cycle agents) arg-seq))
15:07gjohnson (println "Waiting for Agents to Finish...")
15:07gjohnson (apply await agents)
15:07gjohnson (apply concat (map deref agents))))
15:07gjohnsonbah
15:08hiredman:(
15:08gjohnsonlooks like the code didn't make it through unscathed. *sigh*
15:08Chousukelisppaste8: url
15:08lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
15:08stuartsierratry a pastie
15:09gjohnsonalrighty. the , prefix only works for one-liners then?
15:09stuartsierrayep
15:09Chousukeand you can't defn anyway :p
15:10lisppaste8gjohnson pasted "distribute-load-over-processors" at http://paste.lisp.org/display/84459
15:10gjohnsonindeed, that would be a bit of a security hole.
15:10gjohnson;)
15:11Chousukewell, you can get around the protections anyway
15:11Chousukebut as far as I can tell, all you can do is DOS clojurebot :P
15:11gjohnsonhmm...
15:11stuartsierra,(loop [x 1] (recur (inc x))
15:11clojurebotEOF while reading
15:11Chousuketo take over the machine itself, you'd have to break java's sandboxing.
15:12stuartsierraok, I'll play nice, won't retype that
15:12rhickey,(.down (new [] (down [x] (if (zero? x) x (recur (dec x))))) 42)
15:12clojurebot0
15:12gjohnsonwell, now that that's pasted, I was wondering if someone (rich?) could take a look at the code and tell me how different (for better or worse) this function is as compared to pcalls.
15:12hiredmanrhickey: that is awesome
15:12Chousuke,(loop [x 1] (recur (inc x)))
15:12Chousuke:p
15:12hiredman♥ new new
15:12clojurebotExecution Timed Out
15:13stuartsierraClever clojurebot.
15:13hiredman~def pcalls
15:13gjohnsonapparently so.
15:13gjohnsonah, pretty.
15:13hiredmanuh oh
15:14gjohnsonthat url's not working for me.
15:14Chousukegjohnson: you might want to use futures instead of agents; agents have a thread pool anyway.
15:15kotarakChouser: sorry. Had to operate the musicbear. I'm not in the details how proxy works. But if it generates a class clojure/proxy/my/Super.class, my naive view would say that it should be possible to generate a class named foo/bar/clojure/proxy/my/Super.class, no?
15:15gjohnsonas noted. that's why I don't spawn any threads.
15:16gjohnsonI just create a number of agents that are a dynamically bound multiple of the thread pool, and map calls to send across a cycled sequence of the agents.
15:17hiredmanah
15:17gjohnsonthis should just queue up all the functions more or less evenly across my agents and let the fixedthreadpool handle them.
15:17hiredmanbecause that rev is on the new-new branch
15:17hiredmanor not
15:17Chouserkotarak: ah! hm, I don't see why it couldn't.
15:18kotarakThen packaging would be easy. foo/bar/* goes to that .jar, foo/baz/* to that other one.
15:18Chouserrhickey: ,(.no-frickin-way (new [] (#^String no-frickin-way [] "no, really!")))
15:18clojurebotnew Class(x) is (Class. x)
15:18kotarakWithout fiddling with the proxy classes. (Which namespace calls which proxy? Hmm... Bookkeeping ahead...)
15:18Chouser,(.no-frickin-way (new [] (#^String no-frickin-way [] "no, really!")))
15:18clojurebot"no, really!"
15:18gjohnsonmy concern is that if I make less agents that the thread pool size, I'll end up with unused threads.
15:19Chouserrhickey: will the ability to create new methods like that go away?
15:20hiredmangrr
15:24hiredmankotarak: it's lisp! it has eval! and macros! YEAH!
15:26rhickeyChouser: no, that will stay, to allow for the definitions of helper methods. Calling them from outside will always involve reflection though
15:27rhickeythey will have to have names different from those of the supers' methods, and overloading on arity only
15:27Chouseroh, interesting.
15:28Chouserruntime reflection required to call other instances of the same class?
15:28rhickeyChouser: yeah, anything other than this
15:30rhickeythe dashes won't work on all JVMs
15:30rhickeyso I'll have to filter those
15:31rhickey,(class (new []))
15:31clojurebotsandbox$eval$obj__1918
15:37Chouser,(new [] (#^String toString [] (str "what's wrong?")))
15:37clojurebotjava.lang.VerifyError: (class: sandbox$eval$obj__1923, method: toString signature: ()Ljava/lang/String;) Wrong return type in function
15:38hiredman,(class (str "what's wrong?"))
15:38clojurebotjava.lang.String
15:38hiredman:/
15:38hiredman,(new [Object] (#^String toString [] (str "what's wrong?")))
15:38clojurebotjava.lang.VerifyError: (class: sandbox$eval$obj__1932, method: toString signature: ()Ljava/lang/String;) Wrong return type in function
15:39Chouserthe compiler should even know str returns a String
15:39hiredman,(new [] (#^String toString [] (.toString (str "what's wrong?" "foo"))))
15:39clojurebot#<sandbox$eval$obj__1952 what's wrong?foo>
15:41hiredman,(str (new [] (#^String toString [] (str "what's wrong?")))
15:41clojurebotEOF while reading
15:41hiredman,(str (new [] (#^String toString [] (str "what's wrong?"))))
15:41clojurebotjava.lang.VerifyError: (class: sandbox$eval$obj__1981, method: toString signature: ()Ljava/lang/String;) Wrong return type in function
15:41trotterare there any good code coverage tools for clojure?
15:42hiredman,(.foo (new [] (#^String foo [& bar] "foo")) 1 2)
15:42clojurebot"foo"
15:43hiredman,(new [] (#^String toString [] #^String (str "what's wrong?")))
15:43clojurebotjava.lang.VerifyError: (class: sandbox$eval$obj__2016, method: toString signature: ()Ljava/lang/String;) Wrong return type in function
15:43hiredman:(
15:43hiredmanit's too bad
15:45hiredmanlousey Object specifying interface
15:47rhickeyChouser: fixed: http://github.com/richhickey/clojure/commit/3c15d0eb6bdc279c801dd984a3524666d7c5cfbe
15:53Chouserrhickey: Thanks! That's every proxy in contrib, except the read thing: http://n01se.net/paste/knS
15:55rhickeywow
15:56rhickeydoes it still work?
15:59Chouseryes
15:59Chouserer, every proxy of mine
16:00rhickeywill be much nicer without the hints
16:00Chouserthere are still proxies in swing_utils and singleton
16:00Chouseryes, it definitely will.
16:21Fossiso, to come back to my question of tomorrow, if i deref a ref, it's contents doesn't get visited, right?
16:21Fossiso i get whatever state the ref might be in?
16:22Fossis/tomorrow/this morning
16:22hiredmaneh?
16:22Fossihttp://paste.lisp.org/display/84421
16:22hiredman"it's contents doesn't get visited" what does that mean?
16:23Fossi"hiredman: you might just put (vec left-events) in the returned pair"
16:23hiredmanFossi: I remember saying that
16:23ChousukeFossi: camelCase is not very clojurey :p
16:23ChousukeFossi: you should use hyphens with lisp functions.
16:24Fossiso if on the left, i return @state-ref, i get {} mostly
16:24FossiChousuke: ups, all the Java in that app tends to confuse me :)
16:24Chousukealso, I'd recommend not putting any actual dosync logic in your functions.
16:24Fossithat i don't understand
16:25hiredmanFossi: I still want to know what "it's contents doesn't get visited" means
16:25Fossiwell, i deref the ref, but i get {} (for example on the repl)
16:25ChousukeFossi: instead of going a dosync in change-color, write all the transitions as pure functions and then call (dosync (alter state change-color)) in some function that contains most of the "non-functional" logic
16:25hiredmanand?
16:25Fossiif i use *1, i suddently get a value
16:26hiredmanFossi: print out the second item in the return vector of calcGameState forces the map
16:26hiredmanmap being lazy
16:26Fossiyeah, somehow feels weird
16:26Fossisame for try catch really
16:26hiredmanthe functio being mapped as a side effect of changing the ref
16:27hiredmanso the ref does not get changed unless you force the map
16:27Fossibut i guess that's Chousuke's point
16:27ChousukeFossi: What I'm advocating is isolation of side-effects. ref alterations are side-effects :)
16:27FossiChousuke: well, i could have another layer there, yes
16:28Fossibut then, i don't really know what implementors of dispatchEvent might want to do to the state
16:29hiredmananyway
16:29hiredmanyou should force the map
16:30Chousukewhy are you returning a new state-ref though?
16:30Chousukein calcGameState
16:31Fossii return @state-ref now actually
16:31Fossistate-ref was just to test it from the repl
16:32Fossithe idea is to have a load of stm calculations being done to get to the new game state for the "mutable" game objects
16:33Chousukedo you really need a ref though? hmm.
16:33ChousukeI mean, perhaps you could reduce the state over the events with dispatch-event?
16:34hiredmanyeah
16:34alrex021I know this is not really clojure q, but hope someone could help... I need to include Incanter lib jars into my emacs env. How should the (setq swank-clojure-extra-classpaths ..) look? Sorry but I'm new to clojure and lisp too :(
16:35Chousukealrex021: (setq swank... '("file:///some/path/here/javalib.jar" "file://more/paths/")) ought to work
16:35Fossilater on the plan is to do it in parallel
16:36hiredman,(doc pvreduce)
16:36clojurebot"/;nil; "
16:36hiredmanclojurebot: curse you!
16:36clojurebotExcuse me?
16:36Chousukebut if future events depend on the earlier state, it's not very parallelisable :/
16:37alrex021Chousuke: thank you. Do I need to specify each required jar of the lib then of course? Or is it possible to say...all *.jar(s) in following dir?
16:37liebke_alrex021: technomancy created an incanter.el file, that I just added to the Incanter repository today, that might be helpful. It's in the bin/ directory
16:37clojurebottechnomancy is to blame for all failures
16:37ChousukeFossi: oh, and the (do ...) in changeColor is not needed. function bodies have an implicit do.
16:37Fossiah, didn't know pvreduce yet
16:38ChousukeFossi: pvreduce is very new; not in master yet.
16:38FossiChousuke: i know, i still like it for reminding me of side effects
16:38Fossii'll wrap each game object in it's own stm then
16:38alrex021liebke_: ahh, gr8 the author, what a gr8 community :) ...thanks
16:39ChousukeFossi: hmm, yeah :)
16:39Fossiand i don't care much about order of things, or whether they fail at first, with games you do this calculation 60/s, so it doesn't have to be overly correct
16:39liebke_alrex021: good luck, I wish I could be more help, but I'm not an emacs user :)
16:40Fossialrex021: (directory-files "~/projects/android/bannerwars/libs/" t ".*\.jar")
16:41alrex021liebke_: out of curiosity, what do you use for your clojure dev?
16:41liebke_I just use vim and a repl
16:42liebke_emacs is the way to go though... if you can get it configured :)
16:42lbjliebke_: I'll recommend Emacs + SLIME to you, its a fairly effecient combo, and easily installable thanks to technomancy's clojure-mode
16:42Fossiit's infecting
16:42gjohnsonk
16:43Fossii begin to select text with ctrl space in firebird
16:43liebke_lbj: I know, but I've used vi/vim for too long to switch at this point
16:43Fossiand try to swap desktops with shift-left
16:43Fossiliebke_: viper-mode? :)
16:44gjohnsonhow about vimclojure/gorilla
16:46hiredmanhttp://technotales.wordpress.com/2007/10/03/like-slime-for-vim/
16:47kotarak*ieck* do yourself a favour and use vimclojure. (shameless advertisement)
16:47kotarakthe screen has problems.
16:48kotarakIt works but is tricky.
16:48hiredman*shrug*
16:50hiredmanif you ever open a file that contains function calls, not just function definitions, vimclojure will execute those function calls
16:50hiredmanI find that to be unacceptable
16:51hiredmanheck
16:51kotarakIMHO, you shouldn't do that. Providing an entry point brings flexibility and advantages when debugging.
16:51hiredmanif you try and edit a .clj file that is not valid (not all the parens are closed, etc) vimclojure will puke
16:51hiredmankotarak: I have an entry point, and I have a .clj file that contains a call to that entry point
16:52hiredmanso if I open up my scratch clojure file, vimclojure pukes
16:52Chousukealso, if the file contains (shell-out "rm -rf /") or something :P
16:52kotarakYou can disable the dynamic part at any time and just use static vim with <C-n> and friends. Works also very well.
16:52hiredmanyeah, I have vim clojure installed and use the static part
16:53hiredmanI never use gorilla
16:53hiredmanI use slime.vim works great, and it works for things besides clojure
16:58Fossiyay. it works again. now that i have that set up, i can start doing more business logic :)
17:11gjohnsonokay, so I know this is a pretty remedial java question...
17:11gjohnsonbut how can I ask a threadpool for its size (number of threads)?
17:11hiredman~jdoc java.util.concurrent.ThreadPool
17:11gjohnsonI see that clojure.lang.Agent uses 2 + the number of cores detected by the runtime for the fixed threadpool size
17:11hiredmandamn
17:12gjohnson?
17:12hiredman~jdoc java.util.concurrent.ThreadPoolExecutor
17:12hiredmanstill no dice
17:12hiredmanhttp://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
17:12hiredmanthere is a getPoolSize method
17:13Chousershow works great for this
17:13gjohnsonah, thanks.
17:13Chouser(show clojure.lang.Agent) --> discover pooledExecutor and soloExecutor
17:14Chouser(show clojure.lang.Agent/pooledExecutor) --> discover getPoolSize and getMaximumPoolSize
17:14Chouser,(.getMaximumPoolSize clojure.lang.Agent/pooledExecutor)
17:14clojurebot3
17:39Drakesonhow can I make a memoized recursive function?
17:41hiredman,(macroexpand '#'foo)
17:41clojurebot(var foo)
17:46Drakesonhiredman: that is (defn f1 [n] (if (zero? n) 0 (+ (#'f1 (dec n)) n))) (def f1 (memoize f1)) ?
17:46hiredmanI am not sure
17:47Chousukethat would work, but it'll blow the stack if the recursion is too deep.
17:48Chouserthat shouldn't be necessary
17:50Chouser(defn f1 [n] (prn n) (when (> n 0) (f1 (dec n))))
17:50Chouser(def f1 (memoize f1))
17:50Chouser(f1 5) ; prints 5 to 0
17:50Chouser(f1 10) ; prints 10 to 6
17:51DrakesonChouser: thanks. That is an interesting way to test :)
17:59alrex021_I have been trying to pluggin this .el script into my .emacs for the past hour with no luck :( http://github.com/liebke/incanter/raw/fcbcdcc788916c204aca32e6b7810de4a6d0e6d2/bin/incanter.el
18:05alrex021_Could someone enlighten me on how one can configure "properly" full clojure support for emacs?
18:05alrex021_I am really struggling with this
18:05hiredman~emacs
18:05clojurebotemacs is best configured for Clojure with instructions at http://technomancy.us/126
18:05hiredman*shrug*
18:15alrex021_hhm: Clojure install failed .. git clone git://github.com/kevinoneill/clojure.git when following http://technomancy.us/126 instructuins
18:16durka42hmm, those instructions are old, the git repository is under richhickey
18:16durka42http://github.com/richhickey/clojure/tree/master
18:17technomancyalrex021_: getting the latest version of clojure-mode will fix that problem.
18:18alrex021_hhmm so is ELPA option not gonna work?
18:19alrex021_I used ELPA to install latest clojure-mode .. then ran clojure-install ...that didn't work
18:19alrex021_so I take it I need to manual install
18:20technomancyalrex021_: clojure-mode 1.3 is in ELPA
18:20technomancythat will do it
18:21alrex021_(I am extremely new to Emacs) ... do I have to restart after installing 1.3 via ELPA before I run clojure-install?
18:22technomancyyou shouldn't have to, but if you're having problems you might try that.
18:22alrex021_also, I take it I don't have to add anything to my .emacs file after I install the clojure-mode
18:23technomancyno, but it will give you some code to add to your .emacs after M-x clojure-install finishes.
18:23technomancybut it should be pretty clear from the instructions
18:26alrex021_ok I see, thx. I restarted and ran clojure-install...now its getting it from new git location
18:28alrex021_is there a way ti autoreload the .emacs file without restart of emacs?
18:28alrex021_off hand :)
18:28technomancysure; open it and do M-x eval-buffer
18:29alrex021_thx
18:31alrex021_hhmm ok the clojure-install worked and it just gave me 1 liner to add to my .emacs and M-x slime doesn't work (slime not an option)
18:31alrex021_line it gave me is just (clojure-slime-config)
18:33alrex021_so I added (clojure-slime-config) to my .emacs and restarted and then ran: M-x slime
18:33alrex021_but no luck
18:38rhickeynew new: added signature inference, overload detection: http://github.com/richhickey/clojure/commits/new
18:38rhickeyso now you don't need to hint except to disambiguate
18:38hiredman:O
18:38hiredman:D
18:42rhickey,(str (new [] (toString [] "hello")))
18:42clojurebot"sandbox$eval$obj__2040@945b95"
18:43rhickeyhrm
18:46hiredman,(str (new [] (toString [] "hello")))
18:46clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
18:46hiredmanwhelp
18:46hiredmanit was a wild and crazy ride
18:46rhickeyoh no
18:47rhickeydid clojurebot not like proxy either?
18:47hiredmanyep
18:49mebaran151_is there a super type for Float and Double?
18:49mebaran151_other than Number
18:49rhickeyis permission java.lang.RuntimePermission "accessDeclaredMembers"; dangerous?
18:50hiredman,(str (new [] (toString [] "hello")))
18:50clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)
18:51hiredmanI dunno
18:51hiredman,(str (new [] (toString [] "hello")))
18:51clojurebot"hello"
18:51hiredman,(ancestors Float)
18:51clojurebot#{java.lang.Object java.lang.Number java.io.Serializable java.lang.Comparable}
18:55rhickeycool
20:31iBongis there a (sugary) way to set flags like case insensitivity when using #regex literals?
20:44sillycloudyes
20:44sillycloudregexp : /pattern/i
20:45sillycloudor var rgx = new RegExp(); rgx.ignoreCase = true
20:47iBongthx
20:49sillycloudum
20:49sillycloudsorry
20:49sillycloudwrong channel
20:49sillycloudlol
20:49iBonger
20:49sillycloudmy answer is obviously wrong
20:49iBongyeah that didnt work
20:49sillycloud>.<
20:49iBongI was like, cool, just like ruby
20:49sillycloudlols
20:50iBongthe java way is super ugly
20:50iBonghoping clojure had a nice alternative, like not having to escape escapes
20:50Raynessillycloud: Think you're in #scala? :p
20:50sillycloudworse
20:50sillycloudi'm currently in #flash
20:50iBonglol
20:50sillycloudhelping the noobs
20:51sillycloudpersonally
20:51sillycloudi call zomg_var_to_lower_case() on all my string literals
20:51iBongis there a way to set case insensitive on #"regex" ?
20:55arbschtiBong: #"(?i)..."
20:58iBongthats it, nice, thank you
21:11Raynes,(apply str (repeat 10 "(") (repeat 10 ")"))
21:11clojurebot"clojure.lang.LazySeq@b0c04bc1))))))))))"
21:11hiredmanprn-str
21:12RaynesCool.
21:29gjohnsonhi there.
21:30gjohnsonI had a lovely time reading through the code for pcalls, pmap, clojure.lang.Agent, Executors, and ThreadPoolExecutors, and I've just got one question at this point.
21:31gjohnsonwhat is the rationale for the fixed threadpool's size being 2 greater than the number of cores?
21:32gjohnsonanyone?
21:33gjohnsonanyone alive out there?
21:33rhickeygjohnson: there isn't any special rationalization, other than it isn't worthwhile to create many more computation threads than you have procs
21:34gjohnsonrhickey: indeed. I was wondering specifically why you chose to create 2 more than the number of cores.
21:34gjohnsonrhickey: i.e. is there a performance benefit I'm missing from not having the same number or perhaps 1 or 3 more?
21:35rhickeygjohnson: no, it's still subject to change
21:35gjohnsonrhickey: alright. until I finally took the time to poke into clojure.lang.Agent, I had been creating 2*cores agents and queueing up all my work evenly across them.
21:35clojurebotclojure is far closer to perfection then python
21:36gjohnsonrhickey: that worked great on my 2 core machine (since it incidentally creates the same number of agents as your thread formula creates worker threads)
21:36gjohnsonrhickey: but when I scaled up to more agents (say 4*cores), performance was degraded considerably.
21:37rhickeygjohnson: using send or send-off?
21:37Chouser,(.getMaximumPoolSize clojure.lang.Agent/pooledExecutor)
21:37clojurebot3
21:37gjohnsonrhickey: just send, so they were all using the fixedThreadPool
21:38gjohnsonrhickey: seemed like the extra agent overhead was just bogging down my processor without getting any advantage since there were no free threads.
21:38rhickeythe number of agents shouldn't matter much then
21:39gjohnsonrhickey: well, I need at least at many as there are threads in the thread pool, otherwise I'll have idle threads.
21:39rhickeyit doesn't work that way, there are just jobs in the queues getting pulled off by threads, agents don't do anything themselves
21:39gjohnsonrhickey: right, I understand that, but each agent can only have one thread running on it at a time.
21:39rhickeyyes, I mean when more than numThreads
21:40gjohnsonrhickey: so if there are less agents(work queues) than threads...well, you know.
21:40rhickeyso 4 threads is 4 threads even if 100 agents
21:40gjohnsonrhickey: right, but 4 threads is 3 threads if you only have 3 agents.
21:40hiredman
21:40rhickeybut you said you added more agents and it slowed down
21:40rhickey4 *cores
21:41gjohnsonrhickey: yes, that was my observation. sorry, these are two different issues.
21:41gjohnsonrhickey: what I noticed was that as I added more agents, my processors were being utilized less.
21:41rhickeydo the agents do any io?
21:41gjohnsonrhickey: usage was dropping maybe 10% or so on each one.
21:42gjohnsonrhickey: no, they are doing CPU bounded work (agent-based simulation, no punning intended)
21:43gjohnsonrhickey: perhaps I was just having a strange day at my machine. *shrugs*
21:43rhickeyand was each job the same size?
21:44gjohnsonrhickey: no, they were exploratory tree searches on variable-sized trees.
21:44gjohnsonrhickey: but each time I ran the simulation, it was on the same set of trees.
21:44rhickeywell, than some agents could be done and doing nothing and the work serializes on the others
21:44gjohnsonrhickey: the data didn't change, just possibly the order that the agents got around to processing them.
21:44rhickeythen
21:45rhickeyforkjoin was made for this
21:45rhickeybecause it does work stealing
21:45rhickeyyou should try par
21:45gjohnsonrhickey: hmm...I see.
21:45gjohnsonrhickey: the code pcalls (i.e. pmap) looked very promising for my application actually.
21:46rhickeyagents are really for stateful asynchronous things, for threading you can just use futures, or ideally, try the par branch
21:46gjohnsonrhickey: since I designed my algorithm to break all the work up into a sequence of fns, the futures via pcalls seems like the best idea.
21:46rhickeyin the par branch you can put you job data in a vector and call pvmap, get work stealing etc for free, no coordination
21:47gjohnsonrhickey: when I wrote this code, I don't believe futures had yet been added to the language spec.
21:47gjohnsonrhickey: I've been at these algorithms for the past few years.
21:47rhickeygjohnson: right, I saw so many people using agents because they were a path to threads, but they weren't doing anything actor-like with them
21:48hiredmanfutures weren't present
21:48gjohnsonindeed
21:48gjohnsonack, I seem to have missed that.
21:49gjohnsonrhickey: well, the truth of the matter is IMHO that once you're living and breathing clojure all day and night, it's really a thorn in my side to have to call out to the java Thread and Executors classes to get my concurrency off the ground.
21:50rhickeygjohnson: I'm not recommending that
21:50gjohnsonrhickey: I had written my code with those initially, then switched it over to evenly queueing the tasks over a bunch of agents and passing it off to the threadpool transparently.
21:50gjohnsonrhickey: I've been off in academic development land for quite awhile, and I just came back around and reread all the docs on the website, so futures were a new thing for me this week.
21:50gjohnson(yes, I know that's silly sounding, hiredman)
21:51gjohnsonand I didn't find the parallel library terribly transparent in the website docs.
21:52gjohnsonand the jsr166y link just led to a page that ultimately led me on to the ForkJoin API without a high-level explanation of what it was supposed to be doing.
21:52gjohnsonrhickey: so I've been having a bit of trouble getting traction with it.
21:52gjohnsonrhickey: any pointers on reading references to grok this stuff?
21:53rhickeyhttp://github.com/richhickey/clojure/blob/26f5aed73c9cc2959beee0dd43a0d434fce83631/src/clj/clojure/par.clj
21:54rhickeythere is a par branch on github, try it
21:54rhickeygotta run
21:54gjohnsonalright, thanks
22:38bpattisonI'm looking for a clojure function that tells me if a symbol is in a list -- I know it something obvious but I can't find it in the Clojure API or clojure.contrib
22:38Chouserare you sure you want a list and not a set?
22:39Chouser,(#{:a :b :c :d} :c)
22:39clojurebot:c
22:39Chouser,(#{:a :b :c :d} :e)
22:39clojurebotnil
22:39hiredman(.contains '(:a :b :c) :a)
22:40hiredman,(.contains '(:a :b :c) :a)
22:40clojurebottrue
22:40bpattisonyep, that's perfect -- I'll use a set
22:40hiredman,(.contains [:a :b :c] :a)
22:40clojurebottrue