#clojure logs

2010-12-29

01:03hippiehunterhow 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:14tomojshould println be considered blocking?
01:30tomojyes
04:12zvrbaoh, this article on finger trees was illuminating: http://scienceblogs.com/goodmath/2009/05/finally_finger_trees.php
05:01ejacksonMorning folks
09:23DranikI wanna create an ejb. how to add anotation to gen-class?
09:31Dranikrhickey, hello Rich! is there any description on how to add a java annotation to clojure-generated class?
09:32Dranikaccording to your post here http://groups.google.com/group/clojure/browse_thread/thread/d2128e1505c0c117 the annotations are implemented already
09:32@rhickeyDranik: you mean in a genclass?
09:32Dranikyep
09:32@rhickeyhttps://gist.github.com/377213
09:32Dranikthanks!
09:33@rhickeyDranik: I'm not sure if there is a genclass-specific description, that work followed afterwards
09:33@rhickeyhttps://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/genclass/examples.clj
09:34Dranikthe last was helpful!
09:47sarcher|workare there any good clojure web frameworks out there?
09:47cemericksarcher|work: yes, many
09:47sarcher|workI'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:47RaynesCheck out Compojure or Moustache as a few examples.
09:47cemerickring is foundational; many people stack compojure or moustache on top of it
09:48cemericksarcher|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:48RaynesCompojure doesn't generate HTML at all. You're probably looking at a separate templating library called hiccup.
09:48Draniksarcher|work, well, to my mind all pure clojure web-frameworks are in early stage
09:48RaynesCompojure has bee around for quite a while.
09:49sarcher|workOk, I figured there was a way to generate html without doing it inline.
09:49Raynescemerick: You actually beat me there. My message was longer-winded. :p
09:49sarcher|workI just didn't know what to use.
09:49cemericksarcher|work: enlive is generally considered the clojure-"native" templating system. It's quite amazing.
09:50Raynescemerick: Speaking of enlive, thank you so much for that section of your book. I finally 'get' enlive.
09:50cemerickBeyond that, you could use stringtemplate, velocity, jsp, or any of the others from Java-land, if you prefer.
09:53DranikRaynes, is the book published already?
09:54RaynesDranik: No. I was doing tech review.
09:54Dranik:-(
09:54Raynescemerick: Speaking of that, do you have any dates in your mind for when the book might be finished?
09:56RaynesSpeaking of books, I should really work on mine. /yawn
09:56RaynesSo much to do, so many ways to avoid it.
09:59Raynesfliebel: 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:59Raynes s/viewier/reviewer/
09:59cemerickfliebel: It's only going to get "worse". That's a good thing. :-)
10:00RaynesI woke up like 30 seconds ago.
10:00fliebelcemerick: So which one is with Enlive stuff in it?
10:01cemerickfliebel: The one I'm working on; I'd bet @marick's ring book will cover it too.
10:02fliebelcemerick: Okay, so I haven't really missed anything, since I'm not a reviewer of any books.
10:02@rhickeycemerick: are there drafts of your book somewhere?
10:03cemerickrhickey: not publicly yet, no
10:03Raynesfliebel: You're welcome to take a gander at mine, if you so desire.
10:03cemerickI suspect it'll hit O'Reilly's "rough cuts" store sometime next month.
10:03@rhickeycool
10:03fliebelRaynes: I don't know what gander is, but I think so...
10:04Raynes$dict gander
10:04sexpbotRaynes: noun: The male of any species of goose.
10:04RaynesNot quite what I was looking for, but sure.
10:04fliebelrhickey: Are you in the mood to explain me why there is no interface for Atom and the others?
10:05fliebelRaynes: "a look or glance" is what mine says.
10:05Raynesfliebel: I'm uploading a new draft right now. I'll PM you a link to it in a few.
10:05fliebelcool
10:06@rhickey,(ancestors clojure.lang.Atom)
10:06clojurebot#{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@rhickeyfliebel: ^^
10:09fliebelrhickey: I don't see something like IAtom? And swap! has a type hint like ^clojure.lang.Atom.
10:11@rhickeyfliebel: ah, I see, right no interfaces, probably should be
10:15@rhickeyfliebel: are you envisioning another implementation?
10:18fliebelrhickey: 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@rhickeyfliebel: patch welcome for IAtom
10:21fliebelrhickey: You need my contributors agreement for that
10:21fliebels/that/that?/
10:21sexpbot<fliebel> rhickey: You need my contributors agreement for that?
10:21@rhickeymust be Java
10:21@rhickeyfliebel: yes
10:24fliebelrhickey: 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:24cemerickfliebel: That's pretty clever :-)
10:25Raynesfliebel is extra clever on Wednesdays.
10:26fliebelcemerick, Raynes: Huh? What? Thank you, I guess?
10:26cemerickfliebel: I'd almost want to have the entire database in the atom, not just one document.
10:27cemerick(swap! db-atom update-in ["foo" :bar] inc), etc.
10:27fliebelcemerick: Thinking about it already… You'd almost want swap-in!
10:28cemerick(swap! db-atom assoc "some _id" {:new :doc})
10:28cemerickswap-in!? Which would do....?
10:29@rhickeyfliebel: more thought always welcome :)
10:29fliebelcemerick: 80% of the time you'll be doing update-in, so it'd be a convenience wrapper that needs less arguments.
10:29cemerickoh, i see
10:30cemerickeh, I'd almost prefer keeping things explicit
10:30fliebelrhickey: I'll try to get you my agreement, and at some point, a patch.
10:30@rhickeyok
10:31fliebelcemerick: Okay :) I'll keep thinking.
10:31cemerickfliebel: 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:31cemerick(If it were a db-in-an-atom, rather than limited to document-scope, that is.)
10:33fliebelcemerick: 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:34cemerickfliebel: 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:36fliebelcemerick: 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:47fliebelrhickey: One question about Atom. Why does swap call validate and notifyWatches? It calls compareAndSet, which does both already.
10:49@rhickeyfliebel: no, it calls state.compareAndSet, i.e. on the AtomicReference
11:01fliebelrhickey: 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@rhickeyfliebel: look harder
11:06KirinDaveDamn
11:19fliebelrhickey: 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:59kaiserhi, guys
12:59kaiserhow do i check if an element is in a vector?
12:59Guest63497(contains? [1 2 3] 2) seems not working properly, because the second parameter is an index
12:59Raynes&(some #{4} [1 2 3 4 5 6])
12:59sexpbot⟹ 4
12:59Guest63497hmmm...
13:00RaynesGuest10433: It's working properly, it just isn't designed for what you're trying to use it for.
13:00Guest63497yes, Raynes...you're right
13:01Guest10433 Raynes: wrong guest :D i need to log in here
13:01RaynesOopsy. :>
13:02Guest63497thank you Raynes
13:03Guest63497how do i remove an item from a vector?
13:04Guest63497i'm using (disj (set vector) item)
13:04Guest63497but i don't think is a good idea
13:04amalloyGuest63497: ##(remove #{3} [5 6 8 3 1 2])
13:04sexpbot⟹ (5 6 8 1 2)
13:05RaynesIf you know the index of the element, dissoc would work as well.
13:05Guest63497thanks amalloy and Raynes
13:05amalloyRaynes: really? i thought that wasn't the case unless it's at an edge
13:05amalloy&(dissoc [5 6 8 3 1 2] 2)
13:05sexpbotjava.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap
13:05Raynes&(dissoc [1 2 3] 1)
13:05sexpbotjava.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.IPersistentMap
13:05RaynesColor me surprised.
13:05RaynesI could have swore...
13:05Raynes&(assoc [1 2 3] 1 3)
13:05sexpbot⟹ [1 3 3]
13:05amalloyRaynes: insert/remove in the middle of a vector isn't fast, so it's not made easy
13:06RaynesBizarre.
13:06amalloyseems reasonable to me
13:58markskilbeckHey, 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:58markskilbeckHow should I proceed?
14:02mister_robotoMarkskilbeck Looks like u need to add those repositories to your pom file
14:03mister_robotoAlso you don't need snapshot since 1.2.0 is released now
14:04mister_robotoMaybe that's the only problem. Snapshot probably not in the main maven repo
14:06markskilbeckmister_roboto: Domo arigato.
14:35markskilbeckHi, 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:38tonylare the clojure files namespaced? something like (ns examples.file1)
14:39tonylif that is the case just (require 'examples) should be fine
14:39markskilbeckYup. introductions.clj is namespaced as examples.introduction.
14:40amalloymarkskilbeck: introductions.clj should be namespaced as examples.introductions (ie, filenames must match exactly)
14:41markskilbeckThat was a typo on my part - the file is introduction.clj. My apologies.
14:41markskilbeckhttp://pastebin.com/EEH1Mckq is the output.
14:43amalloymarkskilbeck: well, looks like your require command is right. does (System/getProperty "user.dir") return the directory above examples?
14:43amalloyer...wait, that's probably a silly thing to check. the classpath is more interesting than the cwd
14:45amalloyso (System/getProperty "java.class.path") should be some list that includes the directory above examples
14:45amalloymarkskilbeck: ^
14:46markskilbeckamalloy: http://pastebin.com/dDPu6yL5
14:47ordnungswidrigmarkskilbeck: there should not be the .clj files on the classpath but the directory containing them.
14:47amalloymarkskilbeck: right
14:49markskilbeckordnungswidrig: amalloy: you're right - I f'd up. Thanks :)
14:50sarcher|workRandom question, but what types of apps are y'all using clojure to build?
14:50ordnungswidrigsarcher|work: web, erp
14:51sarcher|workcool I'm just trying to figure out where clojure would be a good fit for me.
14:51sarcher|workI wasn't sure if people wrote tcp/ip servers, services, webapps, desktop apps or what in clojure.
14:51amalloysarcher|work: a card-game solver/ai, and www.github.com/Raynes/sexpbot
14:51dnolensarcher|work: all of the above
14:52sarcher|workAt my current job we have a java / tomcat / mysql webapp.
14:52sarcher|workI'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:53ordnungswidrigsarcher|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:54sarcher|workordnungswidrig: that makes sense.
14:54sarcher|worka 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:54sarcher|workit's pretty straight forward for the most part.
14:54ordnungswidrigsarcher|work: that's where fp shines
14:55sarcher|workyeah that's what I'd like to learn. how to apply those concepts and clojure to our existing app to make it better.
14:55gju_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:55sarcher|workI'm reading "Programming Clojure" now
14:56sarcher|workbut 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:57ordnungswidriggju_: can you give an example of what you want to accomplish?
15:00gju_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:05fliebelgju_: 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:05fliebelgju_: The Clojure reader would return the appropriate type for one…
15:07fliebel&(load-string "1e1")
15:07sexpbotjava.lang.SecurityException: You tripped the alarm! load-string is bad!
15:12cemericksarcher|work: do look at clojure.xml and clojure.contrib.zip-filter.xml
15:28ordnungswidrighow can i parse html into a hiccup-friendly datastructure?
16:09raekordnungswidrig: enlive and https://gist.github.com/633049
16:10raekordnungswidrig: I also once saw a wrapper lib for tagsoup (same as enlive uses) that used the hiccup structure
16:12mrBlissraek: https://github.com/brool/beaujiful-soup or https://github.com/antoniogarrote/apricot-soup
16:15raekto get clojure.xml to use tagsoup isn't very hard: https://github.com/raek/klouzher/blob/master/src/se/raek/html.clj
16:16raekmrBliss: actually, I think it was yet another one I had seen: https://github.com/nathell/clj-tagsoup
16:17mrBlissraek: enough soups to choose from :-) Too bad I don't like soup (the one you eat)
17:13benreesmananyone here using aleph as an http client?
17:17amalloychouser: it's been a while since i checked - what's the status of finger trees these days?
17:19pdkvery moist
18:20BerengalSo 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:21BerengalDoes anyone know why?
18:22technomancyrecur doesn't involve var resolution
18:23BerengalI'm not using recur, I'm using the name
18:23AWizzArdBerengal: 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:23AWizzArdWithout recur your recursion is limited.
18:23raekvars have static scope, but can be dynamically bound
18:24qbgBerengal: Try using #'<fn name> instead
18:24BerengalHere http://pastebin.com/2sy4zVdY
18:24raek(scope = what variable does the name stand for?, binding = what value does the variable have?)
18:25qbgWhat version of Clojure are you using?
18:25Berengalqbg: Yes, that works, but then the rebinding has to be premeditated
18:25Berengal1.2
18:28raekhrm. my intuition says that this example should work. but why doesn't it?
18:28BerengalCould it be that when defining add-nat it's resolving the actual value, i.e. the original function?
18:29raekit should not... I think
18:29BerengalNo, not from what I've read, but from what actually happens that's a possible explanation.
18:30raek(defn x [] 1) (defn y [] (x)) (binding [x (fn [] 2)] (y)) => 2
18:30BerengalYeah, I tried that as well. Wrapping works, but self-references do not
18:30raekah
18:31raek(defn foo [x] ...) becomes (def foo (fn foo [x] ...))
18:31raeknote the extra foo
18:31BerengalSo you could make a second function, add-nat*, and just bounce the self-recursion off of that, and it'd work
18:31BerengalAaah
18:32cemerickBerengal: just using #' would be simpler and more future-proof. Vars are no longer dynamic by default in 1.3.
18:32ossarehraek++
18:32qbg,(macroexpand '(defn foo [x] (+ x 2)))
18:32clojurebotDENIED
18:32Berengalcemerick: Using #' would have to be premeditated.
18:33raek(def add-nat (fn [x y] ...)) gives the result you expected
18:33cemerickBerengal: as I say, all dynamic rebinding will have to be premeditated in 1.3+
18:33cemerickso, might as well get in the habit, is my point :-)
18:33Berengalcemerick: Yeah, a bit of a shame. Do you know the reasoning why?
18:33qbgMost likely performance
18:34BerengalThought as much
18:35raekBerengal: this might be interesting for adding trace printlns: https://github.com/technomancy/robert-hooke
18:35cemerickBerengal: see http://dev.clojure.org/pages/viewpage.action?pageId=950293 and http://dev.clojure.org/display/design/Improve+Binding
18:35technomancyheh; was about to suggest hooke
18:35raek(inc technomancy)
18:35sexpbot⟹ 5
18:36cemerickRich went into the motivations/consequences in detail at the conj; watch for his second talk's video.
18:36Derander(inc technomancy)
18:36sexpbot⟹ 6
18:36technomancyBerengal: the hooke approach will work across threads in any version of clojure
18:36raekhrm, I should use robert.hooke for debugging stateful code more often...
18:36qbgIs his second talk up yet?
18:36cemericknot yet
18:36Berengaltechnomancy: So one thread could enable logging of function calls in another thread?
18:37ossarehahh, raek I wanted to inc you not ++ you earlier.
18:37ossareh(inc raek)
18:37sexpbot⟹ 2
18:38technomancyBerengal: something like this, yes. (add-hook #'add-nat (fn [add-nat x y] (println "args:" x y) (doto (add-nat x y) println)))
18:39technomancyBerengal: but it sounds like what you want is clojure.contrib.trace/dotrace
18:39technomancywell, if you just want it to work. but if you want to understand it, you can reimplement it with ooke =)
18:39technomancy*hooke
18:39raekneat. I somehow forgot that doto can be used for other things than java interop.
18:40technomancyraek: my favourite: (doto 'clojure.repl require in-ns)
18:40technomancyalways makes me smile.
18:40Berengaltechnomancy: Actually, I'm just poking around at internals. I always end up doing that when learning a new language :)
18:40raektechnomancy: wow.
18:41RaynesIt would be nice if Clojure automagically make earmuff vars dynamic.
18:41RaynesTo, at the very least, give meaning to earmuffs.
18:42raekdidn't 1.3 do that for a while?
18:43AWizzArdRaynes: you want the * to be a reader macro?
18:43RaynesI don't know what I want. I really just want earmuffs to have solid meaning.
18:44tomojwhy should that particular set of symbols have any special meaning?
18:44cemerickGiven how rare vars are actually used dynamically, that doesn't make a lot of sense.
18:44cemerick^:dynamic is perfect, IMO
18:45AWizzArdAt the moment I am with cemerick on this.
18:45AWizzArdOften those global defs can also be for constants or just parameters of a program.
18:46RaynesIt's a bizarre convention.
18:46tomojbut no earmuffs for those, right?
18:47RaynesIf you put earmuffs on non-dynamic vars, you're doin' it wrong.
18:47RaynesI guess people still do it though.
18:47technomancyyeah, that makes sense to me
18:47technomancywhy should the compiler need extra help to figure out something a human can tell at a glance?
18:47AWizzArdtomoj: the ** mark global defs. They visually stand out of vars introduced via let
18:48Raynes** marks dynamic defs.
18:48tomojAWizzArd: that's not the orthodox position :)
18:48RaynesAt least, that's what it said in my memo.
18:49AWizzArdIt just happens to be the case that a subset of the globally visible vars are used as dynamically bindable.
18:49tomojhttp://www.assembla.com/wiki/show/clojure/Clojure_Library_Coding_Standards
18:49tomoj"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:49RaynesThere is no convention for constants.
18:49AWizzArdOnly because this site says it means that this is something objective.
18:50AWizzArdThe rule is simply „wrong” — in the opinion of some people.
18:50tomojmany other symbol styles are available which are hardly if ever used
18:50AWizzArdyes
18:50tomojguess there aren't enough useful conventions to use them up
18:51AWizzArdtomoj: 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:51RaynesIf I had to type hint all of my code, I'd probably stop writing it. :\
18:51tomojnaturally people disagree, I meant "orthodox" as a joke
18:52AWizzArdI 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:52opqdonut_except that's impossible with many arrayish things
18:52AWizzArdtomoj: several “styles” were used before Clojure. They are not objectively good or bad, it’s opinion.
18:53AWizzArdopqdonut_: do you have an example?
18:53opqdonut_and there's a ton of reflection warnings coming from :use'd libraries
18:53opqdonut_even non-contrib ones
18:53RaynesAWizzArd: ##(class (.getBytes "a b c"))
18:53sexpbot⟹ [B
18:53technomancywhat's the point of avoiding reflection that only happens during startup for long-lived servers?
18:54opqdonut_AWizzArd: it's a good method, but it hasn't worked out that well for our project
18:54AWizzArdI type-hint in my code for example: (defn foo [^"[[Ljava.lang.String;" a] ...)
18:54AWizzArdFor a 2d String array.
18:54opqdonut_i've had problems with aset and aget not being resolved
18:54AWizzArdAnd ^"[B" seems to be a fine type hint too.
18:54opqdonut_especially if one writed general-purpose array-handling functions
18:54AWizzArdopqdonut_: yes true, I also had problems with those.
18:55opqdonut_err, wrote
18:55opqdonut_I'm tired
18:55AWizzArdThough this seems to be fixable as well, if it is really true.
18:55AWizzArdI was able to type-hint the reflection warnings for my agets away.
18:55opqdonut_I've tried
18:55opqdonut_anyway, off to sleep ->
18:55AWizzArdnighty :)
19:03ysphSay 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:03ysphsuch a functionality, or should I just let it return false and be done with it?
19:03SomelauwI am checking out clojure.
19:03SomelauwSo far it seems great.
19:03AWizzArdysph: can you return a defrecord maybe?
19:04qbgysph: Make a not-valid? that returns the reason when it is not valid
19:04qbg(maybe)
19:04dsopis there a way to force clojure.contrib.logging to use java.util.logger instead of apache commons?
19:05SomelauwBut java is completely different from clojure, I think.
19:05AWizzArdSomelauw: depends on what you mean by “completely” (:
19:05AWizzArdThey share an infinite number of things.
19:06amalloyysph: you can either do not-valid? instead, or return something like [validity & reasons]
19:06Somelauwdynamic vs static typed, functional vs object orientated, optimized for conditional branching vs tail recursion.
19:06amalloythe client who doesn't care why can grab only the first element; the one who does can look at the whole thing
19:06AWizzArdSomelauw: Yes, there are major differences in the non-trivial areas.
19:07ysphqbg: amalloy: not-valid? would work i think in a majority of cases
19:07Somelauwloop - recur seems nice to me, but it probably can't be nested since recur would always recurse to the latter loop.
19:07AWizzArdSomelauw: do you mean mutual recursion? Clojure also offers trampolines.
19:08AWizzArdOtherwise I am not sure what you mean by nested recursion.
19:12_na_ka_na_,(try (finally (doseq [_ []])))
19:12clojurebot_na_ka_na_: Gabh mo leithscéal?
19:13_na_ka_na_&(try (finally (doseq [_ []])))
19:13sexpbotjava.lang.UnsupportedOperationException: Cannot recur from catch/finally
19:13_na_ka_na_Hey guys where can I report ^^ bug
19:16SomelauwI will read about trampolines in that case.
19:25dsophas someone experience with logging on appengine?
19:33amalloySomelauw: in a functional context it doesn't make sense to want to recur to any loop but the inner one
19:34amalloythe 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:38Somelauwamalloy, I am not sure, I will try to make up some code in which I would like to have a nested loop.
19:38amalloySomelauw: great. if you find some, i'd love to be enlightened
19:43auserso 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:46amalloyauser: 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:47Somelauwamalloy, can clojure do this with loop-recur? http://pastebin.com/C0i8z3zS
19:47auserno, I just wanted to make sure that's how it works
19:51bdeshamsorry for the newbie question, but I just downloaded clojure-contrib from github. where do I need to "install" it?
19:51bdeshamthe .jar file or whatever else
19:52amalloySomelauw: i don't have much scheme experience. is the desired output 0 1 2 2 3 4?
19:52SomelauwI didn't insert spaces or newlines, so it is 01223444234442344423444.
19:52technomancybdesham: 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:53bdeshamtechnomancy: hmm, okay. thanks!
19:55SomelauwIt's not hard to understand, a named let works just like a function that is immediately applicated.
19:57SomelauwWhen 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:57SomelauwIn short, can you nest loop-recur in clojure?
19:58auserah I see amalloy
20:00amalloySomelauw: 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:03SomelauwI think scheme will tail-recurse that code, although I am not completely sure.
20:04amalloySomelauw: 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:04amalloyanyway https://gist.github.com/fcd4dc5f2050e65d998c is a direct translation
20:04amalloyloop/recur is intentionally allowed only for cases that can be TCOd
20:07amalloyor 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:07amalloysadly i gtg. i'll read your response later though, Somelauw
20:08SomelauwWill this work: http://pastebin.com/6t68Bq3z
20:08SomelauwRespond me later
20:09SomelauwSince the previous link will expire in 24 hours, here is a permanent one: http://pastebin.com/rTSY79bM
20:39amalloySomelauw: i don't get it. isn't that identical to the paste you made before?
20:40SomelauwThe call to the outer loop is now outside of the named let.
20:40clojurebotRoger.
20:41amalloyclojurebot: forget The call to the outer loop
20:41clojurebotjcall is http://paste.lisp.org/display/67182
20:41amalloyugh
20:43amalloySomelauw: 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:45Somelauwamalloy, my bad
20:45Somelauwhttp://pastebin.com/rTSY79bM