2009-03-23
| 00:01 | durka42 | it seems this has come up |
| 00:01 | durka42 | http://groups.google.com/group/clojure/browse_frm/thread/134642cc76de17f7/90ef52f8f4c68e0a?lnk=gst&q=mevery#90ef52f8f4c68e0a |
| 00:01 | durka42 | page down to chouser's comments on mevery? |
| 00:03 | Mec | yup i agree |
| 00:13 | Mec | how does this make sense, i swap the argument names around, and swap the arguments i pass, and get different values |
| 00:15 | durka42 | paste? |
| 00:16 | Raynes | I hate spending an hour fixing something that isn't broken. |
| 00:16 | Mec | indeed |
| 00:17 | Mec | looks like its working now who knows why |
| 00:28 | nascent16 | ok, let's say i have a map of classes (def classes {:one One, :two Two}). Later on I want to do something like: (let [klass (:one classes)] (klass.)) |
| 00:28 | duncanm | what's the clojure equivalent of EXACT->INEXACT from Scheme? |
| 00:28 | nascent16 | but it doesn't like that |
| 00:28 | Raynes | (-> apply doc) |
| 00:28 | Raynes | That was aweasome. |
| 00:29 | Raynes | awesome* |
| 00:29 | duncanm | how do i convert a ratio to a number with a decimal point? |
| 00:29 | Raynes | ,(double (/ 3 2)) |
| 00:29 | clojurebot | 1.5 |
| 00:29 | Raynes | Like that. |
| 00:29 | duncanm | oh |
| 00:30 | nascent16 | ,(/3 2) |
| 00:30 | clojurebot | Invalid token: /3 |
| 00:30 | nascent16 | ,(/ 3 2) |
| 00:30 | clojurebot | 3/2 |
| 00:30 | Mec | ,(double 3/2) |
| 00:30 | clojurebot | 1.5 |
| 00:30 | Raynes | double simply coerces the value to a double. |
| 00:30 | slashus2 | ,(double (+ 1/4 1/8)) |
| 00:30 | clojurebot | 0.375 |
| 00:31 | nascent16 | ,(+ 1/4 1/8) |
| 00:31 | clojurebot | 3/8 |
| 00:31 | nascent16 | (+ 1/5 1/8) |
| 00:31 | nascent16 | haha |
| 00:31 | duncanm | ,(ratio 0.375) |
| 00:31 | clojurebot | java.lang.Exception: Unable to resolve symbol: ratio in this context |
| 00:31 | duncanm | oh |
| 00:32 | duncanm | ,(Ratio. 0.375) |
| 00:32 | clojurebot | java.lang.IllegalArgumentException: Unable to resolve classname: Ratio |
| 00:32 | durka42 | nascent16: you might have to do that as sort of a macro. (eval `(new ~(:one classes))) |
| 00:32 | duncanm | so there's no INEXACT->EXACT? |
| 00:32 | slashus2 | ,(rationalize 0.375) |
| 00:32 | clojurebot | 3/8 |
| 00:33 | Mec | you could do (defn ration [n] (/ n (pow 10 (count (str n)))) |
| 00:33 | duncanm | oh |
| 00:33 | slashus2 | duncanm: That work? |
| 00:33 | Mec | ((fn ratio [n] (/ n (pow 10 (count (str n))))) .375) |
| 00:33 | durka42 | nascent16: (.newInstance (:one classes)) |
| 00:33 | Mec | ,((fn ratio [n] (/ n (pow 10 (count (str n))))) .375) |
| 00:33 | clojurebot | java.lang.Exception: Unable to resolve symbol: pow in this context |
| 00:33 | Mec | ,((fn ratio [n] (/ n (Math/pow 10 (count (str n))))) .375) |
| 00:33 | clojurebot | java.lang.Exception: Unable to resolve symbol: .375 in this context |
| 00:34 | Mec | sec let me do it in my repl |
| 00:34 | slashus2 | ,(rationalize 0.123456) |
| 00:34 | clojurebot | 1929/15625 |
| 00:34 | nascent16 | durka42: yeah, that worked |
| 00:34 | nascent16 | thanks |
| 00:34 | duncanm | slashus2: yeah, that does |
| 00:35 | Mec | aw boo |
| 00:35 | duncanm | user=> (rationalize (double 1/4)) ;=> 1/4 |
| 00:35 | slashus2 | duncanm: To tell you the truth, I found it in the doc as soon as you asked. Pretty neat. |
| 00:35 | Mec | ,(rationalize Math/pi) |
| 00:35 | clojurebot | java.lang.Exception: No such namespace: Math |
| 00:36 | Mec | orly |
| 00:36 | nascent16 | Mec: that's exactly what I wanted to try |
| 00:36 | duncanm | ,(rationalize Math/PI) |
| 00:36 | clojurebot | 3141592653589793/1000000000000000 |
| 00:36 | nascent16 | boo |
| 00:36 | Mec | lol |
| 00:36 | slashus2 | right hehe |
| 00:40 | nascent16 | ,(def m Math) |
| 00:40 | clojurebot | DENIED |
| 00:40 | nascent16 | fine |
| 00:41 | nascent16 | (let [m Math] m/PI) |
| 00:41 | nascent16 | ,(let [m Math] m/PI) |
| 00:41 | clojurebot | java.lang.Exception: No such namespace: m |
| 00:41 | Mec | any shorthand for (map f1 (map f2 coll)) |
| 00:41 | Mec | hmm #(f1 (f2 %)) lol |
| 00:43 | Raynes | (map (fn [seqstr] (remove #(= % \=) seqstr)) ["lol = haha" "rofl = omfg"]) Fancy. |
| 00:43 | nascent16 | ,(let [m Math] (ns-resolve m PI)) |
| 00:43 | clojurebot | java.lang.Exception: Unable to resolve symbol: PI in this context |
| 00:45 | duncanm | Mec: is that the same as (map (compose f1 f2) coll) ? |
| 00:45 | nascent16 | ,(let [m Math] (ns-refers m)) |
| 00:45 | clojurebot | java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.Symbol |
| 00:45 | Mec | there is no compose, but thats how you would define it |
| 00:45 | duncanm | and compose is something like (fn [x] (f1 (f2 x))) |
| 00:45 | Mec | (doc compose) |
| 00:45 | clojurebot | excusez-moi |
| 00:46 | duncanm | (defn compose [f1 f2] (fn [x] (f1 (f2 x)))) |
| 00:46 | slashus2 | (doc comp) |
| 00:46 | clojurebot | Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc.; arglists ([& fs]) |
| 00:46 | duncanm | oh |
| 00:46 | duncanm | there we go |
| 00:46 | duncanm | (map (comp f1 f2) coll) |
| 00:47 | Mec | nice |
| 00:52 | nascent16 | ,(let [m Math] (.get (.getField m "PI") m)) |
| 00:52 | clojurebot | 3.141592653589793 |
| 00:52 | nascent16 | There's got to be a better way than that |
| 00:54 | Mec | to do what |
| 00:55 | nascent16 | get static members out of a reference to a class |
| 00:55 | Mec | ,(Math/PI) |
| 00:55 | clojurebot | 3.141592653589793 |
| 00:55 | Mec | oh |
| 00:55 | nascent16 | yeah, but this doesn't work: |
| 00:55 | nascent16 | (let [m Math] m/PI) |
| 00:55 | nascent16 | ,(let [m Math] m/PI) |
| 00:55 | clojurebot | java.lang.Exception: No such namespace: m |
| 00:56 | replaca | nascent16: that's because you're giving it the name m/PI |
| 00:57 | replaca | that's all one thing, not a reference to the symbol you bound earlier |
| 00:57 | replaca | with the let |
| 00:57 | nascent16 | I understand why it doesn't work, but I don't understand how to make it work |
| 00:57 | nascent16 | except for that ugly thing i did above |
| 00:58 | replaca | this seems like a pretty uncommon case, but you could write a simple function if you want to do it often |
| 00:58 | Mec | (. Math PI) |
| 00:58 | Mec | ,(. Math PI) |
| 00:58 | clojurebot | 3.141592653589793 |
| 00:58 | nascent16 | haha |
| 00:59 | Mec | ,(let [m Math] (. m PI)) |
| 00:59 | clojurebot | java.lang.IllegalArgumentException: No matching field found: PI for class java.lang.Class |
| 00:59 | durka42 | ,(let [m Math] (eval `(. ~m PI))) |
| 00:59 | clojurebot | DENIED |
| 00:59 | Mec | i can haz confusion |
| 00:59 | nascent16 | so m becomes a generic Class reference, whereas Math is a specific class (java.lang.Math) |
| 01:00 | Mec | ,((let [m Math] `(. ~m PI))) |
| 01:00 | clojurebot | java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn |
| 01:00 | Mec | say what |
| 01:00 | nascent16 | i'm not sure |
| 01:00 | durka42 | ,(let [m Math] `(. ~m PI)) |
| 01:00 | clojurebot | (. java.lang.Math sandbox/PI) |
| 01:01 | Mec | ,(let [m Math] (`(. ~m PI))) |
| 01:01 | clojurebot | java.lang.ClassCastException: clojure.lang.Cons cannot be cast to clojure.lang.IFn |
| 01:01 | Mec | ,(let [m Math] (identity \`(. ~m PI))) |
| 01:01 | clojurebot | java.lang.IllegalStateException: Var clojure.core/unquote is unbound. |
| 01:01 | Mec | ,(let [m Math] (identity `(. ~m PI))) |
| 01:01 | clojurebot | (. java.lang.Math sandbox/PI) |
| 01:01 | Mec | i quit |
| 01:01 | nascent16 | haha... what's this sandbox business? |
| 01:01 | Mec | thats just the namespace instead of user |
| 01:01 | replaca | you keep trying to evaluate a list as a function |
| 01:01 | nascent16 | ah |
| 01:01 | durka42 | which you need eval for |
| 01:02 | replaca | you really don't ever want backquote outside a func |
| 01:02 | replaca | no, even with eval, a list isn't a function. It's a list |
| 01:02 | durka42 | you need eval to treat it as code |
| 01:02 | replaca | you can eval the list itself, but that's not a different thing |
| 01:03 | replaca | ,('(1 2) 7) |
| 01:03 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn |
| 01:03 | replaca | is basically what you were trying there |
| 01:04 | danlarkin | I'm slightly confused as to why (. Math PI) isn't good enough for you? |
| 01:04 | nascent16 | let's say I had a variety of options for which PI was all different |
| 01:04 | nascent16 | MyMath YourMath HisMath |
| 01:04 | nascent16 | and depending on which Math was chosen, I want to use the correct value of PI |
| 01:04 | danlarkin | ,(#(. %1 %2) Math PI) |
| 01:04 | clojurebot | java.lang.Exception: Unable to resolve symbol: PI in this context |
| 01:05 | replaca | I think that Rich has really special-cased <classname>/<static> and . in a way that doesn't work generally |
| 01:05 | danlarkin | barf |
| 01:06 | nascent16 | ,(#(. %1 %2) Math 'PI) |
| 01:06 | clojurebot | java.lang.IllegalArgumentException: No matching field found: p2__2425 for class java.lang.Class |
| 01:07 | replaca | I think . may be doing some capture at readtime |
| 01:07 | replaca | looking at that error |
| 01:07 | danlarkin | . is a special form |
| 01:08 | danlarkin | so it does fanciness |
| 01:20 | Mec | is there a way to interrupt the currently executing expresion in emacs without haveing to break and restart the lisp connection |
| 01:20 | replaca | nascent16: try this: |
| 01:21 | replaca | (defmacro getStatic [c f] `(.get (.getField ~c (name '~f)) ~c)) |
| 01:21 | replaca | then, (getStatic m PI) does what you want |
| 01:21 | nascent16 | nice |
| 01:22 | nascent16 | hardly elegant, but it looks like it'll do the trick |
| 01:22 | replaca | Mec: Chouser posted something to contrib a while back, but I don't know if anyone's tested it in emacs |
| 01:22 | replaca | Mec: I've been meaning to, but haven't gotten around to it |
| 01:23 | replaca | nascent16: the great things about macros is that they can hide various sorts of inelegance |
| 01:23 | replaca | and leave your program feeling nice and clean |
| 01:24 | technomancy | like freshly brushed teeth |
| 01:24 | nascent16 | and i suppose that's the point afterall, to make these horrible machines look pretty and well behaved |
| 02:34 | vagif | Hello, anyone using slime with clojure ? |
| 02:39 | arbscht | vagif: yes |
| 02:49 | Raynes | I say kill them all and let fate sort out the mess. |
| 03:07 | vagif | arbscht: in emacs when I put cursor on function name, it shows me Evaluation Aborted. Is this how it should behave ? |
| 03:17 | Raynes | No th... Oh, he's gone. |
| 04:13 | lisppaste8 | Rayne pasted "Anyone know how to indent this and make it look good? :\" at http://paste.lisp.org/display/77455 |
| 04:17 | Carke | make a file->seq function and a remove= function |
| 04:18 | Carke | also i beleive (map f (map g ...)) is like (map (comp f g) ...) |
| 04:35 | Raynes | Carke: Thanks for the input. I don't think I can turn this into a comp in this specific situation however. But splitting it up into several functions makes my code look less crappy, thanks. |
| 04:38 | Cark | mhh yes you could (map (comp stringify remove=) (-> "text.txt" FileReader. BufferedReader. line-seq)) |
| 04:38 | Cark | or something like that |
| 04:38 | Cark | ,(doc comp) |
| 04:38 | clojurebot | "([& fs]); Takes a set of functions and returns a fn that is the composition of those fns. The returned fn takes a variable number of args, applies the rightmost of fns to the args, the next fn (right-to-left) to the result, etc." |
| 04:39 | Raynes | Well yeah if I split those functions up as well. |
| 04:40 | Cark | (map (comp #(apply str %) (fn [s] (remove #(= \= %) s))) (-> "text.txt" FileReader. BufferedReader. line-seq)) |
| 04:40 | Cark | (map (comp #(apply str %) (fn [s] (remove #(= \= %) s))) (-> "text.txt" FileReader. BufferedReader. line-seq)) |
| 04:40 | Cark | hum oops |
| 04:41 | Cark | mirc is no good to edit code ! |
| 04:41 | slashus2 | for the last part can you just not do (line-seq (File. "text.txt")) |
| 04:41 | Raynes | slashus2: No. |
| 04:42 | Raynes | (doc line-seq) |
| 04:42 | slashus2 | no. |
| 04:42 | clojurebot | Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader.; arglists ([rdr]) |
| 04:42 | slashus2 | oh |
| 04:42 | slashus2 | that is line-seq |
| 04:42 | slashus2 | I was seeing file-seq |
| 04:42 | Cark | ,(doc file-seq) |
| 04:42 | Raynes | Cark: Thanks, I tried that, I guess I'm just too tired and screwed something up. |
| 04:42 | clojurebot | "([dir]); A tree seq on java.io.Files" |
| 04:42 | Raynes | <3 |
| 04:43 | Cark | you probably got the order wrong in your composition |
| 04:44 | Raynes | Cark: Probably mismatched parentheses actually. |
| 04:44 | Raynes | I can't think very well when I'm tired. |
| 04:45 | Raynes | (-> "Hi" println) |
| 04:46 | Raynes | Oops, this isn't my REPL |
| 04:46 | Raynes | :| |
| 04:46 | Cark | ,(-> "hi" println) |
| 04:46 | clojurebot | hi |
| 04:46 | slashus2 | Raynes: We may need sleep. |
| 04:47 | Cark | ,(-> "derit" reverse #(apply str %) prinln) |
| 04:47 | clojurebot | java.lang.Exception: Unable to resolve symbol: prinln in this context |
| 04:47 | Cark | ,(-> "derit" reverse #(apply str %) println) |
| 04:47 | clojurebot | java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector |
| 04:48 | Cark | ,(-> "derit" seq reverse #(apply str %) println) |
| 04:48 | clojurebot | java.lang.ClassCastException: clojure.lang.Symbol cannot be cast to clojure.lang.IPersistentVector |
| 04:48 | Cark | ahwell |
| 04:49 | Raynes | ,(-> "Hi there!" .toUpperCase println)) |
| 04:49 | clojurebot | HI THERE! |
| 04:49 | Raynes | Oh I see. |
| 04:50 | Raynes | It's bed time. |
| 04:50 | Raynes | Night, thanks for the help Cark., |
| 04:50 | Cark | gnight raynes |
| 06:11 | AWizzArd | cd #Foswiki |
| 06:11 | AWizzArd | sorry |
| 08:27 | MikeSeth | weee clojure people |
| 08:31 | leafw | just awaking. |
| 08:54 | AWizzArd | clojurebot: max people |
| 08:54 | clojurebot | max people is 164 |
| 08:55 | vdrab | I'm curious about parallel processing with pmap. Most of the programs I run these days are perl scripts that do perl things... "read lines from a file, do some processing for each line and put the results in a hash" - type of stuff. Given enough cores, is there any performance boost to be expected from wrapping the file in a seq and processing it with pmap, or will the IO overhead and low cost of processing a single line negate the benefits of parall |
| 08:55 | vdrab | elization (say, on a machine with 8 cores and memory to spare) |
| 08:56 | rsynnott | if IO's the bottleneck, it will likely continue to be the bottleneck |
| 08:56 | MikeSeth | sounds like a task for hadoop et al.. though dont take my word for it |
| 08:58 | vdrab | yeah... I was just wondering whether there is any clear point at which clojure's parallelization options become really attractive for performance |
| 09:00 | vdrab | I guess it's no silver bullet, but was curious to hear some use cases where you got big speedups from pmap |
| 09:01 | davatk | if you did some performance tests, I bet people would be interested. |
| 09:02 | vdrab | davatk: hehe... right, point taken. |
| 10:32 | cconstantine_ | how do I use pmax? I get a "Unable to resolve symbol: pmax in this context" when I try to just use it, and I can't figure out how to reference into the parallel namespace where it appears to live |
| 10:52 | Chousuke | cconstantine_: (use 'clojure.parallel)? |
| 10:53 | cconstantine_ | this needs java 1.6 doesn't it? |
| 10:55 | Chousuke | I think it needs an experimental jar. |
| 10:55 | Chousuke | you should read the parallel.clj file, it's documented there :P |
| 10:56 | cconstantine_ | :/ |
| 11:05 | thickey | cconstantine_: you need the jar here http://clojure.googlegroups.com/web/jsr166y.jar |
| 11:08 | cconstantine_ | thanks |
| 11:08 | hiredman | erm |
| 11:16 | cconstantine_ | has anyone considered a parallel lazy-sequence; ie, start computing the next value when returning the current value? |
| 11:17 | cconstantine_ | or even caching up to N values ahead |
| 11:22 | hiredman | ,(doc seque) |
| 11:22 | clojurebot | "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer." |
| 11:23 | cconstantine_ | oh |
| 11:23 | cconstantine_ | well there ya go :) |
| 11:27 | cconstantine_ | wow, so that doesn't always help |
| 11:27 | MarkVolkmann | What is the function that returns the first item in a sequence for which a given predicate returns true? |
| 11:29 | cconstantine_ | drop-while will ive you the first element that pred returns false on... |
| 11:29 | cconstantine_ | (first (drop-while (complement pred) sequence)) |
| 11:31 | hiredman | ,(some (partial < 3) (range 10)) |
| 11:31 | clojurebot | true |
| 11:31 | MarkVolkmann | Ah ... I just found find-first in clojure.contrib.seq-utils |
| 11:31 | hiredman | hmmm |
| 11:31 | hiredman | oh |
| 11:31 | hiredman | right |
| 11:31 | hiredman | ,(some #(if (< 3 %) % nil) (range 10)) |
| 11:31 | clojurebot | 4 |
| 11:34 | hiredman | ,(some #(and (< 3 %) %) (range 10)) |
| 11:34 | clojurebot | 4 |
| 11:34 | hiredman | ,(meta and) |
| 11:34 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/and |
| 11:34 | hiredman | ,(meta (var and)) |
| 11:35 | clojurebot | {:macro true, :ns #<Namespace clojure.core>, :name and, :file "core.clj", :line 513, :arglists ([] [x] [x & next]), :doc "Evaluates exprs one at a time, from left to right. If a form\n returns logical false (nil or false), and returns that value and\n doesn't evaluate any of the other expressions, otherwise it returns\n the value of the last expr. (and) returns true."} |
| 11:59 | hiredman | btw, if you ever want to use binding to bind a macro to another symbol, var is how you do it |
| 12:04 | cconstantine_ | (var macro) returns the macro expanded? |
| 12:04 | cconstantine_ | no.. the macro as a thing. cool |
| 12:06 | cconstantine_ | so, pmax isn't exactly standard because of parallelization stuffs. Is there a non-parallel max that takes a collection instead of a set of things? |
| 12:06 | hiredman | (doc max) |
| 12:06 | clojurebot | Returns the greatest of the nums.; arglists ([x] [x y] [x y & more]) |
| 12:06 | hiredman | ,(apply max (java.util.ArrayList. [1 2 3])) |
| 12:07 | clojurebot | 3 |
| 12:07 | hiredman | looks like it works on collections to me |
| 12:07 | cconstantine_ | right, so how do a take a collection and turn it into an argument list? |
| 12:07 | hiredman | actually, I think max was faster using reduce then apply |
| 12:08 | cconstantine_ | When I call max on a list it just returns the list... do I need to convert it into something else? |
| 12:09 | hiredman | ,(binding [doc (var or)] (doc nil :a)) |
| 12:09 | clojurebot | java.lang.RuntimeException: java.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$my-doc |
| 12:09 | hiredman | :( |
| 12:09 | hiredman | well, that usually works |
| 12:09 | hiredman | cconstantine_: max does not take a list |
| 12:09 | hiredman | it takes a series of things |
| 12:09 | hiredman | ,(max 1 2 3) |
| 12:09 | clojurebot | 3 |
| 12:10 | hiredman | you can use reduce or apply to apply max to a list |
| 12:10 | cconstantine_ | ahh, I see |
| 12:10 | hiredman | ,(reduce max (range 10)) |
| 12:10 | clojurebot | 9 |
| 12:10 | hiredman | ,(apply max (range 10)) |
| 12:10 | clojurebot | 9 |
| 12:10 | cconstantine_ | I missed the 'apply' in your previous thinger |
| 12:10 | hiredman | form |
| 12:11 | digash` | hiredman: i am wondering, why do you say that reduce max is faster apply max? |
| 12:11 | hiredman | digash`: because we timed it |
| 12:12 | hiredman | max uses reduce internally for more then one arg |
| 12:12 | hiredman | and the internal reduce produces more calls to max |
| 12:13 | hiredman | so it is faster (or at least it was) to use your own reduce |
| 12:14 | digash` | hiredman: i guess i missed part of the conversation |
| 12:14 | hiredman | digash`: it was a few weeks ago |
| 12:17 | digash` | hiredman: it is still faster to call reduce, which is surprising to me |
| 12:18 | hiredman | ~def max |
| 12:20 | hiredman | yeah, so the internel reduce results in something like N*1/2 more calls to max then using reduce yourself |
| 12:22 | Chousuke | hm |
| 12:22 | Chousuke | why? |
| 12:23 | Chousuke | I can't see that from the code :/ |
| 12:23 | hiredman | because it calls max twice in the reduce |
| 12:23 | hiredman | (reduce max (max x y) more) |
| 12:23 | Chousuke | but (max x y) is only evaluated once |
| 12:23 | hiredman | acutally |
| 12:24 | hiredman | I think it may be more then N/2 |
| 12:24 | hiredman | oh |
| 12:24 | hiredman | oh |
| 12:24 | hiredman | yeah |
| 12:24 | hiredman | hmmm |
| 12:24 | digash` | take a look at this |
| 12:24 | digash` | ,(time (apply max 0 0 (range 10000000))) |
| 12:24 | clojurebot | 9999999 |
| 12:24 | clojurebot | "Elapsed time: 1958.762 msecs" |
| 12:25 | digash` | ,(time (apply max (range 10000000))) |
| 12:25 | clojurebot | 9999999 |
| 12:25 | clojurebot | "Elapsed time: 3589.016 msecs" |
| 12:25 | Chousuke | huh? |
| 12:25 | hiredman | hah |
| 12:26 | Chousuke | ,(time (reduce max 0 (range 10000000))) |
| 12:26 | clojurebot | 9999999 |
| 12:26 | clojurebot | "Elapsed time: 1923.614 msecs" |
| 12:26 | digash` | something strange in the jit land? |
| 12:38 | danlarkin | digash`: who knows, maybe a cronjob was running... statistical outlier... it's meaningless |
| 12:39 | hiredman | ... |
| 12:53 | cconstantine_ | speaking of which.. is there an easy way to evaluate an expression multiple times and grab statistics on how long each time took to run? |
| 12:55 | AWizzArd | How can one access environment variables? (be it Windows or Unix ones) |
| 12:56 | hiredman | ,(time (dotimes [i 10000] (reduce max 0 (range 100000000)))) |
| 12:56 | clojurebot | Execution Timed Out |
| 12:56 | hiredman | :( |
| 12:57 | hiredman | ,(time (dotimes [i 100] (reduce max 0 (range 100000000)))) |
| 12:57 | Cark | clojurebot is ronning on a zx spectrum |
| 12:57 | clojurebot | Execution Timed Out |
| 12:57 | Cark | *running |
| 12:57 | hiredman | "On the Java platform, an application uses System.getEnv to retrieve environment variable values." |
| 12:59 | AWizzArd | thx |
| 13:00 | cconstantine_ | hiredman: that just gives me the time to execute that many times, I'm thinking things like min, max, avg, etc |
| 13:01 | cconstantine_ | or even just give backa list of time to execute |
| 13:02 | cconstantine_ | *list of times to execute |
| 13:03 | hiredman | *shrug* |
| 13:03 | cconstantine_ | that would be really helpfull for doing timing tests |
| 13:04 | cconstantine_ | particularly if you have to interact over a network |
| 13:05 | cconstantine_ | or even just get back the time to execute of an expression as an object instead of putting it to stdout |
| 13:05 | AWizzArd | ,(first (System/getenv)) |
| 13:05 | clojurebot | java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.*) |
| 13:06 | AWizzArd | cconstantine_: (dotimes [i 10] (time (print (+ 100 i)))) |
| 13:07 | AWizzArd | ,(with-out-str (dotimes [i 5] (time (+ 100 i)))) |
| 13:07 | clojurebot | "\"Elapsed time: 0.046 msecs\"\n\"Elapsed time: 0.0080 msecs\"\n\"Elapsed time: 0.0040 msecs\"\n\"Elapsed time: 0.0050 msecs\"\n\"Elapsed time: 0.0040 msecs\"\n" |
| 13:07 | AWizzArd | run a regexp over this result string, collect the times and enjoy |
| 13:07 | cconstantine_ | wow |
| 13:08 | cconstantine_ | that.... works. but it seems like overkill |
| 13:08 | cconstantine_ | not overkill.... overly complicated |
| 13:08 | AWizzArd | macro this complexity away |
| 13:08 | AWizzArd | write a macro (profile (+ 10 5)) or something like that |
| 13:08 | AWizzArd | and a function (report) |
| 13:09 | AWizzArd | or just use an existing profiler |
| 13:09 | cconstantine_ | the regex is still happening in the background |
| 13:09 | dnolen_ | also time is a fairly simple macro in core.clj (5 LOC), instead of hacking around it just write your own. |
| 13:10 | pjstadig | ~def time |
| 13:10 | cconstantine_ | dnolen_: that sounds like a much better option :) |
| 13:10 | Chouser_ | cgrand: so have you realized yet that zip-filter's not going to cut it? |
| 13:12 | cconstantine_ | in CL it's possible to return multiple values, is that possible in clojure? |
| 13:12 | bitbckt | cconstantine_: return a vector |
| 13:12 | dnolen_ | or anything, the point is that you can destructure |
| 13:13 | cconstantine_ | bitbckt: right, but that means the caller has to look into the returned value. Ok. In the case of my new timing function it would be easier to not force the caller to change they way they handle the return value... I never liked multiple return values anyway |
| 13:14 | bitbckt | destructuring is idiomatic in Clojure |
| 13:14 | cconstantine_ | yeah |
| 13:14 | dnolen_ | if you want to include extra info some reason you could always add metadata |
| 13:14 | cconstantine_ | ooooo |
| 13:14 | cconstantine_ | I like that |
| 13:14 | pjstadig | cconstantine_: jeffery chu posted a (IMO pretty briliant) example of rolling your own in Clojure http://paste.lisp.org/display/68919 |
| 13:14 | cconstantine_ | add the time to execute as metadata |
| 13:14 | hiredman | when I first showed up in #clojure, someone was rewriting time so it attached the time result as metadata to the result |
| 13:14 | pjstadig | multiple value return isn't exactly the same as returning a vector |
| 13:15 | cconstantine_ | pjstadig: thanks |
| 13:15 | cconstantine_ | pjstadig: I think I like the meta-data thing better |
| 13:15 | Cark | question : i read on the mailing list that subvec retains the full original vector, is that true ? |
| 13:15 | hiredman | the problem with metadata is attaching it to things that don't support metadata |
| 13:16 | hiredman | ~def subvec |
| 13:16 | cconstantine_ | hiredman: is that a lot of stuff? |
| 13:16 | hiredman | cconstantine_: yes |
| 13:16 | cconstantine_ | hiredman: oh :( |
| 13:16 | hiredman | but clojure collections support metadata |
| 13:17 | hiredman | ~def clojure.lang.RT |
| 13:17 | hiredman | ~def c.l.APersistentVector |
| 13:18 | Cark | looks like it does |
| 13:18 | Cark | this.v = v; |
| 13:18 | cconstantine_ | hiredman: yeah... if enough stuff does it shouldn't be too bad |
| 13:26 | hiredman | clojurebot: botsnack |
| 13:26 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 13:27 | bitbckt | cogito ergo nom |
| 13:31 | Chouser_ | you can't put metadata on strings, numbers, or keywords. Only things that inherit from IMeta. |
| 13:32 | hiredman | ,(ancestores (class :a)) |
| 13:32 | clojurebot | java.lang.Exception: Unable to resolve symbol: ancestores in this context |
| 13:32 | hiredman | ,(ancestors (class :a)) |
| 13:32 | clojurebot | #{clojure.lang.Named clojure.lang.IFn java.lang.Object java.lang.Runnable java.lang.Comparable java.util.concurrent.Callable} |
| 13:32 | hiredman | ,(ancestors clojure.lang.IFn) |
| 13:32 | clojurebot | #{java.lang.Runnable java.util.concurrent.Callable} |
| 13:33 | digash`` | t |
| 13:40 | cconstantine_ | ew, refs don't even support metadata |
| 13:40 | Cark | ~def concat |
| 13:43 | dnolen_ | cconstantine: why do need refs themselves need it? |
| 13:43 | dnolen_ | ,(meta @(ref (with-meta {:mykey :myval} {:mymetakey :mymetaval}))) |
| 13:43 | clojurebot | {:mymetakey :mymetaval} |
| 13:43 | cconstantine_ | dnolen: I'm trying to think of something I can wrap non-metadata-holding types in. |
| 14:45 | cads | from inside clj, how may I find out the version of clojure i'm using? |
| 14:52 | danlarkin | cads: you can't |
| 14:55 | cads | could we write a function like that? |
| 14:57 | danlarkin | it's been proposed before... I don't think there was agreement on where the version should come from, or where it should go, at what point.. etc |
| 14:58 | Lau_of_DK | Good evening all |
| 14:58 | danlarkin | Hey Lau |
| 15:06 | tashafa | (doc with-meta) |
| 15:06 | clojurebot | Returns an object of the same type and value as obj, with map m as its metadata.; arglists ([obj m]) |
| 15:13 | cads | (+ 1 2 3) |
| 15:13 | clojurebot | *suffusion of yellow* |
| 15:15 | triddell | ,(+ 1 2 3) |
| 15:15 | clojurebot | 6 |
| 15:16 | triddell | cads: need a comma above ^ |
| 15:27 | gnuvince | Hey, Clojure is at revision 1337! |
| 15:28 | cgrand | Chouser: the tricky part is to update a bunch of locs. The other thing is that zip-filter is a fold on the selector while, for Enlive, I'll prefer to fold over paths |
| 15:35 | hiredman | ~latest |
| 15:35 | clojurebot | latest is 1337 |
| 15:35 | hiredman | it sure is |
| 15:36 | JasonCWarner | Hi room. Anyone here working on any compojure stuff? |
| 15:42 | dnolen | JasonCWarner: i'm starting to play around with it, yeah, but haven't got too far into it yet. |
| 15:43 | JasonCWarner | I'm just starting as well. Hoping to find some people to help with a problem. Can't quite figure out how to configure Jetty to serve static content (public/) with the new ring compojure code |
| 15:44 | pjstadig | i was gonna say check the wiki (because I think they have an example for serving static code, but that's probably not for the ring code) |
| 15:44 | pjstadig | i've played with compojure minimally |
| 15:45 | dnolen | JasonCWarner: there's a Compojure google group, people are relatively responsive, also perhaps the clojure ring project has an example on github? |
| 15:45 | pjstadig | there's a google group not sure if you've checked that out |
| 15:45 | pjstadig | they should have a #compojure channel |
| 15:45 | pjstadig | i'd hang out in there |
| 15:56 | Lau_of_DK | Can somebody explains Compojures decorators to me ? |
| 15:56 | Lau_of_DK | -s |
| 16:23 | JasonCWarner | Thanks, pjstadig, joining that room now... |
| 16:51 | digash` | Clojure is the future. |
| 16:55 | slashus3 | digash`: Was Rich's tutorial filmed yesterday at the international lisp conference? |
| 16:56 | digash` | yes, there were cameras |
| 16:57 | slashus3 | Probably will be released later. |
| 16:58 | digash` | you can probably bug Daniel Weinreb, http://www.international-lisp-conference.org/2009/committee |
| 16:59 | digash` | the whole discussion, is around clojure |
| 17:01 | hiredman | how awesome it is? how much they hate it? |
| 17:01 | digash` | i did not here any negative comment yet |
| 17:01 | hiredman | how it's a mistake and should just be another doohickey (he he hickey) tacked on to common lisp? |
| 17:01 | hiredman | excellent |
| 17:04 | digash` | The first comment negative comment from Pascal "JVM and CLR must die!" |
| 17:04 | pjstadig | my only concern about all of the attention for clojure at these conferences is that it's taking away Rich's time |
| 17:04 | pjstadig | he's making presentations instead of hacking clojure! |
| 17:04 | slashus3 | I am sure it gives him time to think. |
| 17:05 | triddell | agreed... clojure isn't where it is because Rich has been in a vacuum |
| 17:10 | digash` | Kent: "Standardisation is one big mutex." |
| 17:14 | cconstantine | I have no idea what is being said at this conference... but I see Clojure beating CL for one reason; it *has* a standard compiled distribution model (class files). |
| 17:15 | digash` | Sussman: "Language is a medium for expressing ideas clearly" |
| 17:24 | cconstantine | So what does that say about most perl scripts? ;) |
| 17:25 | hiredman | you use a lot of foul language |
| 17:27 | digash` | ouch, somebody just suggested that Lisp is not popular with women. |
| 17:29 | Chousuke | Well, maybe women are just jealous, since lisp has nice curves. :P |
| 17:29 | hiredman | clojurebot: women? |
| 17:29 | clojurebot | Huh? |
| 17:29 | hiredman | clojurebot: women is <reply>women are just jealous, since lisp has nice curves. -- Chousuke |
| 17:29 | clojurebot | Roger. |
| 17:29 | stuhood | oh no |
| 17:30 | Chousuke | ;( |
| 17:31 | hiredman | clojurebot: men? |
| 17:31 | clojurebot | namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it |
| 17:31 | hiredman | Huh |
| 17:32 | hiredman | I guess that is one for the ages |
| 17:34 | digash` | "Common Lisp is a giant casserole". |
| 17:35 | bitbckt | Wow. clojurebot needs a copy editor |
| 17:36 | Chousuke | bitbckt: you can always tell it new stuff |
| 17:36 | bitbckt | Chousuke: I know. |
| 17:37 | Chousuke | meaning you can also override old definitions :P |
| 17:37 | bitbckt | Chousuke: Yes, I know. |
| 17:39 | hiredman | overriding that one would be very interesting |
| 17:40 | hiredman | clojurebot: foo.bar |
| 17:40 | clojurebot | amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it |
| 17:40 | hiredman | very interesing indeed |
| 17:45 | kefka | Hey. I think I may have found a case of insufficient parallelism w/ futures. |
| 17:46 | kefka | This should take ~0 sec to return and ~9 to display at the REPL, though it'd take 45 to display with no paralleism at all. In practice, it seems to take 25. |
| 17:46 | kefka | ,(map #(future (Thread/sleep (* 1000 %)) %) (range 10)) |
| 17:46 | clojurebot | (#<Object$Future$IDeref@1ae9cec: 0> #<Object$Future$IDeref@c08964: 1> #<Object$Future$IDeref@7c06ab: 2> #<Object$Future$IDeref@9a0466: 3> #<Object$Future$IDeref@196de7e: 4> #<Object$Future$IDeref@1e9315f: 5> #<Object$Future$IDeref@a86249: 6> #<Object$Future$IDeref@ccdd53: 7> #<Object$Future$IDeref@1d69fa3: 8> #<Object$Future$IDeref@18ab25b: 9>) |
| 17:46 | kefka | Huh. The Clojure bot did it in decent time. |
| 17:47 | kefka | Have futures been altered in the past week in any way that would affect parallelism/concurrency? |
| 17:48 | kefka | On my REPL, it takes about 25 seconds to display, indicating that it's getting some (but poor) parallelism |
| 17:48 | hiredman | erm |
| 17:48 | hiredman | ,(doc future) |
| 17:48 | clojurebot | "([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block." |
| 17:50 | hiredman | are you sure you didn't leave out a zero on that test |
| 17:51 | hiredman | futures are concurrent in the sense that they execute in another thread, but derefing them will block |
| 17:51 | hiredman | and printing the output at the repl derefs them |
| 17:51 | hiredman | so print is blocking for each thread/sleep as it goes down the seq |
| 18:00 | slashus3 | ,(time (first (map #(future (Thread/sleep (* 1000 %)) %) (range 10)))) |
| 18:00 | clojurebot | java.lang.Exception: Unable to resolve symbol: in this context |
| 18:01 | slashus3 | ,(time (first (map #(future (Thread/sleep (* 1000 %)) %) (range 10)))) |
| 18:02 | slashus3 | hmm |
| 18:02 | hiredman | clojurebot: ping? |
| 18:02 | clojurebot | PONG! |
| 18:02 | slashus3 | not quite sure what happened there. |
| 18:03 | slashus3 | Well anyway, if you retrieve the second one it takes around one second, confirming the case. |
| 18:04 | slashus3 | the blocking deference |
| 18:04 | slashus3 | dereference |
| 18:04 | kefka | I think I figured the issue out. It's that map is lazy. |
| 18:04 | kefka | err, I mean map returns a lazy sequence |
| 18:05 | slashus3 | kefka: Where was the problem? |
| 18:05 | kefka | if you evaluate the futures as the map runs, they go off sequentially -> poor performance. |
| 18:06 | kefka | If you don't force the seq produced by the map to be consumed at time 0 (or as close as possible) the futures aren't instantiated at time 0, so you get poor performance. |
| 18:06 | kefka | But this will run in about 0.9 seconds, as it should: |
| 18:07 | kefka | Edit: never mind. I didn't find it. |
| 18:07 | kefka | Here's something that should run in 0.9 sec, but takes 4.5 |
| 18:07 | kefka | ,(time (apply + (map deref (map #(future (Thread/sleep (* 100 %)) %) (range 10))))) |
| 18:07 | clojurebot | 45 |
| 18:07 | clojurebot | "Elapsed time: 4511.046 msecs" |
| 18:08 | kefka | ,(time (apply + (pmap deref (pmap #(future (Thread/sleep (* 100 %)) %) (range 10))))) |
| 18:08 | clojurebot | 45 |
| 18:08 | clojurebot | "Elapsed time: 1114.229 msecs" |
| 18:09 | kefka | So it works properly with pmap, but that shouldn't matter, because the function future should be returning immediately, allowing the next future to start. |
| 18:09 | slashus3 | kefka: Running that map on my computer takes 25 seconds too. |
| 18:09 | Chousuke | slashus3: are you sure you have multiple cores? :P |
| 18:10 | Chousuke | ah, wait, guess that shouldn't matter ;( |
| 18:10 | slashus3 | I don't have multiple cores. |
| 18:10 | slashus3 | On this computer. |
| 18:11 | slashus3 | If it is derefing the objects one by one shouldn't it be 10 seconds? |
| 18:11 | slashus3 | wait |
| 18:11 | slashus3 | no |
| 18:12 | slashus3 | That is correct. |
| 18:12 | kefka | ,(time (apply + (map deref (pmap #(future (Thread/sleep (* 100 %)) %) (range 10))))) |
| 18:13 | clojurebot | 45 |
| 18:13 | clojurebot | "Elapsed time: 1505.738 msecs" |
| 18:13 | kefka | ,(time (apply + (pmap deref (pmap #(future (Thread/sleep (* 100 %)) %) (range 10))))) |
| 18:13 | clojurebot | 45 |
| 18:13 | clojurebot | "Elapsed time: 1104.012 msecs" |
| 18:13 | kefka | ,(time (apply + (pmap deref (map #(future (Thread/sleep (* 100 %)) %) (range 10))))) |
| 18:13 | clojurebot | 45 |
| 18:13 | clojurebot | "Elapsed time: 1504.964 msecs" |
| 18:13 | kefka | ,(time (apply + (map deref (map #(future (Thread/sleep (* 100 %)) %) (range 10))))) |
| 18:13 | clojurebot | 45 |
| 18:13 | clojurebot | "Elapsed time: 4511.04 msecs" |
| 18:14 | kefka | ,(time (apply + (map deref (into [] (map #(future (Thread/sleep (* 100 %)) %) (range 10)))))) |
| 18:14 | clojurebot | 45 |
| 18:14 | clojurebot | "Elapsed time: 902.647 msecs" |
| 18:14 | hiredman | ,(time (apply + (seque 10 (map #(future (Thread/sleep (* 100 %)) %) (range))))) |
| 18:14 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: core$range |
| 18:14 | hiredman | ,(time (apply + (seque 10 (map #(future (Thread/sleep (* 100 %)) %) (range 10))))) |
| 18:14 | clojurebot | java.lang.ClassCastException: clojure.proxy.java.lang.Object$Future$IDeref cannot be cast to java.lang.Number |
| 18:14 | kefka | Huh. So I get best performance when I send it right into a vector, instead of using the Lazy-seq. |
| 18:14 | hiredman | ,(time (apply + (seque 10 (map #(deref (future (Thread/sleep (* 100 %)) %)) (range 10))))) |
| 18:14 | kefka | ,(doc seque) |
| 18:14 | clojurebot | 45 |
| 18:14 | clojurebot | "Elapsed time: 4513.484 msecs" |
| 18:14 | clojurebot | "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer." |
| 18:16 | slashus3 | ,(time (map #(future (Thread/sleep 1000) %) (range 10))) |
| 18:16 | clojurebot | (#<Object$Future$IDeref@1a142ec: 0> #<Object$Future$IDeref@26d149: 1> #<Object$Future$IDeref@76481e: 2> #<Object$Future$IDeref@178c581: 3> #<Object$Future$IDeref@1eea016: 4> #<Object$Future$IDeref@150262b: 5> #<Object$Future$IDeref@f9de08: 6> #<Object$Future$IDeref@600ee8: 7> #<Object$Future$IDeref@72add8: 8> #<Object$Future$IDeref@f36617: 9>) |
| 18:16 | clojurebot | "Elapsed time: 0.474 msecs" |
| 18:16 | slashus3 | oh |
| 18:17 | slashus3 | Why does that take 5 seconds on my machine to print out? |
| 18:17 | kefka | You don't get a useful time unless you time something that requires derefing it. |
| 18:18 | kefka | Otherwise, it returns immediately though computation is still going on, so your quoted time is short. |
| 18:18 | kefka | e.g. this: |
| 18:18 | kefka | ,(time (apply + (map deref (into [] (map #(future (Thread/sleep (* 100 %)) %) (range 10)))))) |
| 18:18 | clojurebot | 45 |
| 18:18 | clojurebot | "Elapsed time: 910.095 msecs" |
| 18:18 | slashus3 | kefka: On my machine it takes about 5 seconds |
| 18:18 | kefka | The one I did? |
| 18:18 | slashus3 | The one I posted. |
| 18:19 | kefka | Yeah, it seems the work-around is to put the futures into a vector and then map deref across that vector |
| 18:19 | slashus3 | When I do reduce + and map deref to it it takes 10 seconds. |
| 18:19 | slashus3 | So that is correct. |
| 18:19 | kefka | Try the one I just did. Tell me what you get. |
| 18:19 | slashus3 | same |
| 18:19 | slashus3 | 920 |
| 18:20 | kefka | I get 910. |
| 18:20 | kefka | Yeah, so what's happening is that if you don't force the futures by doing something with the map-- the (into [] %) works-- you don't get the futures to go off immediately. |
| 18:20 | slashus3 | Wonder why it is 5 seconds. I don't see where that is coming from on mine. |
| 18:21 | kefka | It's because map is lazy. |
| 18:21 | kefka | So the futures don't start running until the last one has returned. |
| 18:21 | kefka | It's not actually a bug, I don't think, since map is supposed to return something lazy |
| 18:21 | hiredman | clojurebot: map? |
| 18:21 | clojurebot | map is *LAZY* |
| 18:22 | slashus3 | So that time is inaccurate. |
| 18:22 | slashus3 | because of the laziness |
| 18:23 | kefka | Yes, but it still takes 4.5 seconds if you don't force the futures to start immediately. |
| 18:23 | kefka | ,(map #(future (Thread/sleep (* 100 %)) %) (range 10)) ;; takes 4.5 seconds |
| 18:23 | clojurebot | (#<Object$Future$IDeref@14563d4: 0> #<Object$Future$IDeref@9d10ab: 1> #<Object$Future$IDeref@1b18970: 2> #<Object$Future$IDeref@b6481e: 3> #<Object$Future$IDeref@138c394: 4> #<Object$Future$IDeref@1b0595c: 5> #<Object$Future$IDeref@bac49a: 6> #<Object$Future$IDeref@1c1902d: 7> #<Object$Future$IDeref@e09a07: 8> #<Object$Future$IDeref@1a07a6f: 9>) |
| 18:23 | hiredman | calling it inaccurate because it does exactly what the docstrings say it does? |
| 18:24 | slashus3 | It is accurate. Just confusing. |
| 18:24 | slashus3 | laziness is hard |
| 18:24 | hiredman | clojurebot: lazy? |
| 18:24 | kefka | ,(into [] (map #(future (Thread/sleep (* 100 %) %)) (range 10))) ;; takes ~0.9 seconds |
| 18:24 | clojurebot | lazy is hard |
| 18:24 | clojurebot | [#<Object$Future$IDeref@d547f8: nil> #<Object$Future$IDeref@67fb9f: nil> #<Object$Future$IDeref@1c48403: nil> #<Object$Future$IDeref@b6e2e3: nil> #<Object$Future$IDeref@e9d39c: nil> #<Object$Future$IDeref@143b598: nil> #<Object$Future$IDeref@472c8d: nil> #<Object$Future$IDeref@be0b48: nil> #<Object$Future$IDeref@d6e0df: nil> #<Object$Future$IDeref@1456c99: nil>] |
| 18:24 | hiredman | kefka: generally, to force a lazy-seq people use dorun or doall |
| 18:25 | hiredman | ,(doc dorun) |
| 18:25 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil." |
| 18:25 | kefka | ,(doc doall) |
| 18:25 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time." |
| 18:26 | slashus3 | doall is appropriate in this case? |
| 18:26 | hiredman | it depends |
| 18:30 | hiredman | this case is just some code that does nothing |
| 18:30 | hiredman | so dorun would be fine |
| 18:30 | slashus3 | If you want to add up all of the numbers returned you would use doall? |
| 18:31 | hiredman | or just use reduce |
| 18:31 | slashus3 | yeah |
| 18:32 | hiredman | ugh, I keep expecting excel to close my parens for me |
| 18:32 | slashus3 | hehe |
| 19:04 | duderdo | Hello. |
| 19:05 | duderdo | Quick question. Why does "(let [x #{}] (conj x "foo") x)" return #{}? |
| 19:05 | Chousuke | because it returns x, and x is #{} |
| 19:06 | duderdo | How do I add "foo" to x then? |
| 19:06 | Chousuke | with conj, but that will no longer be named x |
| 19:06 | Chousuke | clojure has no variables, just names :), in the let binding you declare "x" to be #{}, and that it will be until later rebound in a let. |
| 19:07 | Chousuke | the key word here is immutability. |
| 19:07 | duderdo | Sorry, I'm coming from CL :) |
| 19:07 | duderdo | So if I have a collection and I want to add items to it what do I use? |
| 19:07 | duderdo | And yes I will read up on clojure immutabiliy ;) |
| 19:08 | Chousuke | you don't add items to a collection. You return a new collection with the item added :) |
| 19:09 | dnolen | ,(let [x #{}] (conj x 'a)) |
| 19:09 | clojurebot | #{a} |
| 19:09 | Chousuke | like that. |
| 19:09 | Chousuke | note, however, that x still remains #{} :) |
| 19:10 | duderdo | Right... |
| 19:10 | duderdo | I need to read more I guess |
| 19:10 | Chousuke | ,(let [x #{}, y (conj "foo" x)] (= x y)) |
| 19:10 | clojurebot | java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IPersistentCollection |
| 19:10 | Chousuke | oops |
| 19:10 | Chousuke | ,(let [x #{}, y (conj x "foo")] (= x y)) |
| 19:10 | clojurebot | false |
| 19:11 | duderdo | I understand it doesn't work but I don't see why yet |
| 19:11 | Chousuke | it starts making sense if you stop thinking of the names you see in code as variables. |
| 19:11 | dnolen | duderdo: x is immutable, you can't change it. |
| 19:12 | Chousuke | they're simply *names*, given to some value. |
| 19:12 | Chousuke | like in maths, x := 3 |
| 19:13 | Chousuke | now x = 3, but you can't change the value of x in any way; you can't change "3" to be something else. |
| 19:13 | duderdo | I see. But if I want to modify a collection and use it later, what is the procedure? The examples I see use globals which doesn't make sense to me. |
| 19:13 | Chousuke | one solution is to have a ref or two. |
| 19:14 | Chousuke | a reference is something that you *can* change. it's a method of indirection. |
| 19:14 | Chousuke | for example, if you define *today* to be a reference to the current date, the value of *today* will of course change over time. |
| 19:15 | Chousuke | however, once you read a value from *today*, you get something like "24.03", and *that* can not be changed |
| 19:16 | Chousuke | teh clojure reference type allows you to do this. |
| 19:16 | duderdo | It's making sense now. Thanks. I'm just use to using LET+PUSH from cl |
| 19:16 | Chousuke | though just for modifying a collection I wouldn't look at refs right away |
| 19:16 | Chousuke | just write functions that return new collections with the values added/removed/whatever. |
| 19:17 | Chousuke | it's fast enough :) |
| 19:17 | duderdo | I'll start thinking in that direction. Thanks Chousuke. |
| 19:17 | Chousuke | You're welcome. |
| 19:59 | cconstantine | What is the equivalent of (reduce and ...) that works? |
| 20:00 | hiredman | ,(reduce #(and % %2) ...) |
| 20:00 | clojurebot | java.lang.Exception: Unable to resolve symbol: ... in this context |
| 20:01 | hiredman | well |
| 20:01 | hiredman | that is a literal equivilent |
| 20:01 | hiredman | ,(doc every?) |
| 20:01 | clojurebot | "([pred coll]); Returns true if (pred x) is logical true for every x in coll, else false." |
| 20:01 | cconstantine | and is a macro... so reduce won't take it |
| 20:01 | cconstantine | every! |
| 20:01 | cconstantine | I knew tehre was something like that... and failed at finding it in the docs |
| 20:02 | hiredman | ,(every? identity [1 2 nil]) |
| 20:02 | clojurebot | nil |
| 20:02 | hiredman | ,(every? identity [1 2 3]) |
| 20:02 | clojurebot | true |
| 20:03 | cconstantine | ,(every? true? (list true true true) |
| 20:03 | clojurebot | EOF while reading |
| 20:03 | cconstantine | bah |
| 20:08 | durka42 | ,(reduce #(and %1 %2) [1 2 3]) |
| 20:08 | clojurebot | 3 |
| 20:38 | digash` | "Q: What happens when amateur does programming language? A: Phd" -- Guy Steel |
| 20:39 | sellout | Yeah, that was a good one. |
| 20:39 | sellout | even better with the context of the original answer: PHP |
| 20:59 | Mec | anyone know the clojurebox key commands to eval defun or region? |
| 21:06 | cconstantine | I'm not using clojurebox (didn't know there was one), but it's C-c C-e for me |
| 21:07 | Mec | hmm that brings up some eval |
| 21:08 | cconstantine | C-c C-z opens clojure |
| 21:08 | cconstantine | again... for me :) |
| 21:08 | Mec | that brought up the slime-repl which for some reason isnt the actual repl evaluations go to |
| 21:08 | cconstantine | I followed http://riddell.us/tutorial/slime_swank/slime_swank.html |
| 21:09 | Mec | ok let me take a look at that |
| 21:09 | cconstantine | oh wait... that's for my linux box... |
| 21:10 | cconstantine | I did this for my mac http://paulbarry.com/articles/2008/07/02/getting-started-with-clojure-and-aquamacs |
| 21:11 | Mec | c-x c-e executed, but it didnt go to the repl it went to that thing at the very bottom of emacs |
| 21:13 | cconstantine | is there a clojure menu? that might show you the shortcut |
| 21:14 | Mec | there is, but no shortcuts |
| 21:15 | cconstantine | hmm |
| 21:24 | Mec | bah any thoughts on how to up the heap space size, its only taking 90meg on a 4gig system |
| 21:25 | cconstantine | it's a java param |
| 21:25 | cconstantine | http://hausheer.osola.com/docs/5 |
| 21:27 | Mec | says it can be set in the java control panel but i know i didnt see it in there when i looked |
| 21:27 | Mec | i wouldnt know where to find the java command line in clojurebox |
| 21:28 | cconstantine | not sure... search the clojurebox file a file containing "clojure.jar"? |
| 21:29 | Mec | ah i found it |
| 21:29 | Mec | would this be considered applet or application? |
| 21:30 | Mec | well since application doesnt have a space for runtime param i guess applet |
| 21:31 | cconstantine | that's an odd distinction to make.. |
| 21:32 | Mec | those are the 2 options under the java control panel |
| 21:32 | cconstantine | yeah |
| 21:33 | banisterfiend | hru bbs |
| 21:34 | Mec | bah i set it to 1gig and it still wont go above 90meg |
| 21:34 | banisterfiend | is scala better than clojure? |
| 21:35 | Mec | thems fightin words |
| 21:36 | cconstantine | Mec: modifying my clojure script with the arguments in the last link I gave you worked well for me |
| 21:37 | cconstantine | banisterfiend: that's an odd question to ask in #clojure... or an odd way of phrasing it |
| 21:37 | gnuvince_ | banisterfiend: totally |
| 21:37 | Mec | i dont know how clojurebox starts up to add it to the command line |
| 21:38 | cconstantine | as an aside I really hate the way java handles the heap |
| 21:38 | Mec | hmm thats the problem, the java control panel wont keep the params i entered |
| 21:38 | banisterfiend | gnuvince, hey vince |
| 21:39 | cconstantine | at the very least a fixed number for max-heap is stupid... and 90 is way low |
| 21:39 | Mec | local java programs should use all available memory, theres no reason not to |
| 21:40 | cconstantine | yup |
| 21:40 | banisterfiend | gnuvince, hey vincent im downloading an iain m. banks audiobook - in particular the newest sci fi novel: Matter, but im also downloading the Algebraist audio book too. |
| 21:41 | Mec | im at my whits end, java wont accept any of the changes i make |
| 21:42 | cconstantine | Mec: Sorry I can't help more... I don't even have access to a windows box right now |
| 21:43 | Mec | no sweat, i shall beat java into submission |
| 21:43 | cconstantine | It is the kind of thing that must be physically afraid of you. |
| 21:55 | SethTisue | the whole fixed heap ceiling thing my least favorite thing about the JVM |
| 23:20 | cemerick | ~max |
| 23:20 | clojurebot | max people is 164 |
| 23:25 | cemerick | ~max |
| 23:25 | clojurebot | max people is 164 |