2008-12-22
| 00:03 | hiredman | the hard drive in the machine that was running clojurebot died |
| 00:24 | Chouser | hiredman: :-( |
| 00:25 | hiredman | it maybe a week or two before it gets rebuilt |
| 00:50 | joha1 | would like to get unbuffered console input (e.g. pressing a key should return at once, instead of waiting for ENTER), preferably without having to use something big like JCurses. So far I'm failing. Any ideas? |
| 00:56 | Chouser | joha1: in C you'd use tcsetattr to set the terminal's parameters |
| 00:58 | joha1 | yes, I tried something similar with stty (I'm on Linux). Didn't work, but perhaps my mistake |
| 00:59 | Chouser | ah, shelling out to stty? |
| 00:59 | Chouser | that rings a bell... |
| 00:59 | joha1 | well, I couldn't make it work, but perhaps you have seen something similar? |
| 01:00 | Chouser | not from java/clojure, but I'm pretty sure I've done it. maybe from perl? |
| 01:00 | joha1 | Hmm, perhaps I should google a bit more. I already tried "stty -icanon min 1" |
| 01:05 | Chouser | try adding "time 0" to that |
| 01:11 | Chouser | I don't think that's it. |
| 01:12 | Chouser | you're using Runtime's .exec method? |
| 01:19 | joha1 | chouser: yes i am |
| 01:19 | joha1 | must be a better way |
| 01:19 | Chouser | ok, the problem is that the sub-process is run in a way that's not associated with the terminal |
| 01:20 | joha1 | makes sense |
| 01:20 | Chouser | if I add -F /dev/pts/termnum to the stty command line, it works |
| 01:20 | Chouser | so, what to use for termnum? |
| 01:20 | Chouser | I tested by running "tty" on the command line and copying the result into my test program manually. |
| 01:21 | Chouser | but I don't know if there's anyway to get the terminal associated with the java process's stdin |
| 01:22 | joha1 | running tty from Runtime.exec would give the tty for the new process instead, right? |
| 01:22 | Chouser | right. |
| 01:22 | Chouser | trying that got me back the string "not a tty" |
| 01:23 | joha1 | in worst case I could always to to get JCurses to work. Much overhead for something so simple, though... |
| 01:24 | joha1 | thanks anyway |
| 01:24 | Chouser | or use Swing. :-) |
| 01:24 | joha1 | sure, but sometimes you just need a text console |
| 01:24 | joha1 | :) |
| 01:24 | Chouser | I think you mean a JTextPane |
| 01:24 | Chouser | sometimes you just need a JTextPane |
| 01:25 | joha1 | not if I don't have X on my server |
| 01:26 | zakwilson | People have X on servers? |
| 01:29 | Chouser | joha1: you could do the stty setup/teardown in a launching script |
| 01:31 | joha1 | I've just found a page describing how to set up nonblocking input in Java using the stty method |
| 01:31 | joha1 | http://www.darkcoding.net/software/non-blocking-console-io-is-not-possible/ |
| 01:31 | joha1 | will try to get this working in clojure |
| 01:32 | joha1 | but of course I could set it up in a calling script as well |
| 01:36 | Chouser | huh, he bounces it through "sh -c ... < /dev/tty" and apparently that does it. |
| 01:39 | Chouser | oh, nope, I screwed up my test. |
| 01:47 | joha1 | Yeah, this works! |
| 01:47 | joha1 | (import '(jline ConsoleReader)) |
| 01:47 | joha1 | (.readVirtualKey (new ConsoleReader)) |
| 01:47 | joha1 | and there are lots of other useful functions in Jline |
| 01:47 | Chouser | :-) |
| 01:58 | lisppaste8 | Chouser pasted "unbuffered input at text terminal" at http://paste.lisp.org/display/72515 |
| 01:59 | joha1 | nice |
| 02:00 | Chouser | but if jline of jcurses is an option, I'm sure you'll have better results there. |
| 02:01 | joha1 | it will certainly be easier, and multi-platform. Still interesting to know that it can be done |
| 04:10 | klinkers | how fast is Clojure? |
| 04:10 | klinkers | benchmarks? |
| 04:14 | leafw | klinkers: as fast as java. |
| 04:15 | leafw | but, considering it enables better algorithms, your programs may be faster than naive, imperative implementations in java. |
| 04:18 | klinkers | enables bette ralgorithms? |
| 04:18 | klinkers | dont yu always have more options in java? you can do inplce sorting etc |
| 04:18 | klinkers | ormaybe you cna in clojrue too |
| 04:19 | klinkers | anyway does AOT mean I can compile to a JAR? and that other java-libs can use my clojure code? |
| 04:19 | leafw | yes. |
| 04:26 | lisppaste8 | leafw pasted "benchmark" at http://paste.lisp.org/display/72517 |
| 04:26 | leafw | klinkers: have a look for yourself. |
| 04:26 | leafw | it's a very simple benchmark, adding numbers. |
| 04:34 | klinkers | janino? |
| 04:35 | klinkers | clojure wih primitives is that doing things like : (+ (int 5) (int 6)) ? |
| 04:37 | leafw | and type declarations. |
| 04:44 | klinkers | that is a type declaration no? |
| 04:49 | leafw | well, (int 5) is a type declaration indeed, although I can't help thinking of it as a cast (but it isn't) |
| 04:50 | leafw | although (int 1.5) prints 1. |
| 04:50 | leafw | "Coerce to int", (doc int) says. |
| 05:00 | klinkers | clojure.examples.hello |
| 05:00 | klinkers | is clojure and examples directories then? |
| 05:01 | hoeck | klinkers: right |
| 05:02 | hoeck | ./clojure/examples/hello.clj |
| 05:05 | klinkers | hmm i use september there fore compiel is not working? |
| 05:06 | leafw | klinkers: pull svn |
| 05:08 | hoeck | klinkers: or use the clojure pre realease |
| 05:08 | hoeck | (the download link on clojure.org) |
| 06:18 | bOR_ | Hi all, I ran into: java.lang.Exception: Transaction failed after reaching retry limit (NO_SOURCE_FILE:0) |
| 06:18 | bOR_ | and on the forum I see that stuart sierra ran into the same thing, and rich recommended not using a wait function. |
| 06:19 | bOR_ | wondered if the official (await ... ... ..) is also a dont-use-this-in-very-long-loops wait function |
| 06:19 | bOR_ | http://groups.google.com/group/clojure/browse_thread/thread/c8c3510f01f951e1/a2b74c4fd85c89bb?lnk=gst&q=retry+limit#a2b74c4fd85c89bb |
| 06:22 | bOR_ | it seems that all elements in my vector of refs are locked now. |
| 06:22 | bOR_ | mm. |
| 06:23 | fyuryu | bOR_: I can't really answer your question, never encountered the problem so far, but try asking in a couple of hours (5-6) |
| 06:23 | fyuryu | bOR_: and a source snippet would help |
| 06:23 | bOR_ | I'll drop it into the forum then. |
| 06:26 | fyuryu | try structuring the code differently, waiting in a loop doesn't seem like a goo idea (but without knowing what you want to do exactly, it's hard to tell) |
| 06:26 | fyuryu | maybe agents would be a good fit for you task? |
| 06:29 | fyuryu | bOR_: oh wait, you're using await in that loop? |
| 06:35 | jgracin | replaca: fantastic job on cl-format! I was hoping someone would do it eventually, and this was quick. |
| 06:43 | bOR_ | (sorry, was cleaning my bike). I've 8 agents that each are send off in a loop, at the end of sending them off, I await them all. |
| 06:43 | bOR_ | the loop itself is a million times. |
| 06:43 | bOR_ | (but I'm not sending off 8 million agents at the same time) |
| 06:43 | bOR_ | (just 8) |
| 06:44 | bOR_ | each agent has the task of doing 7 things to every reference in a vector, in random order. |
| 06:44 | bOR_ | and right now, while we're no longer in a loop or anything, |
| 06:45 | bOR_ | I can't even do a single thing to a single ref anymore without it failing due to many retries. |
| 06:45 | bOR_ | is there any way to see which refs are all locked right now, and by whom they are locked? |
| 06:54 | fyuryu | and how big is the vector that the agents operate on? |
| 06:55 | bOR_ | vector of 1000 refs |
| 06:56 | bOR_ | it's an agent-based model. each ref might contain a host, and the 7 things I'm doing to them are birth / death / evolution / infection. |
| 06:57 | bOR_ | thanks for talking though, will help in knowing what information to put in the google group post. |
| 06:58 | fyuryu | bOR_: I don't think there is a way to see who locks the refs in a given moment |
| 06:59 | bOR_ | think I know.. |
| 06:59 | bOR_ | based on doc await. |
| 06:59 | bOR_ | if there's one of the transactions not returning. |
| 06:59 | bOR_ | await just keeps blocking everything, I guess. |
| 07:00 | fyuryu | ah, so you're not sure if every agent completes his work? |
| 07:00 | bOR_ | as await might still be waiting for one of the (send-off) to finish. |
| 07:00 | bOR_ | normally it should. |
| 07:00 | bOR_ | and it tends to |
| 07:01 | bOR_ | but maybe if for some reason I don't know yet, one of the send-off agents blocks. |
| 07:01 | bOR_ | ok.. |
| 07:01 | bOR_ | that's a good question. |
| 07:01 | bOR_ | what happens with await, when one of your threads runs into the retry limit. |
| 07:02 | fyuryu | (doc await-for) |
| 07:02 | bOR_ | gracias. that might work indeed. |
| 07:02 | bOR_ | normally, a single year takes about 60 seconds to compute. |
| 07:03 | bOR_ | well, sometimes 90 |
| 07:03 | bOR_ | so I can just put the await on 3 minutes. |
| 07:04 | bOR_ | I'll make a post, cause I wonder what happens with the thread that didn't return on await. |
| 07:24 | klinkers | im trying to compile but the examples are not so easy |
| 07:24 | klinkers | ok i have a file C:/clojure/progs/hello.clj |
| 07:24 | klinkers | how would I compile it? |
| 07:24 | klinkers | hte namespeace should contain :gen-class? |
| 07:24 | klinkers | and the compeltr apth? |
| 07:25 | leafw | klinkers: http://pacific.mpi-cbg.de/wiki/index.php/Clojure_Scripting#Generating_java_classes_in_.class_files_from_clojure_code |
| 07:26 | leafw | klinkers: http://clojure.org/compilation |
| 07:49 | klinkers | yes but what im wondering voer is namespaces |
| 07:50 | klinkers | if i ahve a file |
| 07:50 | klinkers | C:/clojure/progs/hello.clj |
| 07:50 | klinkers | what namespace should i put it in? |
| 07:51 | Chouser | klinkers: they only way for that path to be a valid lib would be if it has the namespace progs.hello (and C:/clojure is in your classpath) or the namespace clojure.progs.hello (with C:/ in your classpath) |
| 07:54 | klinkers | i have C:/clojure in my classpath and I have the file int he namespace progs.hello |
| 07:55 | klinkers | i do (compile 'progs.hello) and i get: |
| 07:55 | klinkers | java.io.IOException: The system cannot find the path specified (hello.clj:1) |
| 07:55 | klinkers | user=> |
| 08:00 | fyuryu | klinkers: "progs.hello" namespace == "c:/some-path/progs/hello.clj", and c:/some-path AND c:/some-path/classes must be in your classpath. |
| 08:04 | klinkers | java.io.IOException: The system cannot find the path specified (hello.clj:1) |
| 08:04 | klinkers | progs.hello=> |
| 08:04 | klinkers | what is classes there btw? |
| 08:04 | klinkers | the classes it uses u mean? |
| 08:05 | Chousuke | klinkers: the classes dir contains the compiled code |
| 08:05 | Chousuke | or will contain |
| 08:05 | Chousuke | it needs to exist and be in the classpath before compilation though. |
| 08:05 | klinkers | http://hpaste.org/13252 |
| 08:06 | Chousuke | which I think is not very nice, but I don't know a way around it either. |
| 08:06 | klinkers | should it be called classes? |
| 08:07 | Chousuke | klinkers: you don't need str with println btw. |
| 08:07 | Chousuke | it can take multiple arguments. |
| 08:07 | acieroid | how can I cast an Integer to a Char with clojure ? |
| 08:07 | klinkers | still: progs.hello=> java.io.IOException: The system cannot find the path specified (hello.clj:1) |
| 08:08 | Chousuke | you'll want your classpath to contain C:/clojure/;C:/clojure/classes/ |
| 08:09 | Chousuke | along with the others |
| 08:09 | Chousuke | and remove the entry with hello.clj in it |
| 08:09 | kogu | acieriod: char? |
| 08:09 | acieroid | hum |
| 08:09 | acieroid | forgot this function >< |
| 08:09 | Chousuke | klinkers: and make sure C:/clojure/classes/ exists |
| 08:10 | kogu | ok, im really new to lisp, can someone help me with this really basic thing? |
| 08:10 | kogu | http://hpaste.org/13253 |
| 08:11 | kogu | it always prints 0 |
| 08:11 | klinkers | you should use if |
| 08:11 | klinkers | instead of when |
| 08:11 | klinkers | i think |
| 08:11 | acieroid | no |
| 08:11 | Chousuke | no |
| 08:11 | acieroid | because data are immutables |
| 08:11 | klinkers | yes and branch |
| 08:11 | Chousuke | kogu: + does not change points |
| 08:12 | klinkers | ah ysw recur points |
| 08:12 | Chousuke | kogu: it only outputs a new value, which is promptly discarded |
| 08:12 | kogu | i see, so how can i use a global variable for points? |
| 08:12 | acieroid | with refs |
| 08:12 | rhickey | could everyone please use paste.lisp.org please? then we get a single archive to look back through |
| 08:13 | rhickey | lisppaste8: url |
| 08:13 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 08:13 | Chousuke | kogu: once you (let [points 0]) points is 0 and will not change |
| 08:13 | kogu | ok, so how do i define a variable which will change |
| 08:13 | Chousuke | kogu: for that code, you don't. |
| 08:14 | Chousuke | kogu: simply modify the logic to call recur in a way that passes the change to the next loop :) |
| 08:14 | kogu | ah i see, that makes sense, thanks a bunch, emacs you bastard, here i come |
| 08:14 | Chousuke | but if you really need a global "points" state, the way to do that is to use a ref and dosync |
| 08:15 | kogu | i haven't gotten to that part yet, but i will keep that in mind |
| 08:15 | Chousuke | but surprisingly many apps don't even need refs |
| 08:16 | Chousuke | you can also have state as something that is passed to each function and they then return a new state |
| 08:18 | kogu | hmmmm |
| 08:18 | kogu | have to grok it, still think in java |
| 08:18 | kogu | one more ques, how can i do a lot of if elseif elseif else? |
| 08:19 | Chousuke | cond |
| 08:19 | kogu | wow, thats right |
| 08:19 | kogu | ty again |
| 08:21 | Chousuke | using (or) can also be useful if you need to stop as soon as you get something non-false |
| 08:23 | Chousuke | or returns the first non-false value as is, so the following will work assuming the search function returns nil if an item is not found: (defn get-item [] (or (search source1) (search source2) :default-item)) |
| 08:24 | klinkers | acieroid: Integer. |
| 08:25 | acieroid | klinkers, char works perfect |
| 08:27 | klinkers | and it should be c:/clojure/classes/ not c:/clojure/progs/classes or anything? |
| 08:27 | klinkers | progs.hello=> (apply char "2") |
| 08:27 | klinkers | \2 |
| 08:27 | klinkers | progs.hello=> (Integer. "2") |
| 08:27 | klinkers | 2 |
| 08:29 | Chousuke | klinkers: yeah, c:/clojure/classes/ |
| 08:31 | klinkers | so what could i be missing? |
| 08:31 | klinkers | java.io.IOException: The system cannot find the path specified (hello.clj:1) |
| 08:31 | klinkers | i ahve the correct paths in the classpath |
| 08:32 | klinkers | path specified (hello.clj |
| 08:32 | klinkers | should that says the whole pth to hello.clj? |
| 08:32 | Chousuke | no. |
| 08:33 | Chousuke | does the classes dir exist? |
| 08:33 | Chousuke | it must exist when you start the VM |
| 08:33 | hoeck | klinkers: have you set *compile-path* to "c:\\clojure\\classes" ? |
| 08:34 | Chousuke | shouldn't that be the default. |
| 08:34 | klinkers | oh |
| 08:34 | klinkers | where is compile-path? |
| 08:34 | klinkers | where do is et it anyway? |
| 08:34 | Chousuke | in your clojure program |
| 08:34 | hoeck | it defaults to "classes" |
| 08:35 | Chousuke | a simple (set! *compile-path* "c:/clojure/classes") at the top of your script should do I guess. |
| 08:35 | klinkers | set! ? |
| 08:36 | hoeck | or do (binding [*compile-path* "bla\\foo"] (compile 'clojure.expamples.hello)) |
| 08:36 | klinkers | u emand ef? |
| 08:37 | hoeck | *compile-path* is bound above the repl so you can set! it |
| 08:37 | klinkers | im using emacslisp in clojure then? |
| 08:37 | Chousuke | no. |
| 08:37 | Chousuke | *compile-path* is a clojure setting, not an emacs one |
| 08:38 | klinkers | hello mama! |
| 08:38 | klinkers | there it worked |
| 08:38 | klinkers | it egenrates a bunch of .class stuff |
| 08:39 | klinkers | then i can compile that to a JAR with javac!? |
| 08:39 | Chouser | I use the 'jar' command to produce a .jar file |
| 08:42 | klinkers | exactly how? you mvoe to ~/classes/ and then? |
| 08:43 | klinkers | or jsut form anywhere(mind me i dont know java tow ell) |
| 08:43 | kogu | klinkers: you just zip that folder, and rename it's extension to .jar |
| 08:44 | kogu | klinkers: make sure that the folder path is preserved |
| 08:47 | Chouser | kogu/hoek: you can set up the manifest correctly like that? |
| 08:48 | kogu | cho: usually if you don't have a main class, you don't need the manufest file |
| 08:48 | Chouser | ah, ok. |
| 08:49 | klinkers | jars a re zipped .class-collections? |
| 08:49 | Chouser | klinkers: yes |
| 08:49 | Chouser | with some (apparently optional) extra header info |
| 08:50 | kogu | jars, wars, *ars |
| 08:50 | kogu | all the same |
| 08:50 | klinkers | so i should have another word between progs and the actual program then |
| 08:54 | lisppaste8 | kogu pasted "untitled" at http://paste.lisp.org/display/72523 |
| 08:54 | kogu | ummm, how to i return the points from that function? |
| 08:55 | Chousuke | kogu: use let instead of def |
| 08:55 | Chousuke | kogu: and: (do (println points) points) |
| 08:55 | klinkers | kogu: exactly what are yout rying to do? idiomatically you shouldnt use de flike that |
| 08:55 | Chousuke | print* |
| 08:56 | kogu | cho: print is just for debugging |
| 08:56 | kogu | cho: im loopping 10 times, creating a new roll each time, eval the roll and adding points accordingly |
| 08:57 | Chousuke | kogu: oh right. |
| 08:57 | Chousuke | kogu: I misread that thing :P |
| 08:57 | Chousuke | use if instead of when then |
| 08:57 | Chouser | change your (when (> counter 0) ...) to (if (zero? counter) points (do ...)) |
| 08:58 | kogu | cho: ah i see, ty, so i change def -> let, and change when->if |
| 08:58 | kogu | cho: ty |
| 08:58 | Chouser | right -- those changes are related, but you need both. |
| 08:58 | Chouser | those changes are NOT related, but you need both |
| 08:59 | kogu | cho: right, let because i want it scoped locally, and if to return the points |
| 08:59 | Chouser | right |
| 08:59 | Chousuke | kogu: (if (> counter 0) (let [roll (new-roll)] (print points) (recur (dec counter) (+ points (eval-roll roll)))) points) |
| 08:59 | Chousuke | parentheses may not match... |
| 08:59 | Chouser | well, also 'let' because 'def' inside a function like that is icky. |
| 09:00 | hoeck | kogu: or do (reduce + (take 10 (repeatedly new-roll))) |
| 09:04 | Chousuke | or because you need eval-roll: (reduce + (take 10 (repeatedly #(eval-roll (new-roll))))) |
| 09:05 | kogu | cho: whoa!!! |
| 09:05 | kogu | let me try that |
| 09:14 | kogu | cho: dude! that was awesome, that worked like a charm |
| 09:17 | Chousuke | it was hoeck's idea though. I just fixed it to match your code. :) |
| 09:18 | Chousuke | often you can use the higher-order functions and reduce instead of explicit loops. |
| 09:19 | kogu | cho: well i got both working, i need to look into this reduce, never used this before |
| 09:23 | Chousuke | kogu: reduce is a function which takes a function of (at least) two arguments and a sequence, then applies that function to the first two values of the seq, then again to the result and the next value in the seq, etc. |
| 09:24 | kogu | hmmm, never thought it could be used like this |
| 09:24 | Chousuke | so (reduce + [1 2 3 4]) = (+ 4 (+ 3 (+ 1 2))) |
| 09:24 | kogu | btw, anyone using clojure-mode on emacs here? how to see which parens does the parens under the cursor match to? |
| 09:24 | hoeck | kogu: i recommend the http://clojure.org/sequences page for an overview over the sequence library, though you may just use (doc reduce) at the repl |
| 09:25 | kogu | will read it, right now |
| 09:25 | Chousuke | but of course works with any function |
| 09:25 | Chousuke | for example, to find the max value of a sequence: (reduce #(if (< %1 %2) %2 %1)) [] |
| 09:26 | Chousuke | oopw |
| 09:26 | Chousuke | well something like that |
| 09:26 | jdz | kogu: that's an emacs configuration option, "paren match highlighting" in options menu |
| 09:26 | Chousuke | does anyone know how to make emacs emit only spaces instead of tabs? |
| 09:26 | Chousuke | I noticed mine emits tabs and that screw up formatting sometimes. |
| 09:27 | jdz | Chousuke: indent-tabs-mode |
| 09:27 | jdz | (set it to nil ;) |
| 09:27 | hoeck | (setq-default indent-tabs-mode nil) |
| 09:27 | hoeck | but mine is an xemacs |
| 09:27 | jdz | yes, M-x customize-variable intent-tabs-mode |
| 09:29 | Chousuke | the customisation facilities in emacs are awesome |
| 09:30 | Chousuke | maybe a bit too awesome |
| 09:30 | Chousuke | there's so much to customise it can be difficult to find the relevant stuff |
| 09:31 | hoeck | but you can do <tab> and look at the autocomplete buffer |
| 09:32 | hoeck | i whish i could do this in the crappy powerbuilder ide i have to use at work :( |
| 09:36 | klinkers | nice |
| 09:36 | bOR_ | Hi rhickey, working on a reproducable version that doesn't take 3 hours on 8 cores :) |
| 09:37 | bOR_ | posted the source online. |
| 09:38 | klinkers | when will v1.0 of clojure come out? |
| 09:38 | bOR_ | as long as none of you here are in the competitive field of doomsaying, I shouldn't get into trouble of sharing it here. |
| 09:40 | hoeck | klinkers: http://groups.google.com/group/clojure/browse_thread/thread/381e575bad1cfb77 |
| 10:00 | rhickey | bOR_: I put up a rev that might help your problem - I think once you started failing you might have quickly wrapped the timestamp - now an AtomicLong in svn 1181 |
| 10:01 | bOR_ | thanks. |
| 10:01 | bOR_ | not sure I understand. |
| 10:01 | bOR_ | what you mean with wrapped the timestamp / now an AtomicLong. |
| 10:02 | kogu | rhickey : thank you for clojure |
| 10:02 | rhickey | bOR_: was an AtomicInteger - but once you started failing and let the sim continue you'd consume timestamps at a high rate |
| 10:02 | rhickey | kogu: you're welcome! |
| 10:02 | bOR_ | ok. |
| 10:03 | bOR_ | the high rate was 1.8 seconds? ("Elapsed time: 1871.911 msecs" ) |
| 10:05 | rhickey | bOR_: that would explain your locked up situation afterwards, but you probably still have some bad transaction granularity. |
| 10:06 | bOR_ | hehe. getting something to run concurrent in clojure is easier than understanding all the things that go wrong. Reading up on transaction granularity now. I'll just see if I can make a version of the model that quickly produces the error. |
| 10:09 | bOR_ | I'll see if I can reduce it somehow. |
| 10:11 | bOR_ | from birth: (let [living (apply vector (gather :born)) |
| 10:11 | bOR_ | ah. |
| 10:11 | rhickey | right |
| 10:11 | bOR_ | birth is doing a gather of all living. |
| 10:11 | bOR_ | and gather will be locking the whole thing. |
| 10:11 | rhickey | that's the gather I saw |
| 10:11 | bOR_ | the rest almost only messes with a single ref. |
| 10:12 | rhickey | bOR_: it won't be locking, as it is only a read, but it will increase the footprint of the world snapshot required for that dosync |
| 10:13 | bOR_ | ah. |
| 10:14 | bOR_ | but if that is just a memory thing, I seem to have enough memory. |
| 10:14 | bOR_ | for a moment thought it would be locking, but it is indeed only reading, and using a snapshot of what once was a father ;) |
| 10:16 | bOR_ | at most I'm doing 8 births at the same time in the whole population. that doesn't seem too bad. |
| 10:16 | bOR_ | (8 processors) |
| 10:27 | klinkers | how can i remove a namespace from the repl? |
| 10:28 | hoeck | (doc remove-ns) |
| 10:28 | klinkers | and how do I require my user-file? do i have to put it in a namespace? |
| 10:29 | klinkers | but the repl still says the old namespace... |
| 10:35 | kogu | what's the opp of "nil?" |
| 10:37 | Chouser | kogu: depends, but generally 'seq' or just the object itself |
| 10:37 | Chouser | s/generally/usually/ |
| 10:39 | kogu | cho: its a number, hmmm |
| 10:39 | kogu | (defn eval-roll [roll] |
| 10:39 | kogu | (let [payout (odds roll)] |
| 10:39 | kogu | (if (nil? payout) -1 (- payout 1))) |
| 10:39 | kogu | where "odds" is a map |
| 10:39 | Chouser | you want to know if the map is empty? |
| 10:40 | Chousuke | payout is a number? |
| 10:40 | kogu | no, if i don't know have the key in the "odds" map, i get back null, which throws nullpointer |
| 10:40 | kogu | in if(payout) |
| 10:40 | Chousuke | kogu: you could use (get odds roll 0) |
| 10:40 | Chousuke | for a default value |
| 10:40 | Chouser | right, or just (odds roll 0) |
| 10:43 | kogu | (defn eval-roll [roll] |
| 10:43 | kogu | (let [payout (odds roll 0)] |
| 10:43 | kogu | (if (payout) -1 (- payout 1)))) |
| 10:43 | Chouser | no |
| 10:43 | Chouser | (defn eval-roll [roll] (- (odds roll 0) 1)) |
| 10:44 | kogu | yeah, that makes more sense |
| 10:44 | kogu | ty again |
| 10:44 | Chouser | but in the general case of wanting to handle a failed lookup separately, by default map lookups return 'nil', which in an 'if' means the same as false. |
| 10:45 | Chouser | so: (let [payout (odds roll)] (if payout (- payout 1) -1)) |
| 10:45 | Chousuke | note no parentheses around payout. :) |
| 10:45 | kogu | ah, that was where i was stuck |
| 10:45 | Chouser | or: (if-let [payout (odds roll)] (- payout 1) -1) |
| 10:47 | kogu | cho: final question for you, I have a list of 2 random numbers, i have a odds table like this |
| 10:47 | kogu | (def odds {'(5 5 5) 25 '(4 4 4) 5 '(3 3 3) 5 '(2 2 2) 5 '(1 1 1) 5 '(0 0 0) 5}) |
| 10:48 | kogu | now i need to check if i have 2 zeros 1 non zero |
| 10:48 | kogu | what would be the lispy way todo this |
| 10:49 | kogu | as i need to check for (0 0 *) (0 * 0) and (0 0 *) |
| 10:49 | Chouser | you have a list of 3 numbers? |
| 10:49 | kogu | yes, i have a list of 3 numbers (0-5 0-5 0-5) |
| 10:50 | kogu | for checking 3 numbers i made a map above |
| 10:50 | Chousuke | (= 2 (count (filter zero? triple)) |
| 10:50 | Chousuke | ) |
| 10:51 | Chouser | though I had: (= '(0 0) (filter zero? triple)) |
| 10:52 | kogu | yes, that works perfectly |
| 10:53 | kogu | infact thats a better approach than the map for the 3 identical values |
| 10:53 | kogu | ty again |
| 10:54 | kogu | any fucntion to check if all values are identical? |
| 10:54 | Chouser | (apply = coll) |
| 10:55 | Chousuke | heh. |
| 10:57 | Chousuke | many of these solutions have the "d'oh" look to the |
| 10:57 | Chousuke | tem |
| 10:57 | Chousuke | ... |
| 10:57 | Chousuke | them |
| 10:57 | kogu | (defn eval-roll [roll] |
| 10:57 | kogu | (cond |
| 10:57 | kogu | (apply = roll) 25 |
| 10:57 | kogu | (= 2 (count (filter zero? roll))) 10 |
| 10:57 | kogu | (= 1 (count (filter zero? roll))) 1 |
| 10:57 | kogu | () -1)) |
| 10:57 | kogu | how does this look |
| 10:57 | kogu | i think im done |
| 10:58 | Chouser | use :else instead of () |
| 10:58 | kogu | done |
| 10:58 | kogu | time to benchmark against the java code, woohoo!!! |
| 10:59 | Chouser | you're sure it matters? |
| 10:59 | Chousuke | kogu: most likely it'll be a fair bit slower :) |
| 11:00 | Chouser | the most important benchmark is LOC, or some more reliable measure of mental complexity. |
| 11:00 | Chousuke | benchmarking might make java look good but does the *code* look as good as the clojure equivalent? |
| 11:00 | Chousuke | or "equivalent" :/ |
| 11:02 | kogu | loc : 18 vs 57 |
| 11:02 | Chouser | I wonder if condp would help here. I have no sense of how to use its features yet. |
| 11:02 | Chouser | kogu: ah, nice. That's worht so much more than 5 seconds vs. 1 second of processing time, or whatever. |
| 11:03 | kogu | speed : 7 sec vs 2, that's not bad |
| 11:03 | kogu | cho: ty again, you are truly awesome |
| 11:04 | Chouser | you could get back some or all of that speed, but it would start to cost you in code clarity |
| 11:06 | danm_ | good morning |
| 11:08 | kogu | gm |
| 11:15 | kogu | any recommended profilers for clojure? |
| 11:44 | RSchulz | YourKit is what I use, though I've yet to apply it to Clojure code. |
| 11:44 | RSchulz | kogu: ^^^ |
| 11:44 | kogu | rs: ty |
| 11:45 | kogu | does anyone of anywork on something like jsp's for clojure? |
| 11:45 | kogu | as in, compile to servlets |
| 11:46 | duck1123 | kogu: there's been varying amounts of success with compojure |
| 11:46 | kogu | i did look into compojure, but right now there is no mention of any templating system |
| 11:46 | kogu | its much better to write html and embedd lisp rather than the other way around |
| 11:47 | duck1123 | it uses compojure.html to generate html from vectors |
| 11:48 | kogu | duck: yeah, but i would like to write html file, and embedd bits of lisp in it |
| 11:48 | duck1123 | There was a thread recently on that subject, I don't know how far anyone got |
| 11:49 | kogu | cool, let me dig that up |
| 11:49 | hiredman | ugh |
| 11:49 | hiredman | why would you want to write any html at all? |
| 11:50 | kogu | hehe, work!!! |
| 11:51 | kogu | is jvm good for anything else? |
| 11:51 | Chousuke | s-expressions map nicely to HTML anyway |
| 11:51 | qebab | hey, is it possible to use keyword params or optional params? |
| 11:53 | duck1123 | kogu: http://tinyurl.com/7vlcj6 |
| 11:53 | kogu | step 1: download free html template |
| 11:53 | kogu | step 2: write clojure blogging system |
| 11:53 | kogu | step 3: ??? |
| 11:53 | kogu | step 4: profit!!! |
| 11:53 | hiredman | sounds horrible :( |
| 11:54 | Chouser | qebab: http://groups.google.com/group/clojure/msg/51bb53ca077154f8 |
| 11:54 | hiredman | compojure's vector -> html deal is great |
| 11:55 | Chouser | qebab: that's some old code, so it could probably be written more concisely now. But at first glance it looks like it would still work. |
| 11:58 | qebab | Chouser: I don't really need it, I just think it'd be convenient. :) |
| 11:58 | qebab | Chouser: Thanks, though. |
| 11:58 | Chouser | if you just want some keyword args tacked on the end of zero or more positional args, you can do it in about one line |
| 12:02 | Chouser | (defn foo [a b c & keyargs] (let [{:keys [d e f]} (apply hash-map keyargs)] [a b c d e f])) |
| 12:02 | Chouser | (foo 1 2 3 :e 9) ==> [1 2 3 nil 9 nil] |
| 12:39 | daswerth | Chouser: yesterday you wrote up something on unbuffered input to a text terminal: http://paste.lisp.org/display/72515 |
| 12:39 | Chouser | yep |
| 12:40 | daswerth | I'm afraid I don't understand why there are to defn's for "system"? |
| 12:40 | Chouser | just a pasting mistake on my part. The first is overridden by the second. |
| 12:41 | Chouser | as in, replaced. The first is completely unnecessary. |
| 12:41 | daswerth | ah, great. :) |
| 13:30 | klinkers | booya clojure is awesome |
| 13:30 | zakwilson | We've noticed. That's why we're here. |
| 13:30 | klinkers | a nice fairly pure functional language + a lot of good javalibs |
| 13:31 | klinkers | anyone working on machine learning stuff? |
| 13:31 | Chouser | people seem to ask about genetic programming a lot |
| 13:31 | klinkers | i working on webapp/mobile app using machine elarning for secret stuff and great profits! |
| 13:32 | klinkers | maybe i will eb the first big clojure success story |
| 13:33 | Kerris7 | I've been tinkering with the idea of writing a Chinese Chess a.i. in Clojure |
| 13:34 | Kerris7 | should make for a decent final year project, but the other candidates are quite strong (Scala) |
| 13:36 | klinkers | final year of what? |
| 13:37 | klinkers | undergrad? |
| 13:37 | klinkers | i wrote an optimal-playing tictactoe in clojure but chinese chess is a little harder :) |
| 13:38 | Kerris7 | klinkers: undergrad |
| 13:43 | Kerris7 | klinkers: yes, a little harder :P http://en.wikipedia.org/wiki/Xiangqi |
| 13:44 | Chouser | Kerris7: I was learning Scala before I abandoned it for Clojure, in case that's worth anything to you. |
| 13:45 | Kerris7 | Chouser: I'm working on a portfolio that'll hopefully admit me to a good Master program and the existing material for that domain is mainly in OCaml |
| 13:46 | Chouser | Kerris7: ah. sounds like you may have significantly different goals than I had. |
| 13:46 | Kerris7 | Chouser: if you don't mind me prying, what were your intentions? |
| 13:46 | Chouser | for a masters program, Clojure's non-invasive type system may look less impressive. |
| 13:48 | Chouser | Kerris7: For years I'd been looking for a practical language that was very "expressive", or at least that's the term I generally use. |
| 13:50 | Kerris7 | alright |
| 13:50 | Chouser | ...which means something along the lines of getting the most done with the least amount of code, where the things being done are the sorts of things python and ruby have been good at: command-line tools, data and string wrangling, web apps, etc. |
| 13:50 | gnuvince | Hehe |
| 13:50 | technomancy | heh; I guess for education purposes, Scala has the advantage of looking more impressive since the type system is harder to use. =) |
| 13:50 | Chouser | technomancy: exactly what I was thinking. |
| 13:50 | gnuvince | "Dude, Clojure is too easy, no way you're getting that Masters Degree!" |
| 13:51 | gnuvince | Throw in partial continuations and amb in there to make it look more impressive |
| 13:51 | Chouser | I was skating through project euler problems in Scala, liking it just fine. |
| 13:52 | Chouser | Then I tried to write a nice API (a.k.a. embedded DSL) for querying XML documents. |
| 13:52 | gnuvince | Didn't like it so much then? |
| 13:52 | Chouser | the type system bit me hard. I was trying to use the code as I wrote it to help me think about the problem. When I got it into a state that seemed to express what I wanted, I still couldn't test it because my types were all messed up. |
| 13:53 | Chouser | I spent a few days trying to get my trivial 4 or 5 function system to actually compile. |
| 13:54 | Chouser | and even then the lack of macros meant my API wasn't as tidy as I wanted. |
| 13:54 | Kerris7 | If I can find sufficient material on writing lexers with Lisp maybe I can muster up something with Clojure |
| 13:55 | Chouser | Anyway, a couple rhickey videos later, and I'd found a new home here. The result a similar project in Clojure is at clojure.contrib.zip-filter |
| 13:56 | gnuvince | Chouser: are you a Java refugiee? |
| 13:56 | Chouser | not really. I learned Java a tiny bit ages ago -- actually learned threading in Java -- but I've never liked it much. |
| 13:57 | gnuvince | ok |
| 13:57 | gnuvince | I'm thinking I should probably learn Java |
| 13:58 | Chouser | I was giving the JVM a chance because Yegge talked me into Rhino, shortly before Project Euler talked me right back out of it. |
| 13:58 | gnuvince | Rhino... |
| 13:58 | gnuvince | *meh* |
| 13:59 | Chouser | Well, I thought I wanted an optional type system and C-like syntax. |
| 13:59 | gnuvince | Is there a Java library to do like Python's struct.pack and struct.unpack? |
| 13:59 | technomancy | the way they promoted it early on was pretty weird--hey guys, you can use all these awesome Java libraries and package stuff up as a WAR file. |
| 13:59 | gnuvince | Nobody really wants C-like syntax; people just think they want it. |
| 13:59 | Chouser | gnuvince: for C library interop, or more general binary data packing? |
| 13:59 | technomancy | and Ruby users look at the Java libs, and they have uniformly horrible APIs... and we have no idea what a WAR is, but it sounds violent. |
| 14:00 | technomancy | so it was hard to get excited about JRuby at first. =) |
| 14:00 | hiredman | technomancy: but uniformly documented |
| 14:00 | gnuvince | Chouser: general binary data unpacking |
| 14:01 | Chouser | gnuvince: ah, don't know. sorry. |
| 14:01 | technomancy | hiredman: you only have to learn a library once; you have to deal with the API forever. =) |
| 14:01 | gnuvince | Chouser: thanks |
| 14:01 | hiredman | technomancy: you just deal with the api long enough to wrap it with something more sane |
| 14:02 | hiredman | javadoc is a life saver |
| 14:02 | technomancy | well, the only Java libraries I've used have been jakarta httpclient (wretched, horrible API) and ROME (decently usable, but the docs weren't very good) |
| 14:03 | technomancy | why you'd name a library after Jakarta is beyond me; I've been there, and it's a pretty miserable city. |
| 14:04 | hiredman | maybe that is why they renamed it to apache commons |
| 14:04 | Kerris7 | maybe it was mainly developed by programmers from the city :V |
| 14:06 | leafw | likely it was chosen beause of the 'j' in the name. |
| 14:06 | hiredman | heh |
| 14:06 | lisppaste8 | drewr pasted "atom exception -- how is this possible?" at http://paste.lisp.org/display/72540 |
| 14:06 | technomancy | leafw: probably. It's a good warning for what happens when you pick a name without doing research first. |
| 14:07 | drewr | I think there's either a bug in atom or swap!. |
| 14:07 | hiredman | someone in #java just asked about a "macro system" for java, and someone said "macros are for desktop apps like word and excel or for editors." |
| 14:07 | drewr | Somehow iref is nil in get-validator. |
| 14:07 | Chouser | drewr: got any code to reproduce it? |
| 14:08 | technomancy | heh |
| 14:08 | leafw | hiredman: difficult to preach to the blind. |
| 14:08 | Kerris7 | or the deaf |
| 14:08 | drewr | Chouser: I'm trying to distill. My smaller test cases aren't triggering it. |
| 14:08 | Chouser | drewr: are you using validators? |
| 14:08 | drewr | I thought I would start with the exception first, because it's pretty strange. |
| 14:10 | Chouser | drewr: I can replicate the top 3 lines of that stack trace with: (swap! nil inc) |
| 14:11 | lisppaste8 | drewr annotated #72540 with "possible sample code" at http://paste.lisp.org/display/72540#1 |
| 14:13 | Chouser | drewr: so if your agent's map ever loses its :foo key, you'd get that exception. |
| 14:14 | drewr | Chouser: I'm trying to see if that happens. |
| 14:15 | drewr | Dangit, it's nil. This thing is supposed to be immutable! :-) |
| 14:17 | Chouser | hm, the agent? not likely. :-) |
| 14:17 | technomancy | has anyone here tried hashdot? (http://hashdot.sf.net) it seems to make the JVM CLI experience somewhat less onerous. |
| 14:17 | drewr | Chouser: No, the map :-) |
| 14:41 | gnuvince | How come (reduce str xs) is so much slower than (apply str xs)? |
| 14:42 | hiredman | str makes stringbuilders I believe |
| 14:43 | hiredman | so reduce ends up instanciating a lot more objects |
| 14:45 | gnuvince | How does apply avoid that? |
| 14:48 | rhickey | gnuvince: a single call to str creates one StringBuilder, and apply is a single call to str |
| 14:48 | rhickey | reduce is many calls to str |
| 14:50 | gnuvince | apply creates a single StringBuilder and calls .add() (or whatever the name is) n times while reduce creates n StringBuilders and calls .add() only once on those? |
| 14:52 | rhickey | gnuvince: it's best to forget about str - apply calls a fn once with a sequence of args, reduce calls it once for each pair of elements. str optimizes the concatenation of its args, but can't across calls |
| 14:55 | gnuvince | ok |
| 14:55 | hiredman | the "namespaces, keywords, and symbols" looks like it might need a faq entry |
| 14:57 | duck1123 | Does anyone know if a SVG version of the clojure logo exists? |
| 14:58 | RSchulz | hiredman: Whatever makes you think that?? |
| 15:01 | hiredman | :P |
| 15:16 | hoeck | duck1123: clojure-glyph.svg in the files section of the google group |
| 15:21 | Chouser | it only seems complicated if you try to think about it |
| 15:22 | hiredman | Chouser:? |
| 15:22 | Chouser | namespaces, vars, symbols, keywords. They all work very naturally almost all the time. |
| 15:23 | hiredman | yes |
| 15:23 | hiredman | I don't mean it is complicated, I mean there are two different threads in group about it, so maybe it is a faq |
| 15:23 | Chouser | it's only when you try to think about edge cases or unusualy usages that it starts to seem complicated. |
| 15:23 | Chouser | oh |
| 15:27 | Chouser | it does seem a bit hard to pin down what should go in a faq vs. an appropriate place in the regular docs. |
| 15:29 | hiredman | well |
| 15:29 | hiredman | things that are asked about frequently can go in the faq? |
| 15:29 | Chouser | if the docs were complete, would they still be asked about frequently? |
| 15:30 | hiredman | the only way to find out is to complete the docs |
| 15:30 | Chouser | if I want to learn about topic X, do I need to read it's section in the regular docs plus in the FAQ in order to get a complete picture? |
| 15:32 | hiredman | if the docs clear it up, and people stop asking about it, it can be removed from the faq |
| 15:32 | hiredman | it's not like this is being carved in stone, it's html |
| 15:38 | technomancy | is it safe to say atoms are meant for idempotent actions? |
| 15:40 | Chouser | not necessarily. |
| 15:41 | Chouser | Someone mentioned on the group the function of generating unique ids, where skipping an id is acceptible. atom would work fine for that. |
| 15:42 | technomancy | that makes sense |
| 15:47 | klinkers | if i have a file main that uses the namespace progs.someapp.donkey and progs.someapp.horse and they both happen to have a function group-by. now, how do i refer to each group-by in main? |
| 15:49 | Chouser | if you try to (use ...) both of them, it should complain on the second one. |
| 15:52 | Chouser | klinkers: so you can either do (use '[progs.someapp.horse :rename {group-by horse-group-by}]) |
| 15:53 | Chouser | or (require '[progs.someapp.horse :as horse]) and say (horse/group-by ...) |
| 16:47 | hiredman | why don't explanations of what a monad is make sense? |
| 17:04 | Chousuke | hiredman: actually, reading through the wikipedia explanation I think I can see some sense in it. |
| 17:05 | hiredman | then you are a better man than I |
| 17:06 | Chousuke | hiredman: it seems monads can be used to specify semantics to computations without affecting the "functional" nature of the values those computations return |
| 17:06 | hiredman | *woosh* |
| 17:07 | Chousuke | I think the Maybe monad is pretty simple to understand: the computation can fail, so the Maybe monad wraps the value in something that can tell you whether it failed or not. |
| 17:07 | amit_ | any idea why i might get an IllegalAccessError trying to invoke a constructor for a java class even though I'm able to import it succesfully ? (I'm on the clojure prompt) |
| 17:08 | Chousuke | but if it doesn't fail, the result is safe to extract from the monad and treat as if it were just another value |
| 17:08 | hiredman | sounds like Just Another Object |
| 17:11 | Chousuke | for IO I guess the IO monad "describes" the IO required to get the value (a string, for example), but once you have the value and have extracted it from the monad, it's immutable just like any other value |
| 17:11 | Chousuke | so monads give you a way to explicitly define that something else than just functional value computation is going on, and work with that. |
| 17:12 | hiredman | uh huh |
| 17:50 | drewr | Is there any way I can get @@(send-off (agent :a) (fn [x] (send-off (agent :b) (fn [y] y)))) to work? |
| 17:50 | drewr | Work == return :b immediately. |
| 17:52 | Chouser | you want the top-level expression to not return until both agents have updated their status? |
| 17:53 | Chouser | s/status/state/ |
| 17:53 | drewr | Yes, that would be ideal. |
| 17:54 | Chouser | using agents synchronously like this is a bit non-idiomatic (are you sure you don't want refs?) which costs you some complexity, but it can be done. |
| 17:54 | drewr | In my use case, :a is a long-running thread which fires b's off periodically. What happens is b agents are return immediately, but their actions aren't fired until what seems like too late. |
| 17:55 | Chouser | 'sends' done in an agent's action are held until the action is complete. this is a feature. |
| 17:56 | Chouser | agent :a is in some kind of loop, but not sending to itself? |
| 17:57 | drewr | Yes, :a is doing something similar to (loop [] (something-that-eventually-fires-b) (Thread/sleep ...) (recur)). |
| 17:58 | Chouser | it might help to (send *agent* thisfn) instead of recur. That will allow other sends to go as well. |
| 17:59 | drewr | You mean recurse by creating another agent? |
| 17:59 | hiredman | this might also be faq worthy |
| 17:59 | Chouser | drewr: no, recurse by sending to your own agent again |
| 18:00 | hiredman | *agent* is bound to the current agent inside an agent action |
| 18:00 | Chouser | drewr: this is how at least one of the agents behaves in Rich's ant demo |
| 18:00 | drewr | Ah. Hm, let me look at that. |
| 18:02 | hiredman | man, I miss clojurebot |
| 18:02 | hiredman | it's like phantom limb |
| 18:02 | drewr | OK, (send-off *agent* #'behave). |
| 18:04 | hiredman | clojurebot: FAQ#2 is sends and send-offs that occur in an action sent to an agent do not take place until the agent's state changes |
| 18:05 | Chouser | drewr: right, though there's no need for the #' prefix anymore |
| 18:06 | Chousuke | hiredman: talking to ghosts now? where is clojurebot, anyway? |
| 18:06 | hiredman | hard drive died, so I need to rebuild the machine |
| 18:06 | Chousuke | ah. |
| 18:06 | drewr | Chouser: So send* won't consume the stack? |
| 18:07 | drewr | It will just fire off new threads and the old ones gc? |
| 18:07 | Chouser | (send (agent 9) (fn act [v] (prn v) (when (pos? v) (send *agent* act) (dec v)))) |
| 18:07 | hiredman | cute |
| 18:08 | Chouser | drewr: even better, it will probably return the current thread to the pool before the new one is needed, so it may even use the same thread. |
| 18:08 | Chouser | but yes, no consumption of finite resources |
| 18:10 | Chouser | interesting -- using 'send' on this dual-core laptop, the action is indeed run on the same thread each time. |
| 18:10 | drewr | Sweet. |
| 18:11 | Chouser | using 'send-off' it oscilates between two threads. |
| 18:11 | Chouser | I wouldn't bet too heavily on either behavior in any given circumstance, of course. |
| 18:12 | Chouser | drewr: so that'll get your sends to agent :b going periodically. you still need the top-level thread to wait until they're all done? |
| 18:13 | drewr | In this case, :b is a network connection, and :a watches to see if any die and restarts them. |
| 18:14 | drewr | Starting works great, but the restarts involve the nested agent issue. |
| 18:14 | Chouser | sure. |
| 18:14 | drewr | Each connection has a listener agent which is another long-running loop that's doing (read-line) on the input stream. |
| 18:15 | drewr | These listener agents (and their associated async msg queues) don't ever have their actions fired. |
| 18:15 | drewr | Presumably that's because of my infintely loop-recurs that don't return. |
| 18:16 | Chouser | right. another benefit of the re-send looping is you can swap in a new definition of your function at runtime and the next send will pick it up. |
| 18:16 | drewr | Ah, yes. |
| 18:24 | drewr | So in (send *agent* foo), does the arg to foo become the future state of the first run through foo? |
| 18:25 | Chouser | no, the return value of the action becomes the new state of the agent. |
| 18:25 | Chouser | in that little example I posted above, I did the (dec v) after the (send ...) |
| 18:26 | drewr | That's what I was basing that on. I think you said what I meant by my question. |
| 18:26 | drewr | Just didn't express it clearly. |
| 18:26 | Chouser | :-) ok |
| 18:54 | arohner | I'm trying to read out of a socket, and BufferedReader.read() wants a buffer to fill up. What is the easiest way to create a buffer from clojure? |
| 18:56 | Chouser | you want the classic char[] variety? |
| 18:56 | arohner | ah, make-array |
| 18:56 | arohner | Chouser: yes |
| 18:56 | Chouser | right, (make-array Character/TYPE 1024) |
| 18:57 | arohner | thanks |
| 21:28 | arohner | (java.util.regex.Pattern/matches "(.+): (.+)" "Host: localhost:1344") |
| 21:28 | arohner | true |
| 21:29 | arohner | user> (. #"(.+): (.+)" (split "Host: localhost:1344")) |
| 21:29 | arohner | #<String[] [Ljava.lang.String;@19ad02> |
| 21:29 | arohner | user> (alength (. #"(.+): (.+)" (split "Host: localhost:1344"))) |
| 21:29 | arohner | 0 |
| 21:29 | arohner | That is *completely* unhelpful |
| 21:29 | arohner | matches with zero length? |
| 21:35 | Chouser | (re-seq #"(.+): (.+)" "Host: localhost:1344") |
| 21:36 | Chouser | the regex matches the entire string, so it's a match and you get an array |
| 21:36 | Chouser | but the contents of the array are the pieces of the string separated by what matched -- which is nothing. |
| 21:39 | arohner | oh, I needed to use re-matches |
| 22:07 | pjb3 | Hey, I have a solution for Paul Graham |
| 22:07 | pjb3 | 's Accumulator Generator in Clojure: http://github.com/pjb3/accgen/tree/master/accgen.clj |
| 22:07 | pjb3 | This seems pretty good, any ideas on how to do it differently? |
| 22:08 | hiredman | lisppaste8: url? |
| 22:08 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 22:10 | hiredman | pjb3: http://paste.lisp.org/display/70873 |
| 22:11 | pjb3 | hiredman: huh? |
| 22:11 | hiredman | its a counter |
| 22:12 | pjb3 | The problem: Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i. |
| 22:12 | hiredman | so how c works is |
| 22:12 | hiredman | (c 3) returns a function |
| 22:13 | hiredman | which returns a function, etc |
| 22:13 | hiredman | until you pass the function something not a number |
| 22:13 | hiredman | at which point it tells you how many times you called the function |
| 22:13 | pjb3 | hiredman: well, that's nice, but I don't see how that's a solution to the problem |
| 22:14 | hiredman | it is a subset of the problem, the case where you increment by 1 |
| 22:15 | hiredman | anyway |
| 22:16 | pjb3 | hiredman: It's a solution to a different problem |
| 22:16 | hiredman | I did not read the problem, I just saw "Accumulator Generator" |
| 22:16 | pjb3 | (let [acc (foo 1)] (acc 20) (acc 21)) |
| 22:16 | pjb3 | should be 42 |
| 22:17 | pjb3 | I think the original intent of the problem is basically a test to see "does your language have closures and lambas" |
| 22:17 | pjb3 | Which PG considers to be important things |
| 22:18 | pjb3 | but the other thing you need is mutable state |
| 22:19 | pjb3 | This works pretty much the same way, except you have to give the function access to the atom as a closure |
| 22:33 | doublefree | Hi all, I'm new to Clojure, and I wonder what is a fast way to select a (or n) random element(s) from a potentially large set? |
| 22:35 | doublefree | I'd like to avoid converting the set to a vector if possible |
| 22:40 | pjb3 | doublefree: Off the top of my head, I don't know of a way to do that without converting it to a vector |
| 22:42 | doublefree | pjb3: ok - perhaps it is my data's destiny to live in a vector after all |
| 22:42 | pjb3 | doublefree: Does this help? http://stackoverflow.com/questions/124671/picking-a-random-element-from-a-set |
| 22:47 | doublefree | I see the proposed Lisp solution there reflects my initial approach (the following doesn't work because PersistentHashSet does not support nth which makes sense I suppose): (defn pick-random [set] (nth set (random (count set)))) |
| 22:47 | pjb3 | huh, sets aren't seqs? |
| 22:48 | pjb3 | doublefree: Yeah, I was just trying that, but ran into sets not being a seq |
| 22:49 | hiredman | nothing is it's own seq except lists |
| 22:49 | hiredman | but seq knows how to turn sets into seqs |
| 22:49 | hiredman | user=> (seq #{:a :b :C}) |
| 22:49 | hiredman | (:b :a :C) |
| 22:50 | pjb3 | (defn pick-random [set] (let [sq (seq set)] (nth sq (rand-int (count sq))))) |
| 22:53 | doublefree | pjb3: thanks works well enough for now! |
| 22:53 | pjb3 | doublefree: yeah, not sure if that's "fast" |
| 22:53 | pjb3 | is (seq #{...}) O(n)? |
| 22:54 | pjb3 | Or is there some fast way under the covers of making a lazy-seq from a set |
| 22:55 | pjb3 | clojurebot: ? |
| 22:56 | hiredman | I have the new hard drives for the clojurebot machine |
| 22:56 | hiredman | so it will be back soon |
| 22:56 | pjb3 | anyway, the docs for nth say it takes a coll, and the docs for sets says it is a collection |
| 22:57 | pjb3 | Right, and (coll? #{}) is true |
| 22:57 | pjb3 | so, that's a little confusing |
| 22:59 | hiredman | maybe something to mention to rhickey |
| 23:08 | Chouser | almost none of the collections are seqs, but all provide efficient (generally lazy) seqs when you pass them to seq |
| 23:09 | Chouser | nth doesn't work on all collections, and unlike some functions doesn't apply seq to its parameter |
| 23:09 | hiredman | yeah I just looking at the source in google code |
| 23:09 | drewr | I changed some sends I had to send-off and certain things started working and I have no idea why. |
| 23:10 | hiredman | maybe it should say "only works on certain collections" |
| 23:10 | hiredman | I take that back |
| 23:10 | hiredman | the doc string doesn't say it takes collections |
| 23:10 | hiredman | don't know why I thought it did |
| 23:11 | Chouser | it uses 'coll' as the arg name |
| 23:11 | hiredman | short for collar of course |
| 23:47 | doublefree | I find it strange that (first #{1 2}) and (second #{1 2}) work while (nth #{1 2} 0) does not... I see first and second call seq on their args, and apparently nth does not. I wonder why this is. |
| 23:47 | Chouser | nth can't be any faster that O(n) on a seq |
| 23:47 | Chouser | but it it works in O(1) time on vectors, array, etc. |
| 23:53 | doublefree | yes, but nth could seq its arg if it's not of a class that provides constant time lookup itself and in doing so provide a more consistent interface. anyways no biggy. |