6:26 StartsWithK: hi
6:27 how can i get metadata associated with a function?
6:33 hoeck: StartsWithK: hi
6:33 StartsWithK: only symbols and collections support metadata
6:34 StartsWithK: if i type ^#'println i get metadata of println function or println symbol then?
6:35 i woule like to do something like, (defn get-meta [f] (meta (var f)))
6:36 but it dosn't work
6:49 hoeck: with (var f) you are accessing the metadata of a var named "f"
6:50 var is a special form, evaluated at compile-time
6:50 StartsWithK: i know, that is my problem, o would like to say (get-meta printf)
6:52 hoeck: (get-meta (var printf)) ?
6:53 StartsWithK: that works
6:53 so i can use #' shortcut
6:54 hoeck: but then you just renamed meta to get-meta
6:54 StartsWithK: but is there any way to remove it completely
6:55 its just a minimal example
6:55 it would be used more like
6:55 hoeck: i guess no, i think clojure does a statical lookup of vars
6:55 StartsWithK: (defn user [username] (println (str "Homepage of " username")))
6:56 (def views ["/user/<str:username>" user])
6:56 and then i can extract needed parts from request url, find names of arguments for user function and send them in that order
7:03 ok, i can live with #' prefix
7:03 any one tried clojure with osgi?
7:05 hoeck: how do you use metadata for that (just curious)?
7:05 i mean your former example
7:05 StartsWithK: there is arglists metadata associated with each function
7:06 hoeck: ahh, i see
7:06 StartsWithK: so i take (first) from that, turn names of arguments to strings and from map that hold exctracted parts of url i construct list that i use for (apply view args)
9:30 mac_: hello
9:31 I'm having a little problem with how to store a return value from a different thread...
9:33 I want something like a java future but more clojurey, is there a good techniqe for such a thing? I tried doing (let [r (ref nil)] (do-work (dosync (ref-set r (something))) r)) but r seems to retain it's original value?
9:33 do-work here does the next expression in a specific thread
9:36 hmm maybe I'm just checking it too fast? could be that it's not set yet..
9:38 hehe yeah that was it. Sorry to bother anyone with my stupidity :D just needed a little wait loop like the Future.get method to wait for it to complete ;)
9:43 Chouser: mac_: if you use an agent and (send), then you can use (await) in your main thread to collect the results.
9:43 or rather, to wait until the results are ready.
9:45 (let [r (agent nil)] (send r (fn [r2] (dowork) "newvalue")) (await r) (prn @r))
9:45 mac_: Yeah I know, what I did here is a bit re-inventing stuff but I have to please the java libs I'm using. Guess I could restructure things a bit but this works at least..
9:45 Chouser: note that the function you send to agent r has to return the value instead of setting a ref.
9:45 mac_: Oh you mean instead of the ref
9:46 Chouser: yeah.
9:46 mac_: Yeah that's a bit more idiomatic I suppose. Gonna try that
9:46 Chouser: I guess if you already have another thread and a communication mechanism you want to use, what you had might be necessary.
9:47 mac_: Yeah now I'm confusing myself. Of course that's why I had it the way it was hehe
9:47 I have a rendering thread that's always the same, like swing (except this is OpenGL) and I have to use that for loading images
9:48 But in that case, you think what I did was fine?
9:50 I'm pretty new to all this, got my summer vacation now so I'm trying to learn some clojure by making a small game :)
9:55 Chouser: since I have to use a specific thread I guess I'm keeping my solution then, thanks a bunch for the input though
10:15 Chouser: yep, if you need to have the task done in a particular thread, I don't think agents are going to help you at all. Carry on. :-)
10:28 cemerick: is there any circumstance in which loop *doesn't* bind sequentially?
10:29 or, I should say, any circumstance where it's not supposed to bind sequentially?
10:36 Chouser: When you use recur, the values are bound in parallel. Is that what you're asking?
10:38 cemerick: Chouser: No...I've got a loop form that won't compile, indicating that one of the previously-bound symbols is unavailable in that context. Something like (loop [x (foo) y (bar) z (baz x y)] ...), and it's complaining about the usage of x and y as arguments to baz.
10:38 I've not been able to replicate it in a simple case, though.
10:39 Chouser: baz isn't a macro or something, is it? ought to still work, though.
10:39 cemerick: Nope, baz is a very simple helper fn.
10:40 Chouser: how big is your non-simple case? :-) pastable?
10:41 cemerick: Chouser: I'll see if I can whittle it down, and rip out some of the irrelevant details.
10:46 cemerick: If you remove the last binding in the loop (the list destructuring, then foo compiles OK.
10:48 Chouser: nice
10:49 cemerick: I always feel like I'm doing something wrong if I start thinking I'm hitting a compiler bug, but I think this is a legit example. Someone please smack some sense into me before I post it to the google group. :-)
10:49 Chouser: I've looked at the destructuring code before, so let me poke at it a little.
10:50 macroexpand on your loop is looking ... odd
10:52 I'm pretty sure you've found a bug in the loop macro
10:55 Chouser: (loop [x 1 y x [a b] (foo)]) vs. (loop [x 1 y x])
10:55 cemerick: ah, the x's gensym isn't being used
10:56 Chouser: there's a big "if" in the loop macro, to try to detect if it needs to destructure or not. there's bug in there somewhere.
11:32 cemerick: Chouser: I see what the problem is, and I've got a *very* partial fix, but I don't know what the best way is to bring it all the way.
12:53 Chouser: cemerick: I'm back. care to share?
13:01 this is really pretty tricky
13:01 (loop [[a b] [1 2] c a]) ought to work
13:04 cemerick: Chouser: Yes, it really does need to work. Pasting now.
13:07 cemerick: The problem is that loop needs to retain the same "signature" as its literal bindings dictate, so it needs to rewrite destructuring(s) into a nested let. In the process, it gensyms binding names, but doesn't propagate those gensyms down into nested forms.
13:07 Chouser: yep. good summary.
13:08 but with the example I just gave, Im
13:08 I'm not even sure it's possible to solve using this approach.
13:08 cemerick: The "patch" I just pasted makes this work: (loop [x nil [y z] x] nil), but it doesn't help with (loop [x nil z (nil? x) [a b] x] nil), because the gensym for x doesn't get dropped into the (nil?) form.
13:09 I think loop needs to walk all of the value forms, and replace any symbols it finds with gensyms as defined as top-level bindings.
13:09 Chouser: and we don't really want a code-walker to go through all the value expressions looking for names to replace.
13:09 cemerick: That gets super-tricky though.
13:10 Chouser: what if we wrap each value expression in a let that defines all the names given up to that point?
13:10 cemerick: There's really no other way to do it, short of changing how loop binding work (I think). However, getting that right without squashing rebindings in those nested forms would be a serious pain.
13:11 Chouser: actually, I think my idea might work. Here I'll just whip up a new macro. Give me 4 or 5 hours...
13:11 cemerick: whew. yeah, that might do it.
13:11 I'm in there now, I can take a whack.
13:12 Chouser: I should just let you. I have things I Ought to be doing.
13:12 but they're not as fun :-/
13:13 cemerick: Hrm, I don't know if this is fun, either. ;-) I'm not nearly 133t enough to be messing with stuff like this.
13:18 Chouser: let-destructuring in the loop's value expressions will only happen for the initial values. recur calls will fail, won't they?
13:19 oh, nm -- we'll still need an inner let to do the destructuring for the body of the loop. That will take care of recur calls.
13:20 The penalty here will be for initial values the destructuring may happen multiple times.
13:20 cemerick: Chouser: That's not my understanding...
13:20 Yeah. Not much of a penalty, but yeah.
13:21 Chouser: a small runtime cost that hopefully HotSpot can remove when its not needed.
13:21 cemerick: Actually, no, if this is done right, there won't be any unnecessary destructuring.
13:21 Chouser: hm
13:21 cemerick: The nested lets should just pull in the full collections that have been gensymed (?)
13:22 We're just aligning symbols, not setting up destructuring.
13:26 Chouser: I think (loop [[a b] [1 2] c a]) should become:
13:26 (loop* [G__1936 [1 2] G__1937 (clojure/let [[a b] G__1936] a)] (clojure/let [[a b] G__1936 c G__1937]))
13:32 Is there a function that does (subsets '[a b c d]) => [[a] [a b] [a b c] [a b c d]]
13:50 Chouser: cemerick: I think that'll work. not very well tested yet.
13:56 cemerick: Chouser: Yes, I'm pretty sure that will work.
13:56 I was spending a lot of time, and almost have my version completed, but yours is much more concise.
13:59 Chouser: I really should have let you do it. Sorry I couldn't resist.
14:00 cemerick: Chouser: feh, what do I care? Your solution is cleaner anyway. :-)
14:00 Chouser: but see what I mean about the extra destructuring?
14:01 (loop-ch1 [[a b] [1 2] c a d a]) generates (let [[a b] ...] ...) three times, all of which will be run the first time into the loop
14:03 cemerick: ah, yes, I see it now.
14:04 Chouser: If the value to be destructured is side-effecting, that could be more than a performance problem.
14:04 Chouser: hm...
14:05 no, the value parts aren't repeated -- they always use a gensym bound ealier in the loop.
14:05 it's only the destructuring itself (vector accesses, hash lookup, etc.) that are repeated.
14:06 I think. :-)
14:06 cemerick: Yeah. See, I told you I was out of my depth. :-P
14:07 Chouser: by all means post that to the group. Hopefully Rich can test and merge it in semi-soon.
14:17 Chouser: done
14:18 subsets is a bad name for that function, but I haven't thought of anything better.
15:04 Chouser: well, that's not what it does though. From [1 2 3] I want  [1 2] and [1 2 3], but not [2 3] or .
15:05 it's more like "growing sets" or something. I kinda thought haskell had a builtin function for that, but I don't know Haskell well enough to even know how to look it up.
15:06 well, google to the rescue. Haskell calls it "inits"
15:08 JamesIry: Chouser: ah, I misunderstood
15:09 technically I think Haskell's inits would return [[1 2][1 2 3]]
15:11 Nafai: JamesIry: Correct
15:11 Prelude Data.List> inits [1, 2, 3]
15:12 erochester: Chouser: would this do what you want? (reverse (take (count [1 2 3]) (iterate pop [1 2 3])))
15:13 JamesIry: Nafai, Chouser, I think Haskell's inits makes more sense because it's a total function - any sequence is a valid input. Chouser's variation would be undefined for empty sequences
15:15 Nafai: Right, haskell's inits just returns a list of an empty list with an empty list argument
15:20 Chouser: my use case might actually work better with haskell's version
15:20 erochester: nice! here's what I've got at the moment:
15:21 (defn subsets [s] (reduce #(conj %1 (conj (or (last %1) ) %2))  s))
15:24 erochester: iterate pop is genius. I was looking for a way to use iterate, but didn't think of that.
15:24 erochester: cool. yours actually seems more straightforward in some ways. more complicated in others.
15:25 i'd be interested in knowing if you find a better way to limit the output of iterate. the way i did it seemed messy.
15:27 Chouser: (take-while seq (iterate pop [1 2 3]))
15:27 but that makes it harder to go one-more to get inits-like behavior
15:28 erochester: excellent. that's much better (although you're right about going one further.)
15:29 although what i posted won't work for inits-like behavior either. it raises an exception when you try to do (pop )
15:29 Chouser: huh. none of these are lazy, and iterate pop doesn't do what we want when passed a list.
15:31 erochester: no. that's true too. hmm. what you posted might be your best option.
15:34 Chouser: naw, it ought to be lazy.
15:34 JamesIry: Lazy would be best - then you could handle infinite sequences
15:37 I can't help but think something based on map would work
15:38 Each element of the input sequence would get mapped to a sequence that ended with that element
15:41 Chouser: (take 10 (map take (iterate inc 0) (repeat [1 2 3])))
15:42 but you can't count your seq without killing the laziness.
15:49 erochester: This won't win any points for being short or elegant, but I think this works for both vectors and lists, it includes  (for inits behavior), and it's lazy. And it's ugly.
15:49 And did I mention, it's ugly?
15:50 Chouser: it does get the job done.
15:51 by using conj, each "inner" seq is a non-lazy vector. But that's probably fine since you had to calculate all the elements up the the one you're conjing already anyway.
15:52 erochester: I love how easy Clojure makes lazy sequences. I'd gotten used to that with Python, and then every time I went back to common lisp, I was banging my head against my desk.
15:52 You're right. Both about conj and about the assumption I was making that this would be all right.
15:52 Chouser: python does lazy sequences? I missed that somehow.
15:53 erochester: iterators/generators
15:53 Chouser: oh, right.
15:57 Nafai: Lazy sequences are really handy
16:01 Chouser: having to use lazy-cat is annoying.
16:01 and that might be even less efficient -- I don't know if it uses the same s every time, or if it will re-calculate things.
16:03 ok, it does not recalculate. so if I could just figure out how to make take-while go one step further and ditch lazy-cat...
16:16 erochester: That seems to do it. But I can't decide which one I prefer.
16:18 Chouser: you could replace the map and take-while with a for, :while, and destructuring. ...still don't know if that's any better though.
16:19 erochester: Yeah. That's probably a question of what you're used to.
16:22 Chouser: doubtless if rhickey chooses to include an inits, he will produce yet another implementation, and probably with a better name too. :-)
16:22 erochester: lol.
16:26 I think I've come up with about the best I'm going to do. At least until I walk away from the keyboard.
16:26 Chouser: :-)
23:45 ungraspiness: exit
23:55 jgrant: back