2011-10-16
| 00:51 | todun | I'm trying to figure out how this work. It seems simple but I'm not quite sure how inc does its work here. Any assistance is appreciated. http://pastebin.com/mFucfv5n |
| 00:54 | amalloy | todun: do you know what inc does? |
| 00:54 | todun | amalloy: inc a number right? |
| 00:54 | todun | by one |
| 00:54 | todun | so like java's ++ |
| 00:54 | amalloy | not ++, which implies mutation |
| 00:55 | amalloy | it just returns (+ 1 x) |
| 00:55 | todun | amalloy: oh. |
| 00:56 | todun | amalloy: in that case and with recursion in the picture, maybe I see what's happening. |
| 00:56 | todun | amalloy: so inc will keep returning (+ 1 x ) until size (rest v) is empty |
| 00:57 | todun | then all those will be combined? |
| 00:58 | todun | (+ 1 (+ 1 (+ 1 ...(0) ...))) |
| 00:58 | amalloy | indeed, but not (0) |
| 00:58 | amalloy | just 0. stop calling things as functions :) |
| 00:58 | todun | amalloy: oh. ha. |
| 00:59 | todun | (+ 1 (+ 1 ( + 1 ...(+ 1 0) ...) ) ) |
| 01:00 | ibdknox | amalloy: macro question for you |
| 01:01 | ibdknox | amalloy: let's say I have a macro (defmacro aw [q] (+ ~q ~q)) |
| 01:01 | amalloy | ibdknox: plus the missing `? |
| 01:01 | ibdknox | amalloy: er, yes |
| 01:02 | ibdknox | amalloy: will q be evaluated twice? |
| 01:02 | amalloy | yes |
| 01:02 | ibdknox | amalloy: so in such a case, you want to let the result? |
| 01:03 | amalloy | definitely |
| 01:03 | ibdknox | I'm not sure why I never internalized that until now |
| 01:03 | ibdknox | but it explains why my shit was broken :) |
| 01:05 | FrankL | What is a nice way to 'unpack' a map of set -> value relations? e.g. {#{:a :b :c} 1, #{:d} 2} would become {:a 1 :b 1 :c 1 :d 2} |
| 01:05 | amalloy | FrankL: actually, i have that code lying around somewhere |
| 01:06 | FrankL | amalloy, cool! |
| 01:06 | amalloy | https://github.com/flatland/useful/blob/develop/src/useful/map.clj#L172 |
| 01:07 | FrankL | wow, that's exactly what i was looking for |
| 01:07 | ibdknox | haha amalloy: I love this: (map (to-fix (! set?) hash-set) entry) |
| 01:07 | FrankL | thanks! |
| 01:07 | ibdknox | really just the (! set?) |
| 01:12 | amalloy | ibdknox: what's the point of having a utility library if you don't use it to make your code short |
| 01:12 | ibdknox | 's true |
| 01:12 | ibdknox | I just think it reads amusingly :) |
| 01:13 | amalloy | it does. mapping over a collection known to be two elements long is also good for a laugh |
| 01:14 | amalloy | FrankL: it's not exactly what you want, since it produces {:a #{1}} instead |
| 01:14 | ibdknox | all the cool kids are doing it these days :p |
| 01:17 | FrankL | yup |
| 01:18 | FrankL | and i have no idea what's going on in those functions! |
| 01:18 | FrankL | but figuring that out should teach me some things |
| 01:36 | devn | hey all |
| 01:37 | todun | I rewrote my nested reversal function from before to use recur. But now it just always returns an empty list. Am I misusing recur? Thanks. http://pastebin.com/hdRUYY9G |
| 01:38 | ibdknox | todun: you never put anything into acc |
| 01:39 | todun | ibdknox: uhm. |
| 01:39 | todun | ibdknox: let me try something. |
| 01:39 | ibdknox | right now you're just reversing an empty list for every element in lst |
| 01:40 | todun | ibdknox: It seems then I'm using recur rightly but doing recursion wrongly. |
| 01:43 | todun | ibdknox: is this a correct use of let? (recur (let [(rest temp-lst) acc]) (reverse acc) ))) or does the scope of using let have to be in the square-brackets? |
| 01:43 | ibdknox | todun: you have the let backwards |
| 01:44 | todun | how so? |
| 01:44 | ibdknox | ,(let [x (inc 1)] x) |
| 01:44 | clojurebot | 2 |
| 01:45 | todun | uhm. I misread then. thanks. |
| 01:45 | MGT | ,1 |
| 01:45 | clojurebot | 1 |
| 01:49 | kanja | http://pastebin.com/XtS20p38 |
| 01:49 | Raynes | ibdknox: Where is mah noir tryclojure? |
| 01:49 | todun | ibdknox: in your example you have x being the result type. I'm doing the following and it seems that acc isn't being updated. Do I have to put the result type after the let assignment(or I guess it's a local function)? (recur (let [acc (rest temp-lst)]) (reverse acc)))) |
| 01:49 | kanja | I'm getting can't resolve guess in this context - but I have no idea which guess it's talking about. Any ideas? |
| 01:50 | ibdknox | Raynes: I got distracted by more important things :p |
| 01:50 | Raynes | I feel unimportant now. |
| 01:50 | ibdknox | aw |
| 01:50 | ibdknox | but I'm doing it for the greater good! |
| 01:51 | Raynes | kanja: For one, you need to wrap each arity in parentheses. (defn sq-iter ([x] ..) ([guess x] ..)) |
| 01:51 | ibdknox | todun: the scope of the let is only valid for what's inside of it, your use of acc is outside of your let |
| 01:51 | Raynes | Second, don't put closing parens on they're on line. |
| 01:51 | Raynes | their* |
| 01:51 | Raynes | own* |
| 01:51 | todun | ibdknox: ok. thanks. let me try again.. |
| 01:52 | kanja | Raynes: Yeah - Sorry, still learning the syntax. |
| 01:52 | Raynes | I guess that doesn't excuse not being able to type. Maybe my fingers are throbbing with my head. |
| 01:52 | todun | Raynes: sorry. |
| 01:52 | ibdknox | Raynes: get off the computer... that only makes it worse |
| 01:52 | todun | Raynes: idomatic clojure? |
| 01:52 | Raynes | kanja: I wasn't scolding you, just giving you a heads up. :) |
| 01:52 | todun | *idiomatic. |
| 01:52 | Raynes | todun: I was replying to kanja actually. Haven't been following your particular conversation. |
| 01:52 | Raynes | ibdknox: flux helps. |
| 01:52 | todun | Raynes: ok. |
| 01:53 | kanja | :) |
| 01:53 | kanja | Thanks for the help |
| 01:53 | duck1123 | feel free to put parens on their own line while you're coding it, just remember to clean up all that wasted space when you're done |
| 01:53 | kanja | I'm used to emacs lisp so I'm all kind of wierded out :) |
| 01:53 | duck1123 | this is where paredit is great |
| 01:54 | Raynes | duck1123: Why encourage it at all? :p |
| 01:54 | kanja | I'm actually using paredit for the first time with this |
| 01:54 | kanja | I'm having a little trouble getting used to it |
| 01:54 | kanja | what's the right way to do the closing parens? all on the same line? |
| 01:54 | Raynes | Right. |
| 01:54 | ibdknox | Raynes: did you use the paredit clone for vim? |
| 01:54 | Raynes | One or two people in the universe disagree. |
| 01:54 | Raynes | ibdknox: Yes. It was nice. |
| 01:55 | ibdknox | hm, maybe I should do that |
| 01:55 | ibdknox | lol |
| 01:55 | duck1123 | I tend to be free with hitting enter while I'm coding so I have plenty of space to put new stuff, but I always clean up once I know I'm done for now |
| 01:55 | Raynes | ibdknox: Slurp, join, barf. Your life will be so improved. |
| 01:55 | ibdknox | haha |
| 01:55 | ibdknox | such nice names for the commands |
| 01:55 | kanja | haha |
| 01:56 | kanja | the default binding for them on emacs sucks |
| 01:56 | Raynes | duck1123: If there is even one parenthesis on a line alone, I freak out. My eyes start flashing red and sirens sound. It is the only thing I can think about until I fix it. |
| 01:56 | kanja | c-m-left for slurp |
| 01:56 | Raynes | Huh? |
| 01:56 | Raynes | It's C-left/C-right for me. |
| 01:56 | Raynes | No Ms about it. |
| 01:58 | kanja | huh, yeah |
| 01:58 | kanja | I guess I had it wrong |
| 01:59 | Raynes | Vim uses Leader< and Leader> |
| 01:59 | kanja | still not crazy about that though - I hate dropping down to the arrows |
| 01:59 | Raynes | I can't navigate with letter keys. My fingers don't work like that. |
| 01:59 | kanja | huh |
| 02:00 | duck1123 | I use the arrows more, but there's always times when the letters save my life |
| 02:00 | Raynes | Well, I mean character-by-character navigation. Not clever commands. Those are a different beast entirely. |
| 02:03 | kanja | clever commands? |
| 02:03 | duck1123 | C-t is a clever command |
| 02:03 | duck1123 | I never use it right |
| 02:03 | Apage43 | for me i didn't really get used to using letters for navigation until I got really into using all the keys in vi |
| 02:03 | Apage43 | and also xmonad |
| 02:04 | Apage43 | and now it's just a can't be arsed to move my fingers all the way over to the cursor keys thing |
| 02:04 | kanja | yeah that's kind of how I feel |
| 02:04 | kanja | although I haven't made the jump into a twm yet |
| 02:04 | Apage43 | kanja: i don't bother unless i've got a dual monitor setup |
| 02:05 | Apage43 | but in that case it really is nice. It's a "can't be arsed to move my mouse across two whole monitors and arrange crap manually on that much space" thing. |
| 02:05 | duck1123 | I'm a fan of stumpwm |
| 02:05 | kanja | Apage43: Yeah, I'm using a laptop right now without much screen space, but my friends have been yelling about i3 for a while now |
| 02:05 | duck1123 | I bind the stumpwm key to capslock |
| 02:06 | kanja | oof no good with emacs |
| 02:06 | kanja | I need that for control |
| 02:07 | duck1123 | I played with using menu for it, but I've since then assigned that to gnome-do |
| 02:07 | Apage43 | I still haven't been able to get used to using capslock for something else |
| 02:07 | Apage43 | i never really feel like touching that key |
| 02:07 | amalloy | duck1123: i also always forget to use C-t, so i rebound it to transpose-sexps, and now i use it all the time |
| 02:07 | duck1123 | ooh, transpose-sexps... need to learn that one |
| 02:08 | amalloy | you should really rebind caps lock, whatever editor you use. for me, it helped a lot to relieve emacs-pinky |
| 02:09 | kanja | yeah I could never use emacs w/o capslock |
| 02:09 | amalloy | i gather it's just as useful for vim |
| 02:09 | duck1123 | My left wrist has been messed up for like a week now. Damn emacs pinky |
| 02:10 | kanja | haha I just got bit by clj's ratios - the default case used 1 rather than 1.0 so I got a huge ratio and assumed my logic was bad |
| 02:10 | kanja | what's the use of the ratios? |
| 02:10 | kanja | more precision? |
| 02:11 | duck1123 | ,(+ 1/3 1/3 1/3) |
| 02:11 | clojurebot | 1N |
| 02:12 | kanja | what does the N mean? |
| 02:12 | amalloy | &(class 1N) |
| 02:12 | lazybot | java.lang.NumberFormatException: Invalid number: 1N |
| 02:12 | amalloy | ,(class 1N) |
| 02:12 | clojurebot | clojure.lang.BigInt |
| 02:12 | kanja | ah |
| 02:12 | kanja | ty |
| 02:12 | amalloy | i'm surprised that results in 1N rather than 1, duck1123 |
| 02:13 | todun | (recur (let [acc (rest temp-lst) acc (reverse acc)]) acc))) puts the acc in the [] scope. I yield it outside its scope so that recur can have access to its value. It still gives me an empty paren output. I'm obviously still doing something wrong. |
| 02:13 | ibdknox | is there some better way to execute a collection of functions over something than doing (reduce #(%2 %) ...)? My brain has stopped working. |
| 02:13 | duck1123 | amalloy: yeah, same here |
| 02:13 | ibdknox | huh |
| 02:13 | amalloy | ibdknox: ((apply comp fs) x)? |
| 02:13 | amalloy | i guess that goes in the wrong order |
| 02:13 | ibdknox | order doesn't matter |
| 02:14 | duck1123 | It's going to be hell. I've been trying to get Gloss working correctly with 1.3, but right now, just about every single test fails due to comparing ratios with floats |
| 02:14 | ibdknox | duck1123: woah, really? |
| 02:14 | ibdknox | ,(= 1/2 0.5) |
| 02:14 | clojurebot | false |
| 02:14 | ibdknox | ... |
| 02:14 | kanja | yikes |
| 02:14 | duck1123 | As far as I can tell, it still works, but all the tests fail |
| 02:15 | kanja | so uh, what's the point of the ratios? |
| 02:15 | ibdknox | wtf |
| 02:15 | kanja | sounds like they're causing issues |
| 02:15 | duck1123 | There was a thread on the ml about it. word of god was that was intentional and by design |
| 02:15 | amalloy | ,(= 1 (+ (/ 1.0 3) (/ 1 3) (/ 1 3))) |
| 02:15 | clojurebot | false |
| 02:15 | kanja | is clj not ducktyped then? |
| 02:16 | amalloy | that is why ratios exist |
| 02:16 | duck1123 | ,(== 0.5 1/2) |
| 02:16 | clojurebot | true |
| 02:16 | ibdknox | ,(doc ==) |
| 02:16 | clojurebot | "([x] [x y] [x y & more]); Returns non-nil if nums all have the equivalent value (type-independent), otherwise false" |
| 02:16 | kanja | ,(doc =) |
| 02:16 | clojurebot | "([x] [x y] [x y & more]); Equality. Returns true if x equals y, false if not. Same as Java x.equals(y) except it also works for nil, and compares numbers and collections in a type-independent manner. Clojure's immutable data structures define equals() (and thus =) as a value, not an identity, comparison." |
| 02:16 | ibdknox | is that new? |
| 02:16 | kanja | ah interesting |
| 02:16 | amalloy | ibdknox: no |
| 02:17 | duck1123 | == is ancient, iirc |
| 02:17 | amalloy | though i think the docstring is less true in 1.3 than it used to be |
| 02:17 | ibdknox | that doc string is wrong now, type does matter for numbers :p |
| 02:17 | amalloy | ibdknox: i don't remember what the difference is though, do you? |
| 02:18 | ibdknox | amalloy: nope |
| 02:18 | ibdknox | ,(= 1N 1) |
| 02:18 | clojurebot | true |
| 02:18 | ibdknox | ,(= 1/1 1) |
| 02:18 | clojurebot | true |
| 02:19 | duck1123 | ,(== [0.5] [1/2]) |
| 02:19 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 02:19 | ibdknox | I guess I should've looked at the numerics changes closer |
| 02:20 | ibdknox | ,(= 1 1.0) |
| 02:20 | clojurebot | false |
| 02:20 | ibdknox | are floats the only thing that don't play with everyone else now? |
| 02:20 | duck1123 | that one makes sense |
| 02:20 | ibdknox | duck1123: how so? |
| 02:21 | duck1123 | 1.0 is not really 1. 1.0 can approximate 1 but they're not really the same and that difference will bight you |
| 02:22 | duck1123 | Not that I often need that distinction in practice... |
| 02:23 | ibdknox | I haven't done enough real numerical stuff to know why that's the case, but that's counter intuitive to me :) |
| 02:23 | MGT | ,(== 1 1.0) |
| 02:24 | clojurebot | true |
| 02:25 | ibdknox | == seems like the simple solution though |
| 02:25 | ibdknox | assuming you don't care |
| 02:25 | duck1123 | generally though, you're going to know when you're going to be getting floats |
| 02:27 | MGT | ,(replicate 5 'a') |
| 02:27 | clojurebot | (a' a' a' a' a') |
| 02:27 | MGT | ,(replicate 5 "a") |
| 02:27 | clojurebot | ("a" "a" "a" "a" "a") |
| 02:28 | ibdknox | ,'' |
| 02:28 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 02:28 | ibdknox | ,'a' |
| 02:28 | clojurebot | a' |
| 02:28 | ibdknox | interesting |
| 02:28 | ibdknox | learn something new every day |
| 02:29 | amalloy | ibdknox: 1.3 adds terminating-quotes in symbols, yeah? |
| 02:29 | amalloy | or perhaps intervening |
| 02:29 | amalloy | ,'a'b |
| 02:29 | clojurebot | a'b |
| 02:30 | amalloy | mostly in order to get auto-promoting arithmetic operators like +' |
| 02:30 | ibdknox | I see |
| 02:30 | tomoj | didn't replicate get removed? |
| 02:30 | ibdknox | that would make sense |
| 02:30 | ibdknox | ,(doc replicate) |
| 02:30 | clojurebot | "([n x]); DEPRECATED: Use 'repeat' instead. Returns a lazy seq of n xs." |
| 02:31 | ibdknox | not yet |
| 02:31 | amalloy | three cheers for deprecation |
| 02:31 | MGT | ,(doc repeat) |
| 02:31 | clojurebot | "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs." |
| 02:31 | devn | why? |
| 02:31 | clojurebot | devn: because you can't handle the truth! |
| 02:31 | devn | lol |
| 02:31 | ibdknox | (inc clojurebot) |
| 02:31 | lazybot | ⟹ 7 |
| 02:31 | ibdknox | ~anyone |
| 02:31 | clojurebot | Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:32 | ibdknox | good |
| 02:32 | ibdknox | it doesn't say I will answer questions :p |
| 02:32 | devn | ^anti-community statement by clojurebot |
| 02:32 | devn | "don't waste my mother fucking time" |
| 02:32 | ibdknox | yeah |
| 02:32 | ibdknox | lol |
| 02:32 | ibdknox | he's got shit to do |
| 02:33 | MGT | how do i do clojure |
| 02:33 | devn | "I'm an important businessman and I am receiving telegraphs from important foreign dignitaries. Kindly phrase your question in a way that pleases me, else you may shut the fuck up." |
| 02:33 | devn | --clojurebot |
| 02:33 | amalloy | devn: yes please, *don't* waste my time by forcing me to say "yes, i am interested in answering a question" before i can hear your damn question |
| 02:33 | tomoj | "here's a tip that will make it more likely for you to get an answer" |
| 02:34 | devn | MGT: With great aplomb. |
| 02:34 | devn | MGT: That's how. |
| 02:34 | MGT | ,(doc aplomb) |
| 02:34 | clojurebot | Excuse me? |
| 02:34 | MGT | ??? |
| 02:34 | lazybot | MGT: Oh, absolutely. |
| 02:35 | devn | aplomb |əˈpläm, əˈpləm| |
| 02:35 | devn | noun |
| 02:35 | devn | self-confidence or assurance, esp. when in a demanding situation: Diana passed the test with aplomb . |
| 02:36 | ibdknox | clojurebot: anyone is <reply>Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 02:36 | clojurebot | c'est bon! |
| 02:36 | ibdknox | ~anyone |
| 02:36 | clojurebot | Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:36 | ibdknox | amalloy: what'd I do wrong? |
| 02:36 | devn | ibdknox: treat it like an infobot |
| 02:36 | devn | (that's what you did wrong) |
| 02:36 | amalloy | ibdknox: you need to tell him to forget the old one |
| 02:37 | devn | ibdknox: The old way was: "clojurebot: no, anyone is..." |
| 02:37 | devn | Not sure if it conforms to that or not |
| 02:37 | ibdknox | clojurebot: forget anyone is <reply>Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:37 | clojurebot | 'Sea, mhuise. |
| 02:37 | ibdknox | clojurebot: anyone is <reply>Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 02:37 | clojurebot | Ack. Ack. |
| 02:37 | amalloy | noooooo |
| 02:37 | ibdknox | ~anyone |
| 02:37 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 02:37 | devn | clojurebot: no, anyone is a funny thing. |
| 02:37 | clojurebot | Ik begrijp |
| 02:38 | devn | clojurebot: anyone |
| 02:38 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 02:38 | devn | immutability is a harsh mistress every now and again |
| 02:38 | amalloy | ibdknox: the syntax for deleting stuff is really awkward. usually you just end up adding more accidentally |
| 02:38 | ibdknox | lol |
| 02:38 | amalloy | clojurebot: forget anyone? |
| 02:38 | clojurebot | Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:39 | ibdknox | lol |
| 02:39 | amalloy | hm. anyway, my point is he's now learned a meaning for "forget anyone" |
| 02:39 | ibdknox | oh |
| 02:39 | ibdknox | whoops |
| 02:39 | ibdknox | what was the correct way then? |
| 02:39 | amalloy | clojurebot: forget anyone |is| <reply>Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:39 | clojurebot | I forgot that anyone is <reply>Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:39 | ibdknox | ah |
| 02:39 | amalloy | clojurebot: forget forget anyone |is| <reply>Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:39 | clojurebot | I forgot that forget anyone is <reply>Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 02:40 | amalloy | ~anyone |
| 02:40 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 02:42 | devn | wow, that's not confusing. |
| 02:43 | ibdknox | it's why I got it right on my first try ;) |
| 02:51 | MGT | http://pastebin.com/hBx6ZLSX |
| 02:51 | MGT | is the first function as efficient as the second? |
| 02:51 | MGT | oops |
| 02:52 | MGT | http://pastebin.com/5p9xDB7x corrected first function |
| 02:53 | duck1123 | MGT: you only need to check up to n/2 |
| 02:53 | MGT | well |
| 02:53 | MGT | I only need to check up to sqrt(n), strictly speaking |
| 02:53 | clojurebot | brain dump is http://clj.thelastcitadel.com/clojurebot |
| 02:53 | MGT | but the second one uses tail recursion |
| 02:54 | MGT | and I was wondering if that makes it faster |
| 02:54 | ibdknox | lol |
| 02:54 | ibdknox | clojurebot is so weird |
| 02:56 | duck1123 | MGT: some also uses recusion |
| 02:57 | MGT | is it tail recursion? |
| 02:57 | duck1123 | (when (seq coll) (or (pred (first coll)) (recur pred (next coll)))) |
| 02:57 | ibdknox | sweet |
| 02:58 | ibdknox | korma is getting somewhere now :D |
| 02:58 | MGT | sorry, what's that? |
| 02:58 | ibdknox | getting the table prefixes right was a lot harder than I expected |
| 02:58 | MGT | definition of some? |
| 02:58 | duck1123 | MGT: that's the source body of some |
| 02:58 | MGT | ok, thanks |
| 02:58 | MGT | I have to familiarize myself with seq |
| 02:59 | duck1123 | ibdknox: I look forward to giving korma a shot. (once I get back out of the Ruby hell i'm in at work) |
| 02:59 | ibdknox | duck1123: as of tonight it might actually be worth it |
| 03:00 | ibdknox | duck1123: still a few important loose ends I need to tie up |
| 03:00 | ibdknox | but I think I did the hard part |
| 03:00 | duck1123 | did you ever figure out that whole lazy map thing you were working on? |
| 03:01 | ibdknox | I punted on that for now |
| 03:01 | ibdknox | Right now it's set up that if you do a has-many |
| 03:01 | ibdknox | it maps executing that query over the result set |
| 03:02 | ibdknox | so in the case that a user has many addresses |
| 03:02 | ibdknox | (select user (with address)) would return back (map get-and-assoc-addresses users) |
| 03:03 | duck1123 | so are the records returned actual Records (in the defrecord sense) |
| 03:03 | ibdknox | not at this point |
| 03:03 | ibdknox | why, what are you thinking? |
| 03:03 | duck1123 | I rely on being able to determine the class of a record for a lot of Ciste |
| 03:04 | ibdknox | it would be trivial to add meta-data to it |
| 03:04 | ibdknox | saying where something came from |
| 03:04 | ibdknox | creating records dynamically sounds a lil scary |
| 03:05 | amalloy | (inc ibdknox) |
| 03:05 | lazybot | ⟹ 4 |
| 03:05 | tomoj | ciste? is that the gismu or a coincidence? |
| 03:05 | duck1123 | structure |
| 03:05 | tomoj | yeah :) |
| 03:07 | duck1123 | And then I named my identi.ca clone Jiksnu after jikca casnu for "social type of interaction" |
| 04:03 | tolstoy | When I hit "control-c" after "lein run," none of my shutdown hooks are run (Mac OSX). Is that because leiningen forks the JVM? (kill -2 <pid> works just fine). |
| 04:03 | amalloy | ibdknox: you could allow the user to pass you a constructor function at some point, and then dealing with records would be their problem |
| 04:06 | ibdknox | amalloy: that sounds reasonable, I was basically going to add something like that in anyways.. basically a transform that gets applied anytime the entity is retrieved |
| 04:06 | ibdknox | I say basically a lot when I get tired |
| 04:06 | ibdknox | lol |
| 04:06 | ibdknox | I was currently testing how slow string concat is |
| 04:07 | ibdknox | trying to determine if a query should use a single stringbuilder the whole way through |
| 04:07 | ibdknox | seems the difference of marginal practical value |
| 04:07 | ibdknox | I was generating around 30,000 complex queries a second |
| 04:08 | ibdknox | if you actually have a DB that can respond to that... |
| 04:08 | ibdknox | you're awesome :p |
| 04:09 | amalloy | ibdknox: basically, when you get tired, you say a lot |
| 04:10 | ibdknox | amalloy: haha fine. I'll go to bed. |
| 04:10 | amalloy | noooo, how will i query my databases? |
| 04:11 | ibdknox | I hear writing SQL by hand is fun :D |
| 04:12 | tolstoy | Ah, "lein trampoline" solves my problem. |
| 04:13 | ibdknox | alright folks, I've had enough SQL'ing for one day |
| 04:14 | ibdknox | g'nite! |
| 04:24 | archaic_ | i'm trying to unquote from a syntax quote without namespace resolution.. currently i'm using `(~(symbol "+")) to get the job done but i assume there is a better way? |
| 04:24 | amalloy | &`(... ~'+) |
| 04:24 | lazybot | ⇒ (... +) |
| 04:25 | amalloy | though you should usually think twice about why you want to do this |
| 04:26 | archaic_ | yeah thats the one.. thx.. the reason I want this.. I want to print data so I can view it easy.. but reuse it later in code.. otherwise I would get 3-4 lines of output with clojure.core/+ etc.. and I can't view results easy |
| 04:30 | zilti | I need a little help with 4clojure problem 21. What I have by now is #(fn [x] (if (= (count x) (+ (- (count %1) %2) 1)) (recur (rest x)) (first x))) %1) But that doesn't work?? |
| 04:30 | lazybot | zilti: What are you, crazy? Of course not! |
| 04:31 | zilti | lazybot: How could you answer before I released my return key? That's even too fast for a bot! |
| 04:32 | Raynes | amalloy: He has a point. lazybot is awfully fast for such a complexbot. |
| 04:33 | Raynes | I mean, he fires those hooks machine gun style. |
| 04:34 | zilti | That's why, one day, lazybot will take over the world - despite his lazyiness |
| 04:34 | amalloy | zilti: well, #(fn ...) has got to be a mistake |
| 04:34 | amalloy | you don't want to create a function that returns a function, you just want a plain old function |
| 04:35 | zilti | amalloy: I actually wanted to create a function that calls an anonymous function defined within it to use recursion and an additional val. |
| 04:35 | zilti | But I guess that's bad style? |
| 04:36 | amalloy | zilti: that's fine style, sometimes |
| 04:36 | amalloy | here you have some additional problems, like your parens don't match up |
| 04:36 | raek | zilti: a common technique is to let a function called "step" (or something similar) that does the recursion, and then simply call it with the initial parameters in the let body |
| 04:37 | amalloy | well. simpler to use loop/recur if you're going to be recur'ing anyway |
| 04:37 | raek | zilti: but with 'loop' and 'recur', you can often do without the let |
| 04:38 | zilti | I'll try it with let. I'll have to define "step" inside let, right? |
| 04:43 | raek | yes |
| 04:43 | zilti | argh. |
| 04:44 | raek | the idea is that you want to recur with one set of "loop parameters", but the outer function takes another set of parameters |
| 04:44 | zilti | So it is #(let[step (fn [x y z] (...))] (step %1 %1 %2))? But that gives me errors |
| 04:44 | raek | let's take ye olde factorial function as an example |
| 04:46 | raek | (fn factorial [n] (let [step (fn [acc i] (if (zero? i) acc (recur (* acc i) (dec i))))] (step 1 n)) |
| 04:47 | raek | you can rewrite this with loop and recur |
| 04:48 | raek | (fn factorial [n] (loop [acc 1, i n] (if (zero? i) acc (recur (* acc i) (dec i))))) |
| 04:51 | raek | this is also a possible way: |
| 04:51 | raek | (fn factorial [n] ((fn [acc i] (if (zero? i) acc (recur (* acc i) (dec i)))) 1 n)) |
| 04:51 | raek | I think that was what you tried to do originally |
| 04:51 | raek | notice the "((" |
| 04:52 | zilti | Why those? |
| 04:52 | MasseR | Then you evaluate the newly-created function |
| 04:53 | raek | the inner one is for the (fn ...), which creates a new function |
| 04:53 | zilti | I'm totally confused as of now. My solution for problem 21 still doesn't work. |
| 04:53 | raek | the outer one calls that function with the arguments 1 and n (in my case) |
| 04:53 | zilti | "Can only recur from tail" |
| 04:55 | raek | it is also possible to do recursion without TCO by replacing 'recur' with the name of the function |
| 04:55 | raek | anonyous functions can be named too :) |
| 04:55 | raek | (fn f [..] ..f is available here..) |
| 04:56 | raek | a variant of the factorial example that cannot be TCO'ed: |
| 04:56 | raek | (fn factorial [n] (if (zero? n) 1 (* n (factorial (dec n))))) |
| 04:58 | raek | the "(factorial (dec n))" call is not in tail position since the function does not return the result of that expression directly - the (* ..) call waits for its value |
| 05:00 | zilti | So recur-ing inside an if doesn't work as well? |
| 05:00 | amalloy | zilti: it does, because recur can still return immediately - the if "part" has already been evaluated |
| 05:01 | zilti | amalloy: But it doesn't work here. |
| 05:01 | amalloy | zilti: no, something else doesn't work :P |
| 05:01 | zilti | It says "can only recur from tail position" |
| 05:01 | amalloy | ~bug report |
| 05:01 | clojurebot | A bug report has three parts: What you did; what you expected to happen; what happened instead. If any of those three are missing, it is awfully hard to help you. |
| 05:02 | pyninja | Hi, is there a way to run my Ring app in one thread and create another thread which checks every minute for scheduled notifications and sends them? Is this even a good idea? I've kind of avoided threads so far in my life... |
| 05:03 | cark | java.util.Timer, its callback is on a separate thread |
| 05:03 | amalloy | pyninja: certainly it's possible. i don't see any immediate reason why it would be a terrible idea |
| 05:04 | pyninja | cark, amalloy: ok, cool |
| 05:04 | cark | carefull about the Timer callback tho, you'd better spawn another thread from there |
| 05:04 | cark | depending on your use case |
| 05:04 | amalloy | $javadoc java.util.Timer |
| 05:04 | lazybot | http://download.oracle.com/javase/6/docs/api/java/util/Timer.html |
| 05:04 | pyninja | how do you mean? |
| 05:05 | cark | i don't remember right now, but i seem to recall you should not raise exceptions from this callback |
| 05:05 | pyninja | hm ok thanks |
| 05:06 | cark | Timer tasks should complete quickly. If a timer task takes excessive time to complete, it "hogs" the timer's task execution thread |
| 05:06 | raek | pyninja: also take a look at http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledExecutorService.html |
| 05:06 | cark | that's why i was spawning threads |
| 05:06 | raek | it's more mature |
| 05:06 | cark | so it's not about exceptions after all =) |
| 05:07 | raek | http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newScheduledThreadPool(int) |
| 05:07 | pyninja | hm interesting |
| 05:08 | cark | reak: oh this one looks interesting |
| 05:08 | cark | so it picks a free thread from the pool and runs it ? |
| 05:09 | cark | yes that's exactly what pyninja needs |
| 05:10 | pyninja | yeah actually this way i wouldn't have to save scheduled notifications somewhere and send them all at once, i think i could just use scheduler.schedule |
| 05:11 | zilti | Why doesn't this recur work? http://pastie.org/2704759 |
| 05:11 | raek | cron4j is interesting too |
| 05:11 | amalloy | pyninja: i actually wrote a teenty-tiny wrapper around this java functionality a while ago, at https://github.com/amalloy/cronicle/blob/develop/src/cronicle/core.clj |
| 05:12 | pyninja | amalloy: oh, cool. thanks a lot! |
| 05:13 | amalloy | zilti: it's much easier to see the problem if you get the indentation to match with the parens: https://gist.github.com/76362d613a17d59369bb |
| 05:14 | amalloy | the call to (step lst) is actually inside the body of step, not in the outer function |
| 05:16 | amalloy | as an aside, putting braces on the previous line C-style is going to horribly mislead people, especially you. best to keep each open-paren right next to the thing it opens |
| 05:18 | zilti | Oh great. "You tripped the alarm! nth is bad!" I don't even use nth now. Well at least I don't get other errors. |
| 05:21 | amalloy | &(macroexpand '(fn [[x]] x)) ;; zilti - this is usually why that nth-message comes up, but i agree it's a terrible message and wish there were some simple way to explain the issue |
| 05:21 | lazybot | ⇒ (fn* ([p__15973] (clojure.core/let [[x] p__15973] x))) |
| 05:21 | amalloy | &(macroexpand '(let [[x] (range)] x)) |
| 05:21 | lazybot | ⇒ (let* [vec__15981 (range) x (clojure.core/nth vec__15981 0 nil)] x) |
| 05:29 | zilti | Bah. I get a class cast exception on the 4clojure REPL for code that works flawlessly in my REPL. |
| 05:30 | zilti | #((let[step (fn [frag] (if (= (count frag) (+ (- (count %1) %2) 1)) (first frag) (recur (rest frag))))] (step %1))) |
| 05:31 | raek | zilti: you have one pair of parens too much arount let |
| 05:31 | raek | *around |
| 05:33 | raek | also, I think it's easier to spot mistakes like this if you use the (fn ..) syntax instead of the #(..) syntax |
| 05:40 | robermann | hi |
| 05:54 | Borkdude | I'm developing a web noir app on my local machine, but I need to pass a callback url that needs to be in dev-mode "localhost:8080/smth" and on heroku obviously something else. how do I get the "localhost:8080" part programmatically ? |
| 06:26 | todun | I have been trying to fix this recursion for some time. I think I'm just missing something small, but cannot find it. Any help is appreciated: http://pastebin.com/cQsfNjW8 |
| 06:48 | hugod | todun: what does your let form return? |
| 06:49 | todun | hugod: uhm. I don't follow. |
| 06:49 | todun | do you mean what does it match? |
| 06:49 | todun | or yield. |
| 06:51 | todun | or if you mean return in the java sense, I didn't know let could return a value and did not write it thusly. |
| 06:56 | hugod | todun: the value the let form evaluates to |
| 06:56 | todun | hugod: oh ok. I'm not sure. |
| 06:56 | todun | hugod: I was using let so that I could have a computation part and a recursive part. |
| 06:57 | todun | the computation will give the recursive part its result. |
| 06:57 | todun | os so was the plan. |
| 06:57 | todun | the computation will reduce the problem. |
| 06:58 | hugod | ,(let [x 1]) |
| 06:58 | clojurebot | nil |
| 06:58 | todun | hugod: I see. |
| 06:59 | todun | maybe that's my problem, yes? |
| 07:00 | hugod | I'm not sure what the code is supposed to do, but I imagine that is part of the problem |
| 07:01 | zilti | Why doesn't that work: |
| 07:01 | zilti | ,(cons (1) ()) |
| 07:01 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 07:02 | todun | hugod: sorry. it does nested reversals of a list. |
| 07:03 | todun | hugod: so. I'd posted earlier and forgot that I should re-write the description. |
| 07:03 | todun | hugod: so I have reverse. and then, for each list within a list of lists, I want to reverse those so that the list is reversed at all levels. |
| 07:04 | stuarthalloway | ,(1) |
| 07:04 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 07:04 | hugod | todun: you might also want to println the value of acc and temp-lst inside the loop, to get an idea of what is happening |
| 07:04 | todun | hugod: I'm doing a bunch of recursive problems and almost all of them are not working. I believe it is my misuse of recur & loop. |
| 07:04 | todun | hugod: ok. |
| 07:05 | zilti | ,(cons '(1) ()) ; But how can I do that if I just have an argument instead of (1) ? |
| 07:05 | clojurebot | ((1)) |
| 07:05 | daniel__ | anyone ever got: unable to attach to a dyno when running a console session on heroku? |
| 07:06 | daniel__ | nvm, i had to add logging |
| 07:09 | stuarthalloway | ,(let [a '(1)] (cons a ())) |
| 07:09 | clojurebot | ((1)) |
| 07:13 | zilti | stuarthalloway: http://imgur.com/KZB38 |
| 07:13 | zilti | stuarthalloway: Fifth line is the problem, the (cons pack lst) part |
| 07:14 | stuarthalloway | zilti: it is pretty odd to use cons not conj btw |
| 07:16 | stuarthalloway | zilti: partition-by in core is a generalization of the fn you are writing, you should study it |
| 07:17 | stuarthalloway | ,(partition-by identity [1 1 2 1 1 1 3 3]) |
| 07:17 | clojurebot | ((1 1) (2) (1 1 1) (3 3)) |
| 07:19 | hugod | todun: the values passed to recur become the new values associated with the loop variables, so the value returned by let (which was nil) is being assigned to temp-lst on the next time through the loop |
| 07:20 | todun | hugod: uhm ok. I didn't realize this behavior was possible in let. |
| 07:24 | hugod | todun: see the example in http://clojure.org/special_forms#Special%20Forms--(recur%20exprs*) |
| 07:24 | todun | hugod: that makes sense. |
| 07:25 | todun | hugod: so instead of a nil result type, the result is the binding of y |
| 07:26 | todun | hugod: I'm just surprised it's affecting me, because I'm not using the result for anything. should I just set it to something? |
| 07:26 | todun | I thought recur didn't use the result from its first argument. |
| 07:28 | hugod | in your example, the first value passed to recur becomes the value of temp-lst on the next iteration (and the second argument becomes the the value of acc) |
| 07:29 | todun | uhm. ok. that was not the effect I thought of when writing this, but that does help my agenda in this problem. |
| 07:37 | todun | is it possible to do multiple args to a function in clojure and/or currying? http://pastebin.com/u0HsrHUk |
| 07:40 | zilti | todun: There are partials and varargs |
| 07:42 | todun | zilti: uhm. ok. will those let me do (defn yes [y] [n] ...) by default? |
| 07:48 | todun | Is there an inbuilt function to remove a specific item from a list so that the output sequence does not have the item so removed? thanks. |
| 07:53 | zilti | todun: afaik not, but you can partially apply functions using the "partial" macro |
| 07:54 | todun | zilti: ok. I'm reading that up now. |
| 07:55 | zilti | todun: There's no need for currying in a dynamic typed language. Currying is for using a multi-argument-function as an argument to a function that wants a single-argument-function as argument. |
| 07:55 | todun | zilti: also, I couldn't find anything on varargs wrt clojure. will it be like (defn yes [*var] ...)? |
| 07:56 | zilti | todun: The varargs symbol is &, not * |
| 07:56 | todun | zilti: the reason I asked to curry was so I could have multiple args which may or maynot bind. |
| 07:56 | todun | zilti: so (defn yes [&var] ...) ? |
| 07:59 | zilti | todun: almost. (defn yes [& var] ... ) |
| 08:01 | todun | zilti: thanks. |
| 08:01 | todun | zilti: also do you know of any inbuilt function to remove a specific item from a list? |
| 08:03 | zilti | todun: sequences/filter |
| 08:04 | todun | zilti: ok. I'll check it out. thanks. |
| 08:04 | zilti | actually, it's in core, not sequences |
| 08:04 | zilti | http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/filter |
| 08:05 | todun | zilti: I've been having a hard time finding so many high order functions. Is there some repo list I can go to find stuff like this? |
| 08:06 | zilti | todun: Well, there's http://clojure.github.com/clojure/ and http://clojuredocs.org/ but you're right, it's kinda hard if you don't know what you're looking for. |
| 08:07 | todun | zilti: thanks. checking those out. |
| 08:14 | todun | zilti: I'm trying to build a grelim zapper. to that end, I'm trying to construct a string containing all valid stuff I'm interested in and another containing all ASCII characters so I can filter out the good from the bad using both lists. Is there an easier way to do this? |
| 08:14 | todun | zilti: for instance in python I can call something like ascii and I'll have all the ascii characters. |
| 08:15 | todun | or something like that. |
| 08:15 | todun | thanks. |
| 08:17 | zilti | todun: I don't know. I'm quite new to Clojure as well. Sorry. |
| 08:17 | todun | zilti: thanks all the same. :-) |
| 08:18 | zilti | todun: No problem :) |
| 08:23 | todun | zilti: going back to your suggestion about my nested rreversal's use of let, I try that but then I break its validity like so: http://pastebin.com/JugyPFux |
| 08:23 | todun | zilti: perhaps you can see something I'm doing wrong... |
| 08:23 | todun | thanks. |
| 08:42 | hugod | todun: what are you trying to do by using a let? |
| 08:44 | todun | hugod: I'm trying to preserve the value of acc, then transfer it to the second argument of recur. Also to make sure that acc doesn't hold on to its older value(an empty list) for every iteration of the loop. |
| 08:46 | hugod | todun: you can't affect the value of acc on the next iteration, except through the second argument to recur |
| 08:47 | hugod | let can only change the values bound to symbols within its body |
| 08:49 | hugod | todun:so what I think you want is something like (recur (next tmp-lst) (reverse (conj acc (first tmp-list)))) |
| 08:50 | todun_ | hugod: ok. I'm trying that now... |
| 08:53 | hugod | todun: what would you expect (let [x 1] (let [x 2]) (println x)) to print? |
| 08:53 | todun | hugod: the value of the last block evaluated. |
| 08:54 | todun | hugod: so 2 |
| 08:54 | todun | I mean. the value of the last block that binds x's value. |
| 08:54 | todun | I'm wrong. |
| 08:55 | todun | the repl says 1 \n nil \n :-P |
| 08:56 | kjeldahl` | One parens too many after the second let expression []... |
| 08:56 | kjeldahl` | Move it to after the print... |
| 08:57 | kjeldahl` | ,(let [x 1] (let [x 2]) (println x)) |
| 08:57 | clojurebot | 1 |
| 08:57 | kjeldahl` | ,(let [x 1] (let [x 2] (println x))) |
| 08:57 | clojurebot | 2 |
| 09:01 | todun | kjeldahl`: it ran ok as is in the repl for me though. |
| 09:03 | kjeldahl` | todun: If the expression you posted shows 2 in your repl, your repl is mistaken. |
| 09:04 | todun | it shows 1 :-D |
| 09:05 | kjeldahl` | Which is correct. Maybe I just did not understand your question. I though you expected it to show 2, but now I'm not sure. |
| 09:07 | todun | hugod: I get an exception when I tested it: http://pastebin.com/GLZf48dC |
| 09:07 | todun | kjeldahl`: yes I expected it to show 2. but when I did it in the repl, it showed 1. |
| 09:07 | todun | kjeldahl`: and so it was my reasoning about it that was wrong. |
| 09:08 | hugod | todun: don't worry about loop until you understand the lexical scope of let |
| 09:08 | todun | kjeldahl`: I was asking you why you made the comment about the parens. |
| 09:08 | todun | hugod: ok. |
| 09:09 | hugod | loop is not something you need to learn initially |
| 09:10 | todun | hugod: but how can I accomplish my recursion without it? |
| 09:11 | hugod | todun: don't worry about anything until you understand why you got a 1 instead of a 2 |
| 09:11 | todun | hugod: ok. |
| 09:13 | todun | hugod: is this because the value of println x binds to the x coming from the outer let? |
| 09:14 | hugod | the println isn't within the body of the second let, so it sees the value bound by the first let |
| 09:16 | todun | hugod: oh ok. so it binds only with the (let ) scope. |
| 09:16 | todun | hugod: I thought let was more restrictive in that it bound within the [] scope, no? |
| 09:19 | todun | hugod: between, do you know how to use variable arguments in clojure? I'm having a hard time tracking down an explanatory example. thanks. |
| 09:22 | hugod | todun: variable arguments, or multiple arguments? |
| 09:23 | todun | hugod: actually both. |
| 09:23 | todun | hugod: but I think I was making a mistake in my multi-arg...(defn yes [y] [n]...) |
| 09:23 | hugod | todun: (defun f [a b] (println a b)) |
| 09:24 | todun | hugod: wow! that makes more sense! thanks. |
| 09:24 | todun | hugod: now I find examples. I was searching for the wrong thing. |
| 09:24 | hugod | for varargs (defun [a & b] (println a b)) |
| 09:25 | todun | hugod: I was searching for variable arguments instead of multiple arguments. |
| 09:31 | todun | hugod: also, do you know if there is an inbuilt function to make a shell of nested loops? So instead of making the loop flat using flatten, I want to "ghost" the list of its elements. |
| 09:33 | gfredericks | todun: I would like to help but I have no idea what you're talking about |
| 09:34 | todun | gfredericks: an example should solve that problem. :) |
| 09:34 | todun | given (1 (a (eqsd vsa)) 5 6 (7) ( )), the result is ((( )) ( ) ( )). |
| 09:35 | todun | gfredericks: sorry about the confusion :-P |
| 09:35 | gfredericks | ah; so you're want to take a nested list and remove all the elements but keep the structure |
| 09:36 | todun | gfredericks: yes. that sounds like the proper way of saying it too. thanks. |
| 09:36 | gfredericks | well the (sequential?) function could help you pick between the things that are lists and the things that aren't |
| 09:36 | gfredericks | so ##(filter sequential? '(1 (a (eqsd vsa)) 5 6 (7) ( ))) |
| 09:36 | lazybot | ⇒ ((a (eqsd vsa)) (7) ()) |
| 09:37 | gfredericks | and then you can recursively map each one |
| 09:37 | gfredericks | so... |
| 09:37 | Bronsa | m |
| 09:37 | todun | gfredericks: thanks. that helps. |
| 09:37 | todun | gfredericks: I've actually been stuck almost all weekend on recursion. |
| 09:38 | todun | gfredericks: all my recursive implementations seem to not be working. |
| 09:38 | gfredericks | todun: did you want to see my implementation or try it yourself? :) |
| 09:38 | todun | gfredericks: try it out myself. |
| 09:38 | gfredericks | okay |
| 09:38 | todun | gfredericks: but I would like help on recursion. |
| 09:38 | gfredericks | I'm out for breakfast; have fun |
| 09:38 | gfredericks | will be back before too long, if you have specific questions |
| 09:39 | todun | gfredericks: thanks. will compose then as you munch. |
| 10:00 | gfredericks | todun: how's it going? |
| 10:01 | todun | still trying different things and reading more on the topic. |
| 10:01 | gfredericks | it occured to me that a lot of the recursive things you're trying could be handled by clojure.walk; which might again ruin your quest to "learn recursion" |
| 10:02 | todun | gfredericks: let me read up on that..one sec. |
| 10:02 | todun | gfredericks: I also want to use more higher order functions to jump out of the imperative mindset.. |
| 10:04 | todun | gfredericks: it seems walk is like a generator of sorts, no? |
| 10:05 | gfredericks | walk lets you do things recursively to nested stuff |
| 10:05 | gfredericks | without having to do the recursion yourself |
| 10:05 | gfredericks | I just wrote your "list-ghosting" function with postwalk |
| 10:06 | todun | gfredericks: didn't find anything on the postwalk function. |
| 10:07 | gfredericks | http://clojure.github.com/clojure/clojure.walk-api.html#clojure.walk/postwalk |
| 10:09 | todun | gfredericks: uhm ok. I must have been using google wrongly. let me play with postwalk. thanks. |
| 10:20 | todun | gfredericks: do I have to do some import? I keep getting source not available at the repl http://pastebin.com/5wJLKiAz |
| 10:20 | todun | thanks. |
| 10:25 | gfredericks | (use 'clojure.walk) |
| 10:26 | todun | gfredericks: ok. let me try that. thanks. |
| 10:26 | gfredericks | yep |
| 10:27 | ghiu | hi, anyone with a bit of experience in compojure? |
| 10:27 | gfredericks | aye |
| 10:28 | shales | In clojurescript, how do I produce javascript like window["main"]? (aget window "main") isn't working |
| 10:28 | gfredericks | does (.main window) not work? |
| 10:28 | ghiu | gfredericks: this route definition doesn't work (GET "/add/?d=:d" [d] (add-gallery d)) <- can't i directly bind query string params? |
| 10:29 | gfredericks | ghiu: I don't think you need that explicit query string in the route |
| 10:29 | gfredericks | it'll collect all the query params for you, and you can bind them too, though I'm not sure the exact syntax. Might be (GET "/add/" {d :d} ...) or something like that |
| 10:30 | ghiu | (checking ) |
| 10:31 | shales | gfredericks: no, window/main produces window.main, but I want to use javascripts array notation to avoid the advanced compiler renaming "main" |
| 10:32 | gfredericks | shales: okay. I don't know clojurescript well enough to keep helping then, sorry |
| 10:32 | todun | gfredericks: it seems I have to cast the result of the inner seq to that taken by postwalk. |
| 10:32 | gfredericks | todun: eh? |
| 10:32 | todun | gfredericks: I get an exception. |
| 10:32 | todun | http://pastebin.com/r1jra2n2 |
| 10:33 | todun | and I was wondering if the fix was to cast the inner input into the the expected type of the outer one. |
| 10:33 | gfredericks | todun: that's an exception you get if you're accidentally calling a seq like it's a function: ##((range 12)) |
| 10:33 | lazybot | java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn |
| 10:33 | todun | since clojure is dynamically typed, I was not sure that was neccessary.(for I think of dynamic typing to be like automatic gear) |
| 10:34 | gfredericks | todun: yeah I don't think casting means anything in clojure |
| 10:34 | todun | gfredericks: oh. you can't do that in clojure? |
| 10:34 | todun | gfredericks: I thought it was functional |
| 10:34 | gfredericks | todun: you can't call a seq like a function, no |
| 10:34 | gfredericks | what would you expect it to do? |
| 10:35 | todun | I thought it was a value |
| 10:35 | gfredericks | a seq is a value, but it is not a function |
| 10:35 | gfredericks | vectors are functions, and you could maybe want seqs to act like that, but they don't |
| 10:35 | gfredericks | &([7 8 3] 1) |
| 10:35 | lazybot | ⇒ 8 |
| 10:35 | todun | gfredericks: sorry. I meant I thought functions were values..equational reasoning. |
| 10:36 | todun | gfredericks: ok. |
| 10:36 | gfredericks | todun: they are in the sense you're probably thinking of, but that doesn't mean that everything is a function. in particular a seq is not a function, so you can't call it. |
| 10:36 | bpsm | todun: functions are values; but not all values are functions. |
| 10:36 | gfredericks | todun: just like you can't call a number: ##(7 :foo "bar") |
| 10:36 | lazybot | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 10:36 | todun | gfredericks: bpsm I see. thanks. |
| 10:36 | gfredericks | or a string ##("AHAHAHHA") |
| 10:36 | lazybot | java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn |
| 10:36 | ghiu | gfredericks: nope, it doesn't work |
| 10:37 | todun | gfredericks: so putting a & makes it a value? |
| 10:37 | gfredericks | ghiu: how so? |
| 10:37 | gfredericks | todun: no, & is for varags |
| 10:37 | todun | gfredericks: ok. |
| 10:37 | gfredericks | todun: it's hard for me to know what you're thinking about without seeing the code |
| 10:37 | todun | gfredericks: sorry. I thought I posted it.. |
| 10:37 | todun | let me repost. |
| 10:38 | gfredericks | not lately; last paste was just the error message |
| 10:38 | todun | gfredericks: ok. one second.. |
| 10:39 | todun | gfredericks: http://pastebin.com/1dvPXe3V |
| 10:39 | gfredericks | is the fastest way to get the last element of a vector just (v (dec (count v)))? |
| 10:40 | gfredericks | todun: my first result was a bit like that, so I made the same mistake you did |
| 10:40 | todun | gfredericks: I feel encouraged already. |
| 10:40 | gfredericks | todun: postwalk is going to call the function you give it on every element in the structure, including the leaves (e.g., the numbers) which are not seqs, so the function has to be able to handle both types |
| 10:41 | gfredericks | my function started with #(if (sequential? %) ...) |
| 10:41 | todun | ,(%) |
| 10:41 | ghiu | gfredericks: even this doesn't work and gives me page not found .. (GET "/add/" {params :params} (params :d));;(add-gallery d)) |
| 10:41 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: % in this context, compiling:(NO_SOURCE_PATH:0)> |
| 10:41 | gfredericks | todun: Oh I just noticed you aren't even passing a function |
| 10:41 | gfredericks | todun: the first argument to postwalk has to be a function |
| 10:41 | ghiu | gfredericks: calling /add?d=http://asasdasd |
| 10:42 | todun | gfredericks: uhm.. |
| 10:42 | gfredericks | ghiu: I think compojure is sensitive to trailing slash |
| 10:42 | ghiu | (GET "/add" …. doesn't work either! |
| 10:43 | gfredericks | ghiu: it should at least get there, whether or not the query binding works. Can you get it to work with no query-string or binding at all? |
| 10:43 | gfredericks | todun: in higher-order-functions like postwalk you often have to pass it a function |
| 10:44 | todun | gfredericks: (defn f [some-list] (filter sequential? some-list) |
| 10:44 | todun | gfredericks: so I will pass f to it, no? |
| 10:44 | gfredericks | todun: you can do it at the top level using defn like you just suggested |
| 10:44 | gfredericks | you can also give the function inline with (fn [some-list] (filter sequential? some-list)) |
| 10:45 | gfredericks | or more compactly, #(filter sequential? %) |
| 10:46 | todun | gfredericks: ok. so #(filter sequential? %) will be the arg to postwalk? |
| 10:46 | ghiu | gfredericks: this works (GET "/add" {params :params} "asd");;(add-gallery d)) when calling http://127.0.0.1:8080/add?d=http://google.com |
| 10:46 | gfredericks | ghiu: and then it complains it doesn't know what d is? |
| 10:46 | gfredericks | todun: yes |
| 10:47 | gfredericks | todun: you'll get an error on that, but it'll be a different error and you'll be a step closer :) |
| 10:47 | todun | gfredericks: ok. trying that. allot of new syntax and concepts here. so will quickly read up some. |
| 10:48 | todun | gfredericks: I actually tried my way first. and I get another illegalArg exception |
| 10:48 | todun | this time for integers. |
| 10:49 | gfredericks | todun: that's what I was thinking of when I said it was the same mistake I had made |
| 10:49 | ghiu | (GET "/add" {params :params} "asd") -> (GET "/add" {params :params} (params :d) -> error |
| 10:49 | gfredericks | the issue is that the function #(filter sequential? %) is going to be passed both the lists in the structure AND the leaf elements like the numbers |
| 10:49 | gfredericks | so it has to handle both |
| 10:49 | todun | I'm guessing because I have to make multiple functions and guard the inputs to postwalk? |
| 10:49 | gfredericks | right now that function just assumes its argument is a sequence because it passes it to filter |
| 10:49 | todun | true |
| 10:50 | gfredericks | ghiu: what's the error? |
| 10:50 | gfredericks | todun: so the next step would be to expand that function so it handles both cases, e.g. using if |
| 10:50 | gfredericks | in the case that the argument is not a function, you can just return the argument, as there's no transformation to do |
| 10:50 | gfredericks | s/function/seq/ |
| 10:50 | lazybot | <gfredericks> in the case that the argument is not a seq, you can just return the argument, as there's no transformation to do |
| 10:52 | todun | gfredericks: ok. let me try something... |
| 10:52 | ghiu | gfredericks: seems like params keys are strings, not keyword, but anyway, i get no error, it simply return "Page not found" that is my not-found rute |
| 10:53 | gfredericks | ghiu: you go from a 200 to a 404 just by changing the body of the route? |
| 10:54 | todun | gfredericks: between I was trying to correct this code I found online. The error is in float. It takes too many arguments. But I'm not sure how to make sure it takes one argument and still preserve the logic of if. http://pastebin.com/VXgWKFP8 |
| 10:55 | ghiu | gfredericks: yes |
| 10:56 | gfredericks | todun: that makes me think he defined a function called float= somewhere and had a typo when trying to refer to it |
| 10:56 | gfredericks | ghiu: then that is weird and I am confused. |
| 10:56 | todun | gfredericks: yes. that makes sense. woah, clojure truly is homoiconic if it can let you define such a token. thanks. |
| 10:57 | gfredericks | that just means it has permissive syntax for its symbols |
| 10:57 | gfredericks | (type 'float=) |
| 10:57 | gfredericks | ,(type 'float=) |
| 10:57 | clojurebot | clojure.lang.Symbol |
| 10:57 | gfredericks | ,(type '=) |
| 10:57 | clojurebot | clojure.lang.Symbol |
| 10:58 | todun | gfredericks: in clojure is permissive "syntaxing" the same as homoiconicity? |
| 10:59 | gfredericks | todun: no, homoiconicity is the fact that all of the clojure code is a clojure data structure; (+ 3 4) is a list of three elements: a symbol and two numbers |
| 10:59 | gfredericks | and it is also valid clojure code |
| 11:00 | gfredericks | try ((juxt eval reverse) '(+ 3 4)) in your repl |
| 11:00 | todun | gfredericks: ok... |
| 11:00 | gfredericks | I can't do it with the bots because they don't like eval |
| 11:00 | todun | gfredericks: ok. I did. |
| 11:00 | todun | strange |
| 11:01 | todun | never used eval before. |
| 11:01 | gfredericks | the point is you can treat the list like code (with eval) or like a list (with reverse) |
| 11:01 | gfredericks | that's what homoiconicity is talking about |
| 11:02 | todun | gfredericks: code is data, data is code..depending on context. |
| 11:03 | gfredericks | ,(map type '(defn foobar [& xs] (apply + xs))) |
| 11:03 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 11:03 | gfredericks | wut |
| 11:03 | gfredericks | oh geez |
| 11:03 | gfredericks | you could try that in the repl too |
| 11:03 | gfredericks | maybe try guessing what the output will be first |
| 11:03 | todun | gfredericks: strange. |
| 11:04 | todun | gfredericks: but seemingly in line with what we'e talking about. |
| 11:04 | gfredericks | if you look at (defn foobar [& xs] (apply + xs)) as a data structure it should make sense |
| 11:04 | gfredericks | you should notice of course when I'm using the single-quote character to "quote" things |
| 11:05 | gfredericks | it's what keeps the code as a data structure instead of being evaluated |
| 11:05 | todun | gfredericks: making it a list. |
| 11:05 | gfredericks | ,(map type [(+ 3 4) '(+ 3 4)]) |
| 11:05 | clojurebot | (java.lang.Long clojure.lang.PersistentList) |
| 11:05 | gfredericks | ,(list (+ 3 4) '(+ 3 4)) |
| 11:05 | clojurebot | (7 (+ 3 4)) |
| 11:06 | todun | gfredericks: ok. it preserves the data |
| 11:06 | todun | and executes the code. |
| 11:06 | todun | so what did you mean by permissive syntax? |
| 11:07 | gfredericks | todun: just that float= is a valid symbol, which I assume is what you were commenting on |
| 11:08 | gfredericks | my son just woke up so my attention will be sparse from here on out |
| 11:09 | todun | gfredericks: ok yes that's what I was talking about. thanks for all your help. I will come back to this latter in the day. perhaps we can talk more about recursion then. thanks again. |
| 11:55 | ghiu | can anyone check my problem with compojure out? it's described here: http://stackoverflow.com/questions/7785214/compojure-how-to-map-query-parametershttp://stackoverflow.com/questions/7785214/compojure-how-to-map-query-parameters |
| 11:56 | ghiu | ehm http://stackoverflow.com/questions/7785214/compojure-how-to-map-query-parameters |
| 12:00 | kjeldahl` | Isn't params bound by default, see http://en.wikibooks.org/wiki/Compojure/Core_Libraries |
| 12:01 | kjeldahl` | In the 3rd example in the SO article, skip the {...} stuff and it should just work? |
| 12:02 | kjeldahl` | See "servlet bindings" in the wikibooks link. |
| 12:04 | ghiu | kjeldahl`: i've just checked out and get parameters are not bound by default, there's a middleware for that |
| 12:05 | ghiu | kjeldahl`: but i still don't get why "add?:u" doesn't works as expected |
| 12:09 | zakwilson | Is it normal that a jar built under the Sun JDK isn't entirely reliable unde the Open JDK? |
| 12:12 | kjeldahl` | ghiu: I've struggled with the same a long time ago, and I do believe that the params map was (or is) bound by default, but I do not have a handy example. The compojure source also indicates this, by wrapping wrap-keyword-params by default. |
| 12:14 | ghiu | how did you work it out? |
| 12:15 | kjeldahl` | Aha! |
| 12:15 | kjeldahl` | See https://github.com/weavejester/compojure - Breaking changes! |
| 12:25 | ghiu | kjeldahl`: oh! thank you, but… it doesn't seem to work either :( query parapets are still missing from params |
| 12:31 | ghiu | kjeldahl`: is wrap-params supposed to put query params into params? |
| 12:36 | kjeldahl` | ghiu: See the SO page, put working example there. |
| 13:39 | daniel__ | ibdknox: good evening. i was thinking it would be a nice little project to write a web framework in clojure, could you give me any advice on where to start? |
| 13:41 | ibdknox | daniel__: a web framework? That seems like an odd project to do :p |
| 13:41 | ibdknox | daniel__: it depends on how low level you want to go |
| 13:46 | daniel__ | ibdknox: not too low level |
| 13:46 | daniel__ | i dont want to write a server for example |
| 13:47 | ibdknox | daniel__: well ring will start you at the level oh http-request/http-response |
| 13:47 | ibdknox | of* |
| 13:48 | daniel__ | yes, thats about right |
| 13:51 | pyninja | why would I get a "No matching method found: schedule for class java.util.concurrent.ScheduledThreadPoolExecutor" error? it's obviously there: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html |
| 13:51 | ibdknox | daniel__: out of curiosity, is there something that drives you to do this? or is just an interest in learning how such a thing is done? |
| 13:52 | ibdknox | pyninja: gist your code |
| 13:52 | pyninja | ibdknox: https://gist.github.com/b1b8561713cc5adf1611 |
| 13:53 | daniel__ | ibdknox: yes, just an interest |
| 13:55 | terom | daniel__: there's also a framework called conjure, which could be worth looking into |
| 13:56 | dnolen | pyninja: that works just fine for me. what version of Clojure? |
| 13:57 | pyninja | dnolen: 1.2 i think |
| 13:57 | dbushenko | hello guys! |
| 13:57 | pyninja | dnolen: 1.2.1 actually |
| 13:57 | dnolen | pyninja: then you probably need to cast 5 to long with (long 5) |
| 13:58 | pyninja | dnolen: oh, awesome, thanks |
| 13:58 | ibdknox | pyninja: yep, (long) |
| 13:59 | pyninja | how would i cast the first argument? because now it says "java.lang.IllegalArgumentException: More than one matching method found: schedule" |
| 13:59 | ibdknox | pyninja: (.schedule *timer* (fn [] (println "woo")) (long 4) (TimeUnit/MILLISECONDS)) |
| 14:00 | pyninja | ibdknox: that still gives the same error for me |
| 14:00 | dnolen | ,(bases (class #())) |
| 14:00 | clojurebot | (clojure.lang.AFunction) |
| 14:01 | dnolen | ,(supers (class #())) |
| 14:01 | clojurebot | #{clojure.lang.IMeta clojure.lang.AFunction clojure.lang.IFn clojure.lang.IObj java.util.concurrent.Callable ...} |
| 14:01 | ibdknox | pyninja: does your timer creation look something like this? (def *timer* (. Executors newScheduledThreadPool 1)) |
| 14:02 | dnolen | ,((supers (class #())) java.lang.Runnable) |
| 14:02 | clojurebot | java.lang.Runnable |
| 14:02 | dnolen | ,((supers (class #())) java.util.concurrent.Callable) |
| 14:02 | clojurebot | java.util.concurrent.Callable |
| 14:03 | pyninja | ibdknox: hm it worked with that timer. |
| 14:04 | pyninja | ibdknox: i was using https://gist.github.com/2fc8d3345af793d78ebf |
| 14:05 | ibdknox | pyninja: that memoize doesn't make sense to me |
| 14:05 | pyninja | ibdknox: me neither. copied it from https://github.com/amalloy/cronicle haha |
| 14:05 | ibdknox | hah! amalloy is to blame! |
| 14:07 | ibdknox | pyninja: he's planning ahead for something that you're probably less likely to run into. Are you only ever going to have one pool? |
| 14:07 | pyninja | yeah, i think (. Executors newScheduledThreadPool 1) should work for me |
| 14:07 | pyninja | thanks for the help |
| 14:07 | ibdknox | pyninja: yeah do that. Although you probably want more than 1 thread :) |
| 14:08 | pyninja | and dnolen also |
| 14:08 | pyninja | yeah |
| 14:09 | hiredman | (Executors/newScheduledThreadPool 1) |
| 14:10 | khalid | suggest good project source to read |
| 14:11 | ibdknox | khalid: depends on what you want to learn |
| 14:12 | pyninja | hiredman: nice |
| 14:22 | khalid | functional programming (not concurrency specific topics - refs, etc. initially) |
| 14:35 | khalid | I am a newbie and need some help to be upto speed in clojure |
| 14:35 | khalid | have a text mining project and am suggesting clojure |
| 14:36 | khalid | competition is obviously scala |
| 14:36 | khalid | I am liking Clojure - looks pretty fast - just basic things I have played with |
| 14:37 | kjeldahl | ibdknox: Care to clarify how to call render to render a link such as "/adm/user/:username"? I've read the docs and done some test, but I'm still struggling. |
| 14:37 | theignorati | how would I create a map with multiple ranges (range 0 7) (range 16 23) etc as keys, all having nil as value? |
| 14:37 | kjeldahl | ibdknox: noir related, if that wasn't obvious already. |
| 14:37 | ibdknox | kjeldahl: (render "/adm/user/:username" {:username "hey"}) |
| 14:38 | khalid | I am experienced in other lang and want to grok on some real good code |
| 14:38 | kjeldahl | ibdknox: Ah, thanks. I missed the fact that I needed the : part in the first param. |
| 14:41 | OpenJuicer | Hi, is there a way to install the latest clojure with leiningen? |
| 14:41 | raek | theignorati: something like (let [keys (concat (range 0 7) (range 16 23))] (into {} (for [key keys] [key 0]))) perhaps? |
| 14:41 | ibdknox | OpenJuicer: just add org.clojure/clojure "1.3.0" as a dep in your project |
| 14:42 | ibdknox | hm |
| 14:42 | ibdknox | zipmap ftw here |
| 14:42 | ibdknox | (zipmap (concat (range 0 7) (range 16 23)) (repeat nil)) |
| 14:42 | ibdknox | ,(zipmap (concat (range 0 7) (range 16 23)) (repeat nil)) |
| 14:42 | theignorati | thanks I have (zipmap (concat (range 0 7) (range 5 17)) (cycle [nil])) now |
| 14:42 | clojurebot | {0 nil, 1 nil, 2 nil, 3 nil, 4 nil, ...} |
| 14:42 | theignorati | heh |
| 15:05 | pcavs | what's a good library for parsing html in clojure? I just want to scrape google for the top hit for a query. |
| 15:05 | raek | pcavs: enlive |
| 15:06 | raek | https://github.com/swannodette/enlive-tutorial |
| 15:08 | Lajla | Chousuke, my beloved, what is the Finnish word for 'trip' or 'voyage', I take it I can't just say mennäys right? |
| 15:17 | pcavs | raek: many thanks, following it now |
| 15:22 | daniel__ | whats clojure.lang.IFn? |
| 15:27 | duck1123 | daniel__: that's the interface that clojure functions implement |
| 15:27 | gfredericks | ,(map #(instance? clojure.lang.IFn) [#(+ 3 4) {} [] () 15 "hehe" :okay]) |
| 15:27 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox$eval27$fn> |
| 15:27 | gfredericks | wut. |
| 15:28 | gfredericks | oh |
| 15:28 | gfredericks | ,(map #(instance? clojure.lang.IFn %) [#(+ 3 4) {} [] () 15 "hehe" :okay]) |
| 15:28 | clojurebot | (true true true false false ...) |
| 15:28 | gfredericks | grr |
| 15:28 | gfredericks | well you can imagine the rest |
| 15:29 | daniel__ | thanks duck1123, found my problem |
| 15:30 | amcnamara | hash-maps and vecs are considered functions of their items, you can pass a key or index (respectively) to them -- in case you were wondering why they're showing as fns |
| 15:32 | amcnamara | and same deal with keywords for the same reason |
| 15:32 | daniel__ | whats wrong with this? ,(take 5 (repeatedly (+ 1 1))) |
| 15:33 | duck1123 | keywords are fns that look themselves up in the map (that one got cut off) |
| 15:33 | daniel__ | ,(take 5 (repeatedly (+ 1 1))) |
| 15:33 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 15:33 | hiredman | daniel__: read the docs for repeatedly |
| 15:33 | daniel__ | (doc repeatedly) |
| 15:33 | clojurebot | "([f] [n f]); Takes a function of no args, presumably with side effects, and returns an infinite (or length n if supplied) lazy sequence of calls to it" |
| 15:33 | daniel__ | ah |
| 15:34 | raek | ,(take 5 (repeat (+ 1 1))) |
| 15:34 | clojurebot | (2 2 2 2 2) |
| 15:34 | amcnamara | &(instance? clojure.lang.IFn (+ 1 1)) |
| 15:34 | lazybot | ⇒ false |
| 15:34 | daniel__ | ,(repeatedly 5 (+ 1 1)) |
| 15:34 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 15:34 | daniel__ | ,(repeat 5 (+ 1 1)) |
| 15:34 | clojurebot | (2 2 2 2 2) |
| 15:34 | daniel__ | ok |
| 15:34 | Raynes | &(repeatedly 5 #(+ 1 1)) |
| 15:34 | lazybot | ⇒ (2 2 2 2 2) |
| 15:34 | amcnamara | or alternatively ##(take 5 (repeatedly #(+ 1 1))) |
| 15:34 | lazybot | ⇒ (2 2 2 2 2) |
| 15:35 | Raynes | amcnamara: Go away. |
| 15:35 | Raynes | ;) |
| 15:35 | amcnamara | hah |
| 15:35 | amcnamara | lazybot evaluated mine first! |
| 15:35 | amcnamara | (I just know) |
| 15:35 | Raynes | Lies and slander. The bot knows his master |
| 15:37 | daniel__ | i did need repeatedly....repeat evaluates it once and then repeats, rather than repeating the evaluation each time |
| 16:09 | daniel__ | ,(int "2") |
| 16:09 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Character> |
| 16:09 | daniel__ | ? |
| 16:09 | gfredericks | ,(new Integer "2") |
| 16:10 | clojurebot | 2 |
| 16:10 | gfredericks | ,(doc int) |
| 16:10 | clojurebot | "([x]); Coerce to int" |
| 16:10 | daniel__ | ;) thanks |
| 16:11 | raek | ,(Integer/parseInt "2") |
| 16:11 | clojurebot | 2 |
| 16:11 | raek | ,(identical? (Integer/parseInt "2") 2) |
| 16:11 | clojurebot | true |
| 16:11 | gfredericks | ,(map #(try (int %) (catch Exception e :nope)) [7.0 7 7N 7M "7" :7 "seven"])) |
| 16:11 | clojurebot | gfredericks: No entiendo |
| 16:11 | raek | ,(identical? (Integer. "2") 2) |
| 16:11 | clojurebot | false |
| 16:11 | gfredericks | wtf |
| 16:11 | daniel__ | ,(identical? (.Integer "2") 2) |
| 16:11 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching field found: Integer for class java.lang.String> |
| 16:11 | seancorfield | i'm updating clojure.java.jdbc to use regular maps instead of structmaps in the resultset-seq - it passes the tests (and i'm running a build against the world singles' test suite now) - but can anyone think how it might break existing code? |
| 16:11 | daniel__ | ,(identical? (new Integer "2") 2) |
| 16:11 | clojurebot | false |
| 16:11 | gfredericks | raek: what's going on there? |
| 16:12 | raek | Integer/parseInt can reuse Integer instances |
| 16:12 | seancorfield | i'm not really sure what "structmap" is all about so i don't really understand how / why it's different to a regular map... |
| 16:12 | raek | the Integer constructor cannot do that since it has to construct a new object |
| 16:12 | raek | they are equal, though |
| 16:12 | raek | ,(= (Integer/parseInt "2") 2) |
| 16:12 | clojurebot | true |
| 16:13 | raek | ,(= (Integer. "2") 2) |
| 16:13 | clojurebot | true |
| 16:13 | gfredericks | raek: why would parseInt give an identical one? Are the Integers cached somewhere? |
| 16:13 | raek | gfredericks: yes. I think -128 to 127 are interned |
| 16:14 | gfredericks | ,(identical? (Integer/parseInt "23456") 23456) |
| 16:14 | clojurebot | false |
| 16:14 | gfredericks | well wuddayaknow. |
| 16:14 | seancorfield | ah, just spotted a subtlety with structmaps - if no value is supplied for a given key, it gets a nil value... hmm... don't think that will affect java.jdbc tho'... |
| 16:17 | amalloy | seancorfield: structmaps are an earlier iteration of records |
| 16:19 | amalloy | i think they can have default values other than nil, perhaps? that would make a difference |
| 16:19 | gfredericks | are structmaps deprecated? |
| 16:19 | seancorfield | amalloy: ah, makes sense... java.jdbc only uses them to create key/value pairs based on columns in a resultset |
| 16:20 | seancorfield | did they guarantee iteration order? |
| 16:20 | amalloy | not easy to find documentation for them, apparently |
| 16:21 | seancorfield | i.e., if you did (def abc (create-struct :a :b :c)) and then (struct abc 1 2 3) and then map over the result, is there a guarantee that you'll get [:a 1], [:b 2], [:c 3] in order? |
| 16:21 | gfredericks | and what if other keys get added? |
| 16:22 | seancorfield | i replaced that pair of calls with (zipmap keys (row-values)) and got a different order... just not sure if that's going to be significant |
| 16:23 | amalloy | seancorfield: looking at the source it seems you do get them in that order, but i don't know if it's guaranteed because there are like no docs anywhere |
| 16:23 | amalloy | either way, even if it's not guaranteed clients might conceivably be (incorrectly) depending on it |
| 16:23 | seancorfield | heh, well, i'll make the change and see if anyone complains :) |
| 16:24 | seancorfield | initially i had (into {} (map (fn [k v] [k v]) keys (row-values))) which seemed to generate them in the same order but i was under the impression map has no defined order...? |
| 16:25 | amalloy | seancorfield: that function is just vector |
| 16:25 | duck1123 | don't struct maps work like regular maps where you'll get the keys back in order up to a certain point because it's more efficient (but you shouldn't count on it) |
| 16:25 | seancorfield | amalloy: yes, i realized that after i wrote it, but then realized i could replace the whole thing with zipmap :) |
| 16:26 | gfredericks | duck1123: I think the issue is that if he changes the implementation the order might change |
| 16:26 | gfredericks | maybe |
| 16:26 | gfredericks | maybe not |
| 16:26 | seancorfield | yup |
| 16:26 | seancorfield | using zipmap definitely gives a different order |
| 16:27 | duck1123 | but if you have a structmap with a lot of keys, is that order stil preserved? |
| 16:27 | gfredericks | amalloy just looked at the code and said yes |
| 16:27 | amalloy | duck1123: if all the keys are in the basis map, yes |
| 16:27 | seancorfield | but the only situation where i can imagine folks relying on the order is if they do select some,keys,in,order from table and expect to map over them and get :some, :keys, :in, :order again |
| 16:27 | gfredericks | duck1123: the declared keys of a structmap are stored differently than any other keys you might add |
| 16:28 | duck1123 | I always hated that you couldn't dissoc a basis key |
| 16:28 | gfredericks | duck1123: just on principle? Or did you want to do that at some point? |
| 16:29 | duck1123 | I had a use case where I wanted to remove one of the keys and I had to jump through hoops to work around it |
| 16:30 | gfredericks | okay let's say I have an infinite binary tree and I want to create a lazy seq of all the nodes in order of depth. Can I do this without having to take up an arbitrary amount of memory (e.g., keeping an entire level in memory at a time)? |
| 16:31 | tomoj | in order of depth = breadth-first? |
| 16:31 | gfredericks | oh that's trivial, there was another restriction too -- I didn't want to compute the path from the root to the next node every single time |
| 16:32 | gfredericks | tomoj: I believe so, yes |
| 16:32 | tomoj | trivial? |
| 16:32 | tomoj | seems impossible to me |
| 16:32 | tomoj | suppose you're on the far right, now you jump down to the next level on the far left |
| 16:32 | amalloy | gfredericks: the constraints are not well-stated. certainly you can do it, by keeping everything on disk instead of in memory |
| 16:32 | tomoj | didn't you have to have the whole level in memory? |
| 16:33 | gfredericks | amalloy: add that constraint too :P and no keeping stuff in the cloud either |
| 16:33 | gfredericks | tomoj: hmmm |
| 16:33 | gfredericks | tomoj: I think at worst it would require going back up to the root and back down |
| 16:34 | amalloy | gfredericks: which is already infinite memory, in an infinite tree |
| 16:34 | gfredericks | maybe that's the best that can be done as well |
| 16:34 | gfredericks | amalloy: it's a lazy tree |
| 16:34 | amalloy | so? |
| 16:34 | gfredericks | amalloy: oh you mean the path |
| 16:34 | tomoj | pretty strange if it GC's branches you climb back up |
| 16:34 | gfredericks | the path is fine. I don't want any bottleneck worse than the path. |
| 16:35 | amalloy | if you realize the first (say) million left branches, those are all realized, and will stay that way because you're never GCing the root |
| 16:35 | gfredericks | "the whole row" would certainly be worse than the path |
| 16:35 | gfredericks | amalloy: man I'm bad at this describing a problem thing. It's not an actual tree, just a conceptual one. |
| 16:36 | gfredericks | so by lazy tree I just meant that it doesn't exist in memory, just the function to compute the children of a node |
| 16:36 | tomoj | are you using a conceptual computer? :P |
| 16:36 | gfredericks | nevermind, I'll go off in my corner and figure it out :P |
| 16:36 | tomoj | do you have a function to compute the parent given a child? |
| 16:37 | gfredericks | sure |
| 16:37 | gfredericks | I guess that's not obvious, but I do |
| 16:37 | tomoj | I didn't expect that answer. carry on. :) |
| 16:38 | gfredericks | I think I can just deal with having to go back to the root every once in a while... |
| 16:39 | gfredericks | it's at least better than my current implementation which goes back to the root every time |
| 17:24 | seancorfield | as a compromise i'm going to use (into {} (map vector keys (row-values))) which should preserve order for up to 16 columns because it uses a PersistentArrayMap (right?) |
| 17:24 | seancorfield | (sometimes reading the Clojure source code is not as enlightening as others) |
| 17:25 | raek | seancorfield: why not (zipmap keys (row-values)) ? |
| 17:26 | seancorfield | doesn't preserve the order at all |
| 17:26 | seancorfield | i'm worried that some ppl may be relying on getting the columns in the same order as their SQL select... |
| 17:27 | raek | sorry, didn't read the ArrayMap part |
| 17:27 | seancorfield | np, i'm sure it's an edge case anyway |
| 17:27 | gfredericks | hmmm....looks like into uses (reduce conj ...) while zipmap uses repeated assoc |
| 17:27 | seancorfield | i ran a full suite of tests with zipmap and it all passed so i know world singles' code is not relying on ordering :) |
| 17:28 | raek | ,(class (zipmap (range 3) (range 3))) |
| 17:28 | clojurebot | clojure.lang.PersistentArrayMap |
| 17:28 | duck1123 | seancorfield: either make it an ordered map, or tell people there is no guarentee of order |
| 17:28 | raek | ,(zipmap (range 5) (range 5)) |
| 17:28 | clojurebot | {4 4, 3 3, 2 2, 1 1, 0 0} |
| 17:29 | raek | ,(into {} (map vector (range 5) (range 5))) |
| 17:29 | clojurebot | {0 0, 1 1, 2 2, 3 3, 4 4} |
| 17:29 | seancorfield | duck1123: well, there was no specific documented guarantee of order - except insofar as resultset-seq used structmaps |
| 17:29 | raek | tough decision to make... |
| 17:29 | raek | it's not fun to breake people's code |
| 17:30 | raek | but they shouldn't relied on the order of the map entries anyway |
| 17:30 | seancorfield | i don't think structmap provided a documented guarantee of key order either? |
| 17:30 | raek | :/ |
| 17:30 | duck1123 | I would change it to explicitly say "don't count on it, bub" |
| 17:30 | seancorfield | raek: i agree |
| 17:31 | raek | the only guarantee I've heard about is that keys and vals should visit the entries in the same order |
| 17:31 | seancorfield | i think this is a reasonable compromise tho' so that's going in and i'll be declaring 0.1.0 soon... |
| 17:31 | raek | not time for 1.0.0? |
| 17:32 | raek | since people have been using it for ages already |
| 17:32 | gfredericks | 1.0.0 would certainly take away the fear of breaking stuff |
| 17:32 | duck1123 | this is c.j.jdbc, right? |
| 17:32 | duck1123 | isn't it already past 0.1.0? |
| 17:33 | raek | ideally, libs should be at least 1.0.0 when others rely on them |
| 17:35 | seancorfield | 1.0.0 of contrib requires clojure/core approval and there's a lot to improve in c.j.jdbc before it gets there |
| 17:36 | seancorfield | c.j.jdbc is at 0.0.7 now but i'll bump to 0.1.0 now structmaps are out |
| 17:36 | raek | ah, I see... didn't think of the processes involved... :-) |
| 17:36 | seancorfield | the other open tickets are all post 0.1.0 in my mind |
| 17:37 | seancorfield | i'm planning to provide an API overhaul for 0.2.0 based on feedback on clojure-dev and from some users |
| 17:37 | seancorfield | or rather add a new consistent simple API (and maintain the current API) |
| 17:39 | seancorfield | at world singles, we wrote a crud wrapper around c.j.jdbc to make it easier to work with and it fits well with some of the feedback i've been getting so i'm going to fold some of it down into c.j.jdbc |
| 17:40 | seancorfield | there was also specific feedback from clojure/core about binding vs passing in arguments which i've been considering for a while anyway |
| 17:40 | gfredericks | seancorfield: do they prefer one or the other? |
| 17:40 | ibdknox | seancorfield: is c.j.jdbc going to change a lot? |
| 17:41 | seancorfield | and feedback on merging the internal ns into the main ns as private vars (that would allow quite a bit of simplification as well) |
| 17:41 | seancorfield | clojure/core prefer the base API to let you pass everything as arguments - and then you can build the binding-based API on top of that |
| 17:41 | amalloy | really? separate namespaces seem much nicer than private vars |
| 17:41 | ibdknox | seancorfield: I've made a lot of headway on Korma, which has a decent amount of reliance on c.j.jdbc |
| 17:41 | ibdknox | I'm with amalloy on that one |
| 17:42 | seancorfield | ibdknox: no breaking changes, just additions |
| 17:42 | ibdknox | it also gives room to grow |
| 17:42 | gfredericks | I'm curious what simplifications a single ns gets you |
| 17:43 | seancorfield | currently some c.j.j.internal stuff is exposed as public vars in c.j.j by (def public-fn internal-fn) - because c.j.j.internal calls internal-fn |
| 17:44 | seancorfield | if it's all in one ns, the def can go away and the "internal" functions can call the public stuff directly |
| 17:44 | gfredericks | hmm |
| 17:44 | gfredericks | that's essentially a bidirectional dependency, isn't it? |
| 17:44 | seancorfield | when i started with clojure at world singles, we tended to do the same split: public api in a ns, delegating to a "private" api in another "internal" ns |
| 17:45 | seancorfield | but we've moved away from that over time and cleaned up our namespaces quite a bit |
| 17:46 | seancorfield | part of it was driven by our need to expose an API that could be called by non-Clojure code... but that consideration is less important now we have more code in Clojure (and now that we call clojure.core stuff directly in our non-Clojure code so we can create maps etc directly) |
| 17:51 | danielp1234 | yo |
| 17:51 | gfredericks | danielp1234: yo |
| 18:14 | gfredericks | It is counterintuitive that distinct? takes varargs. |
| 18:14 | ibdknox | ,(doc distinct?) |
| 18:14 | clojurebot | "([x] [x y] [x y & more]); Returns true if no two of the arguments are =" |
| 18:15 | gfredericks | particularly since distinct takes a collection |
| 18:22 | amalloy | gfredericks: i wish min/max took collections too, but c'est la vie |
| 18:23 | gfredericks | varargs. they make everything better and worse. |
| 18:26 | technomancy | seancorfield: that's funny; we went the other way at sonian |
| 18:26 | technomancy | partly for testability purposes |
| 18:27 | gfredericks | aren't internal namespaces easier to test than private functions? |
| 18:27 | seancorfield | (let [some-name @#'ns/some-name ...] ...) ;; exposes private function for testing :) |
| 18:27 | gfredericks | at least in the traditional clojure.test setup that lein gives you? |
| 18:27 | seancorfield | the question is: why are you testing private functions? :) |
| 18:28 | seancorfield | the unit testing world seems split on that question |
| 18:28 | gfredericks | does `lein test` run the functions attached to the :test metadata? |
| 18:28 | gfredericks | I don't know if anybody uses test metadata... I just read about it again the other day so it's in my head |
| 18:29 | technomancy | gfredericks: it runs based on all namespaces with corresponding files in the test/ dir |
| 18:30 | technomancy | seancorfield: for the record I much prefer working with the connection as an explicit argument vs the with-* style since the latter can trivially be implemented in terms of the former |
| 18:31 | seancorfield | technomancy: yup, i agree and c.j.j is the way it is because that's how c.c.sql was when i inherited it |
| 18:31 | technomancy | oh, right |
| 18:31 | technomancy | carry on then =) |
| 18:32 | seancorfield | the 0.2.0 API will expose functions with explicit arguments (and rewrite the with-* stuff to depend on those) |
| 18:32 | technomancy | also, what do you think about accepting a database connection URL rather than a map of :user, :host, :password, etc? |
| 18:32 | gfredericks | or both? |
| 18:32 | seancorfield | open a JIRA issue :) |
| 18:32 | technomancy | gfredericks: naturally =) |
| 18:33 | technomancy | seancorfield: will do. I can put together a patch. |
| 18:33 | technomancy | just wanted to run it by you first. |
| 18:33 | gfredericks | multimethod! |
| 18:33 | seancorfield | i don't have strong opinions on stuff like that - if folks would find it useful and it doesn't complicate the API for anyone else, i'm comfortable with it |
| 18:34 | amalloy | gfredericks: {:user "nobody" :host "localhost" :url "mysql:nobody@localhost..."} - an excellent way to do "both" |
| 18:40 | technomancy | yeah, just translate strings into {:url "..."} and extract username etc from the url if it's not already in the map |
| 18:41 | Raynes | When people tell me to open a JIRA issue, I tend to just decide that I don't need whatever it is that I wanted as bad as I previously thought. |
| 18:41 | amalloy | heh. i was *actually* suggesting you require both, just to annoy users, but technomancy's idea is better |
| 18:41 | gfredericks | amalloy: oh so "excellent" was ironic? |
| 18:42 | gfredericks | ah ha you were playing on the word "both". Man I could not figure out why you were recommending that. |
| 18:43 | amalloy | (if-let [x (foo)] (if (bar x) (then x) else) else) - is there any nice way i can remove the duplication of else, here? |
| 18:44 | gfredericks | I almost had something with juxt... |
| 18:44 | tomoj | (let [x (foo)] (if (and x (bar x)) (then x) else)) is that nice? |
| 18:44 | amalloy | i guess i could write (let [x (foo)] (if (and x (bar x)) (then x) else)) |
| 18:44 | ibdknox | I wish if-let would allow multiple bindings |
| 18:44 | tomoj | and/or correct? |
| 18:45 | ibdknox | I almost always do (if-let [x 1] (let [y ... |
| 18:45 | amalloy | tomoj: yeah, that's correct except in the case where x is already bound and the let is intended to replace it |
| 18:45 | gfredericks | (let [x (foo), y (and x (bar x))] (if y (then x) else)) |
| 18:46 | ibdknox | technomancy: why do you prefer the url? |
| 18:46 | tomoj | ibdknox: you'd want it to only check the truthiness of the first binding? |
| 18:46 | ibdknox | tomoj: yep |
| 18:46 | amalloy | ibdknox: i think the reason it doesn't exist is it's not clear what it does |
| 18:46 | ibdknox | it would be fairly trivial to implement a macro that does it |
| 18:46 | ibdknox | amalloy: I agree with that |
| 18:47 | amalloy | it would be equally "obvious/useful" to check the truthiness of all the bindings |
| 18:47 | ibdknox | I'm not sure it's the "right" thing to do... but it's what I want :p |
| 18:47 | ibdknox | I actually expected it would check all of them if you had more than one |
| 18:48 | tomoj | seems likely you'd have to check the values manually in the else anyway |
| 18:48 | tomoj | guess not sometimes.. |
| 18:49 | amalloy | tomoj: anyway, i think that's the right solution to the question i actually asked, except i was glossing over the fact that my if-let is actually an if-user macro that goes and looks the user up in the db |
| 18:50 | amalloy | (if-user [u] (if (test u) (then u) else) else). i guess i could go write let-user |
| 19:01 | devth | any suggestions on a good way to format a map as a querystring? seems reduce is not the way to go. |
| 19:01 | gfredericks | string/join |
| 19:02 | devth | i don't see how that would work with key/vals |
| 19:02 | devth | oh, i suppose you could use map to create the keypair representation |
| 19:02 | amalloy | right |
| 19:02 | gfredericks | (string/join "&" (for [[k v] m] (format "%s=%s" k v))) |
| 19:03 | amalloy | though this function has been written a number of times before |
| 19:03 | gfredericks | ^ and that of course ignores encoding complexity |
| 19:03 | devth | right. thanks. |
| 19:04 | gfredericks | also it assumes keys and vals are strings... :/ |
| 19:07 | tomoj | &(format "%s" {:foo :bar}) |
| 19:07 | lazybot | ⇒ "{:foo :bar}" |
| 19:07 | gfredericks | really? |
| 19:08 | gfredericks | Well I'll be. |
| 19:08 | amalloy | gfredericks: %s calls .toString |
| 19:08 | gfredericks | there goes java. always being relaxed about types. |
| 19:08 | amalloy | the scoundrels |
| 20:25 | technomancy | Raynes: if it were just for me I would probably skip it, but since this is for work I'll put up with jira |
| 20:29 | technomancy | heh; that's funny, most people wishing for multi-if-let want and semantics, and everyone else wants or. this is the first I've heard of "just use the first value" |
| 20:30 | amalloy | technomancy: are you sure? i don't think "or" makes sense as a model |
| 20:31 | amalloy | "bind at least one of these variables, i don't care which"? |
| 20:35 | technomancy | I don't think it makes sense either =) |
| 20:35 | technomancy | but I think I've heard it |
| 20:55 | duck1123 | and makes sense, with one else for if any of them fail |
| 22:43 | khaliG | hm. it takes 12s before my clojure/swing app pops up.. :( |