2010-11-03
| 00:12 | amalloy | i'll get the hang of spelling my name one of these years :P |
| 00:18 | quizme | when i (run-tests 'myproject.core) i get, 0 failures, 0 errors. |
| 00:18 | quizme | but there is a test there. |
| 00:18 | quizme | shouldn't there be at least 1 failure ? |
| 00:19 | quizme | http://www.pastie.org/1268633 |
| 00:21 | amalloy | quizme: (run-tests 'collatz.test.core) |
| 00:21 | quizme | amalloy thanks i'll try |
| 00:23 | quizme | amalloy: awesome thank you |
| 00:23 | amalloy | np. maybe one of these days i'll get around to learning how to use clojure.test myself :P |
| 01:01 | _na_ka_na_ | hellos.. how do I override equals, hashcode using deftype? |
| 01:05 | _na_ka_na_ | (defprotocol P (foo [this]) (^boolean equals [this ^Object o])) |
| 01:06 | _na_ka_na_ | (deftype T [] P (foo [this]) (^boolean equals [this ^Object o])) |
| 01:07 | _na_ka_na_ | gives an error |
| 01:07 | _na_ka_na_ | java.lang.VerifyError: (class: user/T, method: equals signature: (Ljava/lang/Object;)Ljava/lang/Object;) Expecting to find object/array on stack (repl-1:37) |
| 01:08 | _na_ka_na_ | maybe this is the right way |
| 01:08 | _na_ka_na_ | (deftype T [] P (foo [this])) |
| 01:08 | _na_ka_na_ | (deftype T [] P (foo [this]) Object (equals [this o])) |
| 01:08 | amalloy | _na_ka_na_: i just tried (deftype x [] Object (equals [this other] true)) and it works for me |
| 01:09 | _na_ka_na_ | amalloy: yes thx |
| 01:09 | _na_ka_na_ | I figured |
| 01:20 | _na_ka_na_ | amalloy: how can i add static methods to my deftype which can called as T/a-static-fn |
| 01:20 | amalloy | _na_ka_na_: why would you want to? just use a defn |
| 01:21 | _na_ka_na_ | amalloy: hmm you're right |
| 02:06 | _na_ka_na_ | I have a bunch of protocols P1, P2, P3 ... it is possible to have master protocol P which is the union of P1, P2, P3 |
| 02:08 | _na_ka_na_ | for example I want my abstraction to be a union of a protocol I wrote P + Serializable + Comparable |
| 02:10 | amalloy | _na_ka_na_: would you mind explaining why you're doing this? it kinda smells like using clojure to write java, and there might well be an easier way than these protocol gymnastics |
| 02:14 | _na_ka_na_ | amalloy: I want an abstraction which comprises of a set of operations i define + i want it to be serializable + so i can use it in sorted-sets (which is really TreeSet and so Comparable) |
| 02:14 | _na_ka_na_ | how do you think i define that abstraction? |
| 02:15 | _na_ka_na_ | do I even need an abstraction is a separate concern :) |
| 02:17 | amalloy | _na_ka_na_: what about (deftype MyThing [] P Commparable Serializable) and require callers to extend MyThing? |
| 02:17 | amalloy | i don't do a lot of java interop, so this may be a crazy suggestion |
| 02:34 | _na_ka_na_ | amalloy: but deftype doesn't define an abstraction |
| 03:22 | octe | what's the best way of finding memory leaks in clijyure programs? |
| 03:22 | octe | clojure* |
| 03:23 | kryft | ...Memory leaks in clojure programs? How do you get a memory leak with garbage collection? |
| 03:23 | octe | no idea. |
| 03:23 | octe | i'm quite curious about it myself. |
| 03:28 | octe | i'm quite curious about it myself. |
| 03:28 | octe | oops |
| 03:37 | eugu | kryft: This way - you accidentally retain references to the objects which are not used in your program anymore. If this occurs regularly it accumulates and can cause OutOfMemory |
| 03:37 | albino | holding references will usually do it |
| 03:37 | albino | http://www.eclipse.org/mat/ |
| 03:38 | kryft | eugu: Ok, if that counts as a memory leak. :) |
| 03:38 | albino | kryft: it does, because memory is leaked that should be free()d |
| 03:39 | kryft | Does that happen easily in clojure then? |
| 03:39 | albino | Happens often enough in java, I don't know fo clojure |
| 03:41 | albino | happens in python too |
| 03:42 | albino | octe: you could try that tool I linked to, I think it's works for jvm implementations and so could work for clojure code |
| 03:42 | octe | i'm trying jmap / jhat, built into the jdk |
| 03:47 | octe | hmm, that didn't give much useful information.. |
| 03:48 | angerman | is there a list somewhere what charactes are allowd as symbol names/ |
| 04:27 | LauJensen | Morning |
| 04:38 | LuminousMonkey | Afternoon. :P |
| 04:57 | angerman | how do I create a root var? |
| 05:08 | _na_ka_na_ | guys can you let me know if this is a bug |
| 05:08 | _na_ka_na_ | (deftype T [] Object (equals [this o] (if (instance? T o) true false))) |
| 05:09 | _na_ka_na_ | (def t (T.)) |
| 05:09 | _na_ka_na_ | (.equals t t) => false |
| 05:09 | _na_ka_na_ | I'm on 1.2 |
| 05:11 | esj | maybe: (instance this o) |
| 05:11 | esj | in the (if ) |
| 05:12 | esj | wait..... |
| 05:12 | esj | it looks like you're checking if things are of the same type instead of equality. Did you mean to ? |
| 05:12 | jarpiain | or (instance? (identity T) ...) |
| 05:14 | sharat87 | hello, I want to do an operation on every key-value pair in a map, is there a function for that in clojure or contrib? |
| 05:15 | _na_ka_na_ | esj: this is just a dummy to reproduce the issue |
| 05:15 | jarpiain | ,(into {} (map (fn [[k v]] [k (* 2 v)]) {:a 1 :b 2 :c 3})) |
| 05:15 | clojurebot | {:a 2, :b 4, :c 6} |
| 05:16 | _na_ka_na_ | jarpain: why (identity T) ? |
| 05:16 | jarpiain | the compiler has a special case for identity? when the first argument is a symbol that resolves to a class |
| 05:17 | _na_ka_na_ | jarpain: but (instance? T o) should work as (doc deftype) specifically says that I can use the deftype name inside its methods |
| 05:17 | jarpiain | _na_ka_na_: did you try it? |
| 05:17 | _na_ka_na_ | oops its jarpiain, sorry |
| 05:18 | _na_ka_na_ | jarpiain: currently I have (= T (class o)) and that works |
| 05:18 | sharat87 | oh so I can use the map function on maps too, that's an eye opener |
| 05:19 | sharat87 | jarpiain: is that anonymous function using pattern matching to unpack a vector in its first argument? |
| 05:19 | _na_ka_na_ | sharat87: you can also do (zipmap (keys m) (map (partial * 2) (vals m))) |
| 05:19 | sharat87 | yeah, but in the function I need both the key and the val :) |
| 05:20 | _na_ka_na_ | oh ok :) |
| 05:20 | jarpiain | _na_ka_na_: while compiling the deftype, T resolves to a different class object (a compiler-generated stub class) |
| 05:20 | _na_ka_na_ | then (map (fn [[k v]] ...) m) |
| 05:20 | jarpiain | which might conflict with the special inlining of instance? |
| 05:20 | sharat87 | yeah, that's what I need then :) thanks jarpiain and _na_ka_na_ |
| 05:21 | _na_ka_na_ | jarpiain: hmm that might explain it, but its a bug then ? |
| 05:21 | esj | sharat87: btw, what that pattern matching is called destructuring in clojure (and there's lots you can do with it) just in case you want to google it |
| 05:22 | sharat87 | esj: ah thanks for clearing that, as you might have guessed by now, I come from haskell :) |
| 05:23 | _na_ka_na_ | sharat87: welcome :) how did you venture here |
| 05:24 | sharat87 | browsing peepcode, I came across the clojure video, impressed, here I am :) |
| 05:24 | sharat87 | awesome video btw |
| 05:30 | _na_ka_na_ | jarpiain: one more thing, (source +) tells us that it is inlined, but (source instance?) doesn't; how did you it might be inlined |
| 05:30 | jarpiain | _na_ka_na_: it's a really special case. You have to look at Compiler.java |
| 05:31 | _na_ka_na_ | jarpiain: ok, thanks |
| 05:33 | fliebel | Raynes: I've had my Hammock time, I'm ready for it! |
| 05:33 | jarpiain | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L3298 |
| 05:33 | LauJensen | Guys, does this interface seem intuitive? https://gist.github.com/d835630aff8313980813 |
| 05:34 | fliebel | LauJensen: Why the set? |
| 05:34 | LauJensen | fliebel: Which alternative did you have in mind? |
| 05:35 | fliebel | LauJensen: I'm thinking... |
| 05:36 | bsteuber | LauJensen: I do like maps (and would expect an implicit and for more than one entry), but would rather like explicit and and or instead of sets and vectors |
| 05:36 | bsteuber | I also commented on the :invert keyword on github a minute ago |
| 05:37 | LauJensen | bsteuber: Yes thanks I got the notification |
| 05:37 | LauJensen | So you should prefer [:x 5 :or :y 10] ? |
| 05:37 | fliebel | LauJensen: Yea, more like the ns thing. [a :or b |
| 05:37 | LauJensen | But wouldnt it be better simply to write pure SQL ? |
| 05:37 | esj | intuitive |
| 05:38 | angerman | (defprotocol Fly "for flying" (fly [this] "...")) |
| 05:38 | angerman | that's the specification / contract right? |
| 05:39 | LauJensen | esj: what is? |
| 05:39 | angerman | (defrecord [a] Fly (fly [self] (str (:a self) " flies ..."))) should work. no? |
| 05:39 | fliebel | LauJensen: O second thought, I think it should at least be polish notation, so [:or 1 2 3] |
| 05:39 | bsteuber | LauJensen: how about (or {:foo 42} {:bar "baz"})? |
| 05:39 | angerman | but it tells me "self" not found in context |
| 05:39 | esj | the #{}, [], {} interface |
| 05:40 | LauJensen | bsteuber: I wont implement the List interface, that'll rob users of too much power |
| 05:40 | bsteuber | well, [:or] seems fine as well |
| 05:41 | bsteuber | LauJensen: ok, thought of it as plain functions - but I didn't look at your internals |
| 05:42 | LauJensen | bsteuber: The old ClojureQL grabbed all of your Lisp syntax, and made everything (and (> :x 5) (or (< :y 10) (:z 15))) style notation. But that turned out to be a bad idea... I realized after 2.5 yers |
| 05:42 | LauJensen | years |
| 05:42 | bobo_ | hm, why have one map for each statement? and not {:rank "Top" :title "Dev} |
| 05:44 | LauJensen | bobo_: The statements are separated, so it makes to show that in the data structure dont you think? |
| 05:46 | bobo_ | hm, maybe |
| 05:46 | Chousuke | hm |
| 05:46 | bobo_ | it makes more sense in the or example |
| 05:46 | LauJensen | bobo_: You can do both though. The compiler is recursive, so its your choice |
| 05:47 | LauJensen | clojureql.core> (compile {:rank "top" :title "dev"}) |
| 05:47 | LauJensen | "rank=top AND title=dev" |
| 05:47 | LauJensen | |
| 05:47 | Chousuke | I think it's got maybe a bit too much syntax :P |
| 05:47 | LauJensen | Chousuke: Suggestions? |
| 05:47 | clojurebot | Huh? |
| 05:48 | Chousuke | that case is good though. but for the OR case having to wrap each thing in a map might get boring pretty quickly |
| 05:48 | bsteuber | LauJensen: but can't you implement a function and that returns [:and ..] then? |
| 05:48 | fliebel | "To many notes" "Which notes did you hand in mind?" - Mozart |
| 05:48 | bsteuber | so people could still use list notation but don't lose power |
| 05:49 | LauJensen | bsteuber: Sure its possible with a helper |
| 05:49 | fliebel | bsteuber: macroes are icing ;) |
| 05:49 | Chousuke | with that syntax you could save lists for "user-defined" things I suppose |
| 05:50 | LauJensen | Well. I dont want lists in the protocol, that would break {:x 5 :y (let [z ...] z)} |
| 05:50 | Chousuke | like [{:id 5} (like :foo "something")] where like returns something that the compiler can handle |
| 05:50 | Chousuke | yeah |
| 05:52 | LauJensen | I'll try to follow the data-structure trail to the end. Then it might be macro/helper time :] |
| 05:52 | Chousuke | I'd be wary of using #{} though |
| 05:52 | Chousuke | since the order is undefined |
| 05:52 | LauJensen | Chousuke: Order doesnt matter for OR statements |
| 05:53 | Chousuke | until you hit some weird corner case where it does ;P |
| 05:54 | LauJensen | Yea I guess you're right. |
| 05:55 | Chousuke | but if you reserve () for things that are evaluated, it should be easy to implement cql/and and cql/or that you can use in queries |
| 05:55 | Chousuke | in addition to perhaps having syntax for them |
| 05:55 | bsteuber | I would be in for [:or …] etc then |
| 05:55 | LauJensen | yea |
| 05:56 | bsteuber | maybe then also [:not] for invert |
| 05:56 | bsteuber | though I still like select-not :) |
| 05:56 | LauJensen | :invert is a bit counter-intuitive "read this, then totally reverse your understanding" :) |
| 05:56 | bsteuber | exactly :) |
| 05:56 | Chousuke | maybe have a basic set of compiler operations like :and :or :not and then just have [operator parameters*] |
| 05:58 | Chousuke | users wouldn't necessarily have to use that form directly, but it might make sense for the compiler to reduce everything to such vectors before further processing |
| 05:59 | LauJensen | Chousuke: Can you gist an example of how you see this playing out? |
| 06:02 | jjido | wrt using structures isn't this more readable? https://gist.github.com/559c305e432ff0b0e41e |
| 06:03 | LauJensen | jjido: For me its the same, but like I said before, the protocol doesnt do lists |
| 06:03 | jjido | ok use a different keyword then |
| 06:09 | Chousuke | LauJensen: https://gist.github.com/6fec4a139a299dc17627 ? |
| 06:09 | bsteuber | Chousuke: huh, don't like :eq |
| 06:10 | bsteuber | I think maps are fine for k/v-pairs |
| 06:10 | Chousuke | bsteuber: it could be an implementation detail |
| 06:10 | LauJensen | bsteuber: as a user, you would use (= ... |
| 06:10 | LauJensen | Chousuke: Looks interesting. I'll play around a little and see what comes out. Thanks for your input |
| 06:11 | Chousuke | in the sugared form I did use the map thing so I think it's fine. |
| 06:11 | bsteuber | ah, sorry, didn't look at the sugared one |
| 06:11 | bsteuber | yeah, seems cool |
| 06:12 | Chousuke | I think compile could support some of the sugar directly, so that user functions wouldn't have to worry about desugaring maps for example |
| 06:13 | Chousuke | so cql/and could just return [:and {'rank "top"} ...] and the compiler would handle that. |
| 06:13 | bsteuber | but then you don't need :eq at all, I guess :) |
| 06:13 | Chousuke | it might make the implementation easier |
| 06:14 | LauJensen | Yea thats how I imaged I would do it |
| 06:14 | Chousuke | and users could still use the compiler ops directly in their own functions |
| 06:18 | bobo_ | LauJensen: the idea behind clojureql is to abstract away the parts that differ between databases right? |
| 06:19 | LauJensen | bobo_: That was the old idea. The revised idea, which I might blog about today, is just to have some slick integration, where the differences between backends are left to the user |
| 06:21 | bobo_ | ok, please do blog! :-) |
| 06:22 | jjido | https://gist.github.com/559c305e432ff0b0e41e |
| 06:22 | LauJensen | Yes sir :) |
| 06:23 | LauJensen | jjido: Thats definitely not bad |
| 06:24 | jjido | LauJensen: inspired by SQL ;) |
| 06:24 | LauJensen | Who needs hammock time when you've got #clojure :) |
| 06:25 | bobo_ | hm, so [] is or in that example? |
| 06:25 | LauJensen | yea |
| 06:25 | bobo_ | think i like it |
| 06:25 | fliebel | LauJensen: I do, but I do that when I'm not in #clojure (sleeping) |
| 06:26 | bobo_ | i wrote a method that converts all OR to UNIONS yeasterday, things like that would be great to have in clojureql aswell |
| 06:27 | LauJensen | Got gist? |
| 06:27 | bobo_ | no it was java :-( |
| 06:27 | LauJensen | ouch |
| 06:28 | bobo_ | yeh i know. but my sql library at work is getting pretty nice, should write it in clojure for fun. |
| 06:28 | jjido | LauJensen: do you need nested AND? https://gist.github.com/559c305e432ff0b0e41e |
| 06:28 | jjido | LauJensen: does not look as good |
| 06:29 | LauJensen | You're competing against whats already there |
| 06:29 | LauJensen | clojureql.core> (compile #{{:rank "Top"} {:title "Dev" :id 5}}) |
| 06:29 | LauJensen | "(rank=\"Top\" OR title=\"Dev\" AND id=5)" |
| 06:29 | LauJensen | |
| 06:30 | LauJensen | Though the parens needs fixing |
| 06:30 | LauJensen | I think your model is showing some code explosion tendencies |
| 06:48 | ariejan | Maybe a stupid question, but is there anything in Clojure to get a current timestamp? |
| 06:49 | LauJensen | &(-> "x.y" (.split ".") first) |
| 06:49 | sexpbot | ⟹ nil |
| 06:50 | LauJensen | Am I forgetting my Java-fu, shouldnt that return x ? |
| 06:50 | bobo_ | split takes a regexp? |
| 06:50 | bobo_ | or? |
| 06:51 | LauJensen | bobo_: Ah right, Regex AS string :) |
| 06:51 | LauJensen | &(-> "x.y" (.split "\\.") first) |
| 06:51 | sexpbot | ⟹ "x" |
| 06:51 | bobo_ | :-) |
| 06:51 | LauJensen | ariejan: try (java.util.Date.) |
| 06:51 | esj | ariejan: I just go to java with (java.util.Date.) |
| 06:51 | esj | pffft |
| 06:51 | LauJensen | esj: aaah just a wee bit too slow |
| 06:52 | LauJensen | :D |
| 06:52 | ariejan | I just found: (. System (nanoTime)) |
| 06:52 | LauJensen | &(System/nanoTime) |
| 06:52 | sexpbot | ⟹ 185913853697964 |
| 06:53 | ariejan | Exactly. It's just to use some unique value for testing redis performance. |
| 06:53 | bobo_ | &(Math/random) |
| 06:53 | sexpbot | ⟹ 0.698805992174627 |
| 06:54 | LauJensen | bobo_: unique != random |
| 06:54 | bobo_ | true |
| 06:55 | LauJensen | &(java.util.UUID/randomUUID) |
| 06:55 | sexpbot | ⟹ #<UUID d8ec9da7-ea94-430f-8292-fc802a198180> |
| 06:55 | LauJensen | 100% concurrency safe |
| 06:57 | bobo_ | i also think redis already has a testsuite for performancetesting. but thats not as fun |
| 06:58 | ariejan | bobo_: Yes, but I wanted to see clojure aleph in combination with setting a key per request. It's blazingly fast. 0.977ms per request on average on my i5 macbook pro. |
| 06:59 | bobo_ | :-) |
| 07:00 | LauJensen | ariejan: With how many concurrent requests? |
| 07:01 | ariejan | 50 concurrent requests. |
| 07:01 | ariejan | But I see only 8 redis clients connecting. See details here: https://gist.github.com/660970 |
| 07:02 | LauJensen | wow |
| 07:03 | ariejan | LauJensen: With 8 concurrent requests I get 0.739ms/req. (1354 req/sec) |
| 07:03 | ariejan | If there's any optimalisations I can do in my code, please let me know. |
| 07:04 | LauJensen | Could you regist the code, I just logged in/out |
| 07:04 | ariejan | LauJensen https://gist.github.com/660970 |
| 07:13 | ariejan | What is the reason I see 8 clients connecting to redis? Is that a clojure config option, jvm? |
| 07:17 | LauJensen | I think Aleps caps concurrent connections at 8, hence the speed. A Synced framework wouldnt cap so early |
| 07:29 | fliebel | Man, this is crazy… The Python version of my parser is 6 times faster on just reading files. And even worse, it keeps them in memory all at once. When I do this in Clojure it never finishes and takes up a massive amount of memory. |
| 07:38 | fliebel | How much memory will a seq of 99844096 bytes consume? (compared to a string or a byte[] of 99844096 itmes) |
| 07:39 | jarpiain | ,(doc vector-of) |
| 07:39 | clojurebot | "([t]); Creates a new vector of a single primitive type t, where t is one of :int :long :float :double :byte :short :char or :boolean. The resulting vector complies with the interface of vectors in g... |
| 07:41 | fliebel | jarpiain: I'll try it. |
| 07:41 | raek | fliebel: which seq type? |
| 07:42 | fliebel | raek: I do concat on the byte[]'s, so I guess it becomes a lazy seq then. |
| 07:43 | raek | a lazy seq usually constructs conses, so I guess 99844096 * the size of a clojure.lang.Cons |
| 07:43 | raek | also, the bytes will be boxed, so they will consume more than one byte of memory |
| 07:45 | raek | ,(class (seq (make-array Integer/TYPE 3))) |
| 07:45 | clojurebot | clojure.lang.ArraySeq$ArraySeq_int |
| 07:46 | raek | an array of primitives is probably the most compact way of storing the data, if you really need everything in memory at the same time |
| 07:47 | fliebel | raek: I don't really, but I'm trying to figure out why Clojure is 6 times slower at reading the same data Python does. |
| 07:48 | raek | fliebel: how do you do the IO? one byte at a time? |
| 07:48 | fliebel | raek: No, I use a library which returns a byte[] |
| 07:49 | raek | ok. good. |
| 07:50 | raek | do you have both versions in gists? |
| 07:51 | fliebel | raek: On github at least. |
| 07:52 | raek | also, did you manage to get rid of the reflection? (I'm just curious) |
| 07:52 | fliebel | raek: I did. |
| 07:54 | raek | great! |
| 07:54 | fliebel | Python: https://github.com/l0b0/mian/blob/master/mian/mian.py#L244-254 Clojure: https://github.com/pepijndevos/Clomian/blob/master/src/clomian.clj#L101-119 (gets called at line 133) |
| 07:54 | raek | how much did it affect the performance? |
| 07:55 | fliebel | raek: Quite a lot. But the biggest win of the day was using a transient. |
| 07:56 | raek | has this something to do with Minecraft? |
| 07:56 | fliebel | raek: yea, analyzing levels and stuff. |
| 07:58 | raek | cool. IIRC, tomoj has coded something Minecraft-related too |
| 08:00 | raek | is it the data processing or the IO that takes most time? |
| 08:01 | raek | have you compared just reading data in both the clojure and python without processing it? |
| 08:01 | fliebel | raek: I have compared just getting the blocks, not the pure reading. But the functions that spit out the files are equally fast. |
| 08:01 | yayitswei | quick question: why does (map #(Integer/parseInt %) '("1" "2")) work whereas (map Integer/parseInt '("1" "2")) does not? |
| 08:01 | raek | (to rule out that the lib is the bottleneck) |
| 08:02 | Chousuke | yayitswei: Integer/parseInt is not a clojure function |
| 08:02 | raek | yayitswei: Integer/parseInt is not a real function (an onbject that implements clojure.lang.IFn) |
| 08:02 | yayitswei | ah, so the reader macro only works with clojure functions |
| 08:03 | Chousuke | no, the reader macro creates a clojure function |
| 08:03 | fliebel | raek: So I should just do the FileInputStream and read? |
| 08:03 | raek | how is the data read? is it just the bytes of the file? |
| 08:03 | Chousuke | #(Integer/parseInt %) expands to something like (fn [x] (Integer/parseInt x)) |
| 08:03 | Chousuke | which map can use |
| 08:04 | fliebel | raek: it's gzipped, but then it's just bytes I believe. |
| 08:04 | raek | ...which expands to something like (fn [x] (. Integer parseInt x)) |
| 08:05 | yayitswei | oh, right.. so how does the (. Integer parseInt x) work then? |
| 08:05 | raek | well, if the java lib was as fast as the python lib, this will not make any difference, right? |
| 08:05 | raek | yayitswei: it is a special form, handled specially by the compiler. |
| 08:06 | yayitswei | i see. thanks guys |
| 08:09 | raek | fliebel: does the time include the JVM startup delay too? |
| 08:09 | fliebel | raek: no :P |
| 08:10 | raek | good... saw the -main method and started to get suspicious |
| 08:10 | fliebel | raek: nah, did a (time) on the repl |
| 08:11 | fliebel | raek: gtg, I'll test it later. thanks :) |
| 08:55 | tonyl | morning |
| 09:16 | djpowell | has anyone had a look at microsoft's reactive stuff? i was just playing around doing similar stuff in clojure the other day. it looks pretty cool |
| 09:19 | chouser | djpowell: rhickey recommended understanding it recently. |
| 09:19 | djpowell | yeah - i saw that |
| 09:20 | noidi | djpowell, do you have an URL for that? or should I just google for "microsoft's reactive stuff"? :) |
| 09:21 | djpowell | the idea is that sequence type things are the dual of observable type things that you can register with to be notified about data - they are both just sources of data, so a function can generically convert any seq to an observable, and any observable to a seq |
| 09:21 | djpowell | hang on... |
| 09:21 | noidi | blimey, I think that google search actually worked |
| 09:21 | noidi | Reactive Extensions for .NET |
| 09:22 | noidi | I had to give it a try :) |
| 09:22 | djpowell | http://rxwiki.wikidot.com/101samples is a good way to get a quick summary of what you can do with it |
| 09:22 | noidi | djpowell, thanks! |
| 09:24 | djpowell | like clojure, microsoft do lots of things with sequence abstractions - eg LINQ lets you do map/filter higher-order function type stuff with them with an SQL-like syntax. Plus lots of things can be seen as having observable events - Desktop UIs, incoming AJAX requests etc; so bringing the two together seems pretty powerful |
| 09:25 | Bahman | Hi all! |
| 09:25 | djpowell | hi |
| 09:38 | pjstadig | re: "reactive stuff" ...i saw a pres on that at the CUFP looked interesting |
| 09:42 | fogus_ | pjstadig: Matt P at the CAPCLUG is one of the lead devs... you should corner him about it one day. Very interesting ideas |
| 09:48 | pjstadig | fogus_: he hasn't been in a while has he? i don't recall |
| 09:49 | fogus_ | I haven't been in a while either. :-( |
| 11:40 | bhenry | what if i want to pull together a handful of imports into one namespace, and then just be able to (:use namespace]) in multiple (ns) calls? |
| 11:41 | bhenry | and have access to all those imported classes |
| 11:41 | tonyl | have you tried it? |
| 11:42 | bhenry | it doesn't work. i'll show you what i tried in a gist |
| 11:46 | fliebel | raek: I tired the file reading thing, and it takes 1961.726 msecs, so I'm afraid it's the NBT library. |
| 11:48 | bhenry | tonyl: https://gist.github.com/b16af68b7e6482734992 |
| 11:48 | pjstadig | bhenry: checkout nstools |
| 11:49 | pjstadig | i think that might do what you want |
| 11:49 | pjstadig | http://code.google.com/p/clj-nstools/ |
| 11:52 | bhenry | pjstadig: thanks. looks like i can't avoid having two lines where i want one. i'm just being picky. mine has the (use-karras) after the ns call and that has (use 'nstools.ns) before it. |
| 11:54 | tonyl | yeah bhenry, I wouldn't know much about namespaces, but it seems that the ns+ function in nstools might help you |
| 11:56 | fliebel | How can I get the entire content of a GZIPInputStream? |
| 11:57 | pjstadig | clojure.contrib.io/to-byte-array? |
| 11:57 | clojurebot | Yes, Clojure can do that! |
| 11:57 | pjstadig | clojurebot: botsnack |
| 11:57 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 12:01 | fliebel | pjstadig: That might work. What is the classic java way to do that? |
| 12:02 | pjstadig | uh...why would you want to do it in java? |
| 12:02 | pjstadig | it'll set your hair on fire |
| 12:02 | hiredman | to-byte-array is bad |
| 12:02 | fliebel | To understand how it works. |
| 12:02 | pjstadig | you have to use an apache commons library to make it let painful |
| 12:02 | fliebel | and because of what hiredman said ;) |
| 12:02 | pjstadig | hiredman knows nothing |
| 12:02 | joegallo | No! You have to build a ByteArrayOutputStream and copy over the bytes like a boss! |
| 12:02 | hiredman | last I checked to-byte-array shoves things into a StringBuilder then calls getBytes on the String |
| 12:02 | hiredman | horrible |
| 12:03 | pjstadig | oh |
| 12:03 | pjstadig | hiredman is correct |
| 12:03 | pjstadig | but otherwise you have to copy chunks across like joegallo says |
| 12:03 | tonyl | anybody knows of any clojure groups in kansas? |
| 12:04 | hiredman | (with-open [baos (ByteArrayOutputStream.)] (copy gzipstream baoas) (.toByteArray baos)) |
| 12:04 | joegallo | fliebel: Like this: http://stackoverflow.com/questions/67275/reading-from-a-zipinputstream-into-a-bytearrayoutputstream |
| 12:05 | pjstadig | hmm...looks like to-byte-array uses a BAOS http://bit.ly/addDYt for InputStreams |
| 12:05 | fliebel | hiredman: Where does copy live? |
| 12:05 | hiredman | clojure.java.io |
| 12:06 | fliebel | great |
| 12:13 | rata_ | hi all |
| 12:13 | hiredman | actually my local checkouts of clojure and contrib don't seem to have to-byte-array in them |
| 12:18 | rata_ | do you know what's the line to put fnparse 3.x as a dependency in project.clj? |
| 12:19 | edoloughlin | Anyone care to shed some light on destructuring forms? http://stackoverflow.com/questions/4089162 |
| 12:26 | Bootvis | ,`(foo bar) |
| 12:26 | clojurebot | (sandbox/foo sandbox/bar) |
| 12:26 | Bootvis | is it possible to not display the namespace in the above? |
| 12:27 | rata_ | Bootvis: why do you want such a thing? |
| 12:27 | MayDaniel | ,`(~'foo ~'bar) |
| 12:27 | clojurebot | (foo bar) |
| 12:27 | Bootvis | rata: i'm working through land of lisp in clojure |
| 12:27 | rata_ | namespaces are important for macros hygenie IIRC |
| 12:28 | Bootvis | MayDaniel: thanks maybe I can put that transformation in a macro |
| 12:48 | rata_ | do you know what's the line to put fnparse 3.x as a dependency in project.clj? |
| 12:54 | fliebel | rata_: http://clojars.org/search?q=fnparse |
| 12:54 | rata_ | fliebel: oh, thanks a lot =) |
| 12:54 | fliebel | raek: Are you still around? |
| 12:56 | alpheus | Is there a predicate for atom? (I just realized that the obvious meaning of that for a Scheme or Lisp programmer would not apply in Clojure.) |
| 12:57 | tonyl | clojure.inspector/atom? |
| 12:57 | clojurebot | "[Clojure ...] feels like a general-purpose language beamed back from the near future." |
| 12:59 | amalloy | alpheus: there was a longish discussion of this yesterday |
| 12:59 | amalloy | clojurebot: logs? |
| 12:59 | clojurebot | logs is http://clojure-log.n01se.net/ |
| 12:59 | tonyl | http://clojuredocs.org/clojure_core/clojure.inspector/atom_q |
| 12:59 | alpheus | Sorry, I didn't see that. I'll review. |
| 12:59 | tonyl | the one in inspector just checks if it is not an atom |
| 13:00 | amalloy | tonyl: heh, i guess that's one way to do it. personally i'd use (not (coll? x)) directly, but whatever |
| 13:00 | tonyl | s/atom/coll/ |
| 13:00 | sexpbot | <tonyl> the one in inspector just checks if it is not an coll |
| 13:01 | tonyl | sexpbot: cool |
| 13:01 | tonyl | amalloy: yeah, beats requiring a ns |
| 13:02 | mabes | when I call class on a double does it automatically get coerced into a Double? |
| 13:02 | mabes | ,(class (double 1.0)) |
| 13:02 | clojurebot | java.lang.Double |
| 13:02 | mabes | (I'm using 1.2) |
| 13:03 | mabes | I'm dealing with some java interop and I need to pass in an array of doubles (not Doubles). I can't seem to do that though... |
| 13:03 | mabes | ,(into-array (map double [1.0 2.0])) |
| 13:03 | clojurebot | #<Double[] [Ljava.lang.Double;@1280c85> |
| 13:03 | mabes | any ideas? |
| 13:03 | amalloy | &(make-array Double/TYPE 10) |
| 13:03 | sexpbot | ⟹ #<double[] [D@f9de08> |
| 13:04 | amalloy | &(into (make-array Double/TYPE 10) (map double (range 10))) |
| 13:04 | sexpbot | java.lang.ClassCastException: [D cannot be cast to clojure.lang.IPersistentCollection |
| 13:04 | amalloy | oh well :P |
| 13:04 | mabes | amalloy: thanks! I'll try to figure it out from here. |
| 13:05 | mabes | actually.. |
| 13:05 | mabes | ,(into-array Double/TYPE [1.0 2.0]) |
| 13:05 | clojurebot | #<double[] [D@1283826> |
| 13:05 | amalloy | yeah, i just found that too |
| 13:05 | mabes | cool, yeah, I didn't know about the Double/TYPE thing until you showed me |
| 13:06 | amalloy | &String/TYPE |
| 13:06 | sexpbot | java.lang.Exception: Unable to find static field: TYPE in class java.lang.String |
| 13:06 | amalloy | only primitives have this sugar to get at their class |
| 13:07 | alpheus | tonyl: clojure.inspector/atom? is kind of like the Lisp or Scheme version. I was thinking more about clojure.lang.Atom. Then I remembered that class tells me that. |
| 13:09 | amalloy | alpheus: you can generalize with (instance? clojure.lang.IDeref (class foo)) |
| 13:09 | amalloy | if you want to just check whether @foo is legal |
| 13:09 | alpheus | oh, nice |
| 13:13 | alpheus | Shouldn't that be: (instance? clojure.lang.IDeref foo) |
| 13:16 | amalloy | oh |
| 13:16 | amalloy | yeah i guess |
| 13:18 | bhenry | is there something that (this-thing "string") will make clojure think it's dealing with a file? |
| 13:19 | amalloy | bhenry: java has StringReader - probably some clj analogue |
| 13:19 | LOPP | if I have a bunch of calculations that I'd like to start each in its own thread how would I do it? |
| 13:20 | amalloy | LOPP: pmap or manage futures yourself |
| 13:20 | LOPP | ,(doc pmap) |
| 13:20 | clojurebot | "([f coll] [f coll & colls]); Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn't realize the entire result unless requir... |
| 13:21 | kriyative | @bhenry: do you mean something like: with-in-str? |
| 13:21 | bhenry | ,(doc with-in-str) |
| 13:21 | clojurebot | "([s & body]); Evaluates body in a context in which *in* is bound to a fresh StringReader initialized with the string s." |
| 13:23 | alpheus | ,(doc with-out-str) |
| 13:23 | clojurebot | "([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls." |
| 13:23 | bhenry | kriyative: i'm not sure. i'm using line-seq on a file and want to know if i can use a string and pretend it's a file in my tests |
| 13:24 | amalloy | bhenry: you should be able to |
| 13:24 | kriyative | @bhenry: yes, you can use (with-in-str "some string" (line-seq *in*)) |
| 13:24 | bhenry | ah cool. |
| 13:25 | kriyative | @bhenry: also look at with-open, if you don't want *in* to get rebound |
| 13:32 | LOPP | what's that string replace function again |
| 13:32 | LOPP | re-something I think |
| 13:32 | chouser | clojure.string/replace |
| 13:41 | LLLLO | I tried (ns myproj.wiki |
| 13:42 | LLLLO | (:require (clojure.string replace))) |
| 13:42 | LLLLO | doesn't work :( |
| 13:43 | LLLLO | also when I say "lein swank" in project folder, it doesn't actually load anything into repl instance, why's that |
| 13:48 | nishant | ,1 |
| 13:48 | clojurebot | 1 |
| 13:51 | fliebel | Is there a clojure-contrib for use with clojure 1.3? |
| 13:53 | cemerick | alpha contribs have been released in conjunction with clojure alphas |
| 13:55 | fliebel | cemerick: Never mind, cake is completely flipping when I use it. I just wanted to see if it ran and if it ran faster. |
| 13:56 | LLLLO | I'm officially completely confused about build tools and namespaces |
| 13:56 | LLLLO | this stuff never works like it should |
| 13:56 | amalloy | LLLLO: namespaces can be confusing |
| 13:57 | cemerick | LLLLO: build tools and namespaces have nothing to do with each other? |
| 13:57 | amalloy | require only loads the functions, it doesn't create shortcuts for getting at them |
| 13:57 | LLLLO | I have a leinigen project. I go to project folder, I run "lein swank". I run emacs, then I run slime-connect in it |
| 13:57 | amalloy | so after (:require (clojure.string replace)), you could (clojure.string/replace ...) |
| 13:57 | LLLLO | I go to one of my project namespaces and the symbols aren't there |
| 13:58 | amalloy | LLLLO: lein swank doesn't load any clj files. it just starts a server for emacs to load stuff into. C-c C-k will compile a file and load it into the running swank server |
| 13:58 | LLLLO | also stuff like (:require (clojure.string replace)) doesn't even work for me |
| 13:58 | LLLLO | so basically I have to manually open and compile all my stuff in emacs? |
| 13:58 | cemerick | LLLLO: your environment is borked somehow |
| 13:59 | amalloy | LLLLO: yes it does, you're just using it wrong. instead of "it doesn't work", provide a snipped of something you think should work and doesn't |
| 13:59 | technomancy | LLLLO: if you want a namespace to be loaded when your repl or slime starts, set :repl-init-script in project.clj |
| 13:59 | technomancy | I think you need the latest swank snapshot for that |
| 14:00 | LLLLO | (ns ircbot.watch.wiki |
| 14:00 | LLLLO | (:require (clojure.string replace))) |
| 14:00 | LLLLO | |
| 14:00 | LLLLO | this for instance |
| 14:00 | lrenn | (use 'ircbot.watch.wiki) right? |
| 14:00 | cemerick | replace is a function, not a namespace |
| 14:00 | LLLLO | ok |
| 14:00 | cemerick | (:require clojure.string) |
| 14:01 | cemerick | and then code can use (clojure.string/replace …) |
| 14:01 | LLLLO | what if I have multiple |
| 14:01 | LLLLO | requires |
| 14:01 | cemerick | (:require clojure.string clojure.set clojure.contrib.graph), whatever |
| 14:01 | amalloy | or i seem to recall (:require (clojure core string set)) works |
| 14:02 | LLLLO | thanks it works now |
| 14:02 | cemerick | LLLLO: read (doc require) |
| 14:02 | LLLLO | when do I need to use quotation when naming namespaces? |
| 14:02 | cemerick | only outside of an ns form |
| 14:02 | cemerick | e.g. at the REPL |
| 14:02 | LLLLO | oh ok |
| 14:03 | amalloy | cemerick: honestly the documentation on namespaces is really confusing. i've read (doc require) a lot of times, and i still have to look up the syntax every time; plus it doesn't mention the difference between [] and () in (:use) forms |
| 14:03 | noidi | is there a difference? |
| 14:04 | cemerick | amalloy: http://clojure.org/libs *shrug* |
| 14:04 | noidi | and if not, which form is preferred? |
| 14:04 | noidi | I've used vectors so far, as in (:use [clojure.string :only [replace]]) |
| 14:04 | cemerick | noidi: parens define a prefix, brackets are an explicit libspec, allowing you to use :as, :only, :rename, etc |
| 14:04 | LLLLO | ok |
| 14:05 | LLLLO | here's a brain teaser |
| 14:05 | noidi | cemerick, ok, thanks. |
| 14:05 | amalloy | cemerick: okay, lovely. this page is much better than (doc require) |
| 14:06 | LLLLO | I have a string that's all lowercase. Instead of spaces I have _. It can also have ' or -. I'd like to have first letter of each word capitalized. Stuff after - or _ is a new word but not after '. |
| 14:06 | noidi | I used to hate the ns macro until I learned the most common invocations. before that I had to copy & paste snippets from other codebases and modify them :P |
| 14:07 | LLLLO | a_snake's_mumbo-jumbo -> A_Snake's_Mumbo-Jumbo |
| 14:07 | noidi | the error messages could be a lot better |
| 14:07 | LLLLO | looking for an elegant way to do this |
| 14:08 | fliebel | How can I concatenate multiple byte[] into one byte[]? Preferably avoiding boxing of all the bytes. |
| 14:08 | cemerick | fliebel: make-array and System/arraycopy |
| 14:09 | fliebel | cemerick: Thanks |
| 14:10 | tonyl | LLLL0: what do you have so far? |
| 14:10 | cemerick | fliebel: j.io.SequenceInputStream is also handy if you need to concatenate some InputStreams(backed by byte[] if necessary), just FYI |
| 14:10 | LLLLO | nothing tbh. I'll probably write a java function that does this |
| 14:10 | LLLLO | a for loop and some if sentences |
| 14:11 | amalloy | LLLLO: you'll spend way too much time on it in either java or clojure. just use built-in tools like regexes |
| 14:11 | amalloy | &(string/replace "a-bc" #"([-_]\w)" #(.toUpperCase (first %))) |
| 14:11 | sexpbot | java.lang.Exception: No such namespace: string |
| 14:11 | amalloy | &(clojure.string/replace "a-bc" #"([-_]\w)" #(.toUpperCase (first %))) |
| 14:11 | sexpbot | ⟹ "a-Bc" |
| 14:11 | LLLLO | I see |
| 14:13 | amalloy | if you want to capitalize the beginning of the string too: |
| 14:13 | amalloy | &(clojure.string/replace "na-bc" #"(($|[-_])\w)" #(.toUpperCase (first %))) |
| 14:13 | sexpbot | ⟹ "na-Bc" |
| 14:13 | LLLLO | I wasn't aware I can use replace like that |
| 14:13 | amalloy | &(clojure.string/replace "na-bc" #"((^|[-_])\w)" #(.toUpperCase (first %))) |
| 14:13 | sexpbot | ⟹ "Na-Bc" |
| 14:13 | amalloy | String.replace takes regexes, and the clojure wrapper around that allows functions as replacements |
| 14:14 | LLLLO | so basically you get a vector into that function |
| 14:14 | LLLLO | of the match |
| 14:14 | LLLLO | and you can return what you want, which gets replaced for the match |
| 14:14 | amalloy | yeah. first element is the match, further elements are the capturing groups, if any |
| 14:15 | LLLLO | and what you return replaces whole match? or is there an option of specifying replacement for each group |
| 14:15 | amalloy | &(re-seq #"((^|[-_])\w)" "na-bc") |
| 14:15 | sexpbot | ⟹ (["n" "n" ""] ["-b" "-b" "-"]) |
| 14:15 | LLLLO | btw you can make non-capturing groups |
| 14:15 | amalloy | you get passed that vector, and can do anything you want to it to create a string to replace into |
| 14:15 | amalloy | yeah i know |
| 14:15 | LLLLO | (?: ) |
| 14:17 | amalloy | but when i don't care what's in any of the groups, marking them as non-capturing just clutters everything up |
| 14:17 | LLLLO | I hear it works faster |
| 14:17 | amalloy | yep |
| 14:18 | amalloy | sexpbot: let me know if you're getting tired, i'll go easy |
| 14:18 | LLLLO | you can probably remove the outermost parenthesis here without any consequence |
| 14:18 | cemerick | regexes seem like a tough way to handle this... |
| 14:18 | amalloy | yeah, i can |
| 14:18 | amalloy | i forgot it returns the whole match as well as the capturing groups |
| 14:18 | LLLLO | awesome stuff anyway |
| 14:18 | amalloy | cemerick: you have something easier? |
| 14:19 | LLLLO | cemerick: do you have a good idea? |
| 14:20 | cemerick | well, regexes will *work*, but you're drifting into read-only territory |
| 14:20 | cemerick | one sec |
| 14:21 | amalloy | it's true that it's easy to abuse regexes. i'm guilty of that myself |
| 14:21 | LLLLO | what do you mean about drifting into read-only territory |
| 14:22 | amalloy | LLLLO: regexes are a lot easier to write than read |
| 14:22 | LLLLO | oh yes |
| 14:22 | LLLLO | I have a regex in my irc bot that recognizes questions |
| 14:22 | LLLLO | messy stuff |
| 14:23 | amalloy | hm, speaking of which, is there a way to set modifiers in #"" forms, as in m/myregex/x? |
| 14:25 | cemerick | LLLLO: https://gist.github.com/0af84c12661344c75114 |
| 14:25 | cemerick | probably more verbose than necessary |
| 14:25 | LLLLO | aha |
| 14:27 | cemerick | updated, better |
| 14:27 | LLLLO | this partition-by use on strings is a neat trick |
| 14:27 | LLLLO | and using set as a function |
| 14:27 | LLLLO | very nice |
| 14:27 | LLLLO | I never come up with stuff like that :D |
| 14:27 | amalloy | LLLLO: using set as a function is idiomatic |
| 14:28 | amalloy | you get used to it |
| 14:28 | LLLLO | I know it's idiomatic |
| 14:28 | LLLLO | but I would probably make an anonymous fn that returns true or false if a delimiter |
| 14:28 | LLLLO | I usually think only of functions |
| 14:29 | LLLLO | somehow using a datastructure as an active participant doesn't ever occur to me :) |
| 14:30 | cemerick | updated again -- didn't need the second delim check because uppercasing both - and _ is a no-op :-) |
| 14:30 | amalloy | &(filter (comp #{"bar"} :foo) [{:foo 10} {:bleh "bar"} {:foo "bar"}]) |
| 14:30 | sexpbot | ⟹ ({:foo "bar"}) |
| 14:30 | amalloy | LLLLO: you can compose them just like functions too |
| 14:31 | amalloy | get all maps whose :foo key maps to "bar" |
| 14:31 | LLLLO | I know :) but there is a difference between knowing and routinely thinking in these terms and incorporating something in your own designs |
| 14:31 | amalloy | yeah for sure |
| 14:31 | amalloy | exposure helps |
| 14:31 | cemerick | there, that's probably as good as it's going to get: https://gist.github.com/0af84c12661344c75114 |
| 14:32 | LLLLO | these ->> macros also throw me a curveball :) |
| 14:33 | amalloy | cemerick: (fn [[x & more]]) instead of #((first %)...(rest %))? |
| 14:33 | hsuh | doing (apply + [1 2 3]) is the same than (+ 1 2 3); now what if i wanted + to receive 1 argument, [1 2 3] ? |
| 14:33 | hsuh | *that |
| 14:33 | amalloy | hsuh: (+ [1 2 3])... |
| 14:33 | cemerick | amalloy: sure, same thing; destructuring does come with a cost though, so I usually avoid it if I'm not actually using the let-bindings more than once. |
| 14:33 | hsuh | and the function isn't know at compile time.. |
| 14:34 | LLLLO | yeah |
| 14:34 | LLLLO | you can also ask yourself what's faster |
| 14:34 | amalloy | &(let [f rest] (f [1 2 3])) |
| 14:34 | sexpbot | ⟹ (2 3) |
| 14:34 | amalloy | hsuh: ^^? |
| 14:34 | LLLLO | regex or splitting a string into a bunch of sublists then modifying non-mutable strings then recombining them |
| 14:35 | amalloy | LLLLO: probably the latter. regexes do the same work, they just hide it |
| 14:35 | LLLLO | it's a nice piece of code nevertheless |
| 14:35 | LLLLO | they probably have fewer allocations |
| 14:35 | amalloy | but who cares which is faster, most of the time |
| 14:36 | tonyl | ,(map + [1 2 3]) |
| 14:36 | clojurebot | (1 2 3) |
| 14:36 | amalloy | heh |
| 14:36 | amalloy | &(map + [1 2 3] [4 5 6]) |
| 14:36 | sexpbot | ⟹ (5 7 9) |
| 14:36 | LLLLO | clojure really cranks it up with the memory alocation and garbage collection....your usual code creates 1000s of lists, sublist and fragments then recombines them by adding a single element each iteration resulting in boatloads of allocations more |
| 14:36 | hsuh | amalloy: hm, yeah i think that works :) |
| 14:37 | amalloy | LLLLO: it's true, but GC is optimized around the idea of lots of short-lived objects and a few long-lived ones |
| 14:37 | amalloy | and clojure's functional data structures can do a lot of pointer sharing, which limits the problem |
| 14:38 | LLLLO | :) |
| 14:38 | LLLLO | unrelated question |
| 14:38 | LLLLO | is it normal that in emacs pressing TAB does autocomplete just in REPL buffer but not in file buffer |
| 14:39 | amalloy | yes |
| 14:39 | amalloy | C-c TAB if you want it in the file buffer |
| 14:39 | amalloy | TAB alone is for indenting |
| 14:40 | LLLLO | thanks |
| 14:43 | amalloy | i'll rebind mine to C-TAB if i ever look up how to specify non-letter keys :P |
| 14:48 | cemerick | LLLLO, amalloy: FWIW, a version based on a regex is faster in some bad microbenchmarking, but not by a ton (35% diff here) *shrug* https://gist.github.com/0af84c12661344c75114 |
| 14:49 | cemerick | The biggest part of the overhead is the word split, uppercasing, and concat, not the original partition or re-seq |
| 14:49 | cemerick | anyway, back to work |
| 14:50 | amalloy | cemerick: i'd use replace, not re-seq, but i agree the benchmark doesn't really matter |
| 14:50 | amalloy | clojurebot: dotimes? |
| 14:50 | clojurebot | Excuse me? |
| 14:50 | amalloy | clojurebot: benchmark? |
| 14:50 | clojurebot | Excuse me? |
| 14:50 | amalloy | bah |
| 14:50 | amalloy | i'm sure he has something in there about how dotimes is not a benchmarking toolkit |
| 14:52 | Vinzent | Hello. What library for GAE (primarily for accessing it's datastore) you can recommend? There is so much similar libs so I am a little bit confused |
| 14:57 | rata_ | amalloy: [(control tab)] IIRC |
| 14:57 | LLLLO | cemerick you could probably improve on uppercasing by typehinting |
| 14:58 | cemerick | LLLLO: that call is already hinted |
| 14:58 | LLLLO | how? |
| 14:58 | clojurebot | with style and grace |
| 14:58 | cemerick | The ^Character hint? |
| 14:58 | LLLLO | didn't see it in your first version |
| 14:58 | fliebel | Hmmm, is there something like reductions for iterate? |
| 14:59 | cemerick | LLLLO: oh, well go to the latest version :-) |
| 15:02 | fliebel | Oh well, I'll just use reduction. But… can I do a for loop with 2 seqs in parallel? |
| 15:03 | mfex | fliebel: can you give an example of what you want with reductions for iterate? |
| 15:04 | LauJensen | Chousuke: Your suggesting is in the compiler now, sugared (where (either (= {:a 5}) (<= {:b 10}))) = "WHERE ((a = 5) OR (b <= 10))" |
| 15:04 | LauJensen | suggestion |
| 15:04 | fliebel | mfex: nvm |
| 15:05 | fliebel | mfex: (reductions #(+ %1 (count %2)) 0 seqs) |
| 15:07 | fliebel | But what I need now is (doseq [x [1 2 3] y [4 5 6]]) to do 1,4; 2,5; 3,6 |
| 15:08 | mfex | fliebel: (doseq [[a b] (map vector [1 2 3] [4 5 6])] (... a ... b...)) |
| 15:09 | chouser | fliebel: currently, map is _the_way_ to walks seqs in step. map or loop/recur |
| 15:09 | fliebel | chouser: I think loop/recur might be less hacky in this case. |
| 15:12 | amalloy | fliebel: disagree |
| 15:12 | Vinzent | http://github.com/smartrevolution/clj-gae-datastore/ looks fine, but isn't it a bit outdated? |
| 15:12 | rata_ | LLLLO, amalloy: also, if you use autocomplete, you can autocomplete in file buffers with tab |
| 15:12 | fliebel | amalloy: On second thought I disagree with myself as well. |
| 15:13 | amalloy | rata_: i started trying to install autocomplete a while ago, but got confused/frustrated and set it aside |
| 15:16 | puredanger | Rich's hammock talk from the conj in "pencast": http://www.livescribe.com/cgi-bin/WebObjects/LDApp.woa/wa/MLSOverviewPage?sid=R4XrwCpdzj5m |
| 15:16 | puredanger | (not mine, just reposting) |
| 15:16 | rata_ | amalloy: I download it from here http://cx4a.org/software/auto-complete/ |
| 15:17 | rata_ | and put this in .emacs: https://gist.github.com/661549 |
| 15:17 | tonyl | puredanger: thanks! |
| 15:18 | mfex | fliebel: how about (reductions + (map count seqs)) instead of (reductions #(+ %1 (count %2)) 0 seqs) |
| 15:19 | fliebel | mefx: yea, good one :) |
| 15:21 | amalloy | rata_: nice, thanks. looks like it Just Works |
| 15:21 | amalloy | though i haven't figured out how to use it properly yet |
| 15:38 | itistoday | what's the difference between 'seq' and 'sequence'? |
| 15:39 | MayDaniel | ,((juxt sequence seq) ()) |
| 15:39 | clojurebot | [() nil] |
| 15:39 | chouser | seq never returns an empty collection. It returns an ISeq or nil. |
| 15:40 | chouser | ...possibly forcing a step of a lazy seq in order to determine if it's empty or not |
| 15:40 | itistoday | chouser: thanks! |
| 15:42 | rata_ | amalloy: welcome =) |
| 15:57 | fliebel | Yay, an awesome array concatenation function: https://github.com/pepijndevos/Clomian/blob/master/src/clomian.clj#L101 |
| 15:58 | itistoday | why can't i create a record called 'test'? it seems to conflict with clojure.core/test ... but what if the record is created in its own namespace? |
| 15:59 | fliebel | itistoday: core is always there I think. But I also think having a fn named test in your core is a bad move. |
| 15:59 | chouser | itistoday: that's fine, but you have to exclude test from being refered into your namespace |
| 16:00 | itistoday | chouser: ah, i see... using the 'ns' macro probably, thanks |
| 16:00 | itistoday | fliebel: this isn't going into any production code :-p |
| 16:02 | fliebel | itistoday: I was referring to Clojure. I make functions called test all the time, because it saves thinking about a function name. So this is accidental hacking complexity :( |
| 16:02 | raek | itistoday: (ns foo.bar (:refer-clojure :exclude (test))) |
| 16:02 | raek | fliebel: any luck with the gzipped streams? |
| 16:03 | fliebel | raek: yes and no. Reading just the files was quick, so I figured the lib was to blame but... |
| 16:03 | itistoday | fliebel: ah gotcha :-) |
| 16:04 | itistoday | raek: thanks! |
| 16:04 | fliebel | I made a function for concatenating java arrays to save memory, and then it seemed to run faster, so it might have been the casting and boxing that was causing trouble. |
| 16:04 | raek | I guess you code would benefit from the new goodies in 1.3 |
| 16:05 | fliebel | raek: Now the bottleneck moved up to the freqs function. |
| 16:06 | fliebel | raek: cake flipped completely when I tried to get that. Can you give me the correct version number for core and contrib? |
| 16:07 | fliebel | I did 1.3.0-SNAPSHOT for core, and the same but with 1.2 for contrib, but I guess that was wrong :( |
| 16:07 | raek | there is 1.3.0-alpha2 |
| 16:07 | raek | see http://build.clojure.org/releases/ |
| 16:08 | raek | contrib is now split into multiple jars |
| 16:08 | raek | but there is a version containing everything |
| 16:08 | raek | fliebel: I made this once: https://gist.github.com/661631 |
| 16:09 | raek | it is probably not as performant as you would like |
| 16:09 | raek | since it uses lazy seqs |
| 16:10 | fliebel | raek: But what do I enter for contrib now? |
| 16:10 | fliebel | oh well, I'm not even using anything from contrib at the moment. |
| 16:11 | defn | http://tinyurl.com/38agqgm <--- a "Pencast" of Rich's talk "Step Away from the Computer" |
| 16:11 | chouser | defn: I looked at that. Seems like a fun device. |
| 16:12 | nickik | does anybody know when the videos are releaved |
| 16:12 | raek | hrm, was it "complete" or "standalone"... |
| 16:13 | fliebel | raek: cake still goes crazy as soon as I start it. |
| 16:13 | fliebel | raek: standalone |
| 16:13 | fliebel | http://build.clojure.org/releases/org/clojure/contrib/standalone/ |
| 16:13 | defn | yeah, it's interesting. i think they're marketing is off, though. they need to be focusing more on geeks, hacker conferences, etc. |
| 16:14 | defn | @chouser^ |
| 16:14 | defn | they're => their |
| 16:15 | raek | fliebel: I don't use cake, but maybe you have to restart its jvm |
| 16:16 | fliebel | raek: It seems there have been a few 1.3 fixes on github. I'm getting that now. |
| 16:16 | raek | does cake have separate jvm processes for cake stuff and user stuff, à la lein? |
| 16:16 | itistoday | is there a contrib thing for creating records with default values? |
| 16:16 | fliebel | raek: What will I gain from Clojure 1.3? |
| 16:16 | raek | itistoday: you usually make a factory function for that |
| 16:17 | itistoday | raek: ah ok |
| 16:17 | itistoday | just wondering... |
| 16:17 | itistoday | there's this interesting post: http://cemerick.com/2010/08/02/defrecord-slot-defaults/ |
| 16:17 | raek | fliebel: the ability to use unboxed promitives across function boundaries |
| 16:17 | nickik | @itistoday look at defrecord2 on github |
| 16:18 | nickik | they are like super records |
| 16:18 | raek | fliebel: http://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support |
| 16:18 | itistoday | nickik: thanks, i take it you're referring to: https://github.com/david-mcneil/defrecord2 ? |
| 16:19 | raek | I'll be away for a moment. bbl. |
| 16:19 | fliebel | raek: Looks like exactly the thing I need. |
| 16:19 | nickik | yes, but they do not support default values |
| 16:22 | amalloy | raek: yes, cake has two jvms |
| 16:23 | amalloy | (and they're used for cake-stuff vs user-stuff) |
| 16:25 | raek | fliebel: http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly |
| 16:26 | raek | the article contains measurements of various methods for doing io in java |
| 16:27 | raek | the gisted code uses "BufferedInputStream, 8k buffer, varying array read size" (as long as you pass it a BufferedInputStream) |
| 16:28 | raek | fliebel: hrm... do you know if the stream is buffered? if not, you should definitely try to wrap in one... (java.io.BufferedInputStream. the-stream) |
| 16:31 | fliebel | raek: I don't know. They're using some weird input streams over there. |
| 16:35 | fliebel | wtf, cake is giving ssl errors... |
| 16:35 | raek | if adding it has a large effect, they probably don't |
| 16:36 | fliebel | raek: I can't test untill I have cake running again :( |
| 16:36 | tcepsa | Are there any known issues with lein compile in Windows? I have a project that compiles fine in Linux, but throws a "Don't know how to create ISeq from: Clojure.lang.Symbol (with_ns.clj:1)" at the Windows command line |
| 16:39 | tcepsa | Though now that I look more closely, I see that I am using version 1.3.1 on Linux and--apparently--1.1.0 on Windows. I'll see whether upgrading helps. |
| 16:41 | fliebel | Can any cake expert tell me why I'm getting SSl errors for a build tool? Is cake trying to get something from Github, and failing because of their move to https? |
| 16:41 | crowbar7 | Doesn't clojurebot do something with pastebin? |
| 16:42 | crowbar7 | .pastebin |
| 16:42 | hiredman | http://www.delicious.com/clojurebot/pastbin |
| 16:43 | crowbar7 | thanks |
| 16:44 | crowbar7 | So he saves links it looks like |
| 16:44 | tcepsa | fliebel: I am no cake expert, but that seems reasonable; I'm having similar problems attempting to pull down the latest version of Leiningen with lein self-install |
| 16:44 | arkh | is it possible to build a string and pass it to #"" ? |
| 16:45 | LLLLO | don't think so |
| 16:45 | crowbar7 | not that's a cool feature |
| 16:45 | LLLLO | you need to construct it using re-mather |
| 16:45 | crowbar7 | s/not/now/ |
| 16:45 | sexpbot | <crowbar7> now that's a cool feature |
| 16:45 | LLLLO | re-matcher |
| 16:45 | fliebel | arkh: … what LLLLO said |
| 16:45 | chouser | arkh: no, but you can use re-pattern |
| 16:45 | crowbar7 | now that's really a cool feature |
| 16:46 | arkh | ah - re-pattern; that's what I want |
| 16:46 | fliebel | arkh: ony with the function chouser said |
| 16:46 | fliebel | I'm to slow :( |
| 16:49 | amalloy | arkh: also (java.util.regex.Pattern. "some regex str"), which is what re-pattern does |
| 16:50 | amalloy | ~source re-pattern |
| 16:50 | tcepsa | Upgrading to Leiningen 1.3.1 solved the issues I was having (which would not surprise me in the least if they were related to my using a more up-to-date format of project.clj...) |
| 16:51 | amalloy | or i guess it's Pattern.compile, not new Pattern |
| 16:51 | fliebel | tcepsa: I'm doing a git checkout of cake, so I think that would work without downloading stuff. |
| 16:52 | amalloy | fliebel: i don't see why. the git repo doesn't have the lib dependencies afaik |
| 16:53 | tcepsa | fliebel: Don't git checkouts download things? Or does that only happen when you clone? |
| 16:53 | fliebel | amalloy: okay, so what now? |
| 16:54 | arkh | amalloy: thanks - I was looking at that, too : ) |
| 16:55 | amalloy | fliebel: can you post a gist of the error message? a fresh checkout of cake works fine for me |
| 16:56 | amalloy | also maybe ping ninjudd, lancepantz, and Raynes, who are the most likely to be able to help if you find a real problem |
| 16:58 | fliebel | amalloy: http://pastebin.com/eFrTtMZA |
| 17:02 | fliebel | Huh, I'm using lein now for a while but it seems my src dir isn't even on the cp... |
| 17:04 | amalloy | fliebel: sorry, ruby and cake aren't really my dept; i just fake my way through it |
| 17:05 | lancepantz | fliebel: yeah, github has been causing us some headaches |
| 17:05 | lancepantz | fliebel: we'll have a fix recently |
| 17:05 | lancepantz | s/recently/shortly/ |
| 17:05 | sexpbot | <lancepantz> fliebel: we'll have a fix shortly |
| 17:06 | amalloy | but it looks like the "cake" script downloads the latest copy of cake.jar from https://github/blah if you don't already have it |
| 17:06 | fliebel | lancepantz: I'll get back to using the gem and Clojure 1.2 :( |
| 17:06 | ninjudd | fliebel: we had to change the uri to https today because github added a redirect from http to https, but i tested and it seems to work even on a machine where i have nothing in ~/.ssh |
| 17:07 | fliebel | ninjudd: Which means my ssh is seriously messed up? |
| 17:08 | ninjudd | fliebel: not sure. i'm going to create a brand new ssh key now on that machine and see if that causes it |
| 17:08 | amalloy | ninjudd: actually, i'm having some trouble getting cake.jar too, now |
| 17:09 | amalloy | it gets maybe 85% through downloading it, hangs for a while, and gives up on "session expired" |
| 17:09 | ninjudd | if you are running from git, you need to pull |
| 17:09 | amalloy | i did |
| 17:09 | ninjudd | hmm |
| 17:09 | amalloy | right before i started testing fliebel's problem |
| 17:09 | amalloy | and it worked then |
| 17:09 | ninjudd | amalloy: would you classify your connection as fast or slow? |
| 17:10 | amalloy | ninjudd: slowish broadband |
| 17:10 | ninjudd | i need a slow connection at work to test on ;) |
| 17:11 | ninjudd | amalloy: Raynes has had a similar problem, but he is on dialup. he was working on a way to mirror the file on his VPS, but i'm not sure how far he got |
| 17:12 | fliebel | raek: Whoa! Adding the buffered speeds it up quite a lot :) |
| 17:12 | amalloy | ninjudd: i get ~300KB/s as a microbenchmark |
| 17:13 | ninjudd | amalloy: should be plenty fast. it the stop at 85% repeatable? |
| 17:13 | amalloy | well, it's happened twice so far. i'll give it another shot |
| 17:13 | fliebel | ninjudd: Anything I can do to test my problem? |
| 17:14 | amalloy | ninjudd: yes, it's still happening |
| 17:14 | ninjudd | fliebel: does 'wget https://github.com/ninjudd/cake-standalone/raw/master/jars/cake-0.5.4.jar' work for you? |
| 17:14 | amalloy | git show says i'm at commit 95e1a8ebfcf23514afa4adcee39ae652f8aab866, which is from nov 4 |
| 17:14 | fliebel | ninjudd: wget: command not found :D Should I try curl? |
| 17:15 | amalloy | ninjudd: wget fails for me immediately, actually |
| 17:15 | fliebel | ninjudd: curl works :) |
| 17:15 | amalloy | ERROR: certificate common name `*.github.com' doesn't match requested host name `github.com'. |
| 17:15 | ninjudd | fliebel: yeah. curl -O |
| 17:15 | fliebel | -O?? |
| 17:15 | clojurebot | Clojure ranked #21 on 8/14/2009 |
| 17:16 | ninjudd | fliebel: isn't that the option to save to a file? |
| 17:16 | fliebel | ninjudd: I just watched weird chars pass by :) |
| 17:16 | ninjudd | should i more cake-standalone to gitorious? ;) |
| 17:16 | ninjudd | fliebel: got it |
| 17:17 | amalloy | ninjudd: if i tell wget to ignore bad certs, it gets to 84% and stops |
| 17:17 | fliebel | ninjudd: Problem solved: Use system ruby instead of macports :D |
| 17:17 | fliebel | ninjudd: But now I still don't have the 1.3 fixes, do I? |
| 17:18 | amalloy | curl downloads the whole thing successfully |
| 17:19 | LauJensen | For those interested in ClojureQL I blogged a little about the recent changes: http://bestinclass.dk/index.clj/2010/11/clojureql--revolutions.html |
| 17:20 | ninjudd | hmm, gitorious says they will throttle you if you exceed 500MB per month |
| 17:20 | amalloy | ninjudd: ouch, worse than the iphone/att data cap :) |
| 17:21 | fliebel | ninjudd: How do I use cake with clojure 1.3? I have the git version, but that still downloads the standalone. |
| 17:21 | amalloy | fliebel: just list 1.3 as a dependency in project.clj? |
| 17:21 | ninjudd | fliebel: add [clojure "1.3.0-alpha2-SNAPSHOT"] to your :dependencies in project.clj |
| 17:22 | fliebel | amalloy: Hell breaks loose if I do that. |
| 17:22 | amalloy | fliebel: don't do that, then :) |
| 17:22 | ninjudd | fliebel: what kind of hell? that should work with master, it is broken with the current gem version though |
| 17:23 | fliebel | I'll try… but the master still downloads the standalone, so how is that different from the gem? |
| 17:23 | ninjudd | fliebel: your project can use a different version of clojure. |
| 17:24 | ninjudd | fliebel: the standalone is only used for deps, the cake code is still loaded from your git checkout |
| 17:25 | fliebel | yay, works so far :) At least no infinit stacktrace loop :) |
| 17:27 | fliebel | Thanks all, I'm going to sleep now. UGT is having daylight saving time. |
| 17:28 | fliebel | This is what my script is currently doing: |
| 17:29 | fliebel | "Elapsed time: 8608.225 msecs" reading files |
| 17:29 | fliebel | "Elapsed time: 132289.221 msecs" freqs <<< slow! |
| 17:29 | fliebel | "Elapsed time: 236.694 msecs" plotting |
| 17:29 | fliebel | "Elapsed time: 141319.784 msecs" total |
| 17:29 | ninjudd | fliebel, amalloy: i'm switching the uri back to http because that seems to work for me, and i think using https is causing more problems that http was |
| 17:30 | fliebel | ninjudd: cool |
| 17:33 | amalloy | ninjudd: hm. problem sorta solved |
| 17:33 | ninjudd | cool. sorta |
| 17:35 | amalloy | okay, all the way fixed. it wasn't fetching the latest copy of standalone after git pull |
| 17:38 | vibrant | is there an easy way to run some function after for example 60 seconds in clojure? |
| 17:39 | amalloy | vibrant: Thread/sleep |
| 17:39 | tomsw | I'm trying to use clojure to interact with a server over a custom (and horrible) SOAP interface. Starting a session and logging in takes a long time, so ideally I'd like to keep the connection in one thread and send it requests from other threads. Is there a clojure-ish way of doing this? |
| 17:39 | LauJensen | vibrant: just type the function in the repl, wait 60 seconds, then hit enter |
| 17:39 | amalloy | &@(future (Thread/sleep 5000) 1) |
| 17:39 | sexpbot | ⟹ 1 |
| 17:39 | clojurebot | Pardon? |
| 17:39 | vibrant | amalloy; what if i run it 100 times? |
| 17:39 | vibrant | it's not gonna pop up 100 threads? |
| 17:39 | amalloy | use a threadpool |
| 17:41 | amalloy | &@(future (Thread/sleep 5000) 1) |
| 17:42 | sexpbot | ⟹ 1 |
| 17:42 | amalloy | clojurebot: who were you talking to a minute ago? |
| 17:42 | clojurebot | Cool story bro. |
| 17:42 | vibrant | well i guess it's better to make a priority queue and a thread checking it every second or so. |
| 17:42 | vibrant | any ready priority queue struct? |
| 17:42 | vibrant | data type i mean |
| 17:43 | amalloy | vibrant: java has all these things - see java.util.concurrent.* |
| 17:43 | vibrant | k |
| 17:58 | duncanm | is it a known bug that i can't inspect-in-frame in slime? |
| 17:59 | micahmartin | I could use help understanding how var are bound to their namespace |
| 17:59 | micahmartin | here's an example |
| 17:59 | micahmartin | user=> (def my-ns (create-ns 'mine)) |
| 17:59 | micahmartin | #'user/my-ns |
| 17:59 | micahmartin | user=> (binding [*ns* my-ns] (def my-var 1)) |
| 18:00 | micahmartin | Yet if I use load-string .... |
| 18:00 | micahmartin | user=> (binding [*ns* my-ns] (load-string "(def my-var 1)")) |
| 18:00 | micahmartin | #'mine/my-var |
| 18:00 | amalloy | duncanm: yeah, swank-clojure doesn't yet have all the features slime does |
| 18:00 | micahmartin | Why without load-string, does the var get bound to the user ns? |
| 18:03 | micahmartin | rhickey: any idea? |
| 18:06 | raek | LauJensen: reading you blog post... so much DSL beauty! |
| 18:06 | LauJensen | raek: you like? :) |
| 18:06 | raek | LauJensen: but, should it really be "(take users 1) |
| 18:06 | raek | "? |
| 18:07 | raek | I was stunned when I looked at cgrand's slides from the conj |
| 18:07 | LauJensen | Not necessarily, got better ideas? |
| 18:08 | raek | well, the argument order is the opposite of clojure.core/take |
| 18:10 | LauJensen | raek: Thats a minor detail, all my consumers should take the table as the first arg. I think I'll want to work take into select somehow though, giving it a representation in the data |
| 18:11 | raek | also, does take and sort deref the table? |
| 18:12 | LauJensen | yea, they should return a resultset |
| 18:12 | raek | ok, so (resolve 'take) does not yeld #'clojure.core/take... |
| 18:13 | rickmode | LauJensen: with clojureql, the tables are are actually atoms/refs right? you're just overloading @ / deref for this similar persistent meaning? |
| 18:13 | rickmode | s/are are/are not |
| 18:13 | LauJensen | no, Im currently overriding a few functions, conj! disj! < > <= >= = |
| 18:13 | raek | I really like the idea of representing tables with a IDeref thing |
| 18:13 | LauJensen | rickmode: wrong, Im just overloading |
| 18:14 | LauJensen | No need to add Clojures concurrency overhead to something which is already safe |
| 18:14 | raek | disj! and conj! does not take the table as an argument? |
| 18:14 | LauJensen | raek: Sure they do, its their first arg, like I said, uniform interface |
| 18:15 | rickmode | LauJensen: right. interesting. any thought about in-memory cache? |
| 18:15 | raek | LauJensen: in the first disj! and conj! examples, the table argument is missing |
| 18:15 | LauJensen | rickmode: Not yet |
| 18:15 | LauJensen | raek: good catch, thanks |
| 18:16 | raek | btw, I agree that the "haystack" arg should be the first one |
| 18:16 | amalloy | so if you have a -> chain, with just one command where you need to thread at the end instead of the second position, it's pretty easy: (-> thing form1 (->> form2) ...formN) |
| 18:16 | raek | (perhaps with an exception of sequence functions) |
| 18:16 | LauJensen | fixed |
| 18:17 | amalloy | but i don't see a convenient way to do a ->> chain with one -> link |
| 18:17 | rickmode | LauJenson: what if you want to chain operations within a single transaction? |
| 18:17 | LauJensen | amalloy: the trick is, typically -> is for things with lists and ->> for collections |
| 18:17 | kotarak | amalloy: you have to start with ->. (-> x (->> ....) the-->-link (->> more-->>-stuff ...)) |
| 18:17 | LauJensen | rickmode: Next step is making the connections nest and adding a dbsync which covers several actions |
| 18:18 | raek | (->> thing form1 (#(-> % form2)) ...formN) ; a bit hackish |
| 18:18 | kotarak | amalloy: which is a sign, you shouldn't do that. |
| 18:18 | LauJensen | Anyway, Can't touch this, its Hammock Time |
| 18:18 | LauJensen | Good night all |
| 18:18 | kotarak | N8t |
| 18:18 | rickmode | LauJensen: ya - both with one table and spanning tables. |
| 18:21 | amalloy | kotarak: yeah, i haven't actually had a reason to do that yet |
| 18:23 | neotyk | good evening |
| 18:24 | neotyk | Rich Hickey @ Clojure-Conj [Audio] http://sustainablecode.tumblr.com/post/1472289527/rich-hickey-clojure-conj-audio |
| 18:24 | neotyk | is it just me or there is no audio? |
| 18:27 | raek | I hear some audio |
| 18:27 | raek | folloed the link to here http://www.livescribe.com/cgi-bin/WebObjects/LDApp.woa/wa/MLSOverviewPage?sid=R4XrwCpdzj5m |
| 18:28 | raek | is this the legendary "Hammock Time" talk? :) |
| 18:28 | neotyk | it is supposed to be this one |
| 18:29 | neotyk | stop hammock time |
| 18:35 | jjido | = |
| 18:43 | duncanm | is it a bad idea for the arithmatic operators to be generic functions? |
| 18:43 | pppaul | would someone be able to help me with a simple classpath problem? (trying to get contrib to work, i followed a tutorial and it did work for a second, but now is broken) |
| 18:45 | pppaul | anyone? |
| 18:45 | clojurebot | Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 18:45 | amalloy | lol, good work clojurebot |
| 18:46 | amalloy | seriously though pppaul, paste an error message or something. don't make people say "sure i'll help" to find out what your problem is |
| 18:47 | pppaul | user=> (System/getProperty "java.class.path") |
| 18:47 | pppaul | "/home/paul/.clojure/clojure.jar:/home/paul/.clojure/clojure-contrib.jar" |
| 18:47 | pppaul | user=> (clojure.contrib.math/round 1000/3) |
| 18:47 | pppaul | java.lang.ClassNotFoundException: clojure.contrib.math (NO_SOURCE_FILE:0) |
| 18:47 | amalloy | (require 'clojure.contrib.math)? |
| 18:47 | pppaul | i did use that (based on the info on the math API site) |
| 18:48 | pppaul | user=> (require 'clojure.contrib.math) |
| 18:48 | pppaul | nil |
| 18:48 | pppaul | user=> (abs 4) |
| 18:48 | pppaul | java.lang.Exception: Unable to resolve symbol: abs in this context (NO_SOURCE_FILE:3) |
| 18:48 | pppaul | ok, i think i understand what my problem is |
| 18:48 | amalloy | pppaul: require doesn't provide "shortcut" banes |
| 18:49 | amalloy | use (use) instead if you want to refer to them without a namespace |
| 18:49 | pppaul | do i always have to switch the (ns) for shortcuts? |
| 18:49 | amalloy | (use 'clojure.contrib.math) |
| 18:49 | pppaul | thank you |
| 18:50 | amalloy | getting absolute values now? |
| 18:50 | pppaul | yes |
| 18:50 | amalloy | clojurebot: another satisfied customer |
| 18:50 | clojurebot | It's greek to me. |
| 18:51 | raek | pppaul: all the ns clauses do is to call the corresponding functions |
| 18:51 | arohner | ok, stupid question. What is the proper lein declaration to get the newest clojure contrib 1.3? |
| 18:52 | pppaul | thanks. i'll look up the NS functions. |
| 18:52 | arohner | I have [org.clojure.contrib/clojure-contrib "1.3.0-SNAPSHOT"] , which downloads a few poms, and then I get the 'unable to resolve artifact', missing org.clojure.contrib:clojure-contrib:jar:1.3.0-SNAPSHOT |
| 18:52 | raek | it has been split into multiple modules (a big jar of all the modules is available though) |
| 18:52 | arohner | raek: I'm aware it's been split up. My understanding was depending on what I have above would pull in all the little jars as dependencies. Is that incorrect? |
| 18:53 | arohner | and I see that pom in build.clojure.org, but no jar with the same name |
| 18:53 | raek | well, I think [org.clojure.contrib/complete "1.3.0-SNAPSHOT"] does what you describes |
| 18:53 | raek | but I haven't used the new system very much |
| 18:54 | arohner | raek: aha. thanks. d/ling complete now, we'll see what it has |
| 18:55 | raek | I think 'complete' depends on all the others, so you end up with all the module jars |
| 18:56 | raek | I don't remember if there is something like 'complete' but with just one jar |
| 18:59 | arohner | raek: looks like complete is empty, just depends on the others, lein pulled down a bunch of jars. thanks. |
| 19:49 | clizzin | Is there any way to easily do a case-insensitive match for keyword keys in a map? Due to some annoying data inconsistencies, I have keywords in one map that are all lowercase and keywords in another map with some uppercase letters in them. |
| 19:53 | raek | clizzin: you can preprocess the map with (defn lowercase-keys [m] (zipmap (map #(-> % name .toLowerCase keyword) (keys m)) (vals m))) |
| 19:55 | clizzin | raek: Let's say the keys in question are actually within a nested map, i.e. {:blah {:case "foo"}} and {:blah {:cAsE "bar"}}. Is there an easy way to apply the lowercase-keys? Some of the values in the outer maps may not be maps. |
| 19:57 | raek | i guess you could do something like (zipmap (keys outer) (for [v (vals outer)] (if (map? v) (lowercase-keys v) v))) |
| 19:57 | raek | but why not add the lowercase code to the thing that generates the keywords in the first place? |
| 19:58 | bhenry | ^^ that's what i'd do |
| 19:58 | clizzin | we'll do that on the next run of the data, but it's a very big job and we want to do some analysis before we kick off another run |
| 19:58 | clizzin | otherwise, yeah, that would be nice. =/ |
| 21:08 | tufflax | How does lazy-seq work to prevent stack overflows when dealing with recursively defined sequences? It's all a little magical to me. Is is somehow related to closures? I mean, the function used to generate the next element when one needs it, is that a kind of closure? |
| 21:09 | tufflax | Is it* |
| 21:10 | amalloy | tufflax: yes, it is |
| 21:11 | amalloy | each element in a lazy seq is a pair: value, function-to-generate-next-pair |
| 21:12 | amalloy | (probably not exactly true, but close enough to be useful conceptually) |
| 21:15 | tufflax | And when the function-to-generate-next-pair is executed, what is put on the stack? The call to that function, with references to data that is not on the stack? And the next function-to-generate-next-pair is stored together with the seq that's not on the stack? Or something...? :P |
| 21:16 | amalloy | &(macroexpand '(fn f [x] (lazy-seq (cons x (f (inc x)))))) |
| 21:16 | sexpbot | ⟹ (fn* f ([x] (new clojure.lang.LazySeq (fn* [] (cons x (f (inc x))))))) |
| 21:17 | amalloy | so really f just returns a LazySeq object, without recurring |
| 21:18 | tufflax | Yeah ok, thank you. I think I'm starting to understand. |
| 21:18 | amalloy | when you walk a lazy seq, clojure calls the function. that function returns immediately; then it gets the value out and calls the next function |
| 21:19 | tufflax | I see. |
| 21:20 | amalloy | so it doesn't build up the stack at all |
| 21:23 | tufflax | When I was looking for answers to my questions, I came across this http://codemeself.blogspot.com/2010/06/clojurecorelazy-seq-makes-sense.html He uses lazy-seq twice in his function (look at the end of the post) but that is unnecessary, right? |
| 21:26 | amalloy | i don't think so, because my example was recursive, and his isn't |
| 21:27 | amalloy | ie, i have an infinite number of calls to lazy-seq; he only has two |
| 21:28 | amalloy | &(lazy-seq []) |
| 21:28 | sexpbot | ⟹ () |
| 21:28 | amalloy | &(lazy-seq (lazy-seq [])) |
| 21:28 | sexpbot | ⟹ () |
| 21:28 | amalloy | but i don't actually know; i don't build raw lazy-seqs very often |
| 21:29 | tufflax | Yeah I tried his code, it didn't work without both calls. |
| 21:29 | amalloy | &(cons 1 (lazy-seq ())) |
| 21:29 | sexpbot | ⟹ (1) |
| 21:35 | amalloy | anyway, it's definitely good to know how lazy-seq works under the hood, but knowing exactly how to use it is probably unnecessary for quite a while. just combine the built-in lazy functions and let them do the work for you |
| 21:36 | tufflax | Ok :) |
| 21:36 | TheBusby | er, what's the easy way to sort a map by it's values? |
| 21:36 | tufflax | Thanks again |
| 21:39 | amalloy | TheBusby: don't do that :) |
| 21:39 | TheBusby | uh oh, is there a better way to find the most frequent elements among multiple sets then? |
| 21:40 | amalloy | so you have N sets like #{1 3} #{1 5}, and want to find out that 1 is more common than 5? |
| 21:41 | TheBusby | correct, I want to find most common elements |
| 21:41 | TheBusby | hopefully end up with something like [[ 2] [3 1] [5 1]] |
| 21:42 | TheBusby | sorry, that should have read [[1 2] [3 1] [5 1]] |
| 21:43 | amalloy | &(frequencies (concat #{1 3} #{1 5})) |
| 21:43 | sexpbot | ⟹ {1 2, 3 1, 5 1} |
| 21:43 | amalloy | and you want that sorted by value? |
| 21:43 | TheBusby | correct |
| 21:44 | TheBusby | I'll likely be dealing with 10,000+ maps, each containing 2000-5000 values... |
| 21:44 | amalloy | &(sort (comp < val) (frequencies (concat #{1 3} #{1 5}))) |
| 21:44 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$val |
| 21:46 | amalloy | &(sort (fn [[k1 v1] [k2 v2]] (< v1 v2)) (frequencies (concat #{1 3} #{1 5}))) |
| 21:46 | sexpbot | ⟹ ([3 1] [5 1] [1 2]) |
| 21:46 | amalloy | &(sort (fn [[k1 v1] [k2 v2]] (> v1 v2)) (frequencies (concat #{1 3} #{1 5}))) |
| 21:46 | sexpbot | ⟹ ([1 2] [3 1] [5 1]) |
| 21:46 | bhenry | is there a way to sort on keys? |
| 21:47 | amalloy | &(doc sorted-map-by) |
| 21:47 | sexpbot | ⟹ "([comparator & keyvals]); keyval => key val Returns a new sorted map with supplied mappings, using the supplied comparator." |
| 21:47 | kzar | How do you know which different versions of packages there are when writing your project.clj? |
| 21:48 | tufflax | Hm, I briefly tried to learn common lisp before clojure, and in CL they have :key directives (or whatever they call them) to functions like max, sort, map, etc. Why doesn't clojure have that? I noticed clojure have sort-by for example, but no map-by. :P |
| 21:49 | amalloy | &(doc sort) |
| 21:49 | sexpbot | ⟹ "([coll] [comp coll]); Returns a sorted sequence of the items in coll. If no comparator is supplied, uses compare. comparator must implement java.util.Comparator." |
| 21:49 | amalloy | tufflax: just pass in a comparator |
| 21:49 | tufflax | its much easier with a key function |
| 21:49 | tufflax | &(doc sort-by) |
| 21:49 | sexpbot | ⟹ "([keyfn coll] [keyfn comp coll]); Returns a sorted sequence of the items in coll, where the sort order is determined by comparing (keyfn item). If no comparator is supplied, uses compare. comparator must implement java.util.Comparator." |
| 21:50 | amalloy | tufflax: sort-by does something different |
| 21:50 | amalloy | it applies some function to each element of the seq and then compares the result |
| 21:51 | tufflax | Hm, not that different, or what do you mean? |
| 21:51 | tufflax | Yes, thats exactly what its for |
| 21:51 | tufflax | Instead of (sort #(compare (val %1) (val %2)) coll) it becomes (sort-by val coll) |
| 21:51 | tufflax | So, "just pass in a comparator" is not as elegant |
| 21:51 | amalloy | oh, yes. i see what you mean |
| 21:51 | amalloy | that's much nicer |
| 21:52 | tufflax | CL has that for everything |
| 21:52 | tufflax | I think... |
| 21:52 | tufflax | even map |
| 21:52 | TheBusby | ahh, that's exactly what I was looking for |
| 21:52 | tufflax | :) |
| 21:53 | TheBusby | tufflax, amalloy; thank you both. |
| 21:54 | amalloy | tufflax: clojure *has* keyword arguments, but stylistically they're not as prevalent as in CL |
| 21:55 | tufflax | Yeah I know it has keyword arguments, it's just that it would be nice with a :key argument for sort, max, car, filter, etc. |
| 21:55 | tufflax | Why not have :key for sort, instead of sort-by? |
| 21:55 | amalloy | *shrug* |
| 21:55 | tufflax | map, not car* |
| 21:58 | amalloy | why have a function with ten modes instead of ten functions? |
| 21:58 | tufflax | Because you one have to remember one function name :P |
| 21:59 | amalloy | and ten keyword arguments |
| 21:59 | tufflax | but the keyword arguments are the same for all functions |
| 21:59 | amalloy | at least the compiler can help you with autocompletion of function names - it's a lot harder for it to tell you what keyword arguments it will accept |
| 22:01 | tufflax | Yeah, I guess, but it just feels nice to know that :key is always there for you should you need it |
| 22:01 | tufflax | There doesn't seem to be a map-by for example |
| 22:01 | tufflax | I guess one could make his own |
| 22:02 | amalloy | tufflax: i only have a little experience with CL. what would you want map-by to do? |
| 22:03 | tufflax | just apply (key element) to every element before the regular map function |
| 22:03 | hiredman | erm |
| 22:03 | amalloy | use comp |
| 22:03 | tufflax | hm? |
| 22:03 | amalloy | &(map (comp inc :foo) [{:foo 10, :bar 1} {:foo 1}]) |
| 22:03 | sexpbot | ⟹ (11 2) |
| 22:04 | tufflax | ah oh yes |
| 22:04 | tufflax | That's true |
| 22:04 | powr-toc | Hey... Is there any reason why (fn? :foo) ; => false ? |
| 22:04 | qbg | ,(ifn? :foo) |
| 22:04 | clojurebot | true |
| 22:05 | amalloy | &(ifn? :foo) |
| 22:05 | sexpbot | ⟹ true |
| 22:05 | powr-toc | ahh cool |
| 22:05 | powr-toc | why have the distinction? |
| 22:05 | amalloy | things that are callable, vs things that were defined with (fn) |
| 22:05 | qbg | :foo can be used as a function, but isn't actually a function |
| 22:05 | powr-toc | I mean why is it useful to know, whether fn created it? |
| 22:05 | amalloy | i dunno why, but why not |
| 22:06 | tufflax | what qbg said, you can just call :foo like (:foo) |
| 22:06 | tufflax | or, maybe that doesn't make sense |
| 22:06 | tufflax | forget what i said |
| 22:06 | tufflax | :) |
| 22:07 | powr-toc | hmm... ok, I suppose it allows you to nest vectors, keywords and maps, whilst using a predicate function to find function values within them (that aren't the containers themselves) |
| 22:07 | powr-toc | kinda elegant in that case |
| 22:09 | powr-toc | tufflax: :keywords are functions that will look themselves up in maps e.g. (:foo {:foo "bar"}) |
| 22:09 | tufflax | yeah i know, i dunno what i was talking about |
| 22:09 | powr-toc | likewise maps are functions of their values, and vectors are functions of their indicies |
| 22:14 | hiredman | ifn? was split from fn? when trampoline was added |
| 22:15 | powr-toc | does that make it easier to spot the thunk? |
| 22:15 | thunk | no |
| 22:15 | powr-toc | lol |
| 22:15 | powr-toc | the irony, I didn't spot 'the thunk' |
| 22:16 | thunk | the arity! |
| 22:18 | powr-toc | I'm hoping the thunks got nil puns left |
| 22:18 | thunk | Who da thunk? |
| 22:19 | qbg | powr-toc: I think the thunk is just delaying the next one |
| 22:20 | powr-toc | qbg: well for heavens sake don't force him |
| 22:20 | thunk | Hey guys, no arguments. |
| 22:21 | amalloy | oh my god. i'm dying. this is terrible |
| 22:21 | qbg | Well, that is not promise |
| 22:21 | qbg | *no |
| 22:30 | arohner | is anyone using slime with clojure-1.3 successfully? |
| 22:30 | arohner | I'm not getting the stacktrace window when I compile and encounter a stacktrace |
| 22:45 | pppaul | zzz |
| 22:45 | amalloy | pppaul: boring is better than the pun attack we were having earlier |
| 22:46 | pppaul | just testing out my IRC colors.... didn't know what to type :P i think my client is a bit poor, can't tell what i'm changing with respect to the colors |
| 22:46 | pppaul | can't see my own text anymore |
| 22:48 | tufflax | the pun attack was awesome :P |
| 22:49 | amalloy | pppaul: you could do it in #test or something |
| 22:50 | amalloy | not that i especially care, but there are channels for just that purpose |
| 22:52 | pppaul | so, did someone post the pun attack somewhere? |
| 22:52 | amalloy | pppaul: it'll be on n01se if it's not already |
| 22:53 | amalloy | yeh, http://clojure-log.n01se.net/date/2010-11-03.html |
| 22:55 | pppaul | i found it |
| 22:55 | pppaul | seems noisy |
| 22:55 | amalloy | *eyeroll* |
| 23:01 | pppaul | what do you guys think of the clojure euler puzzles? |
| 23:41 | hiredman | as long as it's quiet in hear, I'm going to restart clojurebot with some features that are rather loud the first time they run |
| 23:41 | hiredman | here |
| 23:48 | itistoday | how can i get this sequence to not end in nil? just have the last object be the last object? http://paste.pocoo.org/show/285831/ |
| 23:49 | itistoday | and is there a function to check if a value exists in a sequence (and return true immediately if it does)? |
| 23:52 | amalloy | &(some #{4} (range 1)) |
| 23:52 | sexpbot | ⟹ nil |
| 23:52 | amalloy | &(some #{4} (range 10)) |
| 23:52 | sexpbot | ⟹ 4 |
| 23:53 | amalloy | itistoday: see (iterate) and (take-while) - they should be a cleaner way to do what you want |
| 23:54 | amalloy | &(let [x {:p {:p {:p nil}}}] (take-while identity (iterate :p x))) |
| 23:54 | sexpbot | ⟹ ({:p {:p {:p nil}}} {:p {:p nil}} {:p nil}) |
| 23:55 | itistoday | amalloy: that's really elegant, thanks! |
| 23:56 | amalloy | itistoday: that gets you what you wanted, right? |
| 23:57 | itistoday | amalloy: yup, that seems to be exactly what i want, and it's much shorter and way more elegant |
| 23:58 | itistoday | i'm a n00b to clojure though so i'm not familiar yet with all of its functions... which is why i was toying with the primitive lazy-seq |
| 23:58 | amalloy | sure |