2009-11-05
| 00:22 | adityo | good morning folks! |
| 01:12 | hiredman | clojurebot: ping? |
| 01:12 | clojurebot | PONG! |
| 04:00 | piccolino | I am trying to use a binding as a dynamically scoped variable, but I'm getting a compile error when I reference that variable in another lexical scope (another function that gets called by the binding's form). Is there something I can do about that? |
| 04:00 | liwp | piccolino: are you talking about the (binding ..) form? |
| 04:00 | piccolino | Yeah |
| 04:01 | arbscht | piccolino: paste your code somewhere |
| 04:01 | liwp | ~paste |
| 04:01 | clojurebot | lisppaste8, url |
| 04:01 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 04:01 | liwp | piccolino: and what's the error that you're getting? |
| 04:03 | tomoj | functions don't know about variables that are dynamically bound for them |
| 04:03 | tomoj | unless you tell them |
| 04:03 | piccolino | How do I tell them? |
| 04:03 | tomoj | you'd have to declare everything that might be bound |
| 04:04 | tomoj | there was a discussion about this on the compojure mailing list I think |
| 04:04 | tomoj | someone wanted to do like rails where you can just refer to instance variables in the view whether they exist or not |
| 04:04 | tomoj | and then dynamically bind them in the controller |
| 04:04 | tomoj | but the view function won't compile if the variable doesn't exist |
| 04:05 | piccolino | Ah, OK. |
| 04:05 | piccolino | That actually fixed it, thanks guys. |
| 04:05 | tomoj | hmm |
| 04:06 | piccolino | So binding doesn't do destructuring? |
| 04:06 | tomoj | if you're dynamically binding a var in another namespace, do you have to declare it fully-qualified in the other namespace that uses it? |
| 04:08 | liwp | tomoj: I wouldn't think so, if you are (use...)ng the other namespace |
| 04:17 | tomoj | well my experiments just confused me even more :( |
| 04:32 | AWizzArd | I want to typehint that my function returns an array of (primitive) bytes. Is #^bytes the right tag? |
| 04:35 | tomoj | I think it's [B |
| 04:36 | AWizzArd | funny ;) |
| 04:36 | tomoj | "[" means array, "B" means bytes |
| 04:36 | tomoj | but that's the jvm, I haven't done much typehinting |
| 04:38 | Chousuke | #^bytes should work |
| 04:38 | tomoj | how do you typehint an array of objects? |
| 04:39 | tomoj | #^"[Lthe.class.name" ? |
| 04:42 | cgrand | tomoj: #^"[Lthe.class.name;" (adde semi-colon) |
| 04:42 | cgrand | added |
| 04:43 | carpdiem | hey guys, i've been learning clojure over the past few days (coming from a python background), and i'm having a devil of a time understanding the clojure list comprehension style |
| 04:43 | carpdiem | i was wondering if anyone could help me understand it |
| 04:43 | carpdiem | the (for ...) format is just not clicking with my brain |
| 04:44 | cgrand | (for [x coll] x) is equivalent to (seq coll) |
| 04:44 | cgrand | (for [x coll] (f x)) is equivalent to (map f coll) |
| 04:45 | carpdiem | @cgrand, let me ask a simple and specific question: how would you make a list of, say, 1/n for 0<=n<100? |
| 04:45 | cgrand | (for [x coll1 y coll2] [x y]) returns the cardinal product of coll1 and coll2 (coll1 being the "outer loop") |
| 04:46 | cgrand | ,(for [n (range 10] (/ 1 n)) |
| 04:46 | clojurebot | Unmatched delimiter: ] |
| 04:46 | cgrand | ,(for [n (range 10)] (/ 1 n)) |
| 04:46 | clojurebot | java.lang.ArithmeticException: Divide by zero |
| 04:46 | cgrand | ,(for [n (range 1 10)] (/ 1 n)) |
| 04:46 | clojurebot | (1 1/2 1/3 1/4 1/5 1/6 1/7 1/8 1/9) |
| 04:47 | tomoj | (for [x aseq] (foo x)) is like [foo(x) for x in aseq], I think |
| 04:47 | tomoj | though I'm a python noob |
| 04:47 | yason | Apparently hinting argument types only ensures that they're java.lang.Number? Not specifically #^Integer, #^Double, etc? |
| 04:47 | carpdiem | @cgrand - thanks |
| 04:48 | carpdiem | @tomoj - that's actually really helpful, thanks for the translation |
| 04:48 | tomoj | I dunno if python's list comprehensions can do cartesian products |
| 04:48 | cgrand | yason: hinting is not casting, an hint doesn't cause the compiler to add checks to ensure a avlue is of the specified type |
| 04:49 | cgrand | s/avlue/value/ |
| 04:49 | carpdiem | @tomoj - can you show me an example of a cartesian product with a clojure list? |
| 04:50 | AWizzArd | Chousuke: yes, seems to work |
| 04:50 | carpdiem | something simple, even with just a few terms |
| 04:50 | tomoj | ,(for [x (range 3) y (range 3)] [x y]) |
| 04:50 | clojurebot | ([0 0] [0 1] [0 2] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2]) |
| 04:51 | yason | cgrand: I've understood that Clojure makes static, compile-time checks to ensure you don't, e.g. pass a string as some argument that's been hinted to be a number. |
| 04:51 | carpdiem | @tomoj - i see |
| 04:51 | tomoj | it binds x to the first of the first seq, then runs through the elements of the second, moves on to the second of x, etc |
| 04:51 | tomoj | though you can do more |
| 04:51 | tomoj | ,(for [x (range 2) y (range 2) z (range 2)] [x y z]) |
| 04:51 | clojurebot | ([0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] [1 0 1] [1 1 0] [1 1 1]) |
| 04:51 | carpdiem | yeah, i'm starting to "see" it now |
| 04:52 | carpdiem | your python translation was super helpful |
| 04:52 | tomoj | also.. |
| 04:52 | tomoj | ,(for [[k v] {"foo" 3, "bar" 4, "baz" 5}] (str k v)) |
| 04:52 | clojurebot | ("foo3" "bar4" "baz5") |
| 04:52 | tomoj | destructuring :) |
| 04:53 | yason | cgrand: (defn mult [#^Integer a #^Integer b] (* a b)) happily accepts floats, integers, bignums etc. (Or is #^Integer/TYPE the right form? Same with that, too.) |
| 04:53 | carpdiem | @tomoj - i think it'll take me another day or two before something like that reads comfortably to me |
| 04:53 | tomoj | reading it does take a while I think |
| 04:53 | tomoj | the key is this |
| 04:53 | tomoj | ,(seq {"foo" 3, "bar" 4, "baz" 5}) |
| 04:53 | clojurebot | (["foo" 3] ["bar" 4] ["baz" 5]) |
| 04:54 | cgrand | yason: when you hint something it helps the compiler in picking the right method calls when doing interop. When there's no interop hints change nothing to your code. |
| 04:54 | tomoj | I think python can do something like that as well |
| 04:54 | tomoj | hmm.. maybe not |
| 04:55 | carpdiem | @tomoj - ok, i'm a little confused at what just happened there |
| 04:55 | carpdiem | how did clojure know to make three pairs, rather than, say, two triples? |
| 04:55 | carpdiem | it doesn't care about the commas, right? |
| 04:56 | tomoj | right |
| 04:56 | tomoj | ,(seq {"foo" 3 "bar" 4}) |
| 04:56 | clojurebot | (["foo" 3] ["bar" 4]) |
| 04:56 | yason | cgrand: oh, I see, it's only useful when calling Java code. Right. |
| 04:56 | tomoj | "{}" means a map, maps map keys to values |
| 04:57 | carpdiem | ok |
| 04:57 | carpdiem | but when i run (doc seq), it says "returns a seq on the collection..." |
| 04:57 | carpdiem | what is a 'seq' ? |
| 04:57 | tomoj | when you use a map as a seq, you get a seq of key-value pairs |
| 04:57 | carpdiem | just stripping out all the key-value pairs? |
| 04:58 | tomoj | there's a video you should probably watch |
| 04:58 | cgrand | yason: and once a specific method overlod is picked it's the JVM which enforces the type at runtime |
| 04:58 | tomoj | well, at http://clojure.blip.tv/ |
| 04:58 | tomoj | start at the bottom of the playlist |
| 04:59 | cgrand | yason: mainly usefule calling java code but also when trying to use fast math or array ops |
| 04:59 | carpdiem | all right, i'll check that out |
| 04:59 | carpdiem | i've been going through the ociweb tutorial so far |
| 04:59 | yason | cgrand: okay. So, any purely native clojure function always just takes plain Objects as arguments? That means that i.e. integer/float arguments are always boxed? |
| 04:59 | cgrand | yason: right now yes |
| 05:00 | tomoj | seqs are clojure's big abstraction over all sequential data |
| 05:00 | cgrand | but starting from JRE 6r14 you can ask the JVM to try optimizing boing/unboxing away |
| 05:00 | AWizzArd | oh really? |
| 05:00 | AWizzArd | How would that work? |
| 05:00 | tomoj | vectors, lists, maps, sets, strings, .. whatever else there is |
| 05:01 | tomoj | you can access them all as seqs |
| 05:01 | carpdiem | ok |
| 05:01 | tomoj | and there is a library of functions which operate on seqs so that you can use these functions with all of these kinds of objects |
| 05:01 | tomoj | in (for [x foo] ...), the foo is a seq |
| 05:01 | yason | cgrand: thanks, I'll go explore more |
| 05:01 | carpdiem | thanks, i'll go through those videos now, and come back if i have more questions :-) |
| 05:01 | tomoj | (well, it's either a seq or something that can be turned into a seq) |
| 05:02 | carpdiem | gotcha |
| 05:02 | tomoj | I think those videos are not too out of date.. right? |
| 05:05 | tomoj | carpdiem: glad to have you join us :) |
| 05:05 | carpdiem | thanks |
| 05:05 | carpdiem | i'm enjoying clojure quite a bit so far |
| 05:06 | carpdiem | just need to finish wrapping my brain around the new concepts |
| 05:06 | tomoj | it's well worth it, I think |
| 05:11 | tomoj | I think the only thing I remember being out of date about the seq video is rest/next |
| 05:12 | tomoj | but that's not terribly important, you can just read the docs on those functions as they are now |
| 05:12 | carpdiem | kk |
| 05:29 | AWizzArd | cgrand: do you know how one can ask the JVM to optimize boxing/unboxing away? |
| 05:29 | somnium | is there a way to do (for [x xs] (somefn (for [y ys] (otherfn y)))) with one for statement? |
| 05:30 | cgrand | AWizzArd: -XX:+DoEscapeAnalysis |
| 05:34 | tomoj | somnium: sure |
| 05:34 | tomoj | well |
| 05:35 | tomoj | (repeat (count xs) (somefn (for [y ys] (otherfn y)))) |
| 05:35 | tomoj | but I guess that's not really what you meant |
| 05:35 | AWizzArd | good, thx |
| 05:36 | somnium | well, something like (for [x xs] (apply hash-map (for [[k v] ys] [k (f v)]))) |
| 05:36 | tomoj | hmm |
| 05:36 | tomoj | that still doesn't make sense to me |
| 05:36 | tomoj | you're not using x |
| 05:37 | somnium | (well pretend then function at the end is closing over x) |
| 05:37 | tomoj | so like (for [x xs] (somefn (for [y ys] (otherfn x y)))) basically? |
| 05:38 | somnium | yeah that looks right |
| 05:38 | somnium | doing (for [x xs :let [z (for [y ys] ... seems a little silly |
| 05:38 | somnium | ;) |
| 05:39 | cgrand | AWizzArd: I think I read this flag should be on by default in a next release |
| 05:39 | tomoj | of course you could make one of them a map to have only one 'for' |
| 05:39 | tomoj | but that's a cheap solution |
| 05:39 | somnium | yes, but for is so readable |
| 05:40 | tomoj | one time at an interview they asked me to change some code I wrote with multiple print statements to use only one print statement |
| 05:40 | tomoj | and I gave up, couldn't do it |
| 05:40 | tomoj | the answer was to have a mutable string and replace all but the last print statements with concatenations onto that mutable string |
| 05:40 | tomoj | :'( |
| 05:41 | somnium | is that a 'clojure has made my mind immutable' anecdote, or something else altogether ? |
| 05:42 | tomoj | at that point I didn't know clojure, unfortunately |
| 05:42 | tomoj | but they asked me "can you write this with only one print statement" |
| 05:42 | tomoj | similarly you asked "can you write this with only one 'for'" |
| 05:42 | tomoj | and clearly you can by rewriting it in some other way which is essentially the same, like using map |
| 05:43 | tomoj | which obviously wouldn't satisfy you, right? |
| 05:43 | tomoj | strange thing to me is that that was the answer they were actually looking for, a trivial rewrite that doesn't actually make any difference, but strictly satisfies the question |
| 05:45 | somnium | well, in some cases map is equivalent |
| 05:45 | somnium | but if there are some more lets or filters for is better |
| 05:46 | tomoj | I still have never used those extra features of for |
| 05:46 | somnium | to my eyes they can make involved sequence transformation look so simple it seems like cheating |
| 05:47 | tomoj | but I mean we can clearly rewrite (for [x xs] (somefn (for [y ys] (otherfn x y)))) as (for [x xs] (somefn (map #(otherfn x %) ys))) |
| 05:47 | tomoj | that IS cheating :) |
| 05:47 | tomoj | I mean, it's not a real answer to your question |
| 05:47 | tomoj | (btw, I don't have any real answers :() |
| 05:47 | somnium | (for [x xs :let [z (:mykey x)] :when (< z 100)] (for ... |
| 05:48 | tomoj | essentially it seems like you're doing two nested maps, and I don't see how you could rewrite that as anything except two nested masp |
| 05:48 | somnium | yeah, I briefly wondered if a :for keyword could work, but it would at most save one keystroke from (for ... (for :) |
| 05:49 | tomoj | I wonder if (for [... :let [x ..] :when x] x) is faster than (filter identity? (map .....)) |
| 05:49 | somnium | interesting question |
| 05:50 | somnium | ~clojurebot |
| 05:50 | clojurebot | clojurebot is like life: you make trade-offs |
| 05:50 | somnium | ~clojurebot |
| 05:50 | clojurebot | clojurebot is like life: you make trade-offs |
| 05:50 | somnium | hmm, I guess it picks responses at random |
| 05:51 | AWizzArd | cgrand: yes, that makes sense. I hope Sun will continue to improve this boxing/unboxing stuff, and maybe also add tagged numbers. |
| 05:51 | somnium | wow, the source for for is pretty hairy |
| 05:52 | tomoj | seems to be about the same |
| 05:52 | tomoj | (filter identity (map even? (range 1000000))) and (for [x (range 1000000) :let [z (even? x)]] z) both take around 2s |
| 05:54 | somnium | try macroexpanding for |
| 05:57 | tomoj | heh, yeah |
| 05:57 | tomoj | clojure's safeguards for macro hygiene don't help |
| 05:57 | tomoj | I was thinking of writing a macro to wrap around macroexpand to give a semi-readable expansion |
| 05:58 | somnium | yeah, clojure.core could be dropped at least |
| 05:59 | tomoj | when debugging your own macros I suppose it might be useful to see namespaces on some symbols |
| 06:00 | tomoj | hm, actually |
| 06:00 | somnium | I haven't had the inspiration to try to write one remotely as complicated as for thus far |
| 06:00 | tomoj | it seems swank-clojure already does this |
| 06:00 | somnium | macroexpand in place is a good way to destroy the readability of source files, I found |
| 06:01 | tomoj | (for [x xs] x) at the repl and C-c C-m with point at the beginning and you get a buffer with indented code and clojure.core removed |
| 06:01 | tomoj | though all the gensyms still make it pretty unreadable |
| 06:01 | somnium | hmm, C-m seems bound to return on my setup for some reason |
| 06:01 | somnium | what's the function name? |
| 06:01 | tomoj | and the chunking |
| 06:02 | tomoj | hmm |
| 06:03 | somnium | ah I got it |
| 06:03 | tomoj | C-c RET does it too |
| 06:03 | somnium | that's more expansion that I was hoping for |
| 06:03 | tomoj | slime-macroexpand-1 |
| 06:03 | tomoj | well, that's only one macroexpand, supposedly |
| 06:04 | tomoj | C-c M-m is slime-macroexpand-all for me |
| 06:04 | somnium | looking at the source for for it seems about right |
| 06:04 | tomoj | ah yes |
| 06:04 | tomoj | then the gensyms might actually make some sense I suppose |
| 06:05 | tomoj | clojure's gensym stuff really blew my mind when I first saw it |
| 06:06 | somnium | what (still) gets me is how comparatively easy it is to write a sane macro based on a function, compared to generating a new class in python or ruby |
| 06:10 | somnium | the chunk-family doesn't seem to have doc strings |
| 06:11 | tomoj | I guess they are relatively new? |
| 06:12 | somnium | only docs I found were the assembla ticket, so I guess so |
| 06:22 | adityo | how will i use merge-with to merge maps {:a 1 :b 2} {:a 3 :c 4} |
| 06:23 | hoeck | adityo: like this, for example: (merge-with + {:a 1 :b 2} {:a 3 :c 4}) |
| 06:24 | adityo | yeah, got it thanks hoeck :) |
| 06:25 | hoeck | adityo: np :) |
| 06:53 | AWizzArd | ,(let [x (transient [1])] (into-array Byte/TYPE (map byte (persistent! x)))) |
| 06:53 | clojurebot | #<byte[] [B@f3de46> |
| 06:53 | AWizzArd | but why: |
| 06:53 | AWizzArd | ,(let [x (transient [1])] (into-array Byte/TYPE (map byte (persistent! (conj x 2))))) |
| 06:53 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IPersistentCollection |
| 06:54 | AWizzArd | ah okay, nevermind |
| 07:00 | ambalek | ,(+ 1 2) |
| 07:00 | clojurebot | 3 |
| 07:00 | ambalek | clojurebot: <3 |
| 07:00 | clojurebot | <3 is </3 |
| 07:00 | ambalek | clojurebot: are you saying you don't love me back? |
| 07:00 | clojurebot | Huh? |
| 07:00 | ambalek | you said </3 which kind of looks like a broken heart |
| 07:10 | somnium | clojurebot: </3 |
| 07:10 | clojurebot | Excuse me? |
| 07:18 | ambalek | clojurebot: don't pretend you don't understand |
| 07:18 | clojurebot | No entiendo |
| 07:28 | aatifh | I have a map like {:a nil :b 2 :c nil :d 4 :e 5} and i want to remove all the key/val whose value is nil. Anyone in just one liner elegant way? |
| 07:30 | gerry` | (filter (fn [[k v]] (not= v nil)) yourmap ) |
| 07:32 | tomoj | ,(into {} (filter val {:a nil :b 2 :c nil :d 4 :e 5})) |
| 07:32 | clojurebot | {:b 2, :d 4, :e 5} |
| 07:33 | tomoj | though that will remove pairs with false as a value.. |
| 07:34 | tomoj | ,(into {} (remove (comp nil? val) {:a nil :b 2 :c nil :d 4 :e 5 :f false})) |
| 07:34 | clojurebot | {:b 2, :d 4, :e 5, :f false} |
| 07:35 | gerry` | ,(into {} (filter (fn [[k v]] (not= v nil)) {:a nil :b 2 :c nil :d 4 :e 5})) |
| 07:35 | clojurebot | {:b 2, :d 4, :e 5} |
| 07:38 | tomoj | ,(into {} (filter (comp (complement nil?) val) {:a nil :b 2 :c nil :d 4 :e 5 :f false})) |
| 07:38 | clojurebot | {:b 2, :d 4, :e 5, :f false} |
| 07:39 | tomoj | hehe |
| 07:41 | djpowell | i was just looking at sinatra, the web framework that influences compojure; but it seems hard to read without all the parens :) |
| 07:42 | djpowell | a magic token stream |
| 07:43 | _ato | djpowell: huh... you're right |
| 07:44 | _ato | that's kind of scary |
| 07:46 | _ato | Compojure is lacking an awesome logo though :p |
| 07:46 | ol3 | hello, i installed clojure-mode and swank-clojure |
| 07:47 | ol3 | what should i do now if I want to start normal cl slime? |
| 07:49 | tomoj | ol3: https://gist.github.com/b06ace1e874298251401 |
| 07:49 | tomoj | that works for me |
| 07:49 | tomoj | M-x slime-clojure or M-x swank-clojure-project to start up a slime repl |
| 07:49 | tomoj | M-x slime starts a cl slime |
| 07:49 | tomoj | or C-u M-x slime to pick which slime you want |
| 07:50 | tomoj | _ato: http://preview.compojure.org/ |
| 07:50 | tomoj | maybe it's not awesome, I dunno |
| 07:53 | ol3 | tomoj: thanks, that what i was looking for |
| 08:08 | _ato | tomoj: very nice! |
| 08:08 | _ato | I hadn't seen that |
| 08:08 | tomoj | it's hidden away for some reason |
| 08:08 | clojurebot | for is not a loop |
| 08:09 | tomoj | I don't really understand the logo |
| 08:09 | tomoj | is it a martini with a blue olive? |
| 08:11 | _ato | yeah looks like a green martini with a blue olive to me |
| 08:11 | tomoj | maybe if we are classy enough to be drinking martinis, we have good composure? |
| 08:13 | _ato | I think it's a reference to Frank Sinatra |
| 08:15 | tomoj | aha |
| 08:16 | tomoj | so a hidden nod to the sinatra framework as well? |
| 08:16 | _ato | yeah, that's my guess anyway |
| 08:24 | tomoj | I have yet to use compojure for anything other than tiny experiments |
| 08:25 | tomoj | it's hard! |
| 08:25 | tomoj | compojure (and I guess sinatra as well? never used it) make you actually make decisions |
| 08:25 | tomoj | instead of having them all already made for you by a danish dude |
| 08:39 | solussd | will 'memoize' work correctly with a function that alters refs? |
| 08:40 | solussd | It seems like it should not, since the input would be just the ref, not the ref's value |
| 08:41 | chouser | solussd: changing a ref is a kind of side-effect |
| 10:33 | djork | it's correct to name .clj files with_underscores.clj |
| 10:33 | djork | right? |
| 10:34 | chouser | yes |
| 10:34 | djork | namespace/with_underscores.clj becomes (ns namespace.with-underscores) |
| 10:34 | chouser | yes |
| 10:34 | djork | k |
| 10:34 | djork | thanks |
| 10:34 | chouser | unfortunately. :-) |
| 10:34 | lisppaste8 | cemerick pasted "rhickey: NoSuchFieldError on keyword lookup (regression?)" at http://paste.lisp.org/display/89834 |
| 10:35 | cemerick | hrm, that doesn't happen with deftype, tho. |
| 10:35 | AWizzArd | Is there an easier for doing this: |
| 10:35 | AWizzArd | ,(apply hash-map (apply concat (pmap #(vector %1 %2) [:a :b :c] [1 2 3]))) |
| 10:35 | clojurebot | {:a 1, :c 3, :b 2} |
| 10:35 | chouser | AWizzArd: you want pmap? |
| 10:36 | AWizzArd | yes, no mapcat please |
| 10:36 | chouser | ,(into {} (pmap #(vector %1 %2) [:a :b :c] [1 2 3])) |
| 10:36 | clojurebot | {:a 1, :b 2, :c 3} |
| 10:36 | AWizzArd | good! |
| 10:36 | chouser | ,(zipmap [:a :b :c] [1 2 3]) |
| 10:36 | clojurebot | {:c 3, :b 2, :a 1} |
| 10:37 | chouser | But no pzipmap or zippmap, I'm afraid. |
| 10:37 | chouser | so you're still churning out vectors. |
| 10:37 | AWizzArd | well, my %2 will be (.foo %2) |
| 10:37 | Anniepoo | anybody know how to get enclojure to start it's repl with a special java cmd line? |
| 10:38 | AWizzArd | so, the pmap is actually doing something |
| 10:41 | notallama | (zipmap [:a :b :c] (pmap foo [1 2 3])) ? |
| 10:41 | chouser | pmap doesn't appear to use chunked seqs yet. |
| 10:41 | chouser | notallama: yes, good! |
| 10:41 | chouser | rhickey: do you want a chunked pmap? |
| 10:42 | AWizzArd | good idea notallama |
| 10:43 | AWizzArd | chouser: what is a chunked pmap? |
| 10:47 | chouser | AWizzArd: if the input seq were chunked, each step would do a whole chunk instead of a single item. |
| 10:51 | chouser | this would reduce the thread-interaction overhead per item and reduce the threshold for the amount of work needed to be done on each item for pmap to be worthwhile. |
| 10:59 | AWizzArd | chouser: and what are the differences between a single item vs. chunk? |
| 11:05 | AWizzArd | git question: when I want to freshly clone the NEW branch of Clojure, how would I do that? |
| 11:09 | rhickey | chouser: chunked pmap is tricky, I've tried it a couple of times without being completely happy. The fundamental problem is you can't presume a uniformity of (chunked-.non) seq type across the iteration |
| 11:09 | rhickey | cemerick: you get that with a clean build all around? |
| 11:10 | cemerick | rhickey: yes, top to bottom, although I've now discovered that it only happens with two of the ~15 defclasses we have. |
| 11:11 | rhickey | method called bounds? |
| 11:12 | rhickey | and ant clean, not just rebuild? |
| 11:12 | cemerick | well, it has a field *and* a method called bounds |
| 11:12 | rhickey | cemerick: that was my quesiton |
| 11:12 | cemerick | rhickey: yes, cleaned all the way down the clojure, and back up |
| 11:12 | rhickey | is that true for other fields that work? |
| 11:12 | rhickey | field + method? |
| 11:13 | cemerick | yes, on the same defclass, there's a field + method called derived that works fine |
| 11:13 | cemerick | oh, I'm seeing a pattern, one sec |
| 11:19 | AWizzArd | What is the "git clone" command to download Clojures "new" branch instead of master? |
| 11:19 | lisppaste8 | cemerick annotated #89834 "untitled" at http://paste.lisp.org/display/89834#1 |
| 11:19 | cemerick | rhickey: ^^ |
| 11:19 | The-Kenny | AWizzArd: After the git clone, do "git checkout new". |
| 11:19 | drewr | AWizzArd: git checkout -b new origin/new |
| 11:20 | The-Kenny | Oh sorry, origin/new. My bad. |
| 11:20 | savanni | Hey, guys, I actually have a question today... |
| 11:22 | savanni | When I try loading clojure.contrib.test-is, I get back an error saying that clojure/test__init.class and clojure/test.clj cannot be found. Any idea why this would happen when I have access to other parts of clojure.contrib? |
| 11:26 | drewr | savanni: test-is was promoted from contrib to core a couple months ago |
| 11:26 | drewr | you may have conflicting versions of both |
| 11:26 | savanni | Oh. Well that makes sense. |
| 11:27 | rhickey | cemerick: fixed |
| 11:28 | rhickey | cemerick: note this is still not full non-primitive-hinted-field support |
| 11:28 | cemerick | rhickey: meaning? |
| 11:29 | rhickey | meaning the hint is ok, but does nothing, and doesn't fail when accessed via :field |
| 11:29 | cemerick | oh, ok |
| 11:29 | rhickey | as you noted yesterday, it's not creating a String field yet |
| 11:29 | cemerick | so usages in method impl bodies will need hinting |
| 11:29 | rhickey | but the lookup thunk looked for one |
| 11:30 | cemerick | ah, I was only referring to the type on the ctor |
| 11:30 | savanni | Did test-is get move into clojure.core for clojure-1.0.0? |
| 11:31 | rhickey | cemerick: I'll have to survey how extensive a change it is to support non-primitive-local hints, it is my intention to support, but in protocol-land right now |
| 11:40 | replaca_ | savanni: nope, it's post-1.0.0 |
| 11:41 | savanni | Thanks. I'll need to get clojure from git, then. |
| 11:42 | replaca_ | savanni: or you can get the 1.0 compatible contrib |
| 11:43 | savanni | That, too. I'm more inclined to get the latest versions, though. |
| 11:43 | replaca_ | (but I just stay at HEAD and everything seems fine) |
| 11:43 | savanni | If I'm getting development versions, I'll just expect things to break occasionally. :) |
| 11:44 | chouser | savanni: you may be disappointed |
| 11:45 | savanni | You mean it rarely breaks? That would be awesome. |
| 11:45 | noidi | does anyone have any idea how to install swank-clojure at the moment? |
| 11:46 | savanni | (my statement sounds really mean, and I didn't expect it to...) |
| 11:46 | noidi | I tried following these instructions http://github.com/jochu/swank-clojure, but when I run M-x slime, I get "Symbol's value as variable is void: package-activated-list" |
| 11:47 | chouser | savanni: oh, no, it's not mean to expect a development branch to break occasionally. But in practice it's pretty rare. |
| 11:47 | chouser | and usually cgrand's fault. |
| 11:48 | chouser | :-) see, now *that* was mean. |
| 11:48 | chouser | cgrand: just kidding! |
| 11:48 | noidi | I guess I'll try the package management thing, maybe installing clojure-mode from git doesn't work anymore |
| 11:48 | rhickey | ouch! |
| 11:48 | fogus_ | zing |
| 11:49 | cemerick | rhickey: That fix is confirmed. I'm hitting a couple of other related issues, as well. Do you want msgs on the list, tickets in assembla, or should I lay them on you here? |
| 11:49 | rhickey | cemerick: start here |
| 11:50 | stuartsierra | noidi: swank-clojure is in flux at the moment, preparing for a release; try the new mailing list http://groups.google.com/group/swank-clojure/browse_frm/thread/20141a1e19c60339 |
| 11:50 | lisppaste8 | cemerick annotated #89834 "untitled" at http://paste.lisp.org/display/89834#2 |
| 11:50 | cemerick | rhickey: ^^ |
| 11:51 | chouser | cgrand: I think I've broken things about as often, and while attempting changes far less useful or significant than transient maps. |
| 11:52 | noidi | stuartsierra, cool, thanks! |
| 11:52 | stuartsierra | noidi: no problem |
| 11:52 | noidi | I guess it's a good thing that &/¤%"#¤ github ate my detailed bug report, then :P |
| 11:54 | cgrand | chouser: well it's usually what I reply when one ask me how stable the dev branch is. "pretty stable unless one of my patches got applied" |
| 11:55 | chouser | heh |
| 11:58 | stuartsierra | Anyone want multi-maps in contrib? |
| 11:59 | lisppaste8 | cemerick annotated #89834 "rhickey: issue #3" at http://paste.lisp.org/display/89834#3 |
| 11:59 | cemerick | That's all I have now -- thankfully, I was able to distill good examples. :-) |
| 12:00 | AWizzArd | drewr: thanks |
| 12:06 | cgrand | about messing with core data structures: stack ops on persistent vectors can be made faster by having the last item or the two last items (depending on the vector parity) stored in fields. Thus the tail array is allocated only once every two conj (or pop) and peek is direct (no array lookup). |
| 12:09 | rhickey | cemerick: first fixed, second a limitation for now (use java-compatible field names) |
| 12:10 | rhickey | cgrand: sounds interesting, what about the cost for ordinary lookup? - definitely adds logic there |
| 12:11 | rhickey | and complexity to seq et al |
| 12:12 | lisppaste8 | stuartsierra pasted "Multimaps" at http://paste.lisp.org/display/89840 |
| 12:13 | cgrand | rhickey: haven't benchmarked the idea on the actual persistent vector but on a simplest prototype. The lookup cost wasn't noticeable (the indirection cost through nodes and arrays dominates I guess) |
| 12:17 | cgrand | seq support: getArrayFor(i) must return a synthetic array when i is the last or the penult (when even) |
| 12:18 | cgrand | transient ops would have added complexity |
| 12:22 | rhickey | cgrand: I don;t think I'd want to take on the complexity right now, but an interesting idea |
| 12:22 | rhickey | another idea I had was to have different types for the different depths, then there would be no recursion, straight-through lookup code per depth |
| 12:24 | savanni | What is a good wai to debug a NullPointerException, when I know which function it is happening in but not which variable or line is null? |
| 12:26 | cemerick | rhickey: confirmed that fix. Thank you very much. :-) |
| 12:26 | rhickey | cemerick: sure - keep em coming, that one was just an undone todo |
| 12:27 | rhickey | cemerick: I'm really glad you are able to try it out - you'd be amazed at how different things are under the hood :) |
| 12:28 | rhickey | e.g. completely changing the compilation of fns, (:foo x) etc |
| 12:28 | djork | oops, I just wrote clojure in my objc code |
| 12:28 | djork | (== 0 section) |
| 12:29 | cemerick | rhickey: it's been wonderfully smooth overall. Q: given that non-primitive hints are ignored right now, are host invocations in method bodies reflective? I'm not getting reflection warnings, but I can't imagine how methods are being invoked on Object fields otherwise. |
| 12:31 | rhickey | cemerick: the hints propagate through as hints, just not as storage types, so, stored as Object, resolved as direct calls due to hinting, no reflection, just checkcast |
| 12:31 | cemerick | ah, OK |
| 12:31 | cemerick | I'm really starting to like the idea of a defstatic or similar for factories. |
| 12:31 | rhickey | leave out hint you should get reflection warning |
| 12:32 | rhickey | cemerick: yes, interfaces + defstatic is near ideal external interface IMO |
| 12:32 | rhickey | as much as this isn't a full interop facility, it really lends to nice, clean designs |
| 12:33 | rhickey | and protocols will totally rock |
| 12:33 | rhickey | as soon as I can figure out MI :( |
| 12:35 | cemerick | rhickey: I had to deal with this yesterday, which was fun. Amazing what can be done in "typical Java" APIs. http://lucene.apache.org/java/2_9_0/api/core/org/apache/lucene/index/IndexWriter.html#constructor_summary |
| 12:36 | rhickey | wow |
| 12:36 | cemerick | half of them are deprecated, but nevertheless.... |
| 12:38 | technomancy | lucene even seemed relatively tame for a Java API to me |
| 12:39 | technomancy | after working with Hadoop... =\ |
| 12:39 | cemerick | uh, yeah, hadoop is pretty mammoth in terms of API surface area |
| 12:40 | cemerick | we've long since stopped using it. Nice concept, but way too much *stuff* to deal with for us. |
| 12:40 | stuartsierra | That's why I wrote clojure-hadoop :) |
| 12:40 | patrkris | does anyone here have experience with using webjure? I just want to hear some opinions on it as a web programming framework? are there any better alternatives? |
| 12:41 | cemerick | just the sysadmin junk associated with it was enough to cause us to look away. |
| 12:41 | cemerick | we're liking simple JMS with couch for data endpoints at the moment |
| 12:41 | stuartsierra | with ec2 & the cloudera scripts it's not too bad |
| 12:42 | patrkris | forget my question - i really should learn to use google |
| 12:52 | jasapp | I'm having a bit of trouble with clojure.xml/parse |
| 12:53 | jasapp | I think this is valid xml |
| 12:53 | jasapp | <foo>\"bar</foo> |
| 12:53 | jasapp | but I get an exception when I try to parse it |
| 12:54 | jasapp | ,(clojure.xml/parse "<foo>bar\"</foo>") |
| 12:54 | clojurebot | java.net.MalformedURLException: no protocol: <foo>bar"</foo> |
| 12:55 | chouser | jasapp: parse wants a sax InputSource, not a string. |
| 12:55 | clojurebot | a is b |
| 12:55 | jasapp | oh, sorry |
| 12:55 | jasapp | I feel silly now, I thought it took strings |
| 12:56 | The-Kenny | ,(doc clojure.xml/parse) |
| 12:56 | clojurebot | "([s] [s startparse]); Parses and loads the source s, which can be a File, InputStream or String naming a URI. Returns a tree of the xml/element struct-map, which has the keys :tag, :attrs, and :content. and accessor fns tag, attrs, and content. Other parsers can be supplied by passing startparse, a fn taking a source and a ContentHandler and returning a parser" |
| 13:01 | jasapp | ahh, much better |
| 13:25 | javuchi | hello |
| 13:25 | Joreji | Hey guys, how can I keep on calling a function over and over (in a while loop) without freezing the clojure repl? |
| 13:25 | Joreji | Is there some agent/thread magick that can achieve that? |
| 13:26 | javuchi | is there going to be a stand-alone clojure ever (with no dependences for the jvm)? |
| 13:28 | patrkris | Joreji: you can send an action to an agent which itself sends an action to the same agent, whenever it wants to continue "the loop" |
| 13:30 | AWizzArd | This works fine for me: |
| 13:30 | AWizzArd | ,(let [a (agent 15), p (promise)] (send a #(do (deliver p (+ % 5)) :ok)) @p) |
| 13:30 | clojurebot | 20 |
| 13:30 | AWizzArd | But, when I make (+ % 5) to (+ % "5") then it hangs |
| 13:31 | Joreji | patrkris: If I do (while 1 (send my-agent (update))) wouldn't that fill the queue of the agent pretty fast? |
| 13:31 | AWizzArd | Can deliver maybe made so that when an exception occurs that it will throw it, instead of hanging? |
| 13:34 | patrkris | Joreji: just a sec, i'll give you an example |
| 13:36 | chouser | javuchi: what would you use it for with no libraries? Clojure depends on a host (JVM, CLR, etc.) for all IO, user interaction, etc. |
| 13:38 | javuchi | chouser: because the jvm consumes too much memory |
| 13:38 | wwood | 4 |
| 13:39 | cemerick | javuchi: so you want to target C or something? |
| 13:39 | patrkris | Joreji: http://pastebin.com/m70303ad7 |
| 13:39 | patrkris | Joreji: just a very simple example |
| 13:40 | patrkris | Joreji: you don't need a while there, because every time the action is called, it will dispatch itself to the agent again and keep it going |
| 13:41 | patrkris | Joreji: and the agent queue wont fill because every time the action is executed, it is taken off the queue |
| 13:42 | Joreji | patrkris: Ah, thanks alot! |
| 13:42 | patrkris | Joreji: and the Thread/sleep is just there to pretend that we're doing some work that takes a little time |
| 13:44 | abedra | should send-off ever block? |
| 13:46 | abedra | basically i want to send an agent off every n seconds |
| 13:46 | abedra | http://gist.github.com/227280 |
| 13:46 | abedra | i started here |
| 13:46 | abedra | but it blocks |
| 13:46 | patrkris | abedra: note that the action is not sent before the current action is done executing |
| 13:46 | drewr | abedra: you probably want *agent* on line 2 |
| 13:50 | abedra | patkris: so I should create *agent* ahead of time? |
| 13:50 | abedra | and use that for both? |
| 13:51 | patrkris | abedra: *agent* refers to the agent currently executing |
| 13:51 | patrkris | abedra: it's a special variable in clojure |
| 13:52 | chouser | javuchi: once we have clojure-in-clojure, ports to other host languages/platforms will be quite a bit easier. Perhaps someone will target ObjectiveC/iPhone or chickenscheme |
| 13:53 | Joreji | patrkris: http://pastebin.com/d5bf739ca |
| 13:53 | Joreji | patrkris: For some reason I'm getting a stack overflow. |
| 13:53 | Joreji | patrkris: Anything obvious which I've done wrong? |
| 13:54 | fradiavalo | is it good clojure style to have code like this? (reduce + (take 100 (repeat 5))) |
| 13:54 | chouser | fradiavalo: it's probably better just to say (* 100 5) |
| 13:54 | chouser | :-) |
| 13:55 | chouser | fradiavalo: but other than that, there's nothing wrong with your expression. What about it makes you ask? |
| 13:56 | fradiavalo | chouser: Thanks, just wondering. I am learning clojure, so quite unsure about the correct idioms. |
| 13:56 | patrkris | Joreji: i'm not exactly sure |
| 13:57 | chouser | fradiavalo: a seq-producer (like repeat) fed through a chain of filters or processors (like take, filter, remove, map, etc.) is quite common, as is collecting up that seq with a 'reduce'. |
| 13:57 | Joreji | patrkris: I also get the stack overflow if I remove the (QApplication/processEvent) call. |
| 13:57 | chouser | there's even a macro to let you write it in what may be a more comfortable order. |
| 13:58 | chouser | ,(->> 5 repeat (take 100) (reduce +)) |
| 13:58 | clojurebot | 500 |
| 13:58 | patrkris | Joreji: do you get the stackoverflow right away? |
| 13:58 | fradiavalo | chouser: I like the ordering without the macro better :) |
| 13:59 | fradiavalo | Guess I like to read right to left |
| 13:59 | Joreji | patrkris: No. After like 3-5 seconds. |
| 13:59 | chouser | fradiavalo: fair enough |
| 14:00 | fradiavalo | I know a little bit of q (http://en.wikipedia.org/wiki/Q_(programming_language_from_Kx_Systems) so the right to left style seems more natural |
| 14:00 | notallama | fradiavalo: with the -> and ->> macros, i often put each form on its own line, so you'd read it top to bottom. |
| 14:01 | patrkris | Joreji: hmm... maybe it's because QApplication/processEvents doesn't take much time, and the agents effectively does a lot of sends really fast... but I'm not sure. |
| 14:01 | patrkris | someone else may be able to answer this |
| 14:01 | stuartsierra | Joreji: does QApplication/processEvents block? |
| 14:01 | fradiavalo | notallama: Thats a good idea to help readability |
| 14:02 | Joreji | stuartsierra: I've removed the QApplication/processEvents. So, no. |
| 14:02 | stuartsierra | then you might be overflowing the agent's event queue |
| 14:02 | Joreji | Ah. |
| 14:03 | patrkris | my thought |
| 14:03 | patrkris | exactly |
| 14:03 | Joreji | Indeed. It works if I add a (Thread/sleep 500) |
| 14:03 | Joreji | Thanks guys! |
| 14:05 | stuartsierra | Joreji: looking at the definition of QApplication/processEvents, you probably don't want to call it in a busy-loop like that. |
| 14:05 | abedra | patkris: thanks, that got me further, however I want to make the agent keep firing the function |
| 14:05 | abedra | patkris: and i get an agent error after the first couple of firings |
| 14:06 | stuartsierra | Clojure agents do not directly support calling an action periodically, you need Java timers or something. |
| 14:06 | Joreji | stuartsierra: Why is that? |
| 14:06 | patrkris | abedra: what is the error? |
| 14:06 | Joreji | stuartsierra: Hm ok. |
| 14:06 | Joreji | Explains why this is not working. |
| 14:07 | stuartsierra | Joreji: the docs say you can call processEvents "periodically", but you're calling it incessantly, like a while(1) loop. |
| 14:07 | technomancy | is there a reason you can only kill all agents at once rather than killing individual ones? |
| 14:07 | hiredman | http://gist.github.com/178350 <- schedule |
| 14:07 | abedra | thanks |
| 14:08 | abedra | patkris: i just get Agent has errors |
| 14:08 | Joreji | stuartsierra: Makes sense. Guess I'll have to take a look at some java timers. |
| 14:08 | abedra | but I think the scheduler would help that out |
| 14:09 | patrkris | abedra: use (agent-errors my-agent) to see the errors |
| 14:09 | patrkris | ,(doc agent-errors) |
| 14:09 | clojurebot | "([a]); Returns a sequence of the exceptions thrown during asynchronous actions of the agent." |
| 14:09 | stuartsierra | technomancy: maybe because the JVM discourages you from killing individual threads? |
| 14:09 | hiredman | the binding of agent to thread is very loose |
| 14:09 | hiredman | an agent's action just runs on whatever thread the threadpool hands it off to |
| 14:11 | hiredman | if you want to be able to cancel async actions you might look at future |
| 14:12 | technomancy | stuartsierra: didn't realize that... (.stop (Thread. foo)) is not kosher? |
| 14:12 | stuartsierra | technomancy: The JDK docs say don't do it, I think b/c it can leave locks/monitors inconsistent. |
| 14:13 | chouser | and skip 'finally' clauses |
| 14:13 | abedra | patkris: IllegalArgumentException: Key must be integer is what gets returned there |
| 14:14 | technomancy | interesting |
| 14:14 | patrkris | abedra: well I guess you're calling something inside your action that expects an integer argument :) |
| 14:14 | Chousuke | the proper way to "stop" a thread is to have it poll for the .interrupted flag |
| 14:15 | abedra | patkris: the funny thing is that it runs twice before that happens :) |
| 14:15 | Chousuke | also if you call .interrupt on a thread while it's waiting, an exception will be raised within it. |
| 14:15 | patrkris | abedra: can you give me a pastbin of your new code? |
| 14:19 | abedra | patkris: http://pastebin.com/m4785c831 |
| 14:19 | abedra | patkris: that's in the middle of trying a few things out |
| 14:20 | AWizzArd | rhickey: it seems that promises can block forever when an agent tries to deliver them with something that throws an exception. For example, paste this into your repl: (let [a (agent 15), p (promise)] (send a #(do (deliver p (+ % "5")) :ok)) @p) |
| 14:21 | patrkris | abedra: ok, first of all, the actions that you send to agents must always take the agent's state as the first argument, so you should probably just have (send-off a api-key-agent) in line 8 |
| 14:22 | patrkris | abedra: and in line 4, you are asking for the agent's errors, but that will fail because a is bound to the agent's state at that point, *not* the agent itself |
| 14:22 | javuchi | why CL's guys still advocates against clojure? |
| 14:23 | djork | because they are smug Lisp weenies |
| 14:23 | djork | and they are no fun |
| 14:23 | stuartsierra | javuchi: because it doesn't have a 50-year-old spec |
| 14:23 | djork | and nobody likes to hang out with them |
| 14:23 | patrkris | abedra: and why don't you just call retrieve-api-keys directly? |
| 14:24 | javuchi | i found this: |
| 14:24 | javuchi | http://www.3ofcoins.net/2009/01/30/common-lisp-clojure-and-seriousness/ |
| 14:24 | drewr | how do you get *ns* bound to the namespace of the fn's var? |
| 14:24 | rhickey | AWizzArd: the exception happens before the transfer of control to deliver. What you are basically saying is, code that throws an exception before it calls deliver doesn't end up calling deliver, which, while correct, is just a program bug, not something promise/deliver can do anything about |
| 14:24 | javuchi | all what he says is that clojure is a toy because it is hosted |
| 14:25 | javuchi | no other technical reasons |
| 14:25 | djork | " a serious language to a toy language." |
| 14:25 | djork | what a dick |
| 14:25 | abedra | patkris: That's what I would like to do... |
| 14:25 | drewr | iow, (in-ns 'foo.bar) (defn baz [x y] *ns*) |
| 14:25 | stuartsierra | The CL guys don't like Clojure because they see it as a concession to the market dominance of Java. |
| 14:25 | djork | the toy language is the one where I can download a jar and fire up a Repl and slap a window on the screen with the stuff already in my OS? |
| 14:25 | abedra | patkris: basically I need to have something keep calling (retrieve-api-keys) in the background while the process is running |
| 14:26 | patrkris | abedra: and you want to do something with the retrieved value, i guess? |
| 14:26 | djork | the toy language is the one where an infinite lazy seq of prime numbers is a one-liner |
| 14:26 | abedra | patkris: no, (retrieve-api-keys) just updates an atom |
| 14:26 | djork | (my favorite clojure example ever, by the way) |
| 14:26 | noidi | "after a nuclear catastrophe, archæologists of future generations should be able to re-implement the language on any hardware, including the Calculor;" |
| 14:26 | noidi | :D |
| 14:26 | AWizzArd | rhickey: ok I understand |
| 14:26 | noidi | yes, all languages should be designed for the post-apocalyptic use case |
| 14:27 | javuchi | hehe |
| 14:27 | djork | Perl and Tcl are toys too? I guess his definition of a toy language is "one that is used to do vast amounts of real work." |
| 14:27 | stuartsierra | I like this comment: http://www.3ofcoins.net/2009/01/30/common-lisp-clojure-and-seriousness/#comment-31 |
| 14:27 | javuchi | i don't see the point in going against the JVM right now that it is GPL |
| 14:28 | djork | Here's the deal: the JVM is specced out, and Clojure is open source. Done. It's just as apocalypse-proof as CL. |
| 14:28 | javuchi | djork: I've never seen a serius project in CL, do you know of one? |
| 14:28 | djork | nope |
| 14:28 | javuchi | in 20 years of existence? |
| 14:28 | djork | it's just so much work to use CL |
| 14:28 | djork | there's no time left to build your project |
| 14:29 | stuartsierra | javuchi: AllegroGraph (huge triple store) was originally written in CL, then ported to Java :) |
| 14:29 | javuchi | what's going to happen to CL today, when multi-threading applications are going to be a must? |
| 14:29 | djork | I feel like clojure/core is not going anywhere... is that right rhickey? It's small and concise enough. |
| 14:30 | patrkris | abedra: do you want the agent itself to hold any particular state, or do you just want it to repeatedly call (retreive-api-keys) with certain intervals? |
| 14:30 | stuartsierra | djork: if you think clojure.core is not going anywhere, you haven't been paying attention :) |
| 14:30 | abedra | patkris: i just want to repeatedly call it |
| 14:30 | djork | I guess not :) |
| 14:30 | stuartsierra | djork: reify, deftype, transients... |
| 14:31 | djork | I don't mean in terms of new features |
| 14:31 | djork | I mean things aren't going away right? |
| 14:31 | stuartsierra | djork: there will probably not be major changes to the existing core functions any time soon |
| 14:32 | djork | "At this point in Lisp’s history a standard was still 25 years in the future." |
| 14:32 | patrkris | abedra: how about something like this: http://pastebin.com/d1eef4361 |
| 14:32 | djork | (the age Clojure is now) |
| 14:33 | javuchi | ok, the question now is: is somebody doing any important project based on clojure? |
| 14:34 | drewr | ,(in-ns 'foo) (defn bar [] *ns*) (in-ns 'baz) (require 'foo) (foo/bar) |
| 14:34 | clojurebot | #<Namespace foo> |
| 14:34 | javuchi | any significant application? |
| 14:34 | abedra | patkris: exactly like that, thanks so much! |
| 14:34 | fogus_ | "Important" is a loaded term, but FlightCaster uses Clojure |
| 14:34 | drewr | ,(ns 'foo) (defn bar [] *ns*) (in-ns 'baz) (require 'foo) (foo/bar) |
| 14:34 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol |
| 14:34 | patrkris | abedra: if you need to update the state of the agent, the last expression in its action should yields its new state.... i haven't taken that into account |
| 14:34 | drewr | ,(ns foo) (defn bar [] *ns*) (in-ns 'baz) (require 'foo) (foo/bar) |
| 14:34 | clojurebot | nil |
| 14:34 | patrkris | abedra: no problem :) |
| 14:34 | drewr | that nil seems wrong to me |
| 14:40 | mikehogye | where is the best place to ask questions about Lancet? |
| 14:47 | weissj | mikehogye: here probably :) i've worked with it some - it's not quite complete, i've made a few fixes that i don't think anyone ever accepted :) |
| 14:48 | mikehogye | weissj: in the runonce method, it seems like access to the "result" atom is not properly synced |
| 14:48 | mikehogye | weissj: http://github.com/stuarthalloway/lancet/blob/master/lancet.clj , lines 68 and following |
| 14:49 | chouser | drewr: switching namespaces within a single top-level form is perilous. You'll get different results if you run each of those in the repl. |
| 14:49 | mikehogye | weissj: ThreadA could execute line 83, find that @result != sentinel |
| 14:50 | mikehogye | weissj: then ThreadB calls reset-fn |
| 14:50 | mikehogye | weissj: then ThreadA derefs result |
| 14:52 | mikehogye | weissj: causing line 85 (and ThreadA's call to runonce) to evaluate to sentinel |
| 14:52 | weissj | mikehogye: to be honest i don't have idea idea what runonce is even for. i just require lancet as ant, and start calling things like ant/unzip, ant/move, etc |
| 14:52 | drewr | chouser: for a var that points to a fn, say foo.bar/baz, is there any way within baz to refer to find foo.bar? |
| 14:53 | mikehogye | weissj: actually, the other question I wanted to ask about Lancet is: is it usable? |
| 14:53 | drewr | I'm not switching namespaces in my real code |
| 14:53 | weissj | mikehogye: all i wanted was clojure bindings into ant, which i get without doing anything special |
| 14:54 | mikehogye | ah |
| 14:54 | mikehogye | weissj: ah, I'm with you |
| 14:54 | drewr | chouser: s/to find/to/ |
| 14:55 | weissj | mikehogye: it's usable for me, but i did have to add a few multimethods like the ones that are already there, for example for exec's arg tag, and echo's level tag |
| 14:55 | chouser | drewr: not sure exactly what you're trying to do. Would this work? (defn baz [] (.ns #'baz)) |
| 14:55 | mikehogye | weissj: any idea whether anyone else is actively working on it? |
| 14:56 | chouser | drewr: or: (def baz (let [ns *ns*] (fn baz [] ns))) |
| 14:56 | weissj | mikehogye: i emailed stuart my additions and never heard anything, and i see the current git copy still doesn't have them. so i'd say no |
| 14:56 | mikehogye | weissj: bleh |
| 14:56 | mikehogye | weissj: thanks |
| 14:56 | weissj | i think he used it as an example from his book and never expected anyone to really use it |
| 14:56 | mikehogye | weissj: that's a shame |
| 14:56 | technomancy | pretty sure lancet is intended just as an instructional project, not to be used for anything serious. |
| 14:56 | technomancy | at least, not as a tool in itself. |
| 14:56 | weissj | technomancy: yeah, which is unfortunate because it's really useful |
| 14:57 | mikehogye | it's such a good idea, though (or, it seems like a good idea to me) |
| 14:57 | weissj | and it's almost complete |
| 14:57 | weissj | then again, if its used as an example in a book, how hard can it be to finish |
| 14:57 | weissj | i haven't finished it because i'm a noob and i haven't had time |
| 14:57 | technomancy | however there *is* an in-process project at http://github.com/technomancy/leiningen that may be more like what you're looking for |
| 14:57 | technomancy | but you didn't hear that from me. |
| 14:57 | weissj | but mikehogye you can have my changes if you want em :) |
| 14:58 | notallama | if ::foo is a child of ::bar, will multimethods always prefer ::foo? or do i have to tell it to prefer ::foo? |
| 14:58 | mikehogye | weissj: I assume you're the weissjeffm on github? |
| 14:58 | drewr | chouser: ah, thanks; ns() is what I needed |
| 14:59 | weissj | mikehogye: yep |
| 14:59 | drewr | it'd be nice to do it without the #'baz, but at least it occurs near the scope |
| 14:59 | mikehogye | technomancy: is leiningen specifically for building Clojure codebases? |
| 14:59 | drewr | I'm trying to convert "foo" to the value that #'foo points to dynamically |
| 15:00 | technomancy | mikehogye: maaaaaaybe. (actually, yes.) |
| 15:00 | djork | someone asked about important projects in Clojure |
| 15:00 | djork | flightcaster.com |
| 15:01 | djork | built a Clojure layer on top of Hadoop and Cascading |
| 15:01 | mikehogye | technomancy: okay -- I will look at leiningen, but what I'm really dying for is Ant without the suckage |
| 15:01 | mikehogye | technomancy: which is to say, Lancet |
| 15:01 | djork | they do massive distributed computations in Clojure |
| 15:01 | djork | it is pretty much their backbone |
| 15:02 | djork | http://www.infoq.com/articles/flightcaster-clojure-rails |
| 15:02 | technomancy | mikehogye: lancet doesn't even ship with a bin script; it's definitely not meant to be used like ant. |
| 15:04 | javuchi | does clojure works on mobile devices supporting java? |
| 15:04 | javuchi | for example, on my nokia 6210 mobile? |
| 15:04 | stuartsierra | javuchi: it's reported to work on Android |
| 15:05 | hiredman | javuchi: most "java" phones are j2me which is garbage :( |
| 15:05 | mikehogye | technomancy: it seems like a basic wrapper script would be fairly easy (although I've given it a grand total of about 30 seconds of thought) |
| 15:05 | chouser | It's been a long time since I've heard anyone talk about clojure on j2me -- I don't remember if people got it working or not. |
| 15:05 | javuchi | hiredman: so it doesn't work? |
| 15:05 | hiredman | chouser: it would be really hard |
| 15:05 | hiredman | I think j2me is mostly java 1.4 |
| 15:06 | hiredman | I forget, but I don't think it even has Collections |
| 15:06 | chouser | oh. ouch. |
| 15:06 | ordnungswidrig | hi |
| 15:06 | hiredman | yeah |
| 15:06 | djork | oh well... j2me devices feel slow with pure Java in the first place |
| 15:06 | djork | I'd hate to see Clojure |
| 15:07 | hiredman | I think that depends on the phone |
| 15:08 | hiredman | I did a game of life for my blackberry and it ran fine :P |
| 15:08 | ordnungswidrig | java on my sony ericsson w800i was surpringsingly fast |
| 15:08 | Chousuke | hm |
| 15:09 | Chousuke | I wonder how to make ant print out the entire stacktrace |
| 15:09 | ordnungswidrig | ant? |
| 15:09 | hiredman | I think palm pre might be the only phone with real java |
| 15:09 | ordnungswidrig | ant -d? |
| 15:09 | Chousuke | I'm trying to run contrib tests with my reader and it fails and it's hiding 80 items from me and not even -v shows them |
| 15:09 | hiredman | chouser: doesn't it usually do that at the end? |
| 15:09 | Chousuke | I get a string out of bounds exception somewhere. |
| 15:10 | hiredman | I would also get an abbreviated exception inline with the test run, and then a dump of all the stacktraces at the end of the ant run |
| 15:11 | djork | I'm happy with Clojure on the desktop right now, since it's all about the Repl anyway. |
| 15:11 | clojurebot | a is b |
| 15:12 | rhickey | woah - http://code.google.com/closure/ |
| 15:12 | djork | wut |
| 15:12 | djork | you know what... the word "closure" looks funny now :) |
| 15:12 | hiredman | rhickey: yeah |
| 15:13 | chouser | ,(swap! (atom [] :validator #(or (empty? %) (number? (peek %)))) conj :oops) |
| 15:13 | clojurebot | java.lang.IllegalStateException: Invalid reference state |
| 15:14 | mikehogye | technomancy: do you know of reasons that bin scripts for Lancet (or a descendent thereof) would be difficult to write? |
| 15:15 | technomancy | mikehogye: no, and that's essentially what leiningen is, plus dependency management and some built-in clojure-specific tasks. it's not hard at all. |
| 15:15 | mikehogye | technomancy: cool. I will definitely take a look. |
| 15:16 | chouser | "it compiles from JavaScript to better JavaScript" hmph. |
| 15:16 | Chousuke | hmh |
| 15:17 | Chousuke | the ant page says to use fork="true" but that's already set... |
| 15:17 | technomancy | mikehogye: once I get the jar task done I will polish it a bit to make it easier to install and make an announcement, but you're welcome to give it a go now. |
| 15:20 | rhickey | chouser: hmph? that sounds awesome to me, like hotspot for js, makes it easier for us |
| 15:22 | javuchi | how much memory consumes an agent? |
| 15:22 | chouser | I'm actually quite ambivalent about compiling to JavaScript. |
| 15:22 | hiredman | chouser: really? I thought most of the java tasks in build.xml did not have fork="true" |
| 15:23 | hiredman | er |
| 15:23 | hiredman | Chousuke: |
| 15:23 | chouser | :-) |
| 15:23 | rhickey | javascript is the new bytecode |
| 15:23 | clojurebot | new Class(x) is (Class. x) |
| 15:23 | fogus_ | chouser: I've spent a lot of time in GWT, so I have similar conflicting feelings. |
| 15:24 | rhickey | unlike gwt, this seems to be the stuff they actually use |
| 15:24 | chouser | rhickey: I'll buy js is bytecode when I see debuggers that tie you back to the original source. |
| 15:25 | rhickey | good point |
| 15:25 | hiredman | hmmm |
| 15:25 | chouser | the wave team apparently uses and loves gwt |
| 15:25 | rhickey | chouser: yeah, the customized new version they had made for them addressing all shortcomings of the stuff everyone else was using |
| 15:26 | chouser | javuchi: agent uses very little memory -- it's not a whole thread or anything |
| 15:26 | chouser | rhickey: oh. :-( |
| 15:27 | javuchi | is it lightweighter tha erlang processes? |
| 15:27 | javuchi | thay consume about 230 bytes |
| 15:27 | chouser | oh, I missed that Closure is from google. |
| 15:28 | fogus_ | GWT has it's nice points, when viewed through the right lens |
| 15:28 | chouser | hm, the Closure inspector sounds interesting -- that might be the missing piece for debugging. We'll just need one for clojurescript |
| 15:29 | chouser | fogus_: I can see some of the benefits, but in general I'd rather write javascript than java. :-P |
| 15:31 | fogus_ | chouser: I agree with you. There is a huge impedance mismatch using GWT and that's tough to swallow. |
| 15:32 | javuchi | chouser: how can i know the size of an agent? |
| 15:32 | G0SUB | a lot of people complain about the debugging facilities of Clojure + SLIME being not so awesome. what is needed to fix the situation? |
| 15:32 | hiredman | more printlns |
| 15:32 | javuchi | G0SUB: i find it nice in the last versions |
| 15:33 | froog | http://georgejahad.com/clojure/cljdb.html |
| 15:33 | G0SUB | hiredman: better sldb integration will be great :) |
| 15:33 | hiredman | G0SUB: *shrug* |
| 15:35 | chouser | javuchi: http://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html :-P |
| 15:35 | G0SUB | rhickey: where can we get the video of your awesome talk about time at the jvm lang summit? |
| 15:37 | javuchi | chouser: so basically i need to create a million agents and measure memory consumption? |
| 15:37 | fogus_ | Hrmmm. Reading about Google-Closure is making bitter. |
| 15:38 | chouser | agent is _meta + validator + watches + state + q + errors |
| 15:38 | djork | you mean (+ _meta validator watches state q errors) :) |
| 15:39 | chouser | each of those one a 32-bit JVM is probably 4 bytes, plus 8 for Object, I'd guess 32 bytes per agent |
| 15:39 | chouser | djork: er, right. of course. |
| 15:39 | RomanRoe | is anybody able to use build.clojure.org as mvn repo? It stopped working for me :-/ |
| 15:40 | djork | my count is 88 bytes on my JVM |
| 15:40 | chouser | on a 64-bit JVM it's probably closer to 64 bytes. |
| 15:40 | javuchi | so it is expected to use 64 bytes on a 64bit machine |
| 15:40 | djork | OS X Snow Leopard |
| 15:40 | chouser | djork: counted how? |
| 15:40 | javuchi | 88 bytes? |
| 15:40 | javuchi | thats much less than 230 bytes for process in erlang |
| 15:40 | djork | (- (mime (agent nil)) (mime nil)) |
| 15:41 | djork | err that doesn't really work right now |
| 15:41 | djork | it's my new toy memory measuring macro |
| 15:41 | chouser | ah |
| 15:42 | djork | but (mime nil) takes 24 bytes to evaluate, and (mime (agent nil)) takes 112 bytes to evaluate |
| 15:42 | chouser | well, that's about as accurate as it's worth trying to get -- something less than 100 bytes per agent. |
| 15:42 | djork | yes |
| 15:42 | javuchi | so it is reasonable to think that we could use around 60 millions of agents with 4gb of memory? |
| 15:42 | javuchi | perhaps 50 millions? |
| 15:43 | chouser | I don't know what all an erlang process has to track, but agents don't have their own stack or instruction pointer or anything like that. |
| 15:43 | chouser | An agent is just a simple one-element container with a queue of actions to perform. |
| 15:43 | tmountain | GOSUB: http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey |
| 15:44 | chouser | javuchi: as you queue up more actions, the agent will hold onto more memory until it can dequeu them. |
| 15:44 | djork | that is some zen stuff there |
| 15:44 | javuchi | so 50 millions is not very reallistic |
| 15:45 | javuchi | perhaps 5 millions would be more reallistic |
| 15:45 | danlarkin | javuchi: there's no way to answer that, it depends on what the agents are doing |
| 15:45 | djork | I would think about my architecture as soon as 5 million of *anything* was being considered. |
| 15:46 | javuchi | djork: think, for example, of a massive IM server |
| 15:47 | javuchi | that's when erlang is brillant |
| 15:47 | javuchi | i'm think if clojure might be better??? |
| 15:47 | dysinger | re: bulid.clojure.org RomanRoe I had to change the url and hadn't got around to posting an updated message to the list |
| 15:47 | ordnungswidrig | javuchi: but 5 million on a single node / server sounds too much even for erlang |
| 15:48 | dysinger | the maven url is http://build.clojure.org/snapshots now RomanRoe |
| 15:48 | hiredman | javuchi: clojure agents are not actors |
| 15:48 | djork | a massive server probably needs to be distributed, whereas clojure's strong point is concurrency |
| 15:48 | dysinger | RomanRoe: I wont mess with it again |
| 15:48 | djork | you could load balance between clojure nodes |
| 15:49 | javuchi | anyway clojure is not designed for being distributed, is it? |
| 15:49 | hiredman | 2009:Sep:22:09:02:37 rhickey : Writing a message queue? use Erlang. Writing an ordinary application? use a message queue. |
| 15:50 | RomanRoe | dysinger: thanks! |
| 15:50 | dysinger | I still like erlang too |
| 15:50 | RomanRoe | dysinger: my clojure hacking evening is safe again.... puhhhh..... ;-) |
| 15:51 | dysinger | there are things you can do with networking and clustering in erlang that are trivial compared to socket programming in java land. |
| 15:51 | djork | indeed |
| 15:52 | djork | I'd say that if you want to, just develop your server in Clojure and then try scaling it with a message queue or something like Hadoop. |
| 15:52 | djork | It would be a good experiment. |
| 15:52 | djork | I don't see it going too badly either. |
| 15:53 | dysinger | I am working on a peer-2-peer work group library in clojure that will allow clusters of repls to work together. Message queues don't solve all problems neatly. |
| 15:53 | djork | mmm distributed repls |
| 15:54 | hiredman | dysinger: sounds kinda like terracotta |
| 15:54 | dysinger | minus 300k lines of code and instrumenting and XML |
| 15:54 | hiredman | :P |
| 15:55 | dysinger | no I don't have any shared memory needs |
| 15:55 | dysinger | I just need lots of machines to work together |
| 15:55 | hiredman | http://vids.myspace.com/index.cfm?fuseaction=vids.individual&videoid=60771080 <-- Origins of APL, the hair styles alone are worth it |
| 16:00 | ordnungswidrig | hiredman: great video :-) |
| 16:00 | ordnungswidrig | event roger moore has a role in it |
| 16:01 | ordnungswidrig | s/nt /n / |
| 16:14 | chouser | they seriously didn't pause for a moment when they realized the development of their language required new keyboard mappings, fonts, and a "type ball"? |
| 16:17 | ordnungswidrig | chouser: they where from IBM, so it was no issue to build some new hardware. |
| 16:17 | ordnungswidrig | chouser: I think |
| 16:18 | froog | besides, the world only needed 5-6 computers |
| 16:18 | froog | back then |
| 16:18 | ordnungswidrig | with a most 640k memory |
| 16:20 | ordnungswidrig | the host is smoking while the guest is talking. different times then. |
| 16:20 | dublindan | how can i force symbol capture in macros? |
| 16:20 | chouser | dublindan: ~'foo |
| 16:20 | clojurebot | foo is is Short, Self Contained, Correct (Compilable), Example http://sscce.org/ |
| 16:20 | dublindan | chouser: thanks! |
| 16:25 | javuchi | dysinger: do you have something done? |
| 16:25 | dysinger | it's a wip - soon |
| 16:25 | dysinger | I love it :) so simple and so cool :) can't wait to share |
| 16:26 | javuchi | would it bring the power of erlang distributed to clojure? |
| 16:27 | chouser | javuchi: http://github.com/amitrathore/swarmiji |
| 16:29 | javuchi | looks nice, chouser |
| 16:29 | javuchi | dysinger: is your library something like that? |
| 16:29 | dysinger | no - that's message queues with no job tracking |
| 16:30 | dysinger | and no peer awareness |
| 16:30 | dysinger | not to knock it - amit is smart |
| 16:30 | dysinger | it's just a different tool than I am targeting |
| 16:31 | javuchi | so what are you doing? |
| 16:34 | javuchi | dysinger? |
| 16:37 | dysinger | javuchi: above "peer-2-peer work group library in clojure that will allow clusters of repls to work together." |
| 16:38 | rhickey | dysinger: are you using something like JGroups under the hood? |
| 16:38 | dysinger | IE, not message queues but clustered interacting repls. |
| 16:38 | dysinger | rhickey: yes-ish + branch/leaf node work tracking |
| 16:39 | rhickey | cool |
| 16:39 | javuchi | dysinger: i'm trying to figure out what exactly you mean |
| 16:39 | dysinger | just give me a couple weeks more I'll get it out there O.S. |
| 16:39 | danlarkin | dysinger is spilling the secret sauce! |
| 16:39 | dysinger | :) |
| 16:40 | rhickey | dysinger: thanks for splitting off new branch on build.clojure.org - much easier to see what is what |
| 16:41 | dysinger | yeah plus it pollutes the maven repo with mixed branches plus there is a bug in hudson that once you add a branch you can't remove it. |
| 16:41 | dysinger | so it's best to just "copy" the job and modify it for the other branch |
| 16:56 | javuchi | what do you think about Shoal? |
| 16:56 | javuchi | (for clustering) |
| 17:01 | twbray | Gosh, it turns out that when you have to say -Xmx900m to get a clojure app to run, and it has tons & tons of threads, it really sucks the life out of your basic MacBook. |
| 17:02 | hiredman | which one is Xmx again? |
| 17:02 | chouser | one of the unsung benefits of single-threaded apps -- no one of them can completely saturate your dual-core machine. :-) |
| 17:03 | hiredman | ~google Xmx |
| 17:03 | clojurebot | First, out of 66500 results is: |
| 17:03 | clojurebot | XMX Home Page |
| 17:03 | clojurebot | http://www.cs.brown.edu/software/xmx/ |
| 17:03 | hiredman | :| |
| 17:03 | danlarkin | it's max heap |
| 17:04 | hiredman | clojurebot: Xmx is max heap |
| 17:04 | clojurebot | Alles klar |
| 17:13 | leafw | twbray: if your mac has two cores, try -Xincgc (incremental garbage collector). I found it to make the JVM perform better when creating lots of throwaway objects like clojure does. |
| 17:14 | twbray | leafw: Cool, will give it a try. But this thing isn't really designed to run on my laptop :) |
| 17:15 | leafw | as for clogging your poor macbook, all one can do is renice the process. Other things help too to avoid swappign: remove window shading, remove window double buffering, closing power hungry apps like MSWord and Photoshop. |
| 17:15 | leafw | twbray: then ssh to a server :) |
| 17:15 | twbray | MSword!?!? Quit talking dirty, this is a respectable IRC channel |
| 17:15 | leafw | twbray: I run ubuntu here on a macbook pro 5,5 |
| 17:16 | leafw | twbray: M$word is used by just about everybody I know. And I know it to be a problem, bot memory wise and because it can't be really swapped out; it keeps constant activity |
| 17:17 | twbray | leafw: You need to start hanging out with a better crowd :) |
| 17:17 | leafw | twbray: the world is larger than you think. |
| 17:21 | javuchi | would clojure work with terracotta? |
| 17:21 | chouser | javuchi: yes, more or less. There's been some work in that direction, not sure of its current state. |
| 17:29 | javuchi | this seems to be the most up to date information?? http://paul.stadig.name/2009/03/clojure-terracotta-next-steps.html |
| 17:31 | jbendig | javuchi: Here is someone who uses Clojure with Terracotta on a live system for a vet hospital. http://groups.google.com/group/clojure/browse_thread/thread/85649a134cf22655?tvc=2 |
| 17:34 | Chousuke | hmmhmm. |
| 17:39 | Chousuke | hoh |
| 17:39 | Chousuke | Finally managed to compile contrib |
| 17:40 | hiredman | :D |
| 17:40 | Chousuke | this is a great step forward :P |
| 17:42 | hiredman | so even after you could read clojure, contrib still had problems? |
| 17:43 | Chousuke | reading is different from reading it correctly so that it can be compiled :P |
| 17:44 | hiredman | I mean, you can read clojure.core in and it compiles fine, yes? |
| 17:46 | Chousuke | yeah. though I haven't tried to use the compiled result |
| 17:46 | Chousuke | ... much :D |
| 17:48 | savanni | I asked this before but may have missed the answer, so I'll ask again. Is there a way to enable a stack trace or something for when I get a Null Pointer Exception in my code? |
| 17:49 | Chousuke | you can do (.printStackTrace *e) |
| 17:49 | Chousuke | if in repl |
| 17:49 | Chousuke | *e means latest exception |
| 17:51 | savanni | Awesome. A little arcane, but that will help out a lot later. |
| 17:51 | Chousuke | hmm, contrib tests pass, except for one that overflows the stack for some reason |
| 18:00 | hiredman | savanni: checkout clojure.stacktrace |
| 18:03 | savanni | Is that in core? |
| 18:03 | hiredman | it's in stacktrace.clj, which is right next to core.clj |
| 18:04 | savanni | Okay... like with test-is, I'm going to need to upgrade to the clojure dev before I will be able to use it. |
| 18:04 | hiredman | are you sure? I'm not sure when it was added |
| 18:05 | savanni | Well, my 1.0.0 library claims that clojure.stacktrace is not found, so I would assume so. |
| 18:39 | cow-orker | is there a practical difference between #_"comment" and ;comment ? I know they have different "scope", but for short comments...? |
| 18:40 | hiredman | #_ eats the following form |
| 18:41 | hiredman | ; drops everything until a newline |
| 18:41 | hiredman | ,#_( |
| 18:41 | clojurebot | EOF while reading |
| 18:41 | hiredman | ,;( |
| 18:41 | clojurebot | EOF while reading |
| 18:41 | hiredman | not a good demo, I guess |
| 18:43 | cow-orker | well.... I got that part more or less :) I asked because #_"" was used for short comments in (defmacro for ...) in core.clj. Just wondered if there was some reason for commenting that way. |
| 18:43 | Chousuke | well, you can put them in the middle of stuff |
| 18:43 | Chousuke | ,[foo #_"bar:" bar] |
| 18:43 | clojurebot | java.lang.Exception: Unable to resolve symbol: foo in this context |
| 18:43 | Chousuke | oops |
| 18:43 | Chousuke | ,'[foo #_"bar:" bar] |
| 18:43 | clojurebot | [foo bar] |
| 18:44 | cow-orker | :) |
| 18:44 | Chousuke | ,'[foo ;bar: bar] |
| 18:44 | clojurebot | EOF while reading |
| 18:48 | cow-orker | what got me wondering was in master/src/clj/clojure/core.clj line 3019, but I guess here it's just style |
| 18:50 | hiredman | interesting |
| 18:51 | hiredman | I think a lot of that is chouser's work |
| 18:51 | hiredman | (maybe all?) |
| 18:53 | cow-orker | thanks, I'll ask him when he's online :) |
| 19:07 | Joreji | Hey guys, is there some way to ensure that an agent is running in the main thread? |
| 19:08 | rhickey | Joreji: will never be |
| 19:09 | rhickey | they run in thread pools |
| 19:10 | Joreji | Oh. |
| 19:10 | Joreji | Ok, thanks. |
| 19:19 | Joreji | How can I translate "new TimerTask() { public void run() { ... } }" into clojure? |
| 19:20 | Chousuke | can you construct TimerTasks from callables? |
| 19:21 | Joreji | In java? Yes. |
| 19:21 | Chousuke | Then you could just do (TimerTask. somefn) |
| 19:21 | Chousuke | eg. (TimerTask (fn [] (println "hello")) |
| 19:21 | hiredman | no, you can't |
| 19:21 | Joreji | But that would require me to write java code. |
| 19:22 | hiredman | Joreji: Chousuke meant "Does the TimerTask constructor take a Runnable" |
| 19:22 | hiredman | which it doesn't |
| 19:22 | Joreji | Ah, no. |
| 19:22 | Joreji | It does not take a Runnable. |
| 19:22 | hiredman | wrapping a fn in a proxied TimerTask is pretty trivial |
| 19:23 | Chousuke | I gues you'll need proxy then :) |
| 19:23 | Chousuke | +s |
| 19:23 | hiredman | I would push you in the direction of ScheduledThreadpoolExecutor |
| 19:23 | hiredman | which takes runnables directly |
| 19:24 | Joreji | hiredman: Hm. Are the java timers all running in a different thread? |
| 19:25 | onigiri | hi guys |
| 19:26 | onigiri | I'm really really new with clojure, I was playing along with the REPL now and tried some functions: |
| 19:26 | onigiri | I've got a utf8/strings bug (or at least what I think is a bug) |
| 19:26 | onigiri | (.toUpperCase "harajuku 原宿") yields "HARAJUKU 僆宯" |
| 19:27 | hiredman | Joreji: Timer uses a single thread |
| 19:28 | Joreji | Hm ok. |
| 19:28 | onigiri | I'm still trying to wrap my head around functional programming, so I thought that the only thing I was able to do was to report it ;) |
| 19:28 | hiredman | onigiri: it might be an issue with java's String |
| 19:28 | hiredman | in which case there is nothing to be done about it |
| 19:29 | Chousuke | onigiri: I don't think that's a Clojure bug :) |
| 19:29 | onigiri | hiredman: oh ok :) |
| 19:29 | Chousuke | amusing, thoug.h |
| 19:29 | onigiri | Chousuke: heh |
| 19:30 | Chousuke | I guess toUpperCase is just a dumb function that assumes its input is actually something that can sanely be uppercased :P |
| 19:31 | onigiri | and the fun thing was that I guess was twbray's fault if I'd tried it :P I remember his talk about unicode and ruby and since he's now learning Clojure, my head mixed the 2 thoughts :P |
| 19:31 | onigiri | Chousuke: yes, I guess so. |
| 19:32 | onigiri | I may peek under the clojure hood to see if there's a hint though |
| 19:32 | technomancy | onigiri: there's not much of a hood; that's a direct JVM method call. =) |
| 19:32 | twbray | onigiri: That is kind of surprising |
| 19:32 | Chousuke | Java strings aren't quite as bad as Ruby (1.8) "strings" but they're not perfect either :/ |
| 19:32 | twbray | String.toUpper looks at your LOCALE and does all sorts of voodoo |
| 19:33 | cemerick | casing is *very* complicated |
| 19:33 | onigiri | technomancy: oooh! you're right! I was in fact reading the direct java call |
| 19:33 | onigiri | paragraph... |
| 19:33 | twbray | but it should realize that that's in a case-free language and just no-op |
| 19:34 | onigiri | twbray: yes, indeed: before asking here I tried with ruby and it worked fine (I tried just to check if I was expecting the correct behaviour) |
| 19:34 | twbray | HOld on, I keep a java sandbox project around for just this sort of thing |
| 19:35 | cemerick | onigiri: http://www.brosinski.com/stephan/2008/02/09/the-evils-of-javalangstringtouppercase/ |
| 19:35 | twbray | onigiri: Remember, in my original Ruby/Unicode talk I basically said "Don't use toUpper/toLower". I still think I was right :) |
| 19:35 | cemerick | if you provide the target locale, it will likely work correctly |
| 19:36 | onigiri | twbray: hehe I know :) I still have that talk burned in my head :) |
| 19:36 | onigiri | cemerick: reading now, thanks |
| 19:37 | twbray | onigiri: When I run it in pure Java in NetBeans, it comes out OK |
| 19:39 | onigiri | twbray: hmm, if you run in your REPL is the "bug" reproduced? |
| 19:40 | twbray | user=> (println (str "In: harajuku 原宿 out: " (. "harajuku 原宿" toUpperCase))) |
| 19:40 | twbray | In: harajuku 原宿 out: HARAJUKU 原宿 |
| 19:40 | cemerick | onigiri: what's your system/java locale? |
| 19:40 | twbray | Right, try echo $LOCALE at shell |
| 19:41 | onigiri | not set |
| 19:42 | onigiri | twbray: I'm on a MBP 10.5, and if I run locale, I get LANG="it_IT.UTF-8" |
| 19:43 | onigiri | but an echo $LOCALE yields a deafening void |
| 19:43 | twbray | As long as it's got UTF-8 in there you should be OK. |
| 19:43 | cemerick | onigiri: eval this in clojure: (java.util.Locale/getDefault) |
| 19:43 | onigiri | twbray: you on SLeopard? |
| 19:44 | twbray | onigiri: yes |
| 19:44 | twbray | Java 6, 64 bit |
| 19:44 | onigiri | cemerick: hehe here's the culprit |
| 19:44 | onigiri | user=> (java.util.Locale/getDefault) |
| 19:44 | onigiri | #<Locale en_US> |
| 19:44 | twbray | onigiri: Same for me, en_US |
| 19:45 | cemerick | yeah, that's mine, I don't have an issue with uppercasing those glyphs |
| 19:45 | cemerick | chars* |
| 19:45 | twbray | onigiri: What environment are you running in? xterm? IDE? |
| 19:45 | onigiri | twbray: plain old Terminal |
| 19:45 | twbray | I'm doing this in NetBeans Enclojure REPL |
| 19:46 | onigiri | a github cloned clojure just builded |
| 19:46 | onigiri | that was run with a java -jar clojure.jar |
| 19:47 | twbray | Hah! When I do it terminal, I see the bug |
| 19:48 | twbray | Mac Terminal.app I mean |
| 19:48 | onigiri | twbray: good, at least I'm not seeing things ;) |
| 19:48 | cemerick | funny. Just set your encodings in terminal's prefs, probably |
| 19:51 | twbray | onigiri: Go get enclojure, it's pretty good |
| 19:51 | twbray | Disabled everything but UTF-8 in the terminal prefs, didn't seem to make any difference. |
| 19:52 | onigiri | twbray: I read your post, I was more partial to try the vimclojure |
| 19:52 | onigiri | I don't have any java IDE or emacs installed |
| 19:52 | twbray | That might work. Still can't figure out what Terminal.app is sending Clojure though. |
| 19:52 | cemerick | twbray: glad you've come around on enclojure :-) |
| 19:53 | onigiri | twbray: for what it matters, I tried setting UTF16, but nothing changed |
| 19:53 | twbray | oh, of course, inside NetBeans, it's probably an all-UTF16 world. |
| 19:54 | cemerick | I presume those are display encodings. It'd be worthwhile to see what code point clojure reports in the terminal for those chars, maybe the input is getting munged. |
| 19:55 | twbray | cemerick: I think that has to be it. |
| 19:56 | twbray | onigiri: Anyhow, the right answer is still the same - don't use toUpper/toLower. (snickers) |
| 19:57 | twbray | Among other things, they're unbelievable performance pigs. |
| 19:57 | onigiri | twbray: hehe |
| 19:58 | cemerick | (int (first "宿")) reports 194 in my terminal, 23487 in enclojure, definitely an input issue |
| 19:58 | cemerick | and (count "宿") is 3 :-) |
| 19:58 | onigiri | at least this bug made me do a foray in the #irc and now this channel is set for autojoin ;) |
| 19:59 | Chousuke | I get 23487 in emacs |
| 19:59 | cemerick | ,(.toUpperCase "宿") |
| 19:59 | clojurebot | "宿" |
| 19:59 | Chousuke | I have it configured to be UTF-8 |
| 19:59 | cemerick | it's crazy that irc is so unicode-friendly these days |
| 19:59 | onigiri | so the Terminal.app is the borked one |
| 20:00 | twbray | I usually drop into an aquamacs shell when I have to do serious non-ASCII at the command-line level |
| 20:00 | Chousuke | cemerick: well, at least English-speaking people won't have to deal with encoding wars because UTF-8 is ascii-compatible :P |
| 20:00 | cemerick | Chousuke: sorry? :-) |
| 20:01 | twbray | Maybe iTerm would be better? |
| 20:01 | Chousuke | cemerick: some years ago there were debates all over the Finnish IRCSpace whether UTF-8 should be allowed or not, because the de-facto standard was ISO-8859-1 and it's UTF-8-incompatible. |
| 20:02 | Chousuke | onigiri: I think you need to specify the encoding with a jvm property somehow. |
| 20:03 | twbray | Debates about i18n stuff used to regularly provoke paralyzing stupidity up until sometime earlier this decade when everyone just rolled over and gave in to Unicode. |
| 20:03 | onigiri | Chousuke: I fear so |
| 20:04 | cemerick | Chousuke: I'm guessing it has nothing to do with java. |
| 20:04 | Chousuke | I get 194 in iTerm as well, with a plain repl. |
| 20:07 | Chousuke | If I do java -Dfile.encoding=UTF-8 -jar clojure.jar then it works. .) |
| 20:07 | cemerick | huh |
| 20:08 | Chousuke | it defaults to MacRoman on OS X I think |
| 20:09 | Chousuke | so when I print UTF-8 in Clojure in an UTF-8 terminal it'll show up even then, but only because the bitpattern happens to match what the terminal expects, not because the JVM prints it out as UTF-8 :) |
| 20:09 | onigiri | Chousuke: oh you beat me: I just found the -D flag ;) nice |
| 20:11 | onigiri | so I guess the matter was solved, thanks everyone! |
| 20:11 | Chousuke | I wonder why the JVM is MacRoman by default anyway :/ |
| 20:11 | Chousuke | OS X is pretty much entirely Unicode otherwise :P |
| 20:22 | onigiri | ok, back to clojure study |
| 20:53 | krumholt | hi can i proxy an abstract class? |
| 20:54 | cemerick | yes |
| 20:55 | krumholt | so if i proxy something it will be an anonymous class extended from the abstract class? |
| 20:56 | cemerick | right |
| 20:56 | krumholt | ok thanks |
| 21:01 | djork | what's the most idiomatic way to do something n times? |
| 21:01 | djork | I've been doing (take n (repeatedly #(foo))) |
| 21:02 | djork | but it seems like the closure is a bit unnecessary |
| 21:02 | cemerick | dotimes if you're looking for side effects |
| 21:03 | mikehinchey | you can just use foo instead of #(foo) if foo is a regular function |
| 21:04 | cemerick | hah, I didn't even notice that :-P |
| 21:04 | cemerick | ,(take 5 (repeatedly rand)) |
| 21:04 | clojurebot | (0.2702439022277704 0.06886273089068606 0.908758027809942 0.5910756151509906 0.9058909510000488) |
| 21:04 | cemerick | I wrote that a couple of times last year :-) |
| 21:05 | djork | I am looking for dotimes, I think |
| 21:05 | cemerick | djork: note that it isn't lazy and returns nil |
| 21:06 | djork | not a problem |
| 21:06 | djork | just need to literally do something |
| 21:06 | djork | purely for side effects |
| 21:06 | icey | Anyone here spend much time with compojure? I'm having an issue that doesn't make sense to me when trying to include it in slime. I'm sure it's a noob issue. |
| 21:06 | hiredman | what is the issue? |
| 21:07 | icey | (I'm getting NoClassDefFoundError on org/apache/commons/fileupload/FileUpload whne I try to (use 'compojure)) |
| 21:07 | hiredman | ah |
| 21:07 | djork | (dotimes [_ 5] (System/gc)) |
| 21:07 | icey | compojure is in my classpath, I am getting the problem on 2 machines, so whatever I've done wrong I've done wrong in a consistent fashion |
| 21:08 | hiredman | just a second |
| 21:08 | cemerick | djork: invoking System/gc is generally a waste of time |
| 21:08 | hiredman | do you have all of compojures dependencies on the classpath? |
| 21:08 | icey | hmm most likely not |
| 21:08 | djork | cemerick: not in this case |
| 21:09 | djork | it's for a very particular purpose |
| 21:09 | hiredman | well, there you go |
| 21:09 | hiredman | if you run ant it will grap a zip of all the deps |
| 21:11 | icey | hiredman: i'm taking a look in the deps dir, just so I'm clear all the jars need to go in the classpath? (sorry, I have done like 0 java prior to touching clojure) |
| 21:12 | hiredman | yes |
| 21:12 | icey | hiredman: i'll give it a swing and see what happens, thanks :D |
| 21:12 | hiredman | you can leave out clojure/contrib if you already have those, but you might run into versioning issues |
| 21:29 | icey | hiredman: thanks for the tip regarding the classpath stuff on compojure; that did the trick for me :D |
| 21:37 | djork | the classpath is a harsh mistress |
| 21:47 | djork | anybody using something like this? http://gist.github.com/227662 |
| 21:47 | djork | is this adequate? |
| 21:47 | djork | I use it in my clj script |
| 21:53 | _mst | the 1.6 JVM actually lets you do java -cp '/some/where/*' to pick up all .jars from that directory |
| 21:54 | _mst | but I've used that same trick in 1.5 :) |
| 21:54 | djork | oh wow that's nice |
| 21:54 | djork | I'm using 1.6 |
| 21:54 | djork | oh well it's already working |
| 21:54 | djork | I can also do . src foo/*.jar to build it |
| 21:54 | djork | real globbing is nice |
| 22:56 | qed | I know this is kind of a lame question but-- I'm wondering if there are any easier ways than using compojure |
| 22:56 | qed | has anyone built an all-in-one installer or package for compojure? |
| 23:08 | hiredman | qed: running ant in the git checkout of compojure will download all the dependencies |
| 23:30 | qed | hiredman: it's not working for me |
| 23:30 | hiredman | what is not working? |
| 23:31 | qed | /Users/defn/src/compojure/build.xml:35: /Users/defn/src/compojure/deps not found. |
| 23:31 | qed | no deps dir in there |
| 23:31 | hiredman | make one? |
| 23:31 | qed | omg im a moron |
| 23:31 | hiredman | … |
| 23:31 | qed | apologies |
| 23:32 | qed | PS: I didn't need the UTF-8 to rub it in |
| 23:39 | technomancy | it would really be great if contrib's 1.0-compat branch got its own version number to distinguish it from master so we could add it to build.clojure.org |
| 23:39 | technomancy | could we bump master up to 1.1.0-alpha-SNAPSHOT to match clojure itself? |