2009-07-30
| 00:11 | Jomyoot | Anyone uses BBEDIT? |
| 00:32 | mebaran151 | any hack to assign metadata to a java object |
| 00:32 | mebaran151 | it would be extremely convenient in this one case |
| 02:23 | Fossi1 | freakin damn lazyness |
| 02:23 | Fossi1 | it got me *again* |
| 02:23 | Raynes | Fossi1: In order to beat the lazy, you must first, think like the lazy. |
| 02:24 | Raynes | Kick 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 | _mst | when 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 | _mst | people will respect you for it :) |
| 02:26 | Fossi1 | hell, i can think lazy ;D |
| 02:27 | Fossi1 | normally it's called procrastination though |
| 02:30 | albino | _mst: I like that advice |
| 02:30 | Fossi1 | lisppaste8: url |
| 02:30 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 02:31 | lisppaste8 | Fossi pasted "ref trouble" at http://paste.lisp.org/display/84421 |
| 02:32 | Fossi1 | when i call this, i get [ref{} ()] back, then when i run *1 on the repl again, ref suddently has a value |
| 02:34 | hiredman | are you sure you want commute there? |
| 02:34 | Fossi1 | could be ref-set, i don't care what color it is, if i have 2 such events |
| 02:35 | Fossi1 | just why does the ref change after the dosync is done? |
| 02:35 | Fossi1 | because everything around it is lazy? |
| 02:35 | Fossi1 | do i need to doall the map? |
| 02:35 | hiredman | yeah |
| 02:36 | hiredman | you might just put (vec left-events) in the returned pair |
| 02:38 | Fossi1 | ok, i'll try |
| 02:45 | Fossi1 | ok, didn't help much with my error, i'll have a look later |
| 02:45 | Fossi1 | off to more professional clojure ventures ;) |
| 02:45 | Fossi1 | bbl |
| 03:32 | lbj | Top of the morning gents |
| 03:44 | AWizzArd | Hi lbj |
| 03:49 | lbj | Any interesting new developers in Clojureland lately? (disregarding new new entirely) |
| 03:50 | lbj | hehe, developers = developments |
| 03:52 | Chousuke | well, the new forkjoin stuff looks promising, and "batch mode" |
| 03:52 | lbj | What are they? |
| 03:54 | lbj | @ Chousuke |
| 03:54 | Chousuke | http://paste.lisp.org/display/84027 <- automatically parallelised vector operations and http://paste.lisp.org/display/84027 (no timing data there though) :/ |
| 03:55 | Chousuke | I wonder which branch the batch stuff was in. |
| 03:56 | lbj | Interesting - Does vec then determine wether or not the task at hand is suited for paralization ? |
| 03:56 | Chousuke | vec does nothing different. it's pvreduce and pvmap that do the parallelisation |
| 03:58 | Chousuke | rhickey says he has a quad core machine, so the results are rather impressive. |
| 03:58 | lbj | Indeed |
| 03:58 | Chousuke | I have a dual core and wasn't able to get 2x improvement :/ I suspect my memory is a bottleneck |
| 03:58 | lbj | But if you replace vec with pvreduce, what would the answer to my question be? |
| 03:59 | Chousuke | pvreduce always divides the work I think |
| 03:59 | lbj | There'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:00 | Chousuke | the 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:00 | Chousuke | lbj: it's not that far automated :) |
| 04:01 | Chousuke | regular reduce and map will remain (the pv* stuff is not lazy anyway) |
| 04:05 | Chousuke | lbj: There's also the chunked seqs branch, but you may have already heard of that :) |
| 04:06 | lbj | That I'm familiar with |
| 04:18 | Chousuke | lbj: I hope this doesn't explode your ERC |
| 04:18 | lbj | Thanks friend - I actually got one of those cool Jaunty notifications :) |
| 04:19 | lbj | Now I just need to work out the hook for private msgs, seems thats handled differently |
| 04:26 | blbrown_win | morning |
| 04:26 | lbj | Morning :) |
| 04:37 | blbrown_win | I wish I got paid for the work I did outside of work |
| 04:38 | hiredman | heh |
| 04:39 | Raynes | I wish I got paid for the work that hiredman does outside of work... |
| 04:39 | blbrown_win | nice |
| 04:39 | blbrown_win | me too |
| 06:00 | angerman | I have two vecotrs, the first one consists of bools and has exactly one set to true. The second one has values. |
| 06:00 | angerman | now I want to get the value that corresponds to the true item |
| 06:01 | angerman | any ideas? |
| 06:01 | angerman | ,(let x [true false false] y ["a" "b" "c"] (for [x x y y :when x] [x])) |
| 06:01 | clojurebot | java.lang.IllegalArgumentException: let requires a vector for its binding |
| 06:07 | jdz | ,(mapcat (fn [x y] (when x (list y))) '[true false false] '["a" "b" "c"]) |
| 06:07 | clojurebot | ("a") |
| 06:07 | angerman | ,(:true (zipmap [:true :false :false] ["a" "b" "c"]) |
| 06:07 | clojurebot | EOF while reading |
| 06:07 | angerman | ,(:true (zipmap [:true :false :false] ["a" "b" "c"])) |
| 06:07 | clojurebot | "a" |
| 06:07 | angerman | does not feel right :/ |
| 06:08 | lbj | angerman: Why are you using a vector? |
| 06:08 | angerman | lbj: ? |
| 06:09 | hiredman | ,((comp second first (partial filter first) (partial map vector)) '[true false false] '["a""b" "c"]) |
| 06:09 | clojurebot | "a" |
| 06:10 | lbj | angerman: It sounded like a job for a map, but anyway, merge the two, maybe applying partition 2 |
| 06:10 | hiredman | ,(zipmap '[true false false] '["a" "b" "c"]) |
| 06:10 | clojurebot | {false "c", true "a"} |
| 06:10 | hiredman | ,((zipmap '[true false false] '["a" "b" "c"]) true) |
| 06:10 | clojurebot | "a" |
| 06:10 | hiredman | I think I win |
| 06:10 | angerman | hiredman: ahh, right |
| 06:10 | angerman | hiredman: :) I tried (true (zipmap ...)) and that didn't work |
| 08:45 | lbj | ... |
| 10:51 | dysinger | moing! |
| 10:53 | cgrand | dysinger: shhh everybody is asleep |
| 11:26 | Drakeson | how 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:28 | stuartsierra | I think there's a contrib fn that does that |
| 11:28 | rhickey | ,(doc max-key) |
| 11:28 | clojurebot | "([k x] [k x y] [k x y & more]); Returns the x for which (k x), a number, is greatest." |
| 11:29 | Drakeson | thanks :) |
| 13:09 | rhickey | new new branch is up |
| 13:10 | stuartsierra | cool |
| 13:10 | rhickey | still work in progress, but can create new instances - all method need full type hints (missing hint means Object) |
| 13:11 | rhickey | will eventually try to match superclasses' sigs |
| 13:11 | rhickey | does accept non-interface superclass with no-arg ctor |
| 13:12 | rhickey | primitives can flow in and out |
| 13:12 | rhickey | no indirection on method calls |
| 13:13 | rhickey | (new [super? interfaces*] thisname? {:flags :here}? (methodname [args] body)*) |
| 13:14 | stuartsierra | "thisname" is a class name? |
| 13:14 | rhickey | hints are metadata on method and arg names |
| 13:14 | rhickey | stuartsierra: no, the name of this object, usually this |
| 13:14 | stuartsierra | ah, ok |
| 13:16 | rhickey | (defn foo [] |
| 13:16 | rhickey | (let [y (int 17)] |
| 13:16 | rhickey | (new [Object clojure.lang.Seqable] this {:foo :bar} |
| 13:16 | rhickey | (#^String toString [] "foo") |
| 13:16 | rhickey | (#^int hashCode [] 42) |
| 13:16 | rhickey | (#^int baz [#^int x] (+ x y)) |
| 13:16 | rhickey | (#^clojure.lang.ISeq seq [] (seq ["woo hoo"]))))) |
| 13:17 | Chousuke | are the flags purely for the compiler or can you access them somehow? |
| 13:18 | rhickey | Chousuke: flags go in bitbucket right now |
| 13:18 | Chousuke | heh. |
| 13:20 | stuartsierra | So this returns an instance of a new dynamically-generated class, which is not a proxy, correct? |
| 13:20 | rhickey | right |
| 13:20 | rhickey | should be much faster than proxy |
| 13:20 | stuartsierra | Gotcha. |
| 13:20 | stuartsierra | And it is not intended to replace gen-class for statically-named classes? |
| 13:20 | rhickey | not right now |
| 13:20 | stuartsierra | ok |
| 13:20 | duck1123 | will this replace proxy, then? |
| 13:21 | rhickey | duck1123: most usage will move to this, but not removing proxy |
| 13:21 | rhickey | proxy does support some dynamic fiddling which this won't |
| 13:22 | rhickey | not much used afaik |
| 13:22 | stuartsierra | Right, this "new" creates a class which cannot be changed, correct? |
| 13:22 | rhickey | right |
| 13:22 | stuartsierra | I didn't realize proxies could be changed. |
| 13:22 | rhickey | but the enclosing 'factory' fn can, since no one depends on the name of the generated class |
| 13:23 | rhickey | ,(doc update-proxy) |
| 13:23 | clojurebot | "([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:25 | stuartsierra | Wow, never saw that before. Can't think I'd use it much; I'd rather call a normal fn and rebind that. |
| 13:25 | Chouser | rhickey: so cool. Are the return type hints required for some reason? |
| 13:25 | rhickey | still 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:26 | Chouser | ah |
| 13:26 | rhickey | stuartsierra: the advantage of that is it updates existing instance |
| 13:26 | stuartsierra | Cool, like prototype classes. |
| 13:27 | rhickey | stuartsierra: well, it's per instance |
| 13:27 | stuartsierra | Ah, like Ruby's instance methods, then. :) |
| 13:27 | Chouser | update-proxy is per instance, delegating do a var and redef or binding that would be per class, and newnew won't do either. |
| 13:27 | rhickey | like I said, I don't know if anyone uses it |
| 13:28 | Chouser | to a var |
| 13:28 | rhickey | new new will be what most people imagine proxy is |
| 13:28 | lbj | Good evening gents |
| 13:29 | rhickey | anyway, what's up there should be usable, and needs a good workout |
| 13:29 | stuartsierra | Same usage pattern as an anonymous inner class in Java, right? |
| 13:30 | rhickey | stuartsierra: sort of, more emphasis on the lexical binding, less on nested class scope |
| 13:30 | stuartsierra | ok |
| 13:30 | rhickey | but supports multiple supers, unlike aic |
| 13:30 | stuartsierra | right, forgot that detail |
| 13:31 | rhickey | no local member not from lexical scope, i.e. no explicit fields, field inits, class init... |
| 13:32 | rhickey | will support volatile declaration making for mutable local in 'this' only |
| 13:32 | rhickey | I would like a good name for these things other than "kind of like an anonymous inner class" though |
| 13:32 | rhickey | :) |
| 13:33 | rhickey | lexical objects? |
| 13:33 | duck1123 | so does "old" new still work the same way, or will usage of it need to be changed? |
| 13:34 | duck1123 | not that I ever use new, I always do (Object.) |
| 13:34 | rhickey | ,(macroexpand-1 '(Object.)) |
| 13:34 | clojurebot | (new Object) |
| 13:35 | lbj | The questions still good :) |
| 13:35 | rhickey | (new classname ...) works as ever, does something different only when it sees vector as first arg |
| 13:36 | Chouser | lexical object isn't bad. I was thinking Clojure object would work. |
| 13:36 | rhickey | Chouser: I want to avoid Band-Aid/Kleenex syndrome |
| 13:36 | lbj | Ok, sounds good |
| 13:37 | Chouser | other languages have lexical objects, but it doesn't seem like there's a whole lot of agreement on what they actually are. |
| 13:37 | duck1123 | I 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:37 | stuartsierra | "temporary-class object"? |
| 13:37 | rhickey | Chouser: right, completely different meanings |
| 13:37 | stuartsierra | "generated object"? |
| 13:37 | y-combinator | Hello. What is the best way to comnvert lazy seq to vector? |
| 13:37 | Chouser | y-combinator: vec |
| 13:38 | stuartsierra | "anonymous instance"? |
| 13:38 | Chouser | you actually get both a class and an object |
| 13:39 | rhickey | please try replacing a proxy or two with new new, admittedly the required hints make it a bit of a pain right now |
| 13:39 | stuartsierra | "generated class instance"? |
| 13:39 | rhickey | Chouser: right, that's the problem |
| 13:39 | Chouser | ooh, sure, I have proxy all over the place. hmm, where to start... |
| 13:40 | Chouser | hm. need ctor args |
| 13:40 | lbj | ~proxy |
| 13:40 | clojurebot | proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays. |
| 13:41 | lbj | To me proxy was downright unuseable, because it could extend far enough |
| 13:47 | Chouser | 'read' requires a PushbackReader; PushbackReader requires an arg for its ctor; have to keep using proxy here I guess. |
| 13:55 | Chouser | Second attempt, this time extending sun.misc.Signal: |
| 13:55 | Chouser | Exception in thread "SIGINT handler" java.lang.AbstractMethodError: clojure.contrib.repl_utils$eval__335$start_handling_break$obj__339.handle(Lsun/misc/Signal;)V |
| 13:57 | Chouser | (new [sun.misc.SignalHandler] this (#^Void handle [sig] (prn :got-it) nil)) |
| 13:59 | Chousuke | Void? not void? |
| 14:00 | Chouser | ,#^Void [] |
| 14:00 | clojurebot | [] |
| 14:00 | Chouser | ,#^void [] |
| 14:00 | clojurebot | java.lang.Exception: Unable to resolve symbol: void in this context |
| 14:00 | Chousuke | hmm |
| 14:00 | Chousuke | ,(str Void/TYPE) |
| 14:00 | clojurebot | "void" |
| 14:01 | stuartsierra | (.getName (.getParent Void)) |
| 14:01 | stuartsierra | ,(.getName (.getParent Void)) |
| 14:01 | clojurebot | java.lang.IllegalArgumentException: No matching field found: getParent for class java.lang.Class |
| 14:06 | rhickey | #^void in new new |
| 14:08 | Chouser | hm. same error though. |
| 14:08 | Chouser | (.handle (new [sun.misc.SignalHandler] this (#^void handle [sig] nil)) nil) |
| 14:08 | stuartsierra | do you need to type-hint sig? |
| 14:09 | rhickey | Chouser: sig is an Object? |
| 14:09 | Chouser | yes |
| 14:09 | Chouser | (.handle (new [sun.misc.SignalHandler] this (#^void handle [sig] nil)) (sun.misc.Signal. "INT")) |
| 14:09 | rhickey | there's no default method for methods yo udon't define |
| 14:10 | rhickey | if they get called you'll get AbstractMethodError |
| 14:10 | Chouser | (.handle (proxy [sun.misc.SignalHandler] [] (handle [sig] nil)) (sun.misc.Signal. "INT")) ;works fine |
| 14:10 | Chouser | rhickey: ok, good to know. sun.misc.SignalHandler has only the one instance method |
| 14:12 | rhickey | Chouser: sig is Signal, no? |
| 14:12 | rhickey | #^Signal sig |
| 14:12 | Chouser | yes, sun.misc.Signal |
| 14:12 | rhickey | then it's not Object |
| 14:12 | Chouser | oh, sorry. I thought you meant non-primitive |
| 14:13 | rhickey | sorry I said an Object before, the sig is not Object |
| 14:13 | Chouser | ah, so I do have to hint the arg |
| 14:13 | rhickey | right now you have to specify exact signatures, I'm not looking at superclasses at all |
| 14:13 | Chouser | ok |
| 14:13 | rhickey | it won't end up being this hard, sorry |
| 14:14 | Chouser | ok! works perfectly. |
| 14:15 | Chouser | so proxy will continue to be useful for when you need to extend classes that require args in their ctors? |
| 14:16 | rhickey | Chouser: 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:17 | Chouser | ok |
| 14:17 | Chouser | in this case (repl-utils/get-source) I only need it because core/read needs a PushbackReader |
| 14:18 | Chousuke | hmm |
| 14:18 | Chousuke | are there any OO languages that allow only interface inheritance? |
| 14:18 | rhickey | But looking at the difference between new new and anonymous inner classes is instructive, all that implicit complexity we become inured to |
| 14:19 | rhickey | Chouser: It's a real pain that there aren't interfaces for java.io |
| 14:19 | rhickey | but when does it stop? |
| 14:20 | Chousuke | is java.nio better in this regard? :/ |
| 14:20 | rhickey | even the no-arg concrete ctors are insidious |
| 14:22 | Chouser | Does java.nio have anything line-based? |
| 14:24 | Chouser | oh, I guess that's not what 'read' cares about. It wants an unread() method. |
| 14:25 | stuartsierra | What's the alternative to no-arg ctors? Factories? |
| 14:26 | rhickey | stuartsierra: it's actually more about concrete derivation than the ctors |
| 14:26 | stuartsierra | right, ok |
| 14:27 | Chouser | I 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:27 | Chousuke | IClojureReader? :P |
| 14:27 | rhickey | Chouser: it could, yes |
| 14:27 | rhickey | IMTiredOfJavaIo |
| 14:28 | Chousuke | :) |
| 14:28 | Chouser | with all that, repl-utils could abandon proxy |
| 14:28 | Chousuke | Probably it would help with clojure-in-clojure as well? |
| 14:28 | stuartsierra | I 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:29 | rhickey | stuartsierra: no, there are interfaces + abstract bases |
| 14:29 | hiredman | clojurebot: a man of means by no means is <reply>da da king of the road |
| 14:29 | clojurebot | Alles klar |
| 14:30 | Chousuke | if you define the clojure reader in terms of Clojure interfaces, it would be more portable across hosts too, I guess. |
| 14:30 | rhickey | I'd love for a different solution than abstract bases, but they don't have (most of) the problems of concrete derivation |
| 14:31 | rhickey | and 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:34 | Chouser | oh, so 'this' is not required, but if not given you have no way to refer to the current instance. |
| 14:34 | clojurebot | this is not a bug |
| 14:35 | Chouser | no indeed |
| 14:35 | rhickey | right, it can get as small as: (str (new [] (#^String toString [] "foo"))) |
| 14:35 | rhickey | and once I get the superclass stuff in, lose the type hint |
| 14:35 | hiredman | ooo |
| 14:36 | stuartsierra | that's nice, that will be really useful. |
| 14:36 | stuartsierra | You could really do prototype-style objects then, right? Just define a "constructor" function that calls newnew. |
| 14:37 | stuartsierra | Well, I guess you can't change the definition of existing objects, but everything else. |
| 14:37 | hiredman | stuartsierra: I doubt that |
| 14:37 | Chouser | you can do even closer to that now with proxy, I'd think |
| 14:37 | hiredman | seems like new has to be a compile time operation |
| 14:38 | rhickey | stuartsierra: it's more a rendition of known good practice - factory fns hiding implementation class details, programming to interfaces only |
| 14:38 | hiredman | which makes it hard to monkey with at runtime |
| 14:39 | stuartsierra | But you could gen-class a superclass if you need static names or mutable definitions, right? |
| 14:39 | stuartsierra | e.g., (gen-class "x.y.z") ... then later (new [x.y.z] ...) |
| 14:40 | hiredman | gen-interface :P |
| 14:40 | Chouser | exactly |
| 14:40 | stuartsierra | cool! |
| 14:40 | Chouser | proxy already gives you a whole lot of this |
| 14:41 | stuartsierra | True. |
| 14:41 | rhickey | stuartsierra: 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:41 | Chouser | Mmmm.. I want gen-static. |
| 14:41 | stuartsierra | Nice. |
| 14:41 | kotarak | what 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:42 | Chouser | I have a gen-class with a whole lot of #^{:static true} |
| 14:43 | rhickey | people 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:43 | rhickey | so I'm trying to encourage that |
| 14:44 | rhickey | and most of Clojure's Java is that way, except the few places where I need to define constructs to manage mutation or laziness |
| 14:44 | stuartsierra | Great idea. A pity it breaks down as soon as you need to do I/O. :) |
| 14:44 | hiredman | java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (fnparse.clj:1) |
| 14:44 | Chouser | kotarak: interesting. would you want a classpath entry per namespace, and somehow tell proxy that? |
| 14:44 | hiredman | :( |
| 14:44 | kotarak | chouser: just a sec |
| 14:46 | rhickey | stuartsierra: 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:46 | rhickey | and supports implementing the interface via composition, which is good |
| 14:47 | Chouser | I suppose 'read' could still accept PushbackReader as well |
| 14:47 | stuartsierra | I suppose it's trivial to wrap java.io.PushbackReader (or whatever) in clojure.lang.BetterReader. |
| 14:47 | rhickey | as soon as there is an interface you can compose |
| 14:48 | rhickey | and with new new implement macros like def-this-on-that |
| 14:48 | stuartsierra | Right, I was just thinking about some kind of "thin proxy" that would delegate from an interface to a concrete class with matching methods. |
| 14:48 | rhickey | and automate all the forwarding associated with composition |
| 14:49 | Chousuke | what methods does the clojure reader need? just read and unread? |
| 14:51 | Chouser | Chousuke: I think that's right. |
| 14:52 | Drakeson | liebke: a suggestion re incanter, could you please remove dependencies from lib/ and put them in cloud.github, as compojure does? thanks :) |
| 14:56 | hiredman | oooh |
| 14:57 | hiredman | new-new works in clojurebot's sandbox |
| 14:57 | rhickey | ,(str (new [] (#^String toString [] "foo"))) |
| 14:57 | clojurebot | "foo" |
| 14:57 | rhickey | cool |
| 14:58 | rhickey | let the AbstractMethodErrors ensue |
| 14:59 | hiredman | ,((new [clojure.lang.IFn] (#^Integer invoke [#^Integer x #^Integer y] (+ x y))) 1 2) |
| 14:59 | clojurebot | java.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:59 | hiredman | :| |
| 14:59 | rhickey | use #^int etc |
| 14:59 | hiredman | oh |
| 14:59 | hiredman | ,((new [clojure.lang.IFn] (#^int invoke [#^int x #^int y] (+ x y))) 1 2) |
| 14:59 | clojurebot | java.lang.AbstractMethodError: sandbox$eval$obj__1945.invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; |
| 15:00 | hiredman | ah |
| 15:00 | hiredman | doesn't match |
| 15:00 | hiredman | I see |
| 15:00 | rhickey | ,((new [clojure.lang.AFn] (invoke [x y] (+ x y))) 1 2) |
| 15:00 | clojurebot | 3 |
| 15:01 | Chousuke | hmm |
| 15:01 | hiredman | ,(import '(clojure.lang IDref AFn IFn)) |
| 15:01 | clojurebot | java.lang.ClassNotFoundException: clojure.lang.IDref |
| 15:01 | hiredman | ,(import '(clojure.lang IDeref AFn IFn)) |
| 15:01 | clojurebot | clojure.lang.IFn |
| 15:01 | rhickey | I 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:01 | rhickey | IDeref |
| 15:01 | hiredman | Excellent |
| 15:02 | hiredman | ~rhickey |
| 15:02 | clojurebot | is_rhickey_is_a_minor_god? is yes |
| 15:02 | Chousuke | funky predicate |
| 15:02 | Chousuke | :P |
| 15:03 | gjohnson | howdy rich. I'm wondering about pcalls in clojure.core |
| 15:03 | rhickey | gjohnson: hi |
| 15:04 | gjohnson | At first glance, I would have imagined it was part of jsr166y. |
| 15:04 | gjohnson | but apparently not. so I'm guessing you're doing some magic with threadpools or somesuch? |
| 15:04 | hiredman | rhickey: so new-new methods aren't backed my fns? |
| 15:04 | rhickey | gjohnson: it's just piggybacking on the agent thread pool |
| 15:05 | gjohnson | ok, that was my guess. |
| 15:05 | rhickey | hiredman: no, pedal to the metal methods |
| 15:05 | rhickey | gjohnson: there is work going on in the par branch to leverage jsr166y, including a fjtask macro |
| 15:05 | hiredman | do they have a frame to recur to? |
| 15:05 | rhickey | returns something that can be forked and joined |
| 15:06 | rhickey | hiredman: yes, should do |
| 15:06 | gjohnson | hmm...so will that ultimately give pcalls a dependency on jsr166y and move it out of core? |
| 15:06 | hiredman | I guess I could have just tried that out :P |
| 15:07 | rhickey | gjohnson: I haven't decided on tying the two together, so probably some new features for fj |
| 15:07 | gjohnson | I 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:07 | stuartsierra | number of cores reported by the runtime |
| 15:07 | gjohnson | ,(defn distribute-load-over-processors |
| 15:07 | gjohnson | [action-fn arg-seq] |
| 15:07 | gjohnson | (let [num-processors (.availableProcessors (Runtime/getRuntime)) |
| 15:07 | gjohnson | agents (map agent (replicate (* *agents-per-processor* num-processors) ()))] |
| 15:07 | gjohnson | (println "Sending Tasks to" (count agents) "Agents...") |
| 15:07 | clojurebot | EOF while reading |
| 15:07 | gjohnson | (dorun (map #(send %1 action-fn %2) (cycle agents) arg-seq)) |
| 15:07 | gjohnson | (println "Waiting for Agents to Finish...") |
| 15:07 | gjohnson | (apply await agents) |
| 15:07 | gjohnson | (apply concat (map deref agents)))) |
| 15:07 | gjohnson | bah |
| 15:08 | hiredman | :( |
| 15:08 | gjohnson | looks like the code didn't make it through unscathed. *sigh* |
| 15:08 | Chousuke | lisppaste8: url |
| 15:08 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 15:08 | stuartsierra | try a pastie |
| 15:09 | gjohnson | alrighty. the , prefix only works for one-liners then? |
| 15:09 | stuartsierra | yep |
| 15:09 | Chousuke | and you can't defn anyway :p |
| 15:10 | lisppaste8 | gjohnson pasted "distribute-load-over-processors" at http://paste.lisp.org/display/84459 |
| 15:10 | gjohnson | indeed, that would be a bit of a security hole. |
| 15:10 | gjohnson | ;) |
| 15:11 | Chousuke | well, you can get around the protections anyway |
| 15:11 | Chousuke | but as far as I can tell, all you can do is DOS clojurebot :P |
| 15:11 | gjohnson | hmm... |
| 15:11 | stuartsierra | ,(loop [x 1] (recur (inc x)) |
| 15:11 | clojurebot | EOF while reading |
| 15:11 | Chousuke | to take over the machine itself, you'd have to break java's sandboxing. |
| 15:12 | stuartsierra | ok, I'll play nice, won't retype that |
| 15:12 | rhickey | ,(.down (new [] (down [x] (if (zero? x) x (recur (dec x))))) 42) |
| 15:12 | clojurebot | 0 |
| 15:12 | gjohnson | well, 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:12 | hiredman | rhickey: that is awesome |
| 15:12 | Chousuke | ,(loop [x 1] (recur (inc x))) |
| 15:12 | Chousuke | :p |
| 15:12 | hiredman | ♥ new new |
| 15:12 | clojurebot | Execution Timed Out |
| 15:13 | stuartsierra | Clever clojurebot. |
| 15:13 | hiredman | ~def pcalls |
| 15:13 | gjohnson | apparently so. |
| 15:13 | gjohnson | ah, pretty. |
| 15:13 | hiredman | uh oh |
| 15:14 | gjohnson | that url's not working for me. |
| 15:14 | Chousuke | gjohnson: you might want to use futures instead of agents; agents have a thread pool anyway. |
| 15:15 | kotarak | Chouser: 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:15 | gjohnson | as noted. that's why I don't spawn any threads. |
| 15:16 | gjohnson | I 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:17 | hiredman | ah |
| 15:17 | gjohnson | this should just queue up all the functions more or less evenly across my agents and let the fixedthreadpool handle them. |
| 15:17 | hiredman | because that rev is on the new-new branch |
| 15:17 | hiredman | or not |
| 15:17 | Chouser | kotarak: ah! hm, I don't see why it couldn't. |
| 15:18 | kotarak | Then packaging would be easy. foo/bar/* goes to that .jar, foo/baz/* to that other one. |
| 15:18 | Chouser | rhickey: ,(.no-frickin-way (new [] (#^String no-frickin-way [] "no, really!"))) |
| 15:18 | clojurebot | new Class(x) is (Class. x) |
| 15:18 | kotarak | Without fiddling with the proxy classes. (Which namespace calls which proxy? Hmm... Bookkeeping ahead...) |
| 15:18 | Chouser | ,(.no-frickin-way (new [] (#^String no-frickin-way [] "no, really!"))) |
| 15:18 | clojurebot | "no, really!" |
| 15:18 | gjohnson | my concern is that if I make less agents that the thread pool size, I'll end up with unused threads. |
| 15:19 | Chouser | rhickey: will the ability to create new methods like that go away? |
| 15:20 | hiredman | grr |
| 15:24 | hiredman | kotarak: it's lisp! it has eval! and macros! YEAH! |
| 15:26 | rhickey | Chouser: no, that will stay, to allow for the definitions of helper methods. Calling them from outside will always involve reflection though |
| 15:27 | rhickey | they will have to have names different from those of the supers' methods, and overloading on arity only |
| 15:27 | Chouser | oh, interesting. |
| 15:28 | Chouser | runtime reflection required to call other instances of the same class? |
| 15:28 | rhickey | Chouser: yeah, anything other than this |
| 15:30 | rhickey | the dashes won't work on all JVMs |
| 15:30 | rhickey | so I'll have to filter those |
| 15:31 | rhickey | ,(class (new [])) |
| 15:31 | clojurebot | sandbox$eval$obj__1918 |
| 15:37 | Chouser | ,(new [] (#^String toString [] (str "what's wrong?"))) |
| 15:37 | clojurebot | java.lang.VerifyError: (class: sandbox$eval$obj__1923, method: toString signature: ()Ljava/lang/String;) Wrong return type in function |
| 15:38 | hiredman | ,(class (str "what's wrong?")) |
| 15:38 | clojurebot | java.lang.String |
| 15:38 | hiredman | :/ |
| 15:38 | hiredman | ,(new [Object] (#^String toString [] (str "what's wrong?"))) |
| 15:38 | clojurebot | java.lang.VerifyError: (class: sandbox$eval$obj__1932, method: toString signature: ()Ljava/lang/String;) Wrong return type in function |
| 15:39 | Chouser | the compiler should even know str returns a String |
| 15:39 | hiredman | ,(new [] (#^String toString [] (.toString (str "what's wrong?" "foo")))) |
| 15:39 | clojurebot | #<sandbox$eval$obj__1952 what's wrong?foo> |
| 15:41 | hiredman | ,(str (new [] (#^String toString [] (str "what's wrong?"))) |
| 15:41 | clojurebot | EOF while reading |
| 15:41 | hiredman | ,(str (new [] (#^String toString [] (str "what's wrong?")))) |
| 15:41 | clojurebot | java.lang.VerifyError: (class: sandbox$eval$obj__1981, method: toString signature: ()Ljava/lang/String;) Wrong return type in function |
| 15:41 | trotter | are there any good code coverage tools for clojure? |
| 15:42 | hiredman | ,(.foo (new [] (#^String foo [& bar] "foo")) 1 2) |
| 15:42 | clojurebot | "foo" |
| 15:43 | hiredman | ,(new [] (#^String toString [] #^String (str "what's wrong?"))) |
| 15:43 | clojurebot | java.lang.VerifyError: (class: sandbox$eval$obj__2016, method: toString signature: ()Ljava/lang/String;) Wrong return type in function |
| 15:43 | hiredman | :( |
| 15:43 | hiredman | it's too bad |
| 15:45 | hiredman | lousey Object specifying interface |
| 15:47 | rhickey | Chouser: fixed: http://github.com/richhickey/clojure/commit/3c15d0eb6bdc279c801dd984a3524666d7c5cfbe |
| 15:53 | Chouser | rhickey: Thanks! That's every proxy in contrib, except the read thing: http://n01se.net/paste/knS |
| 15:55 | rhickey | wow |
| 15:56 | rhickey | does it still work? |
| 15:59 | Chouser | yes |
| 15:59 | Chouser | er, every proxy of mine |
| 16:00 | rhickey | will be much nicer without the hints |
| 16:00 | Chouser | there are still proxies in swing_utils and singleton |
| 16:00 | Chouser | yes, it definitely will. |
| 16:21 | Fossi | so, to come back to my question of tomorrow, if i deref a ref, it's contents doesn't get visited, right? |
| 16:21 | Fossi | so i get whatever state the ref might be in? |
| 16:22 | Fossi | s/tomorrow/this morning |
| 16:22 | hiredman | eh? |
| 16:22 | Fossi | http://paste.lisp.org/display/84421 |
| 16:22 | hiredman | "it's contents doesn't get visited" what does that mean? |
| 16:23 | Fossi | "hiredman: you might just put (vec left-events) in the returned pair" |
| 16:23 | hiredman | Fossi: I remember saying that |
| 16:23 | Chousuke | Fossi: camelCase is not very clojurey :p |
| 16:23 | Chousuke | Fossi: you should use hyphens with lisp functions. |
| 16:24 | Fossi | so if on the left, i return @state-ref, i get {} mostly |
| 16:24 | Fossi | Chousuke: ups, all the Java in that app tends to confuse me :) |
| 16:24 | Chousuke | also, I'd recommend not putting any actual dosync logic in your functions. |
| 16:24 | Fossi | that i don't understand |
| 16:25 | hiredman | Fossi: I still want to know what "it's contents doesn't get visited" means |
| 16:25 | Fossi | well, i deref the ref, but i get {} (for example on the repl) |
| 16:25 | Chousuke | Fossi: 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:25 | hiredman | and? |
| 16:25 | Fossi | if i use *1, i suddently get a value |
| 16:26 | hiredman | Fossi: print out the second item in the return vector of calcGameState forces the map |
| 16:26 | hiredman | map being lazy |
| 16:26 | Fossi | yeah, somehow feels weird |
| 16:26 | Fossi | same for try catch really |
| 16:26 | hiredman | the functio being mapped as a side effect of changing the ref |
| 16:27 | hiredman | so the ref does not get changed unless you force the map |
| 16:27 | Fossi | but i guess that's Chousuke's point |
| 16:27 | Chousuke | Fossi: What I'm advocating is isolation of side-effects. ref alterations are side-effects :) |
| 16:27 | Fossi | Chousuke: well, i could have another layer there, yes |
| 16:28 | Fossi | but then, i don't really know what implementors of dispatchEvent might want to do to the state |
| 16:29 | hiredman | anyway |
| 16:29 | hiredman | you should force the map |
| 16:30 | Chousuke | why are you returning a new state-ref though? |
| 16:30 | Chousuke | in calcGameState |
| 16:31 | Fossi | i return @state-ref now actually |
| 16:31 | Fossi | state-ref was just to test it from the repl |
| 16:32 | Fossi | the idea is to have a load of stm calculations being done to get to the new game state for the "mutable" game objects |
| 16:33 | Chousuke | do you really need a ref though? hmm. |
| 16:33 | Chousuke | I mean, perhaps you could reduce the state over the events with dispatch-event? |
| 16:34 | hiredman | yeah |
| 16:34 | alrex021 | I 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:35 | Chousuke | alrex021: (setq swank... '("file:///some/path/here/javalib.jar" "file://more/paths/")) ought to work |
| 16:35 | Fossi | later on the plan is to do it in parallel |
| 16:36 | hiredman | ,(doc pvreduce) |
| 16:36 | clojurebot | "/;nil; " |
| 16:36 | hiredman | clojurebot: curse you! |
| 16:36 | clojurebot | Excuse me? |
| 16:36 | Chousuke | but if future events depend on the earlier state, it's not very parallelisable :/ |
| 16:37 | alrex021 | Chousuke: 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:37 | liebke_ | 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:37 | clojurebot | technomancy is to blame for all failures |
| 16:37 | Chousuke | Fossi: oh, and the (do ...) in changeColor is not needed. function bodies have an implicit do. |
| 16:37 | Fossi | ah, didn't know pvreduce yet |
| 16:38 | Chousuke | Fossi: pvreduce is very new; not in master yet. |
| 16:38 | Fossi | Chousuke: i know, i still like it for reminding me of side effects |
| 16:38 | Fossi | i'll wrap each game object in it's own stm then |
| 16:38 | alrex021 | liebke_: ahh, gr8 the author, what a gr8 community :) ...thanks |
| 16:39 | Chousuke | Fossi: hmm, yeah :) |
| 16:39 | Fossi | and 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:39 | liebke_ | alrex021: good luck, I wish I could be more help, but I'm not an emacs user :) |
| 16:40 | Fossi | alrex021: (directory-files "~/projects/android/bannerwars/libs/" t ".*\.jar") |
| 16:41 | alrex021 | liebke_: out of curiosity, what do you use for your clojure dev? |
| 16:41 | liebke_ | I just use vim and a repl |
| 16:42 | liebke_ | emacs is the way to go though... if you can get it configured :) |
| 16:42 | lbj | liebke_: I'll recommend Emacs + SLIME to you, its a fairly effecient combo, and easily installable thanks to technomancy's clojure-mode |
| 16:42 | Fossi | it's infecting |
| 16:42 | gjohnson | k |
| 16:43 | Fossi | i begin to select text with ctrl space in firebird |
| 16:43 | liebke_ | lbj: I know, but I've used vi/vim for too long to switch at this point |
| 16:43 | Fossi | and try to swap desktops with shift-left |
| 16:43 | Fossi | liebke_: viper-mode? :) |
| 16:44 | gjohnson | how about vimclojure/gorilla |
| 16:46 | hiredman | http://technotales.wordpress.com/2007/10/03/like-slime-for-vim/ |
| 16:47 | kotarak | *ieck* do yourself a favour and use vimclojure. (shameless advertisement) |
| 16:47 | kotarak | the screen has problems. |
| 16:48 | kotarak | It works but is tricky. |
| 16:48 | hiredman | *shrug* |
| 16:50 | hiredman | if you ever open a file that contains function calls, not just function definitions, vimclojure will execute those function calls |
| 16:50 | hiredman | I find that to be unacceptable |
| 16:51 | hiredman | heck |
| 16:51 | kotarak | IMHO, you shouldn't do that. Providing an entry point brings flexibility and advantages when debugging. |
| 16:51 | hiredman | if you try and edit a .clj file that is not valid (not all the parens are closed, etc) vimclojure will puke |
| 16:51 | hiredman | kotarak: I have an entry point, and I have a .clj file that contains a call to that entry point |
| 16:52 | hiredman | so if I open up my scratch clojure file, vimclojure pukes |
| 16:52 | Chousuke | also, if the file contains (shell-out "rm -rf /") or something :P |
| 16:52 | kotarak | You can disable the dynamic part at any time and just use static vim with <C-n> and friends. Works also very well. |
| 16:52 | hiredman | yeah, I have vim clojure installed and use the static part |
| 16:53 | hiredman | I never use gorilla |
| 16:53 | hiredman | I use slime.vim works great, and it works for things besides clojure |
| 16:58 | Fossi | yay. it works again. now that i have that set up, i can start doing more business logic :) |
| 17:11 | gjohnson | okay, so I know this is a pretty remedial java question... |
| 17:11 | gjohnson | but how can I ask a threadpool for its size (number of threads)? |
| 17:11 | hiredman | ~jdoc java.util.concurrent.ThreadPool |
| 17:11 | gjohnson | I see that clojure.lang.Agent uses 2 + the number of cores detected by the runtime for the fixed threadpool size |
| 17:11 | hiredman | damn |
| 17:12 | gjohnson | ? |
| 17:12 | hiredman | ~jdoc java.util.concurrent.ThreadPoolExecutor |
| 17:12 | hiredman | still no dice |
| 17:12 | hiredman | http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html |
| 17:12 | hiredman | there is a getPoolSize method |
| 17:13 | Chouser | show works great for this |
| 17:13 | gjohnson | ah, thanks. |
| 17:13 | Chouser | (show clojure.lang.Agent) --> discover pooledExecutor and soloExecutor |
| 17:14 | Chouser | (show clojure.lang.Agent/pooledExecutor) --> discover getPoolSize and getMaximumPoolSize |
| 17:14 | Chouser | ,(.getMaximumPoolSize clojure.lang.Agent/pooledExecutor) |
| 17:14 | clojurebot | 3 |
| 17:39 | Drakeson | how can I make a memoized recursive function? |
| 17:41 | hiredman | ,(macroexpand '#'foo) |
| 17:41 | clojurebot | (var foo) |
| 17:46 | Drakeson | hiredman: that is (defn f1 [n] (if (zero? n) 0 (+ (#'f1 (dec n)) n))) (def f1 (memoize f1)) ? |
| 17:46 | hiredman | I am not sure |
| 17:47 | Chousuke | that would work, but it'll blow the stack if the recursion is too deep. |
| 17:48 | Chouser | that shouldn't be necessary |
| 17:50 | Chouser | (defn f1 [n] (prn n) (when (> n 0) (f1 (dec n)))) |
| 17:50 | Chouser | (def f1 (memoize f1)) |
| 17:50 | Chouser | (f1 5) ; prints 5 to 0 |
| 17:50 | Chouser | (f1 10) ; prints 10 to 6 |
| 17:51 | Drakeson | Chouser: thanks. That is an interesting way to test :) |
| 17:59 | alrex021_ | 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:05 | alrex021_ | Could someone enlighten me on how one can configure "properly" full clojure support for emacs? |
| 18:05 | alrex021_ | I am really struggling with this |
| 18:05 | hiredman | ~emacs |
| 18:05 | clojurebot | emacs is best configured for Clojure with instructions at http://technomancy.us/126 |
| 18:05 | hiredman | *shrug* |
| 18:15 | alrex021_ | hhm: Clojure install failed .. git clone git://github.com/kevinoneill/clojure.git when following http://technomancy.us/126 instructuins |
| 18:16 | durka42 | hmm, those instructions are old, the git repository is under richhickey |
| 18:16 | durka42 | http://github.com/richhickey/clojure/tree/master |
| 18:17 | technomancy | alrex021_: getting the latest version of clojure-mode will fix that problem. |
| 18:18 | alrex021_ | hhmm so is ELPA option not gonna work? |
| 18:19 | alrex021_ | I used ELPA to install latest clojure-mode .. then ran clojure-install ...that didn't work |
| 18:19 | alrex021_ | so I take it I need to manual install |
| 18:20 | technomancy | alrex021_: clojure-mode 1.3 is in ELPA |
| 18:20 | technomancy | that will do it |
| 18:21 | alrex021_ | (I am extremely new to Emacs) ... do I have to restart after installing 1.3 via ELPA before I run clojure-install? |
| 18:22 | technomancy | you shouldn't have to, but if you're having problems you might try that. |
| 18:22 | alrex021_ | also, I take it I don't have to add anything to my .emacs file after I install the clojure-mode |
| 18:23 | technomancy | no, but it will give you some code to add to your .emacs after M-x clojure-install finishes. |
| 18:23 | technomancy | but it should be pretty clear from the instructions |
| 18:26 | alrex021_ | ok I see, thx. I restarted and ran clojure-install...now its getting it from new git location |
| 18:28 | alrex021_ | is there a way ti autoreload the .emacs file without restart of emacs? |
| 18:28 | alrex021_ | off hand :) |
| 18:28 | technomancy | sure; open it and do M-x eval-buffer |
| 18:29 | alrex021_ | thx |
| 18:31 | alrex021_ | 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:31 | alrex021_ | line it gave me is just (clojure-slime-config) |
| 18:33 | alrex021_ | so I added (clojure-slime-config) to my .emacs and restarted and then ran: M-x slime |
| 18:33 | alrex021_ | but no luck |
| 18:38 | rhickey | new new: added signature inference, overload detection: http://github.com/richhickey/clojure/commits/new |
| 18:38 | rhickey | so now you don't need to hint except to disambiguate |
| 18:38 | hiredman | :O |
| 18:38 | hiredman | :D |
| 18:42 | rhickey | ,(str (new [] (toString [] "hello"))) |
| 18:42 | clojurebot | "sandbox$eval$obj__2040@945b95" |
| 18:43 | rhickey | hrm |
| 18:46 | hiredman | ,(str (new [] (toString [] "hello"))) |
| 18:46 | clojurebot | java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers) |
| 18:46 | hiredman | whelp |
| 18:46 | hiredman | it was a wild and crazy ride |
| 18:46 | rhickey | oh no |
| 18:47 | rhickey | did clojurebot not like proxy either? |
| 18:47 | hiredman | yep |
| 18:49 | mebaran151_ | is there a super type for Float and Double? |
| 18:49 | mebaran151_ | other than Number |
| 18:49 | rhickey | is permission java.lang.RuntimePermission "accessDeclaredMembers"; dangerous? |
| 18:50 | hiredman | ,(str (new [] (toString [] "hello"))) |
| 18:50 | clojurebot | java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers) |
| 18:51 | hiredman | I dunno |
| 18:51 | hiredman | ,(str (new [] (toString [] "hello"))) |
| 18:51 | clojurebot | "hello" |
| 18:51 | hiredman | ,(ancestors Float) |
| 18:51 | clojurebot | #{java.lang.Object java.lang.Number java.io.Serializable java.lang.Comparable} |
| 18:55 | rhickey | cool |
| 20:31 | iBong | is there a (sugary) way to set flags like case insensitivity when using #regex literals? |
| 20:44 | sillycloud | yes |
| 20:44 | sillycloud | regexp : /pattern/i |
| 20:45 | sillycloud | or var rgx = new RegExp(); rgx.ignoreCase = true |
| 20:47 | iBong | thx |
| 20:49 | sillycloud | um |
| 20:49 | sillycloud | sorry |
| 20:49 | sillycloud | wrong channel |
| 20:49 | sillycloud | lol |
| 20:49 | iBong | er |
| 20:49 | sillycloud | my answer is obviously wrong |
| 20:49 | iBong | yeah that didnt work |
| 20:49 | sillycloud | >.< |
| 20:49 | iBong | I was like, cool, just like ruby |
| 20:49 | sillycloud | lols |
| 20:50 | iBong | the java way is super ugly |
| 20:50 | iBong | hoping clojure had a nice alternative, like not having to escape escapes |
| 20:50 | Raynes | sillycloud: Think you're in #scala? :p |
| 20:50 | sillycloud | worse |
| 20:50 | sillycloud | i'm currently in #flash |
| 20:50 | iBong | lol |
| 20:50 | sillycloud | helping the noobs |
| 20:51 | sillycloud | personally |
| 20:51 | sillycloud | i call zomg_var_to_lower_case() on all my string literals |
| 20:51 | iBong | is there a way to set case insensitive on #"regex" ? |
| 20:55 | arbscht | iBong: #"(?i)..." |
| 20:58 | iBong | thats it, nice, thank you |
| 21:11 | Raynes | ,(apply str (repeat 10 "(") (repeat 10 ")")) |
| 21:11 | clojurebot | "clojure.lang.LazySeq@b0c04bc1))))))))))" |
| 21:11 | hiredman | prn-str |
| 21:12 | Raynes | Cool. |
| 21:29 | gjohnson | hi there. |
| 21:30 | gjohnson | I 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:31 | gjohnson | what is the rationale for the fixed threadpool's size being 2 greater than the number of cores? |
| 21:32 | gjohnson | anyone? |
| 21:33 | gjohnson | anyone alive out there? |
| 21:33 | rhickey | gjohnson: there isn't any special rationalization, other than it isn't worthwhile to create many more computation threads than you have procs |
| 21:34 | gjohnson | rhickey: indeed. I was wondering specifically why you chose to create 2 more than the number of cores. |
| 21:34 | gjohnson | rhickey: i.e. is there a performance benefit I'm missing from not having the same number or perhaps 1 or 3 more? |
| 21:35 | rhickey | gjohnson: no, it's still subject to change |
| 21:35 | gjohnson | rhickey: 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:35 | clojurebot | clojure is far closer to perfection then python |
| 21:36 | gjohnson | rhickey: 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:36 | gjohnson | rhickey: but when I scaled up to more agents (say 4*cores), performance was degraded considerably. |
| 21:37 | rhickey | gjohnson: using send or send-off? |
| 21:37 | Chouser | ,(.getMaximumPoolSize clojure.lang.Agent/pooledExecutor) |
| 21:37 | clojurebot | 3 |
| 21:37 | gjohnson | rhickey: just send, so they were all using the fixedThreadPool |
| 21:38 | gjohnson | rhickey: seemed like the extra agent overhead was just bogging down my processor without getting any advantage since there were no free threads. |
| 21:38 | rhickey | the number of agents shouldn't matter much then |
| 21:39 | gjohnson | rhickey: well, I need at least at many as there are threads in the thread pool, otherwise I'll have idle threads. |
| 21:39 | rhickey | it doesn't work that way, there are just jobs in the queues getting pulled off by threads, agents don't do anything themselves |
| 21:39 | gjohnson | rhickey: right, I understand that, but each agent can only have one thread running on it at a time. |
| 21:39 | rhickey | yes, I mean when more than numThreads |
| 21:40 | gjohnson | rhickey: so if there are less agents(work queues) than threads...well, you know. |
| 21:40 | rhickey | so 4 threads is 4 threads even if 100 agents |
| 21:40 | gjohnson | rhickey: right, but 4 threads is 3 threads if you only have 3 agents. |
| 21:40 | hiredman | … |
| 21:40 | rhickey | but you said you added more agents and it slowed down |
| 21:40 | rhickey | 4 *cores |
| 21:41 | gjohnson | rhickey: yes, that was my observation. sorry, these are two different issues. |
| 21:41 | gjohnson | rhickey: what I noticed was that as I added more agents, my processors were being utilized less. |
| 21:41 | rhickey | do the agents do any io? |
| 21:41 | gjohnson | rhickey: usage was dropping maybe 10% or so on each one. |
| 21:42 | gjohnson | rhickey: no, they are doing CPU bounded work (agent-based simulation, no punning intended) |
| 21:43 | gjohnson | rhickey: perhaps I was just having a strange day at my machine. *shrugs* |
| 21:43 | rhickey | and was each job the same size? |
| 21:44 | gjohnson | rhickey: no, they were exploratory tree searches on variable-sized trees. |
| 21:44 | gjohnson | rhickey: but each time I ran the simulation, it was on the same set of trees. |
| 21:44 | rhickey | well, than some agents could be done and doing nothing and the work serializes on the others |
| 21:44 | gjohnson | rhickey: the data didn't change, just possibly the order that the agents got around to processing them. |
| 21:44 | rhickey | then |
| 21:45 | rhickey | forkjoin was made for this |
| 21:45 | rhickey | because it does work stealing |
| 21:45 | rhickey | you should try par |
| 21:45 | gjohnson | rhickey: hmm...I see. |
| 21:45 | gjohnson | rhickey: the code pcalls (i.e. pmap) looked very promising for my application actually. |
| 21:46 | rhickey | agents are really for stateful asynchronous things, for threading you can just use futures, or ideally, try the par branch |
| 21:46 | gjohnson | rhickey: 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:46 | rhickey | in the par branch you can put you job data in a vector and call pvmap, get work stealing etc for free, no coordination |
| 21:47 | gjohnson | rhickey: when I wrote this code, I don't believe futures had yet been added to the language spec. |
| 21:47 | gjohnson | rhickey: I've been at these algorithms for the past few years. |
| 21:47 | rhickey | gjohnson: 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:48 | hiredman | futures weren't present |
| 21:48 | gjohnson | indeed |
| 21:48 | gjohnson | ack, I seem to have missed that. |
| 21:49 | gjohnson | rhickey: 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:50 | rhickey | gjohnson: I'm not recommending that |
| 21:50 | gjohnson | rhickey: 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:50 | gjohnson | rhickey: 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:50 | gjohnson | (yes, I know that's silly sounding, hiredman) |
| 21:51 | gjohnson | and I didn't find the parallel library terribly transparent in the website docs. |
| 21:52 | gjohnson | and 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:52 | gjohnson | rhickey: so I've been having a bit of trouble getting traction with it. |
| 21:52 | gjohnson | rhickey: any pointers on reading references to grok this stuff? |
| 21:53 | rhickey | http://github.com/richhickey/clojure/blob/26f5aed73c9cc2959beee0dd43a0d434fce83631/src/clj/clojure/par.clj |
| 21:54 | rhickey | there is a par branch on github, try it |
| 21:54 | rhickey | gotta run |
| 21:54 | gjohnson | alright, thanks |
| 22:38 | bpattison | I'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:38 | Chouser | are you sure you want a list and not a set? |
| 22:39 | Chouser | ,(#{:a :b :c :d} :c) |
| 22:39 | clojurebot | :c |
| 22:39 | Chouser | ,(#{:a :b :c :d} :e) |
| 22:39 | clojurebot | nil |
| 22:39 | hiredman | (.contains '(:a :b :c) :a) |
| 22:40 | hiredman | ,(.contains '(:a :b :c) :a) |
| 22:40 | clojurebot | true |
| 22:40 | bpattison | yep, that's perfect -- I'll use a set |
| 22:40 | hiredman | ,(.contains [:a :b :c] :a) |
| 22:40 | clojurebot | true |