2011-03-17
| 00:00 | rata_ | I've used visualvm to detect the bottleneck... and it was that fn... but didn't know how to check if reflection was a bottleneck for that fn |
| 00:01 | technomancy | you should see a lot of clojure.lang.Reflector frames in the traces I think |
| 00:02 | technomancy | that code looks unlikely to reflect a lot since it doesn't look like it makes any Java method calls. pure Clojure shouldn't reflect. |
| 00:03 | amalloy | rata_: i doubt it will make a difference, but you could pull the multiplication from the inner loop up into the outer one, with (apply * rate (mapcat (fn [[mol freq]] [(get-molecule state mol) freq]) lhs)) |
| 00:03 | amalloy | that would probably reduce the amount of boxing and unboxing you do, since you call * in fewer places |
| 00:03 | technomancy | one thing you could do is switch to primitive math, another would be to use a transient map. |
| 00:04 | technomancy | you could also replace for with reduce to avoid laziness overhead |
| 00:04 | rata_ | how do I switch to primitive math in 1.2? or should I move to 1.3? |
| 00:05 | technomancy | 1.3 is only needed if you need your primitives to cross function boundaries |
| 00:06 | rata_ | ok, I think this is not the case |
| 00:06 | rata_ | then how do I use primitive math inside that fn? |
| 00:07 | amalloy | &(doc unchecked-add) |
| 00:07 | sexpbot | ⟹ "([x y]); Returns the sum of x and y, both int or long. Note - uses a primitive operator subject to overflow." |
| 00:07 | amalloy | &(doc int) |
| 00:07 | sexpbot | ⟹ "([x]); Coerce to int" |
| 00:07 | rata_ | &(doc long) |
| 00:07 | sexpbot | ⟹ "([x]); Coerce to long" |
| 00:08 | rata_ | perfect, so it should be (apply unchecked-math (long rate) (map long (mapcat ... lhs)))? |
| 00:09 | rata_ | or does that (map long ...) won't work? |
| 00:09 | symbole | Do clojure projects use the Spring framework in any extensive way? |
| 00:10 | amalloy | rata_: you'll lose the casting if you map it to long - it'll just be boxed it back up into a Seq full of Longs |
| 00:10 | amalloy | that would probably just make it slower |
| 00:12 | scottj | symbole: not unless they have to, from what I've seen |
| 00:12 | technomancy | symbole: never heard of anyone using Spring with clojure |
| 00:12 | amalloy | i don't have much experience with primitive optimization though so take my advice with a lot of skepticism here |
| 00:15 | rata_ | hmmm... then (unchecked-multiply (long rate) (reduce (fn [result [mol freq]] (unchecked-multiply (long result) (unchecked-multiply (long (get-molecule state mol)) (long freq)))) 1 lhs)) |
| 00:16 | rata_ | it'll anyway do some boxing and unboxing |
| 00:18 | rata_ | amalloy: are the math fns you mentioned before, those that throw an error when overflow, present in 1.2? |
| 00:18 | amalloy | i don't think so |
| 00:18 | rata_ | ok |
| 00:19 | rata_ | and does anyone know when 1.3 will be beta or stable? |
| 00:22 | amalloy | rata_: fwiw i just tried (reduce * (range 2 50)) and (reduce unchecked-multiply (map long (range 2 50))) |
| 00:22 | amalloy | unchecked-multiply is a bazillion times slower due to all the boxing |
| 00:23 | amalloy | clarify: it's a lot slower, and *i* think it's cause of the boxing |
| 00:23 | sproust | nrepl.el is born (5 minutes ago). |
| 00:24 | amalloy | sproust: neat |
| 00:25 | rata_ | amalloy: so maybe using unchecked-math before 1.3 is pointless? |
| 00:25 | sproust | Just mucking around with the protocol at this point. |
| 00:26 | amalloy | rata_: no, it's certainly faster in the right circumstances. i think this example would have the same behavior in 1.3 |
| 00:27 | rata_ | it shouldn't, because 1.3 doesn't box automatically, does it? |
| 00:27 | technomancy | rata_: 1.3 allows you to write functions that don't box their args |
| 00:28 | rata_ | ok |
| 00:28 | rata_ | I imagine that'd be very useful here |
| 00:28 | amalloy | but reduce will still have to box at every step, no? |
| 00:29 | amalloy | but would apply * work? |
| 00:31 | rata_ | amalloy: you could write your own reduce that doesn't box |
| 00:31 | amalloy | yes |
| 00:31 | rata_ | but I don't know if apply or reduce won't box by default |
| 00:32 | rata_ | in fact, I know very little about 1.3 features =P |
| 00:35 | scottj | is there a function you can call on x to see if it's a boxed or unboxed long? |
| 00:36 | tomoj | functions box their args (at least in 1.2) |
| 00:37 | scottj | sorry, in 1.3 |
| 00:40 | amalloy | isn't there a function somewhere to tell you what the compiler thinks of a sexp? |
| 00:41 | amalloy | i've seen chouser using it, and that's more or less the only way i can think of that you could use to see whether something is being treated as primitive |
| 01:10 | dsantiago | If you call seq on a map, you get a seq of vectors of key/value pairs. Is there a function to get a map back from that? |
| 01:11 | tomoj | there's into |
| 01:12 | tomoj | they're actually MapEntrys |
| 01:12 | tomoj | &(key [1 2]) |
| 01:12 | sexpbot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.util.Map$Entry |
| 01:12 | tomoj | &(key (first {1 2})) |
| 01:12 | sexpbot | ⟹ 1 |
| 01:13 | tomoj | but into will work with vectors too |
| 01:19 | amalloy | ugh. i've been trying to figure out how to get the compiler to analyze an expr for me. i've gotten as far as finding clojure.lang.Compiler$LetExpr$Parser, which *seems* to have a no-arg constructor, but if i try ##(clojure.lang.Compiler$LetExpr$Parser.) it doesn't work |
| 01:19 | sexpbot | java.lang.IllegalArgumentException: No matching ctor found for class clojure.lang.Compiler$LetExpr$Parser |
| 01:20 | amalloy | can anyone see why? Compiler.java has "new LetExpr.Parser()" in a scope that's not closing around anything, and LetExpr is a static inner class |
| 01:21 | dsantiago | tomoj, thanks! I knew about into, but didn't realize it did that. |
| 01:22 | tomoj | weird: ##(->> (range (* x 10) (* (inc x) 10)) (partition 2) (map vec) (into {}) (for [x (range 10)]) (into {})) |
| 01:22 | sexpbot | java.lang.IllegalArgumentException: Wrong number of args (3) passed to: core$for |
| 01:22 | tomoj | hmm |
| 01:22 | tomoj | well, that was a terrible way to illustrate the weirdness anyway |
| 01:23 | hiredman | amalloy: I thing there is a static analyze method on Compiler, I would see what that does |
| 01:23 | amalloy | tomoj: (for (big-old-expr) [x (range 10)] (into))... |
| 01:23 | tomoj | amalloy: works fine for me here |
| 01:23 | amalloy | hiredman: i couldn't figure out how to get an Expr object to pass it |
| 01:23 | tomoj | ,(->> (range (* x 10) (* (inc x) 10)) (partition 2) (map vec) (into {}) (for [x (range 10)]) (into {})) |
| 01:23 | clojurebot | {0 1, 32 33, 64 65, 96 97, 2 3, 34 35, 66 67, 98 99, 4 5, 36 37, ...} |
| 01:24 | tomoj | &(conj {} (map first [{1 2} {3 4} {5 6}])) |
| 01:24 | sexpbot | ⟹ {5 6, 3 4, 1 2} |
| 01:24 | tomoj | that's the weirdness |
| 01:25 | tomoj | so that (into {} s) where s is a seq of seqs of MapEntrys works, strangely |
| 01:25 | hiredman | amalloy: you can use the specials map near the top to get a Parser object for a given special form, then call .parse |
| 01:25 | amalloy | oh of course. why make my own when there's one right there. thanks |
| 01:26 | tomoj | amalloy: maybe the default constructor is not public? |
| 01:26 | amalloy | tomoj: it is though. none is specified at all |
| 01:26 | tomoj | right, those are public? |
| 01:27 | tomoj | seems its supposed to be the same as the class |
| 01:27 | tomoj | and the class isn't public |
| 01:28 | tomoj | ..or does that nested class inherit public from LetExpr? brings back bad memories of the java cert test |
| 01:29 | tomoj | &(into {} [{1 2} {3 4}]) |
| 01:29 | sexpbot | ⟹ {1 2, 3 4} |
| 01:29 | tomoj | maybe that's why it works? |
| 01:30 | amalloy | ,(.parse (get Compiler/specials 'let*) nil '([x 1] (long x))) |
| 01:30 | clojurebot | java.lang.IllegalArgumentException: Bad binding form, expected vector |
| 01:35 | amalloy | ,(.parse (get Compiler/specials 'let*) nil '(let [x 1] (long x))) |
| 01:35 | clojurebot | java.lang.NullPointerException |
| 01:50 | amalloy | devn: what? |
| 01:52 | rata_ | amalloy: it got better =) 65% now with mapcat and just one * |
| 01:52 | amalloy | hey cool. never would have guessed my suggestion was any good, there |
| 01:55 | rata_ | I'll try with reduce as well, but now it's time to sleep |
| 01:55 | rata_ | thank you amalloy =) |
| 01:56 | metadaddy1 | Anyone having problems with ring/ring-httpcore-adapter 0.3.7? |
| 01:56 | metadaddy1 | I was using it fine yesterday, now lein deps fails w a maven error |
| 01:56 | rata_ | I hope I get that fn to run fast, I think it shouldn't use more than 20% of the time |
| 01:57 | metadaddy1 | and it's missing from http://clojars.org/repo/ring/ring-httpcore-adapter/ |
| 01:57 | rata_ | but maybe I'm too optimistic |
| 01:57 | rata_ | see you guys, good night |
| 01:57 | metadaddy1 | http://clojars.org/repo/ring/ring-jetty-adapter/0.3.7/ is there |
| 02:10 | dnolen | brehaut: there you go, https://github.com/swannodette/bratko-logos/blob/master/src/bratko_logos/monkey_banana.clj in 18 lines of Clojure. |
| 02:10 | brehaut | dnolen: that is very nice |
| 02:11 | dnolen | now sleep |
| 02:12 | brehaut | dnolen: ive been pondering the existance of the move type symbols; are they strictly necessary? seems to me they only exist to clarify it for the humans |
| 02:12 | brehaut | dnolan: gnight |
| 02:36 | metadaddy1 | figured it out, I think |
| 02:56 | letronje | had a n00b doubt |
| 02:56 | waxrosecabal | amalloy, Does lein actually install 1.3 and swank-clojure or is it just for dependencies? |
| 02:56 | letronje | (defn test [n] (do (println "\ntrying " n "\n") (> n 2))) |
| 02:56 | letronje | (first (filter test [1 2 3 4 5 6 7 8 9 10])) |
| 02:57 | letronje | if filter is lazy, why does it go through the entire the vector after it finds 3 ? |
| 02:57 | amalloy | &(class (seq [1 2 3 4])) |
| 02:57 | sexpbot | ⟹ clojure.lang.PersistentVector$ChunkedSeq |
| 02:58 | amalloy | letronje: vectors are chunked |
| 02:59 | amalloy | not sure why that's actually related to your question though, now that i think about it |
| 02:59 | letronje | exactly :) |
| 03:00 | tomoj | &(class (next (filter identity [1 2 3]))) |
| 03:00 | sexpbot | ⟹ clojure.lang.ChunkedCons |
| 03:00 | tomoj | filter preserves chunkiness |
| 03:00 | amalloy | like donuts |
| 03:01 | letronje | is there a function that lets me apply a predicate on a sequence and return the first item in the sequence for which it is true ? |
| 03:02 | amalloy | (comp first filter) |
| 03:02 | letronje | ((comp first filter) test [1 2 3 4 5 6 7 8 9 10]) ? |
| 03:03 | amalloy | that would work |
| 03:03 | letronje | @amalloy: I still see 10 prints |
| 03:03 | amalloy | usually it's written as (first (filter ...)), but it really should be its own function |
| 03:03 | letronje | i wanted something like some |
| 03:03 | amalloy | like tomoj said, filter preserves chunkiness |
| 03:04 | tomoj | letronje: is the problem that you're actually doing side effects? or that applying the pred to a whole chunk is too slow? |
| 03:04 | letronje | the actual predicate that i plan to give to filter is costly ( CPU + IO ) |
| 03:05 | letronje | so i want it to immediately stop once it finds it |
| 03:05 | amalloy | letronje: the easy solution is not to give it something it *can* chunk |
| 03:05 | amalloy | ie not a vector |
| 03:05 | tomoj | sounds strange. but I think there's an unchunker somewhere? |
| 03:06 | amalloy | there is |
| 03:06 | amalloy | &(filter (juxt identity println) (range 4)) |
| 03:06 | sexpbot | ⟹ (01230 1 2 3) |
| 03:06 | amalloy | &(filter (juxt identity println) [0 1 2 3]) |
| 03:06 | sexpbot | ⟹ (01230 1 2 3) |
| 03:06 | amalloy | &(filter (juxt identity println) '(0 1 2 3)) |
| 03:06 | sexpbot | ⟹ (010 21 32 3) |
| 03:07 | amalloy | &(first (filter (juxt identity println) '(0 1 2 3))) |
| 03:07 | sexpbot | ⟹ 0 0 |
| 03:07 | amalloy | &(first (filter (juxt identity println) [0 1 2 3])) |
| 03:07 | sexpbot | ⟹ 0 1 2 3 0 |
| 03:08 | amalloy | would have been a better demo :P |
| 03:08 | letronje | not sure i understand, n00b here |
| 03:09 | amalloy | the point is that only vectors and (range) are chunked currently, i think |
| 03:09 | brehaut | letronje: its confused because the println and the result are on the same line |
| 03:09 | amalloy | so if you filter on something that is neither of those, it won't chunk, and it will be as lazy as you want |
| 03:09 | brehaut | &(let [n 1] (println n) (println "this is the return >") n) |
| 03:09 | sexpbot | ⟹ 1 this is the return > 1 |
| 03:09 | tomoj | letronje: what's the IO? |
| 03:09 | letronje | yup |
| 03:10 | letronje | tomoj: network IO |
| 03:10 | tomoj | I mean, what is it |
| 03:10 | tomoj | what are you actually doing? just curious |
| 03:10 | letronje | scraping a url |
| 03:10 | tomoj | yeah, having that inside the pred seems fishy to me anyway |
| 03:11 | tomoj | though an alternative doesn't quickly spring to mind |
| 03:11 | letronje | a set works |
| 03:11 | amalloy | my irc client hates me. going to bed before it gets worse |
| 03:11 | letronje | ((comp first filter) test #{1 2 3 4 5 6 7 8 9 10}) |
| 03:11 | letronje | prints only till 3 |
| 03:12 | amalloy | letronje: sets do not maintain order |
| 03:12 | amalloy | &(class (list* [1 2 3])) |
| 03:12 | sexpbot | ⟹ clojure.lang.PersistentVector$ChunkedSeq |
| 03:12 | amalloy | dang it |
| 03:12 | letronje | yes, just validated that they are not chunked :) |
| 03:12 | amalloy | &(class (apply list [1 2 3])) |
| 03:12 | sexpbot | ⟹ clojure.lang.PersistentList |
| 03:13 | amalloy | &(filter (juxt println identity) (apply list [1 2 3])) |
| 03:13 | sexpbot | ⟹ (121 32 3) |
| 03:13 | amalloy | &(first (filter (juxt println identity) (apply list [1 2 3]))) |
| 03:13 | sexpbot | ⟹ 1 1 |
| 03:13 | amalloy | so you can use apply list to unchunk something, too |
| 03:13 | letronje | ok |
| 03:14 | letronje | thnx |
| 03:14 | letronje | what does juxt do btw ? |
| 03:15 | tomoj | doesn't it seem like the fact that these problems happen suggests you aren't supposed to do this? |
| 03:15 | letronje | &(map (juxt println identity) [1 2 3 4 5 6 7 8 9 10]) |
| 03:15 | sexpbot | ⟹ (12345678910[nil 1] [nil 2] [nil 3] [nil 4] [nil 5] [nil 6] [nil 7] [nil 8] [nil 9] [nil 10]) |
| 03:15 | tomoj | but how else would you do it? |
| 03:15 | letronje | (loop (recur )) ? |
| 03:16 | tomoj | basically reimplement filter without the chunking.. that doesn't seem right either :( |
| 03:16 | brehaut | letronje: it takes n functions and returns a new function; that new function passes all the arguments to all the functions returning a vector of the results |
| 03:16 | brehaut | letronje: it juxtaposes the functions :) |
| 03:16 | brehaut | &(juxt inc dec) |
| 03:16 | sexpbot | ⟹ #<core$juxt$fn__3661 clojure.core$juxt$fn__3661@1354d59> |
| 03:16 | brehaut | sexpbot: thanks |
| 03:16 | brehaut | &((juxt inc dec) 1) |
| 03:16 | sexpbot | ⟹ [2 0] |
| 03:17 | letronje | ah |
| 03:17 | letronje | interesting :) |
| 03:17 | letronje | why use identity ? |
| 03:18 | letronje | oh ok got it |
| 03:18 | letronje | so that filter gets the orig value ? |
| 03:18 | brehaut | (defn dechunk [xs] (lazy-seq (when xs (cons (first xs) (dechunk (rest xs)))))) ? |
| 03:18 | tomoj | won't that blow the stack? |
| 03:19 | brehaut | tomoj: lazy-seq should avoid that shouldnt it? |
| 03:19 | tomoj | er, infinite seq I mean? |
| 03:19 | tomoj | need next instead of rest or (when (seq xs)) or both, I think |
| 03:19 | brehaut | tomoj: i dunno thats just a naive first guess |
| 03:19 | brehaut | you are correct |
| 03:20 | brehaut | lets go with both. |
| 03:20 | letronje | &(map (juxt inc dec) [ 1 2 3 4 5 6 7 8 9]) |
| 03:20 | sexpbot | ⟹ ([2 0] [3 1] [4 2] [5 3] [6 4] [7 5] [8 6] [9 7] [10 8]) |
| 03:21 | tomoj | right, with next but without seq (dechunk []) is (nil) |
| 03:21 | letronje | &(filter (juxt inc dec) [ 1 2 3 4 5 6 7 8 9]) |
| 03:21 | sexpbot | ⟹ (1 2 3 4 5 6 7 8 9) |
| 03:21 | letronje | &(filter (juxt inc dec) [ 1 2 3 4 nil 5 6 7 8 9]) |
| 03:21 | sexpbot | java.lang.NullPointerException |
| 03:21 | letronje | &(filter (juxt inc dec) [ 1 2 3 4 false 5 6 7 8 9]) |
| 03:21 | sexpbot | java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Number |
| 03:23 | brehaut | &(letfn [(dechunk [xs] (lazy-seq (when (seq xs) (cons (first xs) (dechunk (next xs))))))] (first (map prn (dechunk (iterate inc 1))))) |
| 03:23 | sexpbot | ⟹ 1 nil |
| 03:23 | brehaut | have i dont something to upset sexpbot? |
| 03:23 | brehaut | tomoj: that seems to work |
| 03:24 | brehaut | (in terms of not blowing the stack to bits on lazy seqs) |
| 03:24 | brehaut | im sure there is something dumb about how it works though |
| 03:24 | tomoj | I had thought the unchunker I remembered seeing was more mysterious |
| 03:24 | brehaut | tomoj: yeah exactly |
| 03:25 | tomoj | only problem I can think of though is lazy seq overhead which is no problem here |
| 03:25 | tomoj | and anyway, how could any unchunker not have that overhead? |
| 03:26 | tomoj | sort of the point I guess |
| 03:26 | brehaut | im going to dig into joy of clojure |
| 03:27 | brehaut | i think chouser has one |
| 03:27 | brehaut | tomoj: the unchunker in JoC appears to reify clojure.lang.ISeq |
| 03:27 | brehaut | tomoj: and its called seq1 apparently |
| 06:19 | ZabaQ | intetesting.. |
| 06:28 | ZabaQ | what's this -SNAPSHOT business in the version names? |
| 06:29 | angerman | I assume it's autogenerated (e.g. on a daily basis) stuff from the head of the dev. branch. |
| 06:29 | raek | they act as in-between version numbers |
| 06:29 | waxrosecabal | Basically a nightly build? |
| 06:30 | raek | yes |
| 06:30 | raek | a non-snapshot version of a project should not have snapshot dependencies |
| 06:31 | waxrosecabal | Do you know if the clojure-install from Emacs pulls from the snapshot? |
| 06:31 | raek | Leiningen will always check for new versions of a snapshot dependency when doing lein deps, even if there is a version is in the cache |
| 06:31 | waxrosecabal | hmm |
| 06:32 | raek | waxrosecabal: swank-clojure.el (which contains clojure-install) is old and deprecated |
| 06:33 | waxrosecabal | Man, I think every installation process I've found has been deprecated. :/ |
| 06:33 | raek | these things changed substantially when Leiningen appeared |
| 06:35 | raek | my emacs installation routine: install clojure-mode, slime and slime-repl using package.el and technomancy's repo (included with emacs-starter-kit) |
| 06:35 | raek | add [swank-clojure "1.2.1"] to :dev-dependencies and start a swank server with "lein swank" |
| 06:35 | raek | connect to it from emacs with M-x slime-connect |
| 06:36 | raek | (this assumes you have leiningen and a created a project with it) |
| 06:36 | raek | and that's basically it. |
| 06:36 | waxrosecabal | Cool, thanks. I was just a little confused at lein's roll. |
| 06:36 | raek | I use technomancy's durendal to start the swank server nowaday |
| 06:37 | raek | just run M-c durendal-jack-in when you have a source file of the project open |
| 06:37 | raek | *M-x |
| 06:37 | raek | so that replaces the "lein swank" step |
| 06:38 | waxrosecabal | I'll try that in a little bit. Thanks. Need to update my notes. :P |
| 06:39 | waxrosecabal | Do you have any experience with Clojure on Google App Engine? |
| 06:40 | waxrosecabal | If so, thoughts? |
| 06:40 | raek | not yet :) |
| 06:40 | raek | only ring + moustache + enlive (and a little bit of compojure + hiccup) |
| 06:41 | raek | I've heard that you use the ring stack for the servlet part of a GAE app |
| 06:42 | waxrosecabal | I was going to give Compojure a try first since I've seen a mini guide about it. And yeah, that is what I believe is used. |
| 06:42 | waxrosecabal | mini guide on GAE* |
| 06:44 | raek | this sums up my workflow with the ring stack: http://groups.google.com/group/clojure/browse_thread/thread/4d8a1fc669a5a2df/9a7551ecfc851309?lnk=gst&q=rasmus+app+engine#9a7551ecfc851309 |
| 06:44 | raek | some of it could be useful for GAE development |
| 06:46 | waxrosecabal | Thanks for the link. |
| 06:47 | waxrosecabal | Yeah, looks helpful already. |
| 07:01 | joelr | technomancy: ping |
| 07:31 | hsuh | does the - in (defn -main..) has any meaning to the reader, or its just convention? |
| 07:32 | clgv | it needs to be there in case you create a jar and want it to be the main-method called |
| 07:32 | hsuh | can it be main instead of -main ? |
| 07:33 | angerman | (or want it to be the entry point for $ lein run -m package.class) |
| 07:33 | clgv | hsuh: I dont think so. you can only specify the namespace that contains -main in leiningen afaik |
| 07:33 | hsuh | ok |
| 07:34 | clgv | it doesnt hurt much anyway, I think ;) |
| 07:36 | hsuh | about that, in my top directory i have src/ and script/, and script/ has run.clj inside, which runs swank and then my -main... but after updating lein, i'm getting "Caused by: java.io.FileNotFoundException: Could not locate script/run__init.class or script/run.clj on classpath" |
| 07:36 | hsuh | i'm trying lein run -m script.run (i used to do lein run script/run.clj) |
| 07:37 | angerman | seems like a classpath issue. no? |
| 07:37 | angerman | lein has a command to show the classpath it thinks is correct. iirc. |
| 07:37 | angerman | e.g. $ lein classpath |
| 07:38 | angerman | so that should at least contain "." |
| 07:38 | hsuh | ok, but i thought lein was useful exactly because it handled that :) |
| 07:40 | angerman | I don't know what is with your lein. Haven't had a problem myself. |
| 07:40 | hsuh | lein version ? |
| 07:41 | angerman | 1.4.2 |
| 07:41 | hsuh | ok, same here.. |
| 07:42 | clgv | I guess it doesnt know about your scrip directory |
| 07:43 | angerman | if script was in src. I assume it would work. |
| 07:43 | clgv | is "script" a default leiningen directory? |
| 07:43 | clgv | yeah then it definitely should |
| 07:47 | hsuh | does you run.clj file has a (ns..) declaration? (mine doesnt) |
| 07:48 | clgv | that might be an issue. shouldnt every regular clj-file have an ns declaration? clojure config files lik project.clj excluded |
| 07:58 | clgv | I am tempted to use some sort of callback function for a deftype. this callback is specific problem dependent behavior which can't be determine by the general implementation. Is there a better or more idiomatic way to do this in clojure? |
| 08:06 | hsuh | angerman, clgv: yeah, adding an ns and putting the file into src/ works, i liked the older organization though.. but its time to be pragmatic ......... |
| 08:06 | hsuh | but ty |
| 08:08 | raek | hsuh: "-" is the default prefix for gen-class. you can override it with the :prefix option: http://clojuredocs.org/clojure_core/clojure.core/gen-class |
| 08:09 | hsuh | oh, interesting... thanks. i wont change it, just wanted to understand where did it came frmo |
| 08:09 | clgv | hsuh: there is :repl-init-script option for leiningen. see https://github.com/technomancy/leiningen/blob/stable/sample.project.clj |
| 08:09 | hsuh | great, i can develop with lein repl than! thanks! |
| 08:09 | raek | hsuh: leiningen run feature is a bit different (and opinionated) when compared to the lein-run plugin |
| 08:09 | hsuh | 8then |
| 08:09 | hsuh | *then |
| 08:10 | hsuh | raek: leiningen also has run? now i dont know if im using the plugin or not... |
| 08:10 | raek | from your description it looks like you have the built in one |
| 08:10 | hsuh | that explains a lot... |
| 08:10 | raek | i.e. lein run takes a namespace as a parameter rather than a file |
| 08:11 | raek | and loads plus calls -main, instead of just loading it |
| 08:11 | hsuh | sure, i get it now.. thats why things "changed" so much.. after updating i stopped using the plugin and started using lein's run... |
| 08:11 | raek | heh |
| 08:20 | angerman | hm. Is there a funtion that takes a list of bool and return if all are true? |
| 08:20 | angerman | e.g. (apply and lst) but that doesn't work iirc. |
| 08:20 | angerman | ,(apply and [true true true]) |
| 08:20 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/and |
| 08:23 | clgv | $findfn [true true true] true |
| 08:23 | sexpbot | [clojure.core/== clojure.core/sequential? clojure.core/second clojure.core/last clojure.core/reversible? clojure.core/distinct? clojure.core/boolean clojure.core/vector? clojure.core/counted? clojure.core/associative? clojure.core/< clojure.core/peek clojure.core/fir... http://gist.github.com/874233 |
| 08:24 | angerman | $findfn [true true true false true] false |
| 08:24 | sexpbot | [clojure.core/keyword? clojure.core/chunked-seq? clojure.core/fn? clojure.core/not= clojure.core/nil? clojure.core/string? clojure.core/sorted? clojure.core/false? clojure.core/true? clojure.core/symbol? clojure.core/number? clojure.core/integer? clojure.core/seq? cl... http://gist.github.com/874235 |
| 08:24 | angerman | no. |
| 08:24 | angerman | ,(every? identity [true true true]) |
| 08:24 | clojurebot | true |
| 08:24 | clgv | hm ok not the appropriate use case for that findfn |
| 08:25 | clgv | ,(every? [true true true]) |
| 08:25 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$every-QMARK- |
| 08:25 | angerman | every? expects a predicate |
| 08:25 | clgv | ,(find-doc "all") |
| 08:25 | clojurebot | ------------------------- |
| 08:25 | clojurebot | clojure.contrib.seq/fill-queue |
| 08:25 | clojurebot | ([filler-func & optseq]) |
| 08:25 | clojurebot | filler-func will be called in another thread with a single arg |
| 08:25 | clojurebot | 'fill'. filler-func may call fill repeatedly with one arg each |
| 08:25 | clojurebot | time which will be pushed onto a queue, blocking if needed until |
| 08:25 | clojurebot | this is possible. fill-queue will return a lazy seq of the values |
| 08:25 | clojurebot | filler-func has pushed onto the queue, blocking i... |
| 08:27 | clgv | $help findfn |
| 08:27 | sexpbot | clgv: Finds the clojure fns which, given your input, produce your output. |
| 08:28 | angerman | findfn need more predicates. e.g. given 3 inputs and expected outputs. |
| 08:28 | clgv | yep^^ |
| 08:28 | angerman | Something is weird. My radio clock on the wall is spinning since 9 o'clock. |
| 08:29 | angerman | There must be some issue with the signal. |
| 09:19 | angerman | Japan looks /really/ bad. |
| 09:19 | Fossi | in general? |
| 09:20 | angerman | well, about half a week ago, i thought there was a chance that this could end semi-lucky. |
| 09:21 | angerman | but since then, I'm loosing faith in the success by the hour :/ |
| 09:25 | angerman | Fossi: and in general, that's going to be a very hard setback for japan. High devastation, radiation, national depth at 200% and rising :( |
| 09:25 | __name__ | amalloy_: Is sexpbot FOSS? |
| 09:26 | Fossi | so far the radiation is really low |
| 09:26 | __name__ | angerman: *debt? |
| 09:26 | Fossi | if there hasn't been something big happening in the last hour |
| 09:27 | angerman | Fossi: I guess the question is where and whom you ask. The graphs near the plant look really bad. |
| 09:27 | angerman | __name__: yes. |
| 09:27 | angerman | Fossi: and what are you going to do with the plant's region and it's sourrounding? |
| 09:28 | Fossi | guess it depends on what's "really bad" to you |
| 09:28 | Fossi | the highest reading i heard of was 900mSv |
| 09:29 | Fossi | that won't even cause sustained damage really |
| 09:29 | Fossi | and that was like 3 days ago |
| 09:30 | angerman | Fossi: mSv or muSv? |
| 09:30 | Fossi | mSv |
| 09:31 | Fossi | since you are german: http://www.grs.de/informationen-zur-lage-den-japanischen-kernkraftwerken-fukushima-onagawa-und-tokai |
| 09:31 | Fossi | is a really good summary |
| 09:31 | angerman | Fossi: yep, that's what I'm reading. |
| 09:31 | Fossi | highest reading at the frontdoor was something like 12mSv |
| 09:35 | angerman | Fossi: yes. But what happens to the particles that got in the air, as far as I understand, depending on what escapes it's halflife is from 8 days to multiple years. |
| 09:36 | angerman | Fossi: I understand that there was an elevated radiation level in the athmosphere during the time of atomic bomb tests. |
| 09:40 | Fossi | well, atomic bomb test are something entirely different from this |
| 09:40 | Fossi | and from the readings it's so far pretty obvious that not a whole lot of radioactive material has "escaped" the containments |
| 09:41 | Fossi | the higher readings are from venting the containment |
| 09:42 | choffstein | Does clojure have pattern matching besides multi-methods (e.g. a 'match' method or something similar)? |
| 09:42 | choffstein | My google-fu is failing me for a concrete answer |
| 09:43 | choffstein | Basically, I want my method to do one thing when an input is an empty list, and another when the list has objects in it |
| 09:43 | wtetzner | you can use cond |
| 09:44 | raek | choffstein: well, you have cond, case and (unconditional) destructuring, but nothing like matching in Haskell or Scala |
| 09:44 | wtetzner | (cond (empty? lst) do-something :else do-something-else) |
| 09:44 | choffstein | So just cond and destructure then? |
| 09:44 | raek | if-let can be useful too |
| 09:45 | raek | ...in some cases |
| 09:46 | choffstein | hmmm, okay, thanks |
| 09:46 | raek | choffstein: also, check out https://github.com/dcolthorp/matchure |
| 09:47 | angerman | hmm… http://www.brool.com/index.php/pattern-matching-in-clojure ?! |
| 09:47 | angerman | that's been the first google result for me. |
| 09:54 | raek | I like the syntax of that one |
| 09:54 | raek | (https://github.com/brool/clojure-misc) |
| 09:57 | angerman | it looks a little more like the pattern matching syntax I'm used to then matchure looks. |
| 09:58 | raek | I wonder if it supports [a & d] patterns |
| 10:02 | raek | heh, the documentation does not mention which namespace to use |
| 10:04 | tmountain | if you have a bunch of items in a collection and want to dispatch a function based upon some characteristic of the item, would it be more idiomatic to use protocols and types or something like multimethods? |
| 10:05 | raek | with protocols, you can only dispatch on the type of the first argument |
| 10:06 | raek | multimethods can dispatch on anything |
| 10:08 | raek | (use 'pattern-match) (match [1 2 3] [fst & rst] rst) => (2 3) |
| 10:10 | tmountain | are protocols intended more as a Java bridge technology, or are they first-class citizens IRT program design. for some context, I'm messing around with some basic game logic. when the game server "heartbeat" occurs, all entities in the game need to respond |
| 10:11 | tmountain | I could wrap all that up in a protocol and guarantee that the objects can respond to the event, but I wonder if I'm straying too far from FP design principles there...? |
| 10:11 | angerman | tmountain: clojure is not pure fp |
| 10:12 | raek | they are intended to be a more performant, but restricted, variant of multimethods (with grouping of methods) |
| 10:12 | raek | but they are not a mere interop feature |
| 10:13 | tmountain | angerman: yeah, I know, it's more pragmatic, I just tend to want to treat it as such |
| 10:14 | tmountain | raek: that makes sense, so as long as I'm content with being restricted to dispatching on the first argument, protocols are a good choice? |
| 10:14 | angerman | tmountain: my render should be able to render points, edges and faces. So I could either write structmaps or records and multimehtods to allow one method `render' to work for all, or just go the protocol way. |
| 10:14 | angerman | the letter one looks cleaner. |
| 10:14 | angerman | https://github.com/angerman/planarity/blob/master/src/geometry/renderer.clj |
| 10:17 | raek | tmountain: I haven't done much design using protocols, so I simply do not know... |
| 10:18 | raek | but to me it sounds like protocols is a language feature that could indeed be used to solve yout problem |
| 10:18 | tmountain | angerman: what does the _ argument to the protocol method signatures imply? |
| 10:18 | angerman | well _ is just a throw away place holder. |
| 10:18 | tmountain | raek: no worries, you've been helpful in helping me draw distinctions between strategies |
| 10:18 | angerman | tmountain: could be `this' or `self' as well. |
| 10:18 | tmountain | angerman: basically a placeholder for "this" or the first arg |
| 10:18 | tmountain | ok |
| 10:19 | tmountain | thanks guys |
| 10:19 | raek | that name is what you see in the arglist in the docs (or in the minibuffer of emacs) |
| 10:20 | raek | (hrm, don't know whether autodoc actually supports protocols as a doc source) |
| 10:22 | joelr | good day! how do i find the latest version of composure to depend on? |
| 10:22 | joelr | same for lein-ring for that matter |
| 10:30 | raek | joelr: I usually look in the project.clj of the project (if it's on github, for example) or at http://clojars.org/repo/ |
| 10:30 | joelr | raek: thanks! |
| 10:33 | raek | (also, do not use SNAPSHOT dependencies when releasing non-snapshot versions of you project) |
| 10:48 | choffstein | If I have two lists of maps that are identified by a unique key, like [{:a 5, :b 6} {:a 6, :b 5}] and [{:a 5, :c 7} {:a 6, :c 8}, is there any way to combine them by unique key to get a list that is: [{:a 5 :b 6 :c 7} {:a 6 :b 5 :c 8}]? |
| 11:06 | joly | ,(map into [{:a 5, :b 6} {:a 6, :b 5}] [{:a 5, :c 7} {:a 6, :c 8}]) |
| 11:06 | clojurebot | ({:a 5, :b 6, :c 7} {:a 6, :b 5, :c 8}) |
| 11:06 | joly | choffstein: ^ but I'm not sure that solves the problem you're asking |
| 11:06 | raek | ,(map merge [{:a 5, :b 6} {:a 6, :b 5}] [{:a 5, :c 7} {:a 6, :c 8}]) |
| 11:06 | clojurebot | ({:c 7, :a 5, :b 6} {:c 8, :a 6, :b 5}) |
| 11:08 | clgv | ,(map merge [{:a 5, :b 6} {:a 6, :b 5}] [{:a 5, :c 7} {:a 7, :c 8}]) |
| 11:08 | clojurebot | ({:c 7, :a 5, :b 6} {:c 8, :a 7, :b 5}) |
| 11:08 | clgv | is that intended or did you look for a join-semantic? |
| 11:09 | devn | damn beat me to it |
| 11:11 | choffstein | awesome. thanks! |
| 11:15 | clgv | choffstein: thats ok for you? ##(merge {:a 1, :b 5} {:a 999, :c 8}) |
| 11:15 | sexpbot | ⟹ {:c 8, :a 999, :b 5} |
| 11:17 | choffstein | Hmm, on second thought, not quite. |
| 11:17 | choffstein | I need to be able to define the key I am merging on |
| 11:18 | clgv | it's just merging the maps. it has no sql-like join semantics on any of the keys |
| 11:18 | clojurebot | maps are functions |
| 11:18 | clgv | clojurebot: a cookie for you |
| 11:18 | clojurebot | It's greek to me. |
| 11:19 | choffstein | i think I might have it |
| 11:19 | elegant_knight | ;this may not be a clean way.. do it do the job? |
| 11:19 | elegant_knight | (defn merge-map-lists |
| 11:20 | elegant_knight | "merges the 2 lists of maps" |
| 11:20 | elegant_knight | [list1 list2] |
| 11:20 | elegant_knight | (let [merged (merge (first list1) (first list2))]) |
| 11:20 | elegant_knight | (if (or (= (count list1) 1) (= (count list2) 1)) |
| 11:20 | elegant_knight | (cons merged []) |
| 11:20 | elegant_knight | (cons merged (merge-map-lists (rest list1) (rest list2))))) |
| 11:22 | angerman | why is it `every?' and `some'? |
| 11:22 | clgv | angerman: pure evilness ;) |
| 11:24 | raek | angerman: some not only checks whether there is an element, but can also return it |
| 11:24 | clgv | choffstein: you could use merge-with I guess ##(doc merge-with) |
| 11:24 | sexpbot | ⟹ "([f & maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping(s) from the latter (left-to-right) will be combined with the mapping in the result by calling (f val-in-result val-in-latter)." |
| 11:27 | raek | choffstein: map merge will take the first map of the left list and the first map of the right list and merge them. did you want to merge one the value for a certain key, rather than on the position in the list= |
| 11:27 | raek | ? |
| 11:50 | amalloy | (cons foo []) is the same as (list foo) |
| 11:53 | elegant_knight | amalloy:got it! |
| 11:54 | elegant_knight | i have a list of values. i want to find the index of maximum value in that. whats the easiest way to do it |
| 11:54 | scottj | why does https://gist.github.com/874276 call shutdown-agents if there's no call to agent in the code? |
| 11:56 | mrBliss | ,(let [l [1 2 3 2]] (.indexOf l (reduce max l))) |
| 11:56 | clojurebot | 2 |
| 11:57 | mrBliss | ,(let [l [1 2 3 2]] (apply max-key l (range 0 (count l)))) |
| 11:57 | clojurebot | 2 |
| 11:58 | mrBliss | elegant_knight: ^^ |
| 12:00 | mrBliss | The second one is 3x faster than the first (on my machine) |
| 12:00 | jkkramer | only works on vectors |
| 12:00 | mrBliss | jkkramer: correct |
| 12:01 | ounce | hi |
| 12:03 | jkkramer | scottj: previous versions appeared to use pmap, which uses futures, which use the agents thread pool |
| 12:06 | mrBliss | ,(loop [l '(1 2 3 2), i 0, max -1, max-i -1] (if-let [[head & tail] l] (if (> head max) (recur tail (inc i) head i) (recur tail (inc i) max max-i)) max-i)) |
| 12:06 | clojurebot | 2 |
| 12:06 | mrBliss | Ugly loop, but faster than the previous two |
| 12:09 | scottj | jkkramer: ok that's what I thought |
| 12:10 | elegant_knight | mrBliss : thanks. i have a lazy sequence. so the first way of using .indexOf worked just fine.. second one looks elegant! |
| 12:14 | angerman | is there any logic faillure in (defn any? [pred coll] (every? (complement pred) coll)) ? |
| 12:15 | clgv | angerman: yes. you determine "none?" since you have an "and" over all negated predicates |
| 12:15 | amalloy | more of a vocab failure than a logic failure :) |
| 12:16 | angerman | yea right. fail's on me. |
| 12:17 | clgv | you want to know if not all predicate applications are false? |
| 12:17 | angerman | clgv: as in: (if (none? impossible […])) |
| 12:18 | angerman | hmm that's none? impossible? :D |
| 12:19 | mrBliss | ,(find-doc #"not-.+\?") |
| 12:19 | clojurebot | ------------------------- |
| 12:19 | clgv | you'll get true in your definition for the case that at least one predicate is true when you negate the every? like (not (every? ...)) |
| 12:19 | clojurebot | clojure.core/not-any? |
| 12:19 | clojurebot | ([pred coll]) |
| 12:19 | clojurebot | Returns false if (pred x) is logical true for any x in coll, |
| 12:19 | clojurebot | else true. |
| 12:19 | clojurebot | ------------------------- |
| 12:19 | clojurebot | clojure.core/not-every? |
| 12:19 | clojurebot | ([pred coll]) |
| 12:19 | clojurebot | Returns false if (pred x) is logical true for every x in |
| 12:19 | clojurebot | coll, else true. |
| 12:20 | angerman | there's not-any? wtf. |
| 12:20 | jkkramer | (def any? (comp boolean some)) |
| 12:21 | angerman | ,(some nil? [nil nil nil]) |
| 12:21 | clojurebot | true |
| 12:22 | clgv | angerman: yeah that logic what functions to include there is a bit inconsistent ;) |
| 12:22 | angerman | clgv: I'm getting confused with them too often :/ |
| 12:28 | clgv | wrtie your own "some?" and you are safe ;) |
| 12:47 | angerman | is ^ still the meta reader macro? |
| 12:47 | angerman | ,(:foo ^(with-meta 'x {:foo 'y})) |
| 12:47 | clojurebot | Metadata must be Symbol,Keyword,String or Map |
| 12:47 | fogus`away | ,(doc meta) |
| 12:47 | clojurebot | "([obj]); Returns the metadata of obj, returns nil if there is no metadata." |
| 12:48 | angerman | ok, so I need to use (meta ...) |
| 12:59 | dakrone | is there a way to make a non-seqable string easily? |
| 13:00 | amalloy | dakrone: waaaat? |
| 13:00 | dakrone | I'll take that as a "no one needs that so you're doing it wrong" |
| 13:01 | amalloy | dakrone: well i don't understand what it is you want |
| 13:02 | amalloy | $mail choffstein see also not-empty for your empty-list-finding needs: (if-let [l (not-empty input)] (do stuff with l) (whoops input was empty)) |
| 13:02 | sexpbot | Message saved. |
| 13:03 | amalloy | you want a sequence of characters that can't be treated as a sequence of characters, is all i can get from the original question. i'd say maybe use ##(symbol "some-string"), which keeps all the information and makes it non-seqable, but it's a weird thing to do |
| 13:03 | sexpbot | ⟹ some-string |
| 13:03 | raek | dakrone: there is no way to have something that is a java.lang.String that noone can call seq on |
| 13:03 | dakrone | nevermind, I was doing it wrong, as I suspected |
| 13:03 | amalloy | *chuckle* |
| 13:04 | raek | the question is, what problem is non-seqable string the solution for? |
| 13:06 | dakrone | missing a [] in a lazy-seq and staring at it too long, that's what |
| 13:45 | mattmitchell | i'm trying to create a wrapper around 2 functions that are together like this: (sql/with-connection db-conn (sql/with-query-results res ["my query"]) ...) |
| 13:46 | mattmitchell | the problem is that the with-query-results is a macro and creates "res" -- so I'm not sure how to handle it? |
| 13:47 | mattmitchell | as a first try, this doesn't work: https://gist.github.com/874777 |
| 13:51 | amalloy | mattmitchell: your function will have to be a macro |
| 13:51 | mattmitchell | amalloy: ok i was kinda thinking that |
| 13:52 | amalloy | also did you intend to throw away the query arg? |
| 13:52 | mattmitchell | amalloy: woops, no |
| 13:53 | amalloy | anyway it probably looks basically like (defmacro wqr [query form] `(sqlwc db/conn (sql/wqr ~'res ~query ~@form))) |
| 13:54 | raek | mattmitchell: you can also do something like this: (defn with-query-results [query f] (... (sql/with-query-results res (f res)))) |
| 13:55 | amalloy | good point |
| 13:56 | mattmitchell | raek: right thanks |
| 13:56 | raek | macros really are contagious... this way you can "kill it to keep it from spreading" |
| 13:57 | mattmitchell | raek: i've just barely scratched the surface of macros, it will be a while until i "get" it :) |
| 13:58 | mattmitchell | thanks amalloy |
| 13:58 | amalloy | haha |
| 14:42 | rcadena | 1 |
| 15:08 | mrBliss | k |
| 16:01 | khaliG | hm ive noticed lein uberjar isn't including the jars in lib/dev .. is this normal? |
| 16:03 | Null-A | khaliG: if I had to guess, yes |
| 16:03 | khaliG | ok well that would explain why my jar doesn't work :) |
| 16:04 | Null-A | khaliG: dev dependencies would be like swank server or lein extensions |
| 16:04 | khaliG | ahhh! ok |
| 16:04 | khaliG | so maybe i need to rewrite my project.clj file |
| 16:04 | Null-A | sounds like it |
| 16:04 | khaliG | thank you! |
| 16:04 | Null-A | you could probably put testing dependencies in dev-dependencies too |
| 16:09 | khaliG | hm there is one library which i can't move out from dev .. clj-time |
| 16:09 | khaliG | http://clojars.org/clj-time .. seems it has to be the snapshot? |
| 16:11 | raek | khaliG: yup. they should release a stable version. |
| 16:11 | khaliG | ah damn, so i can't make a jar until they do :/ |
| 16:11 | raek | khaliG: you can, but your project has to be a snapshot version too |
| 16:11 | khaliG | i see |
| 16:13 | raek | khaliG: you could also reate an issue for it, so that they become aware of that this is a problem for people |
| 16:13 | raek | https://github.com/getwoven/clj-time/issues |
| 16:14 | khaliG | i will do that now cheers |
| 16:15 | raek | (a completely different alternative is to use joda-time directly using java interop. in many cases it's just a matter of calling .fooBarBaz insead of boo-bar-baz, since joda-time is very compatible with the clojure philosophy) |
| 16:18 | khaliG | raek, hm i'd rather not do that, i use it quite heavily :/ |
| 16:22 | khaliG | bed time, thanks for the help guys. |
| 16:38 | technomancy | wow, clj-time doesn't bother with releases? |
| 16:38 | technomancy | that's like the third library recently I've heard of that does that. what would prompt someone to actually bother bumping the version number if they haven't released? |
| 16:39 | technomancy | boggling. |
| 16:44 | amalloy | technomancy: so their version number goes straight from 0.1.0-SNAPSHOT to 0.2.0-SNAPSHOT or something? |
| 16:45 | technomancy | amalloy: yes. ಠ_ಠ |
| 16:45 | raek | amalloy: indeed so: http://clojars.org/repo/clj-time/clj-time/ |
| 16:47 | gtrak | with lein test, anyone ever get "Exception in thread "main" java.io.FileNotFoundException: Could not locate robert/hooke__init.class or robert/hooke.clj on classpath:" after adding the :test-selectors map to project.clj? |
| 16:47 | brehaut | technomancy: at least enlive and moustache have had real released |
| 16:48 | technomancy | brehaut: staying on a snapshot can be forgiven if it's the same snapshot. bumping to another snapshot shows you're at least paying some attention to the version number without getting it right. |
| 16:48 | gtrak | ah, nevermind, I found it |
| 16:48 | technomancy | gtrak: it should give you a better error message; shoot |
| 16:49 | gtrak | yes, I found I have to add a dev dependency |
| 16:50 | gtrak | this same issue: http://j.mp/crcQcy |
| 16:50 | brehaut | technomancy: sure that makes sense |
| 16:51 | gtrak | excuse me, a different one http://j.mp/hgOgby |
| 16:53 | technomancy | gtrak: it shouldn't be a dev dependency |
| 16:54 | technomancy | does it say dev-dependency somewhere? if so that needs to be fixed. |
| 16:54 | gtrak | that fixes it for me, same as the issue reporter |
| 16:55 | technomancy | hooke is an implied dev-dependency of every lein project |
| 16:56 | TimMc | Any way to get swank-clojure in all projects by default? |
| 16:56 | gtrak | right, that's what was confusing me, we already are using hooks |
| 16:56 | gtrak | for some reason 'lein test' didn't care |
| 16:56 | gtrak | this is 1.4.2 |
| 16:56 | TimMc | I see that I can use an init.clj, but I don't know what to put in it. |
| 16:57 | amalloy | TimMc: cake project or lein project? |
| 16:57 | TimMc | Wait, nvm. lein plugin should do it |
| 16:57 | raek | TimMc: you can copy the swank-clojure jar to ~/.lein/plugins/ |
| 16:58 | technomancy | raek: yeah, lein plugin actually does that |
| 16:58 | raek | oh. :) |
| 16:58 | TimMc | OK, so now from Emacs, how do I get connected to swank? |
| 16:58 | amalloy | M-x slime-connect |
| 16:59 | amalloy | i bound that to C-c s, because i'm clever enough to do that but not clever enough to get it to autoload or manage multiple swank sessions |
| 17:08 | TimMc | I assume the usual usage is to send each top-level form to the REPL as you edit it, yeah? |
| 17:08 | TimMc | How do I do that? |
| 17:09 | raek | TimMc: the whole file: C-c C-k, the top-level form that encloses the point: C-M-x |
| 17:10 | TimMc | thanks |
| 17:10 | raek | and to change namespace: C-c M-p (requires it to be loaded) |
| 17:12 | TimMc | loaded = eval'd? |
| 17:13 | raek | yes |
| 17:13 | amalloy | raek, TimMc: i use C-c C-c rather than C-M-x. doubt it matters, but i like having all the interesting commands start with C-c |
| 17:14 | raek | (well, the ns form needs to be evaled. otherwise the namespace does not exist and slime will say "no match" or something) |
| 17:17 | jlf | raek: i like ,!p to change namespaces |
| 17:21 | waxrosecabal | raek, I'm still a little confused at how things are connected, so does Lein make it so that projects have clojure and not the actual system? |
| 17:23 | brehaut | TimMc: did you have more luck with your parser? |
| 17:23 | TimMc | brehaut: Working on it. |
| 17:23 | waxrosecabal | TimMc, o/ |
| 17:24 | TimMc | hey, waxrosecabal |
| 17:24 | technomancy | C-M-x is a elispism |
| 17:24 | technomancy | of sorts |
| 17:24 | brehaut | TimMc: cool :) |
| 17:24 | TimMc | Tryng to parse numbers. |
| 17:25 | TimMc | I just need pos/neg decimal integers and positive hex |
| 17:25 | TimMc | Right now I'm trying to figure out why my semantics hook isn't being called. |
| 17:27 | TimMc | brehaut: Any reason why an inline anonymous fn would be called and not a defn'd function? :-/ |
| 17:27 | brehaut | it'll not be called if the parser fails for some reason |
| 17:27 | TimMc | #(println %&) works fine, as-decimal-number is never called. |
| 17:28 | brehaut | otherwise if its not running it should throw an error |
| 17:28 | brehaut | TimMc: that's surprising! |
| 17:28 | TimMc | Oh... my bad |
| 17:28 | TimMc | Forgot to eval that form. |
| 17:28 | TimMc | New at this interactive development thingy. |
| 17:32 | brehaut | oh right :D |
| 17:32 | waxrosecabal | :P |
| 17:35 | TimMc | brehaut: https://gist.github.com/875176 <-- I've got register numbers being extracted, still figuring out the use of semantics. |
| 17:40 | brehaut | TimMc: your use of semantics looks correct to me. you have a bug waiting to trip you up in hex-imm; its using decimal-digit |
| 17:42 | raek | waxrosecabal: to lein, a version of clojure is "just a dependency" of the project. (does that answer your question?) |
| 17:43 | waxrosecabal | raek, Yeah it does. Just matching sure I understand it correctly. |
| 17:44 | brehaut | TimMc: you can replace [[& digit-chars]] with digit-chars in your semantics though i think |
| 17:44 | raek | "the project has a version of clojure" is the case rather than "the system has a version of clojure" |
| 17:44 | waxrosecabal | ah |
| 17:48 | amalloy | brehaut: really? i don't think so |
| 17:48 | amalloy | oh i guess so |
| 17:49 | brehaut | amalloy: hmm i did remove too many brackets |
| 17:49 | amalloy | haha |
| 17:49 | brehaut | amalloy: destructuring a sequence into just a remainder is an identity operation is it not? |
| 17:49 | amalloy | yeah. that was such a glaring error i didn't even notice it; i knew what you meant |
| 17:50 | amalloy | brehaut: yeah. i think of [:as foo] being equivalent to foo, but never really use & that way |
| 17:50 | raek | has anyone made a lib that can catch uncaight exceptions at the top level of an application and (offer the user to) send the stacktrace to the application developer? |
| 17:50 | amalloy | (this is a total lie. i'm just trying to justify my clearly incorrect claims) |
| 17:53 | raek | or does anyone know what terms I should search for in order to find such a lib? |
| 17:57 | xkb | Hi |
| 17:58 | xkb | Can anybody recommend a current compojure tutorial? |
| 17:58 | waxrosecabal | raek, Thanks for the tips. Got every thing hooked up. |
| 18:00 | raek | hrm, turns out log4j could be used for my need... |
| 18:00 | raek | waxrosecabal: np. |
| 18:40 | TimMc | brehaut: Ah, thanks for the digit-chars thing. That was there for hysterical raisins. |
| 18:40 | brehaut | TimMc: haha :) no worries |
| 18:40 | TimMc | And hex-imm is in progress. |
| 18:48 | raek | anyone have any recommendation for a clojure logging tutorial? |
| 18:50 | raek | also, does tools.logging include the recent rewrite of clojure.contrib.logging? |
| 18:54 | technomancy | raek: it does |
| 19:10 | TimMc | The good news: I found out that ##(.intValue (java.math.BigInteger "ffffffff" 16)) works. |
| 19:10 | sexpbot | java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.IFn |
| 19:10 | TimMc | ,(.intValue (java.math.BigInteger. "ffffffff" 16)) |
| 19:10 | clojurebot | -1 |
| 19:10 | TimMc | The bad news: All my hex inputs are actually unsigned values. >_< |
| 19:10 | brehaut | timmc use longs |
| 19:11 | TimMc | Nah, I don't need them. |
| 19:11 | TimMc | They're < 32 bit. |
| 19:11 | TimMc | Memory address literals. |
| 19:13 | brehaut | TimMc: im not following. is it a problem?? |
| 19:13 | brehaut | s/?$// |
| 19:13 | TimMc | The bad news was simply that I didn't have any use for the neat solution. |
| 19:20 | TimMc | java.lang.ClassCastException: org.timmc.mipsiss.instructions.Instr cannot be cast to org.timmc.mipsiss.instructions.Instr |
| 19:21 | TimMc | That's a new one for me. |
| 19:22 | brehaut | it does appear surprising doesnt it |
| 19:22 | amalloy | wrong classloader? |
| 19:23 | amalloy | ie if two classloaders load the same class, they'll have the same name but not be the same class (nor even related) |
| 19:24 | raek | ,(= "org.timmc.mipsiss.instructions.Instr" "org.timmc.mipsiss.instructions.Instr") |
| 19:24 | clojurebot | true |
| 19:25 | TimMc | I *am* doing something that is probably naughty. https://gist.github.com/875355 |
| 19:25 | TimMc | The exception is thrown on the last line of code. |
| 19:26 | TimMc | I should probably convert this to a memoized function. |
| 19:29 | brehaut | TimMc: you could rewrite #(vector …) as (juxt :name identity) |
| 19:30 | TimMc | I was running a computation involving a defrecord (from the same file) at compile time. :-\ |
| 19:30 | brehaut | but btw |
| 19:30 | brehaut | err just |
| 19:30 | brehaut | oh |
| 19:30 | TimMc | brehaut: But then I wouldn't be able to read it! |
| 19:31 | brehaut | TimMc: really?! |
| 19:31 | TimMc | ,((juxt :name identity) {:name 5}) |
| 19:31 | clojurebot | [5 {:name 5}] |
| 19:32 | TimMc | Hmm, I suppose. But is it really any clearer? |
| 19:32 | amalloy | yes |
| 19:32 | brehaut | TimMc: it juxtaposes your functions |
| 19:32 | brehaut | much! |
| 19:33 | amalloy | it proclaims to the world "here are two functions! i am calling them both on the same object! next up: the object i will call them on!" |
| 19:33 | brehaut | (caveat: #clojure has a serious juxt fetish) |
| 19:33 | TimMc | brehaut: I noticed. |
| 19:33 | amalloy | where is the setting to give me a highlight/notify every time someone does something that should be replaced with juxt? |
| 19:34 | TimMc | /hilight ( |
| 19:35 | brehaut | amalloy i think the regexp /[/ should cover it |
| 19:35 | amalloy | brehaut: are you crazy? that wouldn't even catch his one case |
| 19:35 | brehaut | amalloy: im sorry |
| 19:35 | amalloy | /hilight \. |
| 19:40 | brehaut | talking of naming random small functions, ive been tempted to write (defn arguments [& r] r) |
| 19:40 | TimMc | brehaut: "unapply" |
| 19:40 | brehaut | or alias vec or something |
| 19:41 | brehaut | TimMc: hmm. interesting suggestion |
| 19:41 | TimMc | Do you really need that that often? |
| 19:41 | brehaut | i have also convinced my self that aliasing vector is wrong |
| 19:41 | brehaut | TimMc: often enough |
| 19:46 | brehaut | TimMc: i could just use vector most of the time, but i like the clarity of giving it its own name for the purpose |
| 19:46 | brehaut | and vector isnt lazy |
| 19:49 | brehaut | i have just discovered the seque function and am curious about what it could be used for |
| 19:49 | brehaut | (doc seque) |
| 19:49 | clojurebot | "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer." |
| 19:49 | brehaut | ,(doc seque) |
| 19:49 | clojurebot | "([s] [n-or-q s]); Creates a queued seq on another (presumably lazy) seq s. The queued seq will produce a concrete seq in the background, and can get up to n items ahead of the consumer. n-or-q can be an integer n buffer size, or an instance of java.util.concurrent BlockingQueue. Note that reading from a seque can block if the reader gets ahead of the producer." |
| 19:53 | amalloy | brehaut: (def arguments list) |
| 19:54 | TimMc | brehaut: I notice that the example JSON parser built on fnparse passes a struct around instead of a raw token stream. |
| 19:54 | brehaut | amalloy: i dont think thats lazy either |
| 19:55 | amalloy | oh all right. list* if you want lazy |
| 19:55 | brehaut | &(first (apply (fn [ & r ] r) (iterate inc 1))) |
| 19:55 | sexpbot | ⟹ 1 |
| 19:55 | brehaut | &(first (apply list (iterate inc 1))) |
| 19:55 | brehaut | got a link? |
| 19:55 | brehaut | amalloy: ah right |
| 19:55 | sexpbot | Execution Timed Out! |
| 19:55 | TimMc | brehaut: https://github.com/joshua-choi/fnparse/wiki/Sample-JSON-parser |
| 19:55 | amalloy | &(first (apply list* (range))) |
| 19:55 | sexpbot | java.lang.StackOverflowError |
| 19:55 | brehaut | &(first (apply list* (iterate inc 1))) |
| 19:55 | sexpbot | java.lang.StackOverflowError |
| 19:55 | amalloy | lol |
| 19:55 | amalloy | what |
| 19:55 | brehaut | double fial |
| 19:55 | amalloy | ,(first (apply list* (range))) |
| 19:55 | clojurebot | java.lang.StackOverflowError |
| 19:56 | amalloy | why would this overflow |
| 20:01 | brehaut | TimMc: i suspect its a struct because its older than records and it is more than just {:remainder ... } because it also stores column and line information (for error) using get-info and set-info |
| 20:02 | brehaut | TimMc: ah it uses update-info in nb-char and b-char to track that information |
| 20:04 | TimMc | Do I only nee to do something like that if I want debugging info in my parser? |
| 20:04 | brehaut | TimMc: if you look at parse-error you'll see its pulling those out of the state |
| 20:05 | brehaut | parse-error is called by parse-error |
| 20:06 | brehaut | what am i say |
| 20:06 | brehaut | by expectation-error-fn which is used by failpoint in various places |
| 20:06 | brehaut | correct |
| 20:08 | brehaut | well, there might be additional state you need for specific parsers (a python or haskell parser would need to track indentation for example) |
| 21:27 | mec | ,('m) |
| 21:27 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (0) passed to: Symbol |
| 21:37 | amalloy | &('m '{m 10}) |
| 21:37 | sexpbot | ⟹ 10 |
| 21:37 | mec | interesting, i thought that was only keywords |
| 21:40 | amalloy | mec: keywords are a lot better at it than symbols are |
| 21:42 | amalloy | in that you don't have to quote them, and they're faster |
| 22:13 | zakwilson | I want to move a symbol that was defined in namespace a, which is used by namespace b to namespace b without restarting Clojure. Doable? |
| 22:16 | brehaut | zakwilson: you can reload a namespace in your repl (require 'namespace.b :reload) |
| 22:17 | zakwilson | brehaut: thanks |
| 22:17 | TimMc | zakwilson: or even better, :reload-all |
| 22:19 | zakwilson | Hmm... that's not working. I still get an IllegalStateException. I should note I'm using Clojure 1.2. |
| 22:35 | trptcolin | ok, so i'm re-reading JoC and noticed a sidebar i missed the first time around that says positional destructuring works w/ java.util.regex.Matcher |
| 22:35 | trptcolin | ,(let [[a b c] (re-matcher #".*test.*" "this is a test. testing. only a test.")] [a b c]) |
| 22:35 | clojurebot | [nil nil nil] |
| 22:35 | trptcolin | what am i missing here? |
| 22:38 | TimMc | ,(re-matcher #".*test.*" "this is a test. testing. only a test.") |
| 22:38 | brehaut | ,(let [[a b] (re-matches #"a(b)c" "abc")] [:a a :b b]) |
| 22:38 | brehaut | oh my bad |
| 22:38 | clojurebot | #<Matcher java.util.regex.Matcher[pattern=.*test.* region=0,37 lastmatch=]> |
| 22:38 | clojurebot | [:a "abc" :b "b"] |
| 22:39 | TimMc | Ah, re-matche*s* |
| 22:40 | brehaut | TimMc: yeah i used the wrong func |
| 22:42 | amalloy | zakwilson: you want ns-unmap |
| 22:42 | amalloy | (ns-unmap *ns* 'var-i-want-to-move) |
| 22:42 | brehaut | trptcolin: the matcher i get back from your expression raises 'illegalstateexception:no match found' when i try to call nth on it |
| 22:42 | trptcolin | interesting, seems the regex capture changes the output semantics here |
| 22:42 | trptcolin | ,(let [[a b] (re-matches #"abc" "abc")] [:a a :b b]) |
| 22:42 | clojurebot | [:a \a :b \b] |
| 22:43 | zakwilson | amalloy: thanks, that sounds like what I'm looking for. |
| 22:43 | amalloy | &(let [[a b] (re-find #"abc" "abc")] [a b])? |
| 22:43 | sexpbot | ⟹ [\a \b] |
| 22:44 | amalloy | feh. destructuring regex matches seems like such a weird idea it's no wonder the syntax is hard to get right |
| 22:44 | trptcolin | ah, because re-groups returns a string when there are no match groups |
| 22:45 | cemerick | amalloy: I think it's a complete misfeature |
| 22:45 | trptcolin | amalloy: word. i saw the sentence and immediately ran to the REPL, because i can't think of a good use case for it... |
| 22:46 | amalloy | cemerick: that seems like an overstatement to me. there should be *some* way to destructure a match-like-thing into its groups |
| 22:46 | brehaut | trptcolin: but re-matches returns a vector so destructuring is straight forward, re-matcher returns the actual object you mention |
| 22:46 | trptcolin | yup |
| 22:46 | phenom_ | hmmm type hinting is done with the hat right? eg (defn my [^MyType type] ...) |
| 22:46 | phenom_ | for clojure 1.3 |
| 22:46 | cemerick | amalloy: oh, I thought we were talking about java.util.regex.Matcher objects |
| 22:47 | amalloy | cemerick: we probably are |
| 22:47 | amalloy | i can't keep that whole package straight |
| 22:48 | cemerick | amalloy: re-matches returns vectors and strings. re-matcher returns a Matcher object. |
| 22:48 | brehaut | cemerick amalloy we were initially, then i screwed up and muddied the water with re-matches |
| 22:48 | cemerick | ah, my bad then |
| 22:49 | trptcolin | yeah, the question of whether Matcher actually destructures was my confusion |
| 22:49 | brehaut | cemerick: nah i think you were right |
| 22:51 | brehaut | ,(let [match (re-matcher #".*test.*" "this is a test. testing. only a test.")] (destructure [['a 'b 'c] match])) |
| 22:51 | clojurebot | [vec__5270 #<Matcher java.util.regex.Matcher[pattern=.*test.* region=0,37 lastmatch=]> a (clojure.core/nth vec__5270 0 nil) b (clojure.core/nth vec__5270 1 nil) c (clojure.core/nth vec__5270 2 nil)] |
| 22:53 | TimMc | phenom_: type hinting like ^String foo works in 1.2 as well |
| 22:55 | trptcolin | ok, right, so if nth doesn't work on it, it's not gonna fly. |
| 22:55 | brehaut | trptcolin: if i bind that matcher to a name, call .matches and then call nth it works, but not if omit the .matches |
| 22:56 | cemerick | brehaut: that's because Matcher is a stateful thing |
| 22:56 | trptcolin | ok, so depends on lastmatch being set then |
| 22:56 | cemerick | which is why I was saying that the fact that it's destructurable is a misfeature |
| 22:57 | brehaut | cemerick: i now understand why you would say that |
| 22:57 | amalloy | haha |
| 22:57 | cemerick | e.g. you can't destructure it twice, etc |
| 22:57 | cemerick | capture it with :as, and it's useless |
| 22:57 | cemerick | (er, maybe you can reset it or something :-/) |
| 22:57 | amalloy | cemerick: the act of destructuring it causes it to call .find() |
| 22:58 | amalloy | ? |
| 22:58 | cemerick | amalloy: no, .matches |
| 22:58 | amalloy | $google javadoc regex util matcher |
| 22:58 | sexpbot | First out of 2510 results is: Pattern (Java 2 Platform SE v1.4.2) |
| 22:58 | sexpbot | http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html |
| 22:58 | cemerick | Sequential destructurability is a consequence of something being nth-able, and Matchers are (perhaps rightfully) nth-able |
| 22:59 | amalloy | really, it calls matches, not find? |
| 22:59 | cemerick | no, *you* need to call .matches |
| 22:59 | cemerick | nth works only on a matcher that's been init'ed properly (via find or matches) |
| 22:59 | cemerick | ,(nth (re-matcher #".*" "foo") 0) |
| 22:59 | clojurebot | java.lang.IllegalStateException: No match found |
| 23:00 | amalloy | in that case i don't follow your statement about destructuring it making it become useful |
| 23:00 | amalloy | useless |
| 23:00 | cemerick | ,(nth (doto (re-matcher #".*" "foo") .matches) 0) |
| 23:00 | clojurebot | "foo" |
| 23:00 | amalloy | the destructuring itself has no side effects, you just have to call .matches to make it work |
| 23:00 | phenom_ | TimMc for some reason my hints aren't working |
| 23:01 | amalloy | phenom_: hints are not type-checkers |
| 23:01 | phenom_ | it still's using reflection (which i see in the stack trace) |
| 23:02 | cemerick | amalloy: ah, sorry -- I was thinking of the scenario where one is using .find and destructuring |
| 23:03 | cemerick | Then the same Matcher object (potentially) destructures into different values as it goes along the input. |
| 23:04 | amalloy | yes. of course if you're doing that sort of thing you should be using re-seq anyway |
| 23:05 | cemerick | anytime someone says "oh, you're just doing it wrong", there's something gone awry in the system |
| 23:06 | amalloy | if there were a system so well-designed as to make mistakes impossible, it wouldn't need us humans |
| 23:06 | cemerick | 'course, any j.u.List or j.u.Map is destructurable and potentially mutable too, so I guess I'll go sit quietly elsewhere ;-) |
| 23:06 | cemerick | I've just been so spoiled with immutability that anything else just seems irretrievably broken. |
| 23:07 | amalloy | heh |
| 23:07 | amalloy | it is hard to go back |