2010-12-29
| 01:03 | hippiehunter | how do you put java annotations on a class you're implementing in clojure? I looked at the java interop page but I dont see any reference to "annotation" |
| 01:14 | tomoj | should println be considered blocking? |
| 01:30 | tomoj | yes |
| 04:12 | zvrba | oh, this article on finger trees was illuminating: http://scienceblogs.com/goodmath/2009/05/finally_finger_trees.php |
| 05:01 | ejackson | Morning folks |
| 09:23 | Dranik | I wanna create an ejb. how to add anotation to gen-class? |
| 09:31 | Dranik | rhickey, hello Rich! is there any description on how to add a java annotation to clojure-generated class? |
| 09:32 | Dranik | according to your post here http://groups.google.com/group/clojure/browse_thread/thread/d2128e1505c0c117 the annotations are implemented already |
| 09:32 | @rhickey | Dranik: you mean in a genclass? |
| 09:32 | Dranik | yep |
| 09:32 | @rhickey | https://gist.github.com/377213 |
| 09:32 | Dranik | thanks! |
| 09:33 | @rhickey | Dranik: I'm not sure if there is a genclass-specific description, that work followed afterwards |
| 09:33 | @rhickey | https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/genclass/examples.clj |
| 09:34 | Dranik | the last was helpful! |
| 09:47 | sarcher|work | are there any good clojure web frameworks out there? |
| 09:47 | cemerick | sarcher|work: yes, many |
| 09:47 | sarcher|work | I've heard of compojure, but when I look at the examples it generates the html inline which doesn't seem like a good approach. |
| 09:47 | Raynes | Check out Compojure or Moustache as a few examples. |
| 09:47 | cemerick | ring is foundational; many people stack compojure or moustache on top of it |
| 09:48 | cemerick | sarcher|work: That's hiccup -- and I agree, HTML "inline" leaves a sour taste in my mouth. You can use compojure with any templating engine you like. |
| 09:48 | Raynes | Compojure doesn't generate HTML at all. You're probably looking at a separate templating library called hiccup. |
| 09:48 | Dranik | sarcher|work, well, to my mind all pure clojure web-frameworks are in early stage |
| 09:48 | Raynes | Compojure has bee around for quite a while. |
| 09:49 | sarcher|work | Ok, I figured there was a way to generate html without doing it inline. |
| 09:49 | Raynes | cemerick: You actually beat me there. My message was longer-winded. :p |
| 09:49 | sarcher|work | I just didn't know what to use. |
| 09:49 | cemerick | sarcher|work: enlive is generally considered the clojure-"native" templating system. It's quite amazing. |
| 09:50 | Raynes | cemerick: Speaking of enlive, thank you so much for that section of your book. I finally 'get' enlive. |
| 09:50 | cemerick | Beyond that, you could use stringtemplate, velocity, jsp, or any of the others from Java-land, if you prefer. |
| 09:53 | Dranik | Raynes, is the book published already? |
| 09:54 | Raynes | Dranik: No. I was doing tech review. |
| 09:54 | Dranik | :-( |
| 09:54 | Raynes | cemerick: Speaking of that, do you have any dates in your mind for when the book might be finished? |
| 09:56 | Raynes | Speaking of books, I should really work on mine. /yawn |
| 09:56 | Raynes | So much to do, so many ways to avoid it. |
| 09:59 | Raynes | fliebel: I'm pretty sure that outside of my (relatively large) viewer circle, nobody knows the title of my book. It's mostly a working title and likely to change before I finish it. |
| 09:59 | Raynes | s/viewier/reviewer/ |
| 09:59 | cemerick | fliebel: It's only going to get "worse". That's a good thing. :-) |
| 10:00 | Raynes | I woke up like 30 seconds ago. |
| 10:00 | fliebel | cemerick: So which one is with Enlive stuff in it? |
| 10:01 | cemerick | fliebel: The one I'm working on; I'd bet @marick's ring book will cover it too. |
| 10:02 | fliebel | cemerick: Okay, so I haven't really missed anything, since I'm not a reviewer of any books. |
| 10:02 | @rhickey | cemerick: are there drafts of your book somewhere? |
| 10:03 | cemerick | rhickey: not publicly yet, no |
| 10:03 | Raynes | fliebel: You're welcome to take a gander at mine, if you so desire. |
| 10:03 | cemerick | I suspect it'll hit O'Reilly's "rough cuts" store sometime next month. |
| 10:03 | @rhickey | cool |
| 10:03 | fliebel | Raynes: I don't know what gander is, but I think so... |
| 10:04 | Raynes | $dict gander |
| 10:04 | sexpbot | Raynes: noun: The male of any species of goose. |
| 10:04 | Raynes | Not quite what I was looking for, but sure. |
| 10:04 | fliebel | rhickey: Are you in the mood to explain me why there is no interface for Atom and the others? |
| 10:05 | fliebel | Raynes: "a look or glance" is what mine says. |
| 10:05 | Raynes | fliebel: I'm uploading a new draft right now. I'll PM you a link to it in a few. |
| 10:05 | fliebel | cool |
| 10:06 | @rhickey | ,(ancestors clojure.lang.Atom) |
| 10:06 | clojurebot | #{clojure.lang.IMeta clojure.lang.ARef java.lang.Object clojure.lang.IRef clojure.lang.IDeref :clojure.contrib.generic/any clojure.lang.IReference clojure.lang.AReference} |
| 10:06 | @rhickey | fliebel: ^^ |
| 10:09 | fliebel | rhickey: I don't see something like IAtom? And swap! has a type hint like ^clojure.lang.Atom. |
| 10:11 | @rhickey | fliebel: ah, I see, right no interfaces, probably should be |
| 10:15 | @rhickey | fliebel: are you envisioning another implementation? |
| 10:18 | fliebel | rhickey: It fits the CouchDB model rather nicely. Couch is also MMVC and upon updating does basically a compare-and-set! I already did the basic thing using a custom protocol: https://github.com/pepijndevos/couch-atom |
| 10:20 | @rhickey | fliebel: patch welcome for IAtom |
| 10:21 | fliebel | rhickey: You need my contributors agreement for that |
| 10:21 | fliebel | s/that/that?/ |
| 10:21 | sexpbot | <fliebel> rhickey: You need my contributors agreement for that? |
| 10:21 | @rhickey | must be Java |
| 10:21 | @rhickey | fliebel: yes |
| 10:24 | fliebel | rhickey: I'm fine with Java, but I need to give the idea some more thought. Sad thing there aren't any interfaces in java.util.concurrent.atomic. What about ref and agent? I don't know to much about those, nor do I know if an interface is appropriate there. |
| 10:24 | cemerick | fliebel: That's pretty clever :-) |
| 10:25 | Raynes | fliebel is extra clever on Wednesdays. |
| 10:26 | fliebel | cemerick, Raynes: Huh? What? Thank you, I guess? |
| 10:26 | cemerick | fliebel: I'd almost want to have the entire database in the atom, not just one document. |
| 10:27 | cemerick | (swap! db-atom update-in ["foo" :bar] inc), etc. |
| 10:27 | fliebel | cemerick: Thinking about it already… You'd almost want swap-in! |
| 10:28 | cemerick | (swap! db-atom assoc "some _id" {:new :doc}) |
| 10:28 | cemerick | swap-in!? Which would do....? |
| 10:29 | @rhickey | fliebel: more thought always welcome :) |
| 10:29 | fliebel | cemerick: 80% of the time you'll be doing update-in, so it'd be a convenience wrapper that needs less arguments. |
| 10:29 | cemerick | oh, i see |
| 10:30 | cemerick | eh, I'd almost prefer keeping things explicit |
| 10:30 | fliebel | rhickey: I'll try to get you my agreement, and at some point, a patch. |
| 10:30 | @rhickey | ok |
| 10:31 | fliebel | cemerick: Okay :) I'll keep thinking. |
| 10:31 | cemerick | fliebel: I'll be tinkering with it, I'm sure. Would you be open to contributing it to clutch, pending what Tunde thinks of it? Conceptually, it'd make for much more pleasant usage than the with-db boilerplate. |
| 10:31 | cemerick | (If it were a db-in-an-atom, rather than limited to document-scope, that is.) |
| 10:33 | fliebel | cemerick: I contacted him, but I think he was under the impression I was asking a basic Couch question, along the lines of "how do I update a document?" |
| 10:34 | cemerick | fliebel: A google group was just created for clutch; perhaps post there? I can chime in if necessary. http://groups.google.com/group/clojure-clutch |
| 10:36 | fliebel | cemerick: I'll look at it. First step is more hammock time and a patch for Clojure. Once I have done that I'll fork Clutch and see where it goes. |
| 10:47 | fliebel | rhickey: One question about Atom. Why does swap call validate and notifyWatches? It calls compareAndSet, which does both already. |
| 10:49 | @rhickey | fliebel: no, it calls state.compareAndSet, i.e. on the AtomicReference |
| 11:01 | fliebel | rhickey: For performance reasons? In my opinion, the atom interface has only compareAndSet and reset. Swap is built on top of that. Reset could also be based on compareAndSet, but this comes at to high a cost. Currently Atom has a HAS-A relation to AtomicReference, would it be a sensible thing to make it an IS-A relation? Not sure about the practical side of that, but swap! could work for anything in java.util.concurrent.atomic. |
| 11:03 | @rhickey | fliebel: look harder |
| 11:06 | KirinDave | Damn |
| 11:19 | fliebel | rhickey: Nope, looking as hard as I can, but still not seeing why state.compareAndsSet is used. Here is how I see it: Both have the same signature, only difference being the ARef stuff. The ARef stuff is handled by swap. If swap was to drop that, and let compareAndSet handle the validate and notifyWatches, everyone is happy. |
| 12:59 | kaiser | hi, guys |
| 12:59 | kaiser | how do i check if an element is in a vector? |
| 12:59 | Guest63497 | (contains? [1 2 3] 2) seems not working properly, because the second parameter is an index |
| 12:59 | Raynes | &(some #{4} [1 2 3 4 5 6]) |
| 12:59 | sexpbot | ⟹ 4 |
| 12:59 | Guest63497 | hmmm... |
| 13:00 | Raynes | Guest10433: It's working properly, it just isn't designed for what you're trying to use it for. |
| 13:00 | Guest63497 | yes, Raynes...you're right |
| 13:01 | Guest10433 | Raynes: wrong guest :D i need to log in here |
| 13:01 | Raynes | Oopsy. :> |
| 13:02 | Guest63497 | thank you Raynes |
| 13:03 | Guest63497 | how do i remove an item from a vector? |
| 13:04 | Guest63497 | i'm using (disj (set vector) item) |
| 13:04 | Guest63497 | but i don't think is a good idea |
| 13:04 | amalloy | Guest63497: ##(remove #{3} [5 6 8 3 1 2]) |
| 13:04 | sexpbot | ⟹ (5 6 8 1 2) |
| 13:05 | Raynes | If you know the index of the element, dissoc would work as well. |
| 13:05 | Guest63497 | thanks amalloy and Raynes |
| 13:05 | amalloy | Raynes: really? i thought that wasn't the case unless it's at an edge |
| 13:05 | amalloy | &(dissoc [5 6 8 3 1 2] 2) |
| 13:05 | sexpbot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap |
| 13:05 | Raynes | &(dissoc [1 2 3] 1) |
| 13:05 | sexpbot | java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap |
| 13:05 | Raynes | Color me surprised. |
| 13:05 | Raynes | I could have swore... |
| 13:05 | Raynes | &(assoc [1 2 3] 1 3) |
| 13:05 | sexpbot | ⟹ [1 3 3] |
| 13:05 | amalloy | Raynes: insert/remove in the middle of a vector isn't fast, so it's not made easy |
| 13:06 | Raynes | Bizarre. |
| 13:06 | amalloy | seems reasonable to me |
| 13:58 | markskilbeck | Hey, guys. When I run 'mvn package', as per these instructions http://riddell.us/ClojureOnUbuntu.html, I get the following output (the build fails). http://pastebin.com/e01je1EN |
| 13:58 | markskilbeck | How should I proceed? |
| 14:02 | mister_roboto | Markskilbeck Looks like u need to add those repositories to your pom file |
| 14:03 | mister_roboto | Also you don't need snapshot since 1.2.0 is released now |
| 14:04 | mister_roboto | Maybe that's the only problem. Snapshot probably not in the main maven repo |
| 14:06 | markskilbeck | mister_roboto: Domo arigato. |
| 14:35 | markskilbeck | Hi, all. Say I'm in the directory ~/Documents/code, and in the subdirectory examples/ there are clojure files. How do I get require to see these files? |
| 14:38 | tonyl | are the clojure files namespaced? something like (ns examples.file1) |
| 14:39 | tonyl | if that is the case just (require 'examples) should be fine |
| 14:39 | markskilbeck | Yup. introductions.clj is namespaced as examples.introduction. |
| 14:40 | amalloy | markskilbeck: introductions.clj should be namespaced as examples.introductions (ie, filenames must match exactly) |
| 14:41 | markskilbeck | That was a typo on my part - the file is introduction.clj. My apologies. |
| 14:41 | markskilbeck | http://pastebin.com/EEH1Mckq is the output. |
| 14:43 | amalloy | markskilbeck: well, looks like your require command is right. does (System/getProperty "user.dir") return the directory above examples? |
| 14:43 | amalloy | er...wait, that's probably a silly thing to check. the classpath is more interesting than the cwd |
| 14:45 | amalloy | so (System/getProperty "java.class.path") should be some list that includes the directory above examples |
| 14:45 | amalloy | markskilbeck: ^ |
| 14:46 | markskilbeck | amalloy: http://pastebin.com/dDPu6yL5 |
| 14:47 | ordnungswidrig | markskilbeck: there should not be the .clj files on the classpath but the directory containing them. |
| 14:47 | amalloy | markskilbeck: right |
| 14:49 | markskilbeck | ordnungswidrig: amalloy: you're right - I f'd up. Thanks :) |
| 14:50 | sarcher|work | Random question, but what types of apps are y'all using clojure to build? |
| 14:50 | ordnungswidrig | sarcher|work: web, erp |
| 14:51 | sarcher|work | cool I'm just trying to figure out where clojure would be a good fit for me. |
| 14:51 | sarcher|work | I wasn't sure if people wrote tcp/ip servers, services, webapps, desktop apps or what in clojure. |
| 14:51 | amalloy | sarcher|work: a card-game solver/ai, and www.github.com/Raynes/sexpbot |
| 14:51 | dnolen | sarcher|work: all of the above |
| 14:52 | sarcher|work | At my current job we have a java / tomcat / mysql webapp. |
| 14:52 | sarcher|work | I'd like to start using clojure some, but I'm still learning and trying to figure out how and where i could use it at the same time. |
| 14:53 | ordnungswidrig | sarcher|work: clojure fits all, however desktop apps with swing feel a little unnatural (IMHO) because it's all about mutable state. I did not find a clojure lib which gave be the abstractions on top of swing that "felt right" |
| 14:54 | sarcher|work | ordnungswidrig: that makes sense. |
| 14:54 | sarcher|work | a lot of what i do now is retrieve xml data, parse the data into an object, then maybe filter that data and display it on a page. |
| 14:54 | sarcher|work | it's pretty straight forward for the most part. |
| 14:54 | ordnungswidrig | sarcher|work: that's where fp shines |
| 14:55 | sarcher|work | yeah that's what I'd like to learn. how to apply those concepts and clojure to our existing app to make it better. |
| 14:55 | gju_ | can i pass datatypes to functions? like i have a function which returns some data that has to be in the type i gave to the function or sth like that? |
| 14:55 | sarcher|work | I'm reading "Programming Clojure" now |
| 14:56 | sarcher|work | but I'm only about 50 pages in. And fibinacci numbers are great, but not a real-world example of what I'd like to do with the language :) |
| 14:57 | ordnungswidrig | gju_: can you give an example of what you want to accomplish? |
| 15:00 | gju_ | i've got a fn that reads n bytes from a file and at the moment it casts it to string and returns it. but there could be data that's not stored in form of a string but for example as an integer. so it would be neat to have the possibility to tell the fn what data type i want to be returned. |
| 15:05 | fliebel | gju_: From what I understand, you could pass it a cast function, so you do ((fn [f] (f (read-line))) int) But that might be nonsensical… Never mind. |
| 15:05 | fliebel | gju_: The Clojure reader would return the appropriate type for one… |
| 15:07 | fliebel | &(load-string "1e1") |
| 15:07 | sexpbot | java.lang.SecurityException: You tripped the alarm! load-string is bad! |
| 15:12 | cemerick | sarcher|work: do look at clojure.xml and clojure.contrib.zip-filter.xml |
| 15:28 | ordnungswidrig | how can i parse html into a hiccup-friendly datastructure? |
| 16:09 | raek | ordnungswidrig: enlive and https://gist.github.com/633049 |
| 16:10 | raek | ordnungswidrig: I also once saw a wrapper lib for tagsoup (same as enlive uses) that used the hiccup structure |
| 16:12 | mrBliss | raek: https://github.com/brool/beaujiful-soup or https://github.com/antoniogarrote/apricot-soup |
| 16:15 | raek | to get clojure.xml to use tagsoup isn't very hard: https://github.com/raek/klouzher/blob/master/src/se/raek/html.clj |
| 16:16 | raek | mrBliss: actually, I think it was yet another one I had seen: https://github.com/nathell/clj-tagsoup |
| 16:17 | mrBliss | raek: enough soups to choose from :-) Too bad I don't like soup (the one you eat) |
| 17:13 | benreesman | anyone here using aleph as an http client? |
| 17:17 | amalloy | chouser: it's been a while since i checked - what's the status of finger trees these days? |
| 17:19 | pdk | very moist |
| 18:20 | Berengal | So I read that vars are supposed to have dynamic scope and that functions are bound to vars, so you could dynamically add e.g. logging around a function. It doesn't seem to work with self-recursive functions. |
| 18:21 | Berengal | Does anyone know why? |
| 18:22 | technomancy | recur doesn't involve var resolution |
| 18:23 | Berengal | I'm not using recur, I'm using the name |
| 18:23 | AWizzArd | Berengal: I am not so sure what you mean. Dynamic scope is one thing, function composition another one. Composition allows you to decorate existing functions with side-effects, such as logging. |
| 18:23 | AWizzArd | Without recur your recursion is limited. |
| 18:23 | raek | vars have static scope, but can be dynamically bound |
| 18:24 | qbg | Berengal: Try using #'<fn name> instead |
| 18:24 | Berengal | Here http://pastebin.com/2sy4zVdY |
| 18:24 | raek | (scope = what variable does the name stand for?, binding = what value does the variable have?) |
| 18:25 | qbg | What version of Clojure are you using? |
| 18:25 | Berengal | qbg: Yes, that works, but then the rebinding has to be premeditated |
| 18:25 | Berengal | 1.2 |
| 18:28 | raek | hrm. my intuition says that this example should work. but why doesn't it? |
| 18:28 | Berengal | Could it be that when defining add-nat it's resolving the actual value, i.e. the original function? |
| 18:29 | raek | it should not... I think |
| 18:29 | Berengal | No, not from what I've read, but from what actually happens that's a possible explanation. |
| 18:30 | raek | (defn x [] 1) (defn y [] (x)) (binding [x (fn [] 2)] (y)) => 2 |
| 18:30 | Berengal | Yeah, I tried that as well. Wrapping works, but self-references do not |
| 18:30 | raek | ah |
| 18:31 | raek | (defn foo [x] ...) becomes (def foo (fn foo [x] ...)) |
| 18:31 | raek | note the extra foo |
| 18:31 | Berengal | So you could make a second function, add-nat*, and just bounce the self-recursion off of that, and it'd work |
| 18:31 | Berengal | Aaah |
| 18:32 | cemerick | Berengal: just using #' would be simpler and more future-proof. Vars are no longer dynamic by default in 1.3. |
| 18:32 | ossareh | raek++ |
| 18:32 | qbg | ,(macroexpand '(defn foo [x] (+ x 2))) |
| 18:32 | clojurebot | DENIED |
| 18:32 | Berengal | cemerick: Using #' would have to be premeditated. |
| 18:33 | raek | (def add-nat (fn [x y] ...)) gives the result you expected |
| 18:33 | cemerick | Berengal: as I say, all dynamic rebinding will have to be premeditated in 1.3+ |
| 18:33 | cemerick | so, might as well get in the habit, is my point :-) |
| 18:33 | Berengal | cemerick: Yeah, a bit of a shame. Do you know the reasoning why? |
| 18:33 | qbg | Most likely performance |
| 18:34 | Berengal | Thought as much |
| 18:35 | raek | Berengal: this might be interesting for adding trace printlns: https://github.com/technomancy/robert-hooke |
| 18:35 | cemerick | Berengal: see http://dev.clojure.org/pages/viewpage.action?pageId=950293 and http://dev.clojure.org/display/design/Improve+Binding |
| 18:35 | technomancy | heh; was about to suggest hooke |
| 18:35 | raek | (inc technomancy) |
| 18:35 | sexpbot | ⟹ 5 |
| 18:36 | cemerick | Rich went into the motivations/consequences in detail at the conj; watch for his second talk's video. |
| 18:36 | Derander | (inc technomancy) |
| 18:36 | sexpbot | ⟹ 6 |
| 18:36 | technomancy | Berengal: the hooke approach will work across threads in any version of clojure |
| 18:36 | raek | hrm, I should use robert.hooke for debugging stateful code more often... |
| 18:36 | qbg | Is his second talk up yet? |
| 18:36 | cemerick | not yet |
| 18:36 | Berengal | technomancy: So one thread could enable logging of function calls in another thread? |
| 18:37 | ossareh | ahh, raek I wanted to inc you not ++ you earlier. |
| 18:37 | ossareh | (inc raek) |
| 18:37 | sexpbot | ⟹ 2 |
| 18:38 | technomancy | Berengal: something like this, yes. (add-hook #'add-nat (fn [add-nat x y] (println "args:" x y) (doto (add-nat x y) println))) |
| 18:39 | technomancy | Berengal: but it sounds like what you want is clojure.contrib.trace/dotrace |
| 18:39 | technomancy | well, if you just want it to work. but if you want to understand it, you can reimplement it with ooke =) |
| 18:39 | technomancy | *hooke |
| 18:39 | raek | neat. I somehow forgot that doto can be used for other things than java interop. |
| 18:40 | technomancy | raek: my favourite: (doto 'clojure.repl require in-ns) |
| 18:40 | technomancy | always makes me smile. |
| 18:40 | Berengal | technomancy: Actually, I'm just poking around at internals. I always end up doing that when learning a new language :) |
| 18:40 | raek | technomancy: wow. |
| 18:41 | Raynes | It would be nice if Clojure automagically make earmuff vars dynamic. |
| 18:41 | Raynes | To, at the very least, give meaning to earmuffs. |
| 18:42 | raek | didn't 1.3 do that for a while? |
| 18:43 | AWizzArd | Raynes: you want the * to be a reader macro? |
| 18:43 | Raynes | I don't know what I want. I really just want earmuffs to have solid meaning. |
| 18:44 | tomoj | why should that particular set of symbols have any special meaning? |
| 18:44 | cemerick | Given how rare vars are actually used dynamically, that doesn't make a lot of sense. |
| 18:44 | cemerick | ^:dynamic is perfect, IMO |
| 18:45 | AWizzArd | At the moment I am with cemerick on this. |
| 18:45 | AWizzArd | Often those global defs can also be for constants or just parameters of a program. |
| 18:46 | Raynes | It's a bizarre convention. |
| 18:46 | tomoj | but no earmuffs for those, right? |
| 18:47 | Raynes | If you put earmuffs on non-dynamic vars, you're doin' it wrong. |
| 18:47 | Raynes | I guess people still do it though. |
| 18:47 | technomancy | yeah, that makes sense to me |
| 18:47 | technomancy | why should the compiler need extra help to figure out something a human can tell at a glance? |
| 18:47 | AWizzArd | tomoj: the ** mark global defs. They visually stand out of vars introduced via let |
| 18:48 | Raynes | ** marks dynamic defs. |
| 18:48 | tomoj | AWizzArd: that's not the orthodox position :) |
| 18:48 | Raynes | At least, that's what it said in my memo. |
| 18:49 | AWizzArd | It just happens to be the case that a subset of the globally visible vars are used as dynamically bindable. |
| 18:49 | tomoj | http://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards |
| 18:49 | tomoj | "Use *earmuffs* only for things intended for rebinding. Don't use a special notation for constants; everything is assumed a constant unless specified otherwise." |
| 18:49 | Raynes | There is no convention for constants. |
| 18:49 | AWizzArd | Only because this site says it means that this is something objective. |
| 18:50 | AWizzArd | The rule is simply „wrong” — in the opinion of some people. |
| 18:50 | tomoj | many other symbol styles are available which are hardly if ever used |
| 18:50 | AWizzArd | yes |
| 18:50 | tomoj | guess there aren't enough useful conventions to use them up |
| 18:51 | AWizzArd | tomoj: for example: the suggestion to use type hints only on code that is time critical is also plain wrong. In my opinion that is. |
| 18:51 | Raynes | If I had to type hint all of my code, I'd probably stop writing it. :\ |
| 18:51 | tomoj | naturally people disagree, I meant "orthodox" as a joke |
| 18:52 | AWizzArd | I would add to this guide: *warn-on-reflection* should be set to true per default, and all reflection warnings should be eliminated via type hints. |
| 18:52 | opqdonut_ | except that's impossible with many arrayish things |
| 18:52 | AWizzArd | tomoj: several “styles” were used before Clojure. They are not objectively good or bad, it’s opinion. |
| 18:53 | AWizzArd | opqdonut_: do you have an example? |
| 18:53 | opqdonut_ | and there's a ton of reflection warnings coming from :use'd libraries |
| 18:53 | opqdonut_ | even non-contrib ones |
| 18:53 | Raynes | AWizzArd: ##(class (.getBytes "a b c")) |
| 18:53 | sexpbot | ⟹ [B |
| 18:53 | technomancy | what's the point of avoiding reflection that only happens during startup for long-lived servers? |
| 18:54 | opqdonut_ | AWizzArd: it's a good method, but it hasn't worked out that well for our project |
| 18:54 | AWizzArd | I type-hint in my code for example: (defn foo [^"[[Ljava.lang.String;" a] ...) |
| 18:54 | AWizzArd | For a 2d String array. |
| 18:54 | opqdonut_ | i've had problems with aset and aget not being resolved |
| 18:54 | AWizzArd | And ^"[B" seems to be a fine type hint too. |
| 18:54 | opqdonut_ | especially if one writed general-purpose array-handling functions |
| 18:54 | AWizzArd | opqdonut_: yes true, I also had problems with those. |
| 18:55 | opqdonut_ | err, wrote |
| 18:55 | opqdonut_ | I'm tired |
| 18:55 | AWizzArd | Though this seems to be fixable as well, if it is really true. |
| 18:55 | AWizzArd | I was able to type-hint the reflection warnings for my agets away. |
| 18:55 | opqdonut_ | I've tried |
| 18:55 | opqdonut_ | anyway, off to sleep -> |
| 18:55 | AWizzArd | nighty :) |
| 19:03 | ysph | Say I have a function called valid?, which accepts a state and makes a validity determination based on rules it knows about. Obviously, it returns either true or false; however, in the false case, perhaps the client may want to know a reason for declaring the state invalid. To me, this is information about the false case, i.e. metadata. Of course, adding metadata to boolean false is probably a non-starter. Is there any use in pursuing |
| 19:03 | ysph | such a functionality, or should I just let it return false and be done with it? |
| 19:03 | Somelauw | I am checking out clojure. |
| 19:03 | Somelauw | So far it seems great. |
| 19:03 | AWizzArd | ysph: can you return a defrecord maybe? |
| 19:04 | qbg | ysph: Make a not-valid? that returns the reason when it is not valid |
| 19:04 | qbg | (maybe) |
| 19:04 | dsop | is there a way to force clojure.contrib.logging to use java.util.logger instead of apache commons? |
| 19:05 | Somelauw | But java is completely different from clojure, I think. |
| 19:05 | AWizzArd | Somelauw: depends on what you mean by “completely” (: |
| 19:05 | AWizzArd | They share an infinite number of things. |
| 19:06 | amalloy | ysph: you can either do not-valid? instead, or return something like [validity & reasons] |
| 19:06 | Somelauw | dynamic vs static typed, functional vs object orientated, optimized for conditional branching vs tail recursion. |
| 19:06 | amalloy | the client who doesn't care why can grab only the first element; the one who does can look at the whole thing |
| 19:06 | AWizzArd | Somelauw: Yes, there are major differences in the non-trivial areas. |
| 19:07 | ysph | qbg: amalloy: not-valid? would work i think in a majority of cases |
| 19:07 | Somelauw | loop - recur seems nice to me, but it probably can't be nested since recur would always recurse to the latter loop. |
| 19:07 | AWizzArd | Somelauw: do you mean mutual recursion? Clojure also offers trampolines. |
| 19:08 | AWizzArd | Otherwise I am not sure what you mean by nested recursion. |
| 19:12 | _na_ka_na_ | ,(try (finally (doseq [_ []]))) |
| 19:12 | clojurebot | _na_ka_na_: Gabh mo leithscéal? |
| 19:13 | _na_ka_na_ | &(try (finally (doseq [_ []]))) |
| 19:13 | sexpbot | java.lang.UnsupportedOperationException: Cannot recur from catch/finally |
| 19:13 | _na_ka_na_ | Hey guys where can I report ^^ bug |
| 19:16 | Somelauw | I will read about trampolines in that case. |
| 19:25 | dsop | has someone experience with logging on appengine? |
| 19:33 | amalloy | Somelauw: in a functional context it doesn't make sense to want to recur to any loop but the inner one |
| 19:34 | amalloy | the fact that it's not possible is surprisingly unimportant, if you're used to having labeled break/continues (though even in java those are rarely used) |
| 19:38 | Somelauw | amalloy, I am not sure, I will try to make up some code in which I would like to have a nested loop. |
| 19:38 | amalloy | Somelauw: great. if you find some, i'd love to be enlightened |
| 19:43 | auser | so if I have a map with several keynames, i.e. {:a 1 :b 2}, can I replace one of that map? i.e. something like: (alter {:a 1 :b 2} (fn [table] (assoc table :b 3))) |
| 19:46 | amalloy | auser: i don't understand. isn't that what assoc does? are you looking for a way to mutate it in-place rather than get a new, modified version or something? |
| 19:47 | Somelauw | amalloy, can clojure do this with loop-recur? http://pastebin.com/C0i8z3zS |
| 19:47 | auser | no, I just wanted to make sure that's how it works |
| 19:51 | bdesham | sorry for the newbie question, but I just downloaded clojure-contrib from github. where do I need to "install" it? |
| 19:51 | bdesham | the .jar file or whatever else |
| 19:52 | amalloy | Somelauw: i don't have much scheme experience. is the desired output 0 1 2 2 3 4? |
| 19:52 | Somelauw | I didn't insert spaces or newlines, so it is 01223444234442344423444. |
| 19:52 | technomancy | bdesham: clojure doesn't really work that way; you'll have an easier time using something like leiningen rather than manually downloading jars: https://github.com/technomancy/leiningen/blob/master/TUTORIAL.md |
| 19:53 | bdesham | technomancy: hmm, okay. thanks! |
| 19:55 | Somelauw | It's not hard to understand, a named let works just like a function that is immediately applicated. |
| 19:57 | Somelauw | When entering spaces in the outer loop the output becomes: 012 23 4 4 4 23 4 4 4 23 4 4 4 23 4 4 4 |
| 19:57 | Somelauw | In short, can you nest loop-recur in clojure? |
| 19:58 | auser | ah I see amalloy |
| 20:00 | amalloy | Somelauw: okay, i think i get it. but your example requires use of the stack, right? i don't see how you could optimize this for tail-calling |
| 20:03 | Somelauw | I think scheme will tail-recurse that code, although I am not completely sure. |
| 20:04 | amalloy | Somelauw: it can't. you have to call loop2, return, and then call loop1. it needs to keep loop2's data on the stack while calling loop1 |
| 20:04 | amalloy | anyway https://gist.github.com/fcd4dc5f2050e65d998c is a direct translation |
| 20:04 | amalloy | loop/recur is intentionally allowed only for cases that can be TCOd |
| 20:07 | amalloy | or i guess it's calling loop2 a lot of times recursively, then unrolling the stack to call loop1 some more. either way, not tail-calling |
| 20:07 | amalloy | sadly i gtg. i'll read your response later though, Somelauw |
| 20:08 | Somelauw | Will this work: http://pastebin.com/6t68Bq3z |
| 20:08 | Somelauw | Respond me later |
| 20:09 | Somelauw | Since the previous link will expire in 24 hours, here is a permanent one: http://pastebin.com/rTSY79bM |
| 20:39 | amalloy | Somelauw: i don't get it. isn't that identical to the paste you made before? |
| 20:40 | Somelauw | The call to the outer loop is now outside of the named let. |
| 20:40 | clojurebot | Roger. |
| 20:41 | amalloy | clojurebot: forget The call to the outer loop |
| 20:41 | clojurebot | jcall is http://paste.lisp.org/display/67182 |
| 20:41 | amalloy | ugh |
| 20:43 | amalloy | Somelauw: if you moved the call to the outer loop outside, then yes, you could do it with loop/recur. but when i look at your most recent paste it's byte-for-byte identical to the previous one |
| 20:45 | Somelauw | amalloy, my bad |
| 20:45 | Somelauw | http://pastebin.com/rTSY79bM |