1: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"
1:14 tomoj: should println be considered blocking?
1:30 yes
4:12 zvrba: oh, this article on finger trees was illuminating: http://
5:01 ejackson: Morning folks
9:23 Dranik: I wanna create an ejb. how to add anotation to gen-class?
9:31 rhickey, hello Rich! is there any description on how to add a java annotation to clojure-generated class?
9:32 according to your post here http://
9:32 rhickey: Dranik: you mean in a genclass?
9:32 Dranik: yep
9:32 rhickey: https://
9:32 Dranik: thanks!
9:33 rhickey: Dranik: I'm not sure if there is a genclass-specific description, that work followed afterwards
9:33 https://
9:34 Dranik: the last was helpful!
9:47 sarcher|work: are there any good clojure web frameworks out there?
9:47 cemerick: sarcher|work: yes, many
9: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.
9:47 Raynes: Check out Compojure or Moustache as a few examples.
9:47 cemerick: ring is foundational; many people stack compojure or moustache on top of it
9:48 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.
9:48 Raynes: Compojure doesn't generate HTML at all. You're probably looking at a separate templating library called hiccup.
9:48 Dranik: sarcher|work, well, to my mind all pure clojure web-frameworks are in early stage
9:48 * cemerick is just going to let Raynes do the talking from here on out ;-)
9:48 Raynes: Compojure has bee around for quite a while.
9:49 sarcher|work: Ok, I figured there was a way to generate html without doing it inline.
9:49 Raynes: cemerick: You actually beat me there. My message was longer-winded. :p
9:49 sarcher|work: I just didn't know what to use.
9:49 cemerick: sarcher|work: enlive is generally considered the clojure-"native" templating system. It's quite amazing.
9:50 Raynes: cemerick: Speaking of enlive, thank you so much for that section of your book. I finally 'get' enlive.
9:50 cemerick: Beyond that, you could use stringtemplate, velocity, jsp, or any of the others from Java-land, if you prefer.
9:53 Dranik: Raynes, is the book published already?
9:54 Raynes: Dranik: No. I was doing tech review.
9:54 Dranik: :-(
9:54 Raynes: cemerick: Speaking of that, do you have any dates in your mind for when the book might be finished?
9:56 Speaking of books, I should really work on mine. /yawn
9:56 So much to do, so many ways to avoid it.
9:58 * fliebel is confused by all the Clojure books, and tends to forget which book is from who.
9: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.
9:59 s/viewier/reviewer/
9:59 cemerick: fliebel: It's only going to get "worse". That's a good thing. :-)
10:00 * Raynes gives up
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 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 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://
10:20 rhickey: fliebel: patch welcome for IAtom
10:21 fliebel: rhickey: You need my contributors agreement for that
10:21 s/that/that?/
10:21 sexpbot: <fliebel> rhickey: You need my contributors agreement for that?
10:21 rhickey: must be Java
10:21 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 (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 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 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 (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://
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 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
10:51 * fliebel looks better
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 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 how do i remove an item from a vector?
13:04 i'm using (disj (set vector) item)
13:04 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 &(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 I could have swore...
13:05 &(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://
13:58 How should I proceed?
14:02 mister_roboto: Markskilbeck Looks like u need to add those repositories to your pom file
14:03 Also you don't need snapshot since 1.2.0 is released now
14:04 Maybe that's the only problem. Snapshot probably not in the main maven repo
14:06 markskilbeck: mister_roboto: Domo arigato.
14:35 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 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 http://
14:43 amalloy: markskilbeck: well, looks like your require command is right. does (System/getProperty "user.dir") return the directory above examples?
14:43 er...wait, that's probably a silly thing to check. the classpath is more interesting than the cwd
14:45 so (System/getProperty "java.class.path") should be some list that includes the directory above examples
14:45 markskilbeck: ^
14:46 markskilbeck: amalloy: http://
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 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/
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 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 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 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 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 gju_: The Clojure reader would return the appropriate type for one…
15:07 &(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://
16:10 ordnungswidrig: I also once saw a wrapper lib for tagsoup (same as enlive uses) that used the hiccup structure
16:12 mrBliss: raek: https://
16:15 raek: to get clojure.xml to use tagsoup isn't very hard: https://
16:16 mrBliss: actually, I think it was yet another one I had seen: https://
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 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 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://
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 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 (defn foo [x] ...) becomes (def foo (fn foo [x] ...))
18:31 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 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 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://
18:35 cemerick: Berengal: see http://
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 (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 Berengal: but it sounds like what you want is clojure.contrib.trace/dotrace
18:39 well, if you just want it to work. but if you want to understand it, you can reimplement it with ooke =)
18:39 *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 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 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 ^:dynamic is perfect, IMO
18:45 AWizzArd: At the moment I am with cemerick on this.
18:45 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 I guess people still do it though.
18:47 technomancy: yeah, that makes sense to me
18:47 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://
18:49 "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 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 opqdonut_: do you have an example?
18:53 opqdonut_: and there's a ton of reflection warnings coming from :use'd libraries
18:53 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 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 I'm tired
18:55 AWizzArd: Though this seems to be fixable as well, if it is really true.
18:55 I was able to type-hint the reflection warnings for my agets away.
18:55 opqdonut_: I've tried
18:55 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 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 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 (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 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 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 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://
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 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://
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 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 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 anyway https://
20:04 loop/recur is intentionally allowed only for cases that can be TCOd
20:07 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 sadly i gtg. i'll read your response later though, Somelauw
20:08 Somelauw: Will this work: http://
20:08 Respond me later
20:09 Since the previous link will expire in 24 hours, here is a permanent one: http://
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://
20:41 amalloy: ugh
20:43 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