2011-02-01
| 00:02 | amalloy | since it sounds like you just want the handy (for) bindings |
| 00:29 | arohner | amalloy: thanks for the hint. I ended up with (dorun (apply pcalls (for [foo bar] #(body...))) |
| 00:29 | arohner | I needed to use #() rather than constantly, because constantly is a fn, so it evaluated its body |
| 00:30 | amalloy | sure, constantly was just an example |
| 02:13 | sritchie | hey all -- does anyone have any advice on how to read floats out of a binary file with clojure? |
| 02:14 | sritchie | java's DataInputStream is assuming that the file was written using floatToIntBits, which isn't the case |
| 02:21 | amalloy | sritchie: floats, or doubles? |
| 02:22 | sritchie | floats |
| 02:22 | sritchie | I have an array I usually read in python, using numpy's numpy.fromfile method |
| 02:22 | sritchie | I'm trying to use a datainputstream in java, but i think it's reading the bytes in backwards |
| 02:22 | sritchie | or, rather, opposite of what python does |
| 02:24 | amalloy | sritchie: see the docs at http://www.scipy.org/Numpy_Example_List_With_Doc#fromfile |
| 02:24 | amalloy | they say not to rely on tofile..fromfile to store data as they will be stored in a platform-dependent way |
| 02:25 | sritchie | yeah, that makes sense -- |
| 02:25 | sritchie | I'm actually reading this data set -- |
| 02:25 | sritchie | http://iridl.ldeo.columbia.edu/SOURCES/.NOAA/.NCEP/.CPC/.PRECL/.dataset_documentation.html |
| 02:26 | sritchie | I just happen to have some working python code that uses fromfile |
| 02:26 | sritchie | I think java is just reading the bytes in backwards, from what python does |
| 02:26 | amalloy | so my guess would be that numpy is storing them in whatever order your processor happens to be using while java is using network byte order |
| 02:27 | sritchie | amalloy: do you know of any way I could specify a different byte order? I have to live with this data set, unfortunately |
| 02:27 | amalloy | sritchie: flip the bits around yourself |
| 02:29 | sritchie | ah, okay, i'll just use to-byte-array, then Float.intBitsToFloat(bits); |
| 02:30 | amalloy | sritchie: that will be just as backwards since that's what datainput is doing already |
| 02:30 | sritchie | sorry, I meant I'll take four bytes at a time, flip them, |
| 02:30 | sritchie | and then feed them in to intBitsToFloat |
| 02:30 | amalloy | right, that's probably the way to go |
| 02:31 | sritchie | great, thanks |
| 02:32 | amalloy | &(Integer/toHexString (Float/floatToIntBits (float 66.6))) |
| 02:32 | sexpbot | ⟹ "42853333" |
| 02:33 | amalloy | &(Integer/toHexString (Float/floatToIntBits (float 7.5))) is probably more useful :P |
| 02:33 | sexpbot | ⟹ "40f00000" |
| 02:34 | amalloy | sritchie: ^ is something to aim for in your bit-fiddling if it turns out to be more interesting than just reversing all four bytes |
| 02:34 | sritchie | yes, that's really useful |
| 02:35 | sritchie | amalloy: the next step is converting bytes from a byte array into a hex string |
| 02:37 | amalloy | sritchie: plenty of implementations of that exist, but why do you need to? |
| 02:38 | sritchie | amalloy: I've got a byte array, and I was thinking that I'd need to take 4 bytes off of the front, and then combine them into a hex string to feed into intbitstofloat |
| 02:38 | benreesman | anyone had luck using ac-slime with swank-clojure? |
| 02:38 | amalloy | intbitstofloat doesn't want a hex string, though |
| 02:38 | amalloy | it wants an int |
| 02:40 | amalloy | and while i'm sure better solutions exist, i wrote https://github.com/amalloy/bit-packer for fun a while back and it would do what you want |
| 02:41 | amalloy | (unpack your-byte-array 256) will do the trick, if the bytes are in the right order (as mentioned in the readme) |
| 02:43 | sritchie | this assumes big endian, right? |
| 02:43 | tomoj | you have a float, and then what? |
| 02:44 | amalloy | i can never remember which "end" big-endian refers to. it assumes LSB first |
| 02:44 | sritchie | I'm unpacking this binary file into 12 360x720 pixel arrays, where the float on each pixel is mm of rainfall in that .5 degree square on the earth's surface |
| 02:44 | sritchie | amalloy: yeah, I think it assumes what java assumes -- this obnoxious binary file has it backwards |
| 02:44 | amalloy | sritchie: so? (reverse) |
| 02:44 | tomoj | oh |
| 02:45 | sritchie | oh, reverse before the unpack then after would do the trick, wouldn't it |
| 02:45 | amalloy | um, you shouldn't have to reverse after...the whole point is that the bits are in the wrong order |
| 02:46 | amalloy | &(let [bytes (range 12)] (map reverse (partition 4 bytes))) |
| 02:46 | sexpbot | ⟹ ((3 2 1 0) (7 6 5 4) (11 10 9 8)) |
| 02:47 | amalloy | and if you had an unpack function, you could map (comp unpack reverse) |
| 02:47 | amalloy | brehaut: if you're looking for reasons to cry, i made take-randnth actually lazy at https://gist.github.com/805546 |
| 02:48 | sritchie | amalloy: ah. it's late... I was thinking that each float was reversed, |
| 02:48 | sritchie | but the order of the whole thing was correct |
| 02:48 | amalloy | each byte, you mean? |
| 02:49 | sritchie | each group of four bytes |
| 02:49 | sritchie | that each float, when converted to bytes, was serialized differently in java vs whatever wrote this particular binary file |
| 02:49 | amalloy | yes, that is the assumption under which we are operating |
| 02:50 | amalloy | suppose that java writes its float as 0x12345678. then, if endian-ness is the only problem, numpy is probably writing it as 0x78563412 |
| 02:50 | sritchie | well, my first groups of four bytes, probably the first few thousands floats, are (0 -64 121 -60) |
| 02:51 | sritchie | that matches python, if I set numpy to byte format |
| 02:51 | amalloy | and what float does numpy think that represents? |
| 02:51 | sritchie | -999 |
| 02:55 | sritchie | might be time to sleep on this one |
| 02:55 | sritchie | I feel like that's NaN |
| 02:55 | amalloy | sritchie: well first of all you want to stop dealing with negative numbers. -64 is, i think, 0xC0, or 192 |
| 02:55 | sritchie | java's reading it as 1.7676097E-38 |
| 02:56 | amalloy | but i could def be wrong there. it's been a long time since i looked at how two's complement works :P |
| 02:57 | amalloy | sritchie: just (Integer/toHexString (.readInt datainput)) |
| 02:58 | amalloy | that will show you what order it's reading the bytes in |
| 02:58 | amalloy | then you will know how to reorder them |
| 03:00 | sritchie | c079c4 |
| 03:00 | amalloy | hey, i was right about 0xc0, at least |
| 03:00 | sritchie | yup! |
| 03:01 | sritchie | might be time to sleep on this |
| 03:02 | amalloy | yeah, i've got to sleep too |
| 03:02 | sritchie | thanks for your help -- this seems simple, I'm just exhausted |
| 03:02 | sritchie | I'll play with the numpy representation tomorrow and this, and see what I find |
| 03:02 | amalloy | good luck |
| 03:02 | sritchie | thanks, man |
| 03:24 | brehaut | amalloy: belated :'( |
| 03:24 | amalloy | brehaut: yeah, i'm really trying hard to find a non-awful way to write this |
| 03:25 | brehaut | a real unfoldl might help a bunch i think |
| 03:25 | amalloy | brehaut: yeah, i'm writing it with unfold as we speak |
| 03:25 | amalloy | it's shorter but arguably more complicated |
| 03:25 | brehaut | why isnt unfold in the core? |
| 03:26 | amalloy | brehaut: beats me |
| 03:27 | brehaut | im sure theres a good reason though |
| 03:28 | amalloy | brehaut: https://gist.github.com/805583v with unfold |
| 03:28 | brehaut | huh. github is 404ing on that |
| 03:28 | amalloy | oh |
| 03:28 | amalloy | https://gist.github.com/805583 |
| 03:28 | amalloy | i accidentally pasted a v at the end there |
| 03:29 | brehaut | huh. done? makes a bunch of sense in the absense of proper maybe |
| 03:29 | amalloy | brehaut: what? |
| 03:30 | brehaut | oh sorry. in unfold |
| 03:30 | brehaut | im more familiar with the haskell version, where the next fn returns a maybe |
| 03:30 | amalloy | right, i know what done? you're referring to, but i don't see the point youo're making |
| 03:31 | amalloy | brehaut: i implemented http://en.wikipedia.org/wiki/Unfold_%28higher-order_function%29#Anamorphisms_on_lists |
| 03:31 | amalloy | i'm not very familiar with haskell, but it looks like that's basically (defn ana [unspool finished x]) |
| 03:32 | brehaut | amalloy: http://hackage.haskell.org/packages/archive/containers/latest/doc/html/Data-Sequence.html#v:unfoldl thats the one in haskell |
| 03:33 | brehaut | sorry that was an epic sidetrack |
| 03:34 | amalloy | brehaut: ugh, i can't read these curried type definitions |
| 03:34 | amalloy | it's worse than lisp's dang parentheses :) |
| 03:34 | brehaut | haha |
| 03:35 | brehaut | haskells' precedence rules and ops are a head trip to start with |
| 03:38 | amalloy | anyway i'm not sure unfold makes the whole thing that much nicer |
| 03:40 | brehaut | yeah apparently not |
| 05:25 | clgv | I try to compile my clojure library (code without a main method) with leiningen but it does not include any implementation file. what might I do wrong? |
| 06:20 | fliebel | morning |
| 06:20 | ejackson | wotcha |
| 06:23 | clgv | morning |
| 06:24 | fliebel | clgv: Hi, I just read your message… I really thought I got it, with 4 and 6 |
| 06:25 | clgv | fliebel: you can try to improve it by knowing the solution. as soon as it drops out, your criterion has an error ;) |
| 06:26 | clgv | fliebel: maybe I try a clojure solution next weekend ;) |
| 06:27 | fliebel | Well, I would rather like to know *what* makes my solution incorrect. In my opinion, it fits the constraints and the conversation perfectly. |
| 06:29 | clgv | hmm that's not easy since I have to go throught the argumentation and have a look when it drops out ;) |
| 06:30 | fliebel | clgv: Good, I'll try to find a way to figure out your solution, and then verify both min and the 'official' solution. |
| 06:31 | clgv | ah I got the problem |
| 06:31 | clgv | 4+6=10=2*5 |
| 06:32 | clgv | uhm wait, I might have to reconsider. |
| 06:40 | fliebel | amalloy_: ping |
| 06:43 | fliebel | why doesn't rand-int take a start? ##(doc rand-int) |
| 06:43 | sexpbot | ⟹ "([n]); Returns a random integer between 0 (inclusive) and n (exclusive)." |
| 06:52 | gfrlog | ,(let [fliebels-rand-int (fn [a b] (+ a (rand-int (- b a))))] (fliebels-rand-int 10 12)) |
| 06:52 | clojurebot | 11 |
| 06:54 | fliebel | gfrlog: I figured that out already, but I wonder why something that useful and simple is not in core. |
| 06:54 | fliebel | &(source rand-int) |
| 06:54 | sexpbot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 06:56 | raek | this is bad: http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ |
| 06:56 | raek | affects clojure too |
| 06:57 | fliebel | raek: I figured that… I was about to try some other runtimes… |
| 07:15 | clgv | raek: oh thats suprising and will punch all those guys gloating about php in the face. bad incident for java ;) |
| 07:22 | r0man | technomancy: ping! |
| 07:39 | gfrlog | fliebel: Yeah, I agree. |
| 07:42 | gfrlog | ,(let [map-from-fn (fn [f ks] (into {} (map (juxt identity f) ks)))] (map-from-fn inc [7 9 12])) |
| 07:42 | clojurebot | {7 8, 9 10, 12 13} |
| 07:42 | Licenser | aloa |
| 07:43 | fliebel | Licenser: hi |
| 07:49 | fliebel | gfrlog: What about functions taking multiple arguments? |
| 08:51 | chouser | Yet another reason to use rationals instead of floating points |
| 08:58 | gfrlog | fliebel: to be the keys of a map, they'd have to be wrapped in a vector anyhow. So I think that would still work. |
| 09:06 | robzor | have you guy seen this? works in clojure as well |
| 09:06 | robzor | http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/ |
| 09:07 | robzor | (Double/parseDouble "2.2250738585072012e-308") goes in to an infinite loop |
| 09:07 | clgv | did you try that one on sexpbot already? ;) |
| 09:08 | robzor | uhm |
| 09:08 | robzor | ok |
| 09:08 | robzor | ,(Double/parseDouble "2.2250738585072012e-308") |
| 09:08 | clojurebot | Execution Timed Out |
| 09:08 | chouser | you don't even have to work that hard. what do you thing the reader does? |
| 09:08 | robzor | hurray for sandboxing |
| 09:08 | clgv | ok safe programmed ;) |
| 09:08 | chouser | ,2.2250738585072012e-308 |
| 09:08 | clojurebot | Execution Timed Out |
| 09:08 | clgv | ,2.2250738585072011e-308 |
| 09:08 | clojurebot | 2.225073858507201E-308 |
| 09:09 | clgv | ,2.2250738585072013e-308 |
| 09:09 | clojurebot | 2.2250738585072014E-308 |
| 09:09 | robzor | if you look in the addendum of the blog i just linked, there's some other numbers |
| 09:09 | cemerick | Those evaluations are timing out from being reported, but I suspect the relevant worker threads in the execution pool will spin until hiredman bounces the bot. |
| 09:09 | chouser | you don't think he kills the thread? |
| 09:09 | cemerick | (unless they're being .stop'ped) |
| 09:10 | cemerick | chouser: *dangerous* ;-) |
| 09:10 | chouser | yep |
| 09:10 | clgv | would be really bad style if he reports timeouts but doesnt kill the execution |
| 09:10 | cemerick | clgv: a thread's execution cannot safely be halted on the JVM |
| 09:10 | robzor | "something went wrong but i'm not going to bother you with that" |
| 09:11 | clgv | cemerick: it doesnt have to be safely if it's timeout has been reached anyway. brutal killing will suffice ;) |
| 09:12 | cemerick | clgv: that depends on what global resources the thread in question is touching at the time of the .stop |
| 09:12 | chouser | the question is, would it be desriable and possible to add a check to Clojure's reader to avoid passing strings that trigger that bug on to parseDouble |
| 09:12 | Fossi | that's just hiding the real problem |
| 09:12 | Fossi | so i'd say no |
| 09:13 | chouser | But if it means Clojure programs can work more robustly until the JVM is fixed, is that not a win? |
| 09:13 | robzor | would oracle fix this all the way back to 1.5? |
| 09:13 | Fossi | afaik there might also be a lot of other numbers which cause this bug |
| 09:13 | Fossi | the one being published is just an example of what i guess might be a bigger problem |
| 09:14 | chouser | cemerick: if they are, we could save them. If they're using parseDouble directly, we can't help. |
| 09:14 | Fossi | then again i haven't checked the code |
| 09:14 | chouser | oh, it's already fixed in PHP. |
| 09:15 | robzor | chouser: yes, but how many servers out there are still running an ancient version? |
| 09:16 | Fossi | i wonder how often people even have input fields that get converted to a double |
| 09:17 | Fossi | something like clojure might be a little more "vulnerable", if people really use the reader |
| 09:18 | Fossi | then again as cemerick said it's prolly not such a good idea anyway |
| 09:24 | AWizzArd | cemerick: *lol* |
| 09:25 | cemerick | AWizzArd: ? |
| 09:26 | AWizzArd | cemerick: what you said 12 minutes ago. Just sounded funny :) |
| 09:26 | cemerick | ah. :-) |
| 10:42 | sritchie | hey all -- I've written a multimethod to convert various types of arguments into a little-endian HeapByteBuffer, which I'm using as a float array. currently, two of the defmethods change an argument slightly and call the multimethod again -- is there a more idiomatic way to do this? |
| 10:42 | sritchie | https://gist.github.com/806027 |
| 10:42 | sritchie | there are the functions in question |
| 10:44 | nurv101 | I have a question to the room |
| 10:44 | nurv101 | is it possible to create a lisp closure in clojure? |
| 10:55 | zvrba | are there block comments in clojure? |
| 10:55 | tonyl | (comment ) |
| 10:56 | tonyl | but anything inside comment has to be valid forms |
| 10:56 | zvrba | ok, that's fine |
| 11:10 | shortlord | I am using sets of size 1 and 2 to represent different kinds of things (a set with 1 element being a single node and a set with 2 elements being a line between these 2 nodes). Now I often have to implement different method behaviours for single nodes and lines. I could always pass the used set as an argument and then use (case (count my-set)) to distinguish the behaviour or even use a multimethod with count as a dispatch func |
| 11:10 | shortlord | tion, but I guess it would be better to pass the elements of the sets as single argument and then use arity overloading to define the behaviour, right? |
| 11:11 | shortlord | It would have the disadvantage that I'd have to convert between the set representation used in the datastructure and the call to the method which expect a different number of arguments, but that's still the more idiomatic clojure code, isn't it? |
| 11:13 | zvrba | that sounds like a lot of overhead |
| 11:13 | zvrba | how do you store those sets_ |
| 11:14 | shortlord | zvrba: in a map. The sets are the keys and the vals are certain attributes of these nodes and lines |
| 11:14 | zvrba | uh |
| 11:14 | shortlord | performance is not an issue, the maximum number of nodes is 54 and the maximum number of lines is 71 |
| 11:15 | shortlord | zvrba: but how would you have done it instead? |
| 11:15 | gfrlog | why do you have a set of 1 element instead of just the element? |
| 11:15 | zvrba | ah, ok then |
| 11:16 | gfrlog | shortlord: also why not store the nodes and lines separately? |
| 11:16 | zvrba | shortlord: or, why store nodes at all? |
| 11:16 | zvrba | do you have isolated nodes? |
| 11:17 | zvrba | shortlord: otherwise, depends on the size of the problem. there are many different structures to represent graphs. |
| 11:17 | zvrba | shortlord: for example, use a map where a key is the node and the value is either the other node of the line, or nil if it's an isolated node. |
| 11:17 | shortlord | gfrlog: I had them separated before, I might have been quite a good idea after all ;) |
| 11:18 | gfrlog | shortlord: yeah; without knowing what you're doing, I would think it'd be easier to manually treat them the same when that comes up then to have to manually pull them apart |
| 11:18 | zvrba | on a larger scale, instantiating a set for each edge/node seems like a lot of overhead. |
| 11:18 | shortlord | zvrba: yes, true. I guess I'll have to think about my datastructure a bit more |
| 11:18 | gfrlog | if that makes sens |
| 11:18 | zvrba | (space overhead) |
| 11:18 | gfrlog | sets are nice for edges when comparing equality; but there's probably a more performant option |
| 11:19 | shortlord | gfrlog: yes, the idea was to treat them equally in a number of situations, but these situations turned out to be a bit different, I guess I might as well handle them differently again |
| 11:20 | gfrlog | (concat edges nodes) is easier than writing multimethods |
| 11:28 | gfrlog | ,(let [evens (iterate #(+ 2 %) 0), odds (iterate #(+ 2 %) 1)] (take 20 (concat evens odds))) |
| 11:28 | clojurebot | (0 2 4 6 8 10 12 14 16 18 ...) |
| 11:28 | gfrlog | infinite ordinals in clojure |
| 11:43 | shortlord | why is it necessary to put function definitions into parentheses when defining functions with multiple arities? It should be pretty easy for Clojure to figure out that a pair of params and body always makes one definition, similar to let, right? |
| 11:45 | pdk | you can write things like (fn [x] (form1) (form2) ...) |
| 11:45 | pdk | without parens around form1 and form2 etc |
| 11:47 | pdk | so the extra parens disambiguate when you'd be adding a do form or something like that anyway for functions that don't follow the everything-inside-a-let-form format |
| 11:48 | shortlord | pdk: ah, function definitions contain an implicit do. Why is that the case? Although clojure is supposed to be used functional, using a do implicitly nearly everywhere seems rather imperative |
| 11:49 | tonyl | I think he meant the (defn ([] (do-something)) ([x] (do-something-else))) |
| 11:49 | pdk | they have an implicit do yes |
| 11:49 | pdk | though in cases like what tonyl is showing |
| 11:50 | pdk | something like (defn x [] (do-stuff) [x] (do-other-stuff)) |
| 11:50 | pdk | the lack of extra parens doesn't really help to distinguish for it whether the [x] is supposed to be a return value for the [] version or become the start of its own version of the function |
| 11:50 | pdk | so it cries |
| 11:51 | shortlord | pdk: I understand the problem, I was just surprised to find so many things in clojure having an implicit 'do', since do encourages destructive functions |
| 11:52 | pdk | hm there's something |
| 12:05 | fliebel | I love incanter :) |
| 12:06 | jweiss | ,(apply list "" "") |
| 12:06 | clojurebot | ("") |
| 12:06 | jweiss | i don't get it ^ |
| 12:07 | technomancy | jweiss: apply's last arg is treated as a seq |
| 12:07 | fliebel | Some nice scatter plots :) http://yfrog.com/7228285886p http://yfrog.com/7283555419p |
| 12:07 | jweiss | technomancy: yeah i was just realizing that |
| 12:08 | jweiss | so i guess i should wrap my args into a seq to begin with before calling apply |
| 12:08 | technomancy | if you don't have a seq already you don't need apply |
| 12:08 | fliebel | jweiss: Why would you call apply, if you don't have a seq of arguments? |
| 12:09 | jweiss | fliebel: well, in my code i do have a seq |
| 12:09 | fliebel | ah |
| 12:10 | jweiss | the error i'm getting is wrong # of args |
| 12:10 | jweiss | the first 2 args are empty strings in this case |
| 12:11 | tonyl | &(apply list "" "" ["wer" "gdf"]) |
| 12:11 | sexpbot | ⟹ ("" "" "wer" "gdf") |
| 12:20 | edoloughlin | Anyone using CounterClockwise had it go wierd for just one file? Syntax highlighting & colour parens still work but indentation, backspace, element selection are broken. Other files are unaffected. |
| 12:34 | LauJensen | &(double 2.2250738585072012e-308) |
| 12:35 | fliebel | LauJensen: Did you crash it? |
| 12:35 | LauJensen | fliebel: Yes |
| 12:35 | fliebel | clojurebot did this fine this morning... |
| 12:35 | LauJensen | ,(double 2.2250738585072012e-308) |
| 12:35 | robonobo | yeah |
| 12:35 | clojurebot | Execution Timed Out |
| 12:35 | fliebel | see... |
| 12:35 | robonobo | aha! |
| 12:35 | LauJensen | Hmm... |
| 12:35 | LauJensen | They both should do that. I think they use the same code almost |
| 12:35 | robonobo | would be weird if it did crash it |
| 12:36 | LauJensen | &(println "hello?") |
| 12:36 | sexpbot | ⟹ hello? nil |
| 12:36 | fliebel | huh... |
| 12:36 | fliebel | oh, right, threads... |
| 12:36 | fliebel | LauJensen: Maybe sexpbot kills the thread silently? |
| 12:36 | LauJensen | fliebel: yea I think so |
| 12:36 | robonobo | is there a difference beteen sexbot and clojurebot? |
| 12:36 | robonobo | woops |
| 12:36 | robonobo | sexpbot |
| 12:37 | LauJensen | robonobo: Yes, big differences |
| 12:38 | fliebel | &(dorun (repeat 42)) |
| 12:38 | sexpbot | Execution Timed Out! |
| 12:38 | fliebel | … huh? |
| 12:49 | semperos | ^ is now preferred to #^, right? |
| 12:51 | dnolen | semperos: yup |
| 12:51 | semperos | dnolen: thx |
| 13:06 | arohner | what do I put in my project.clj to download all of contrib-1.3? I have [org.clojure.contrib/complete "1.3.0-SNAPSHOT"]. That successfully downloads complete, but I don't see the other libraries in lib, and starting up complains about not finding org.clojure.contrib.shell |
| 13:08 | mattmitchell | aravind: [org.clojure.contrib "1.3.0-SNAPSHOT"] would probably do it |
| 13:09 | mattmitchell | aravind: sorry, this is what I have in mine: [org.clojure/clojure-contrib "1.2.0"] |
| 13:11 | raek | arohner: there's standalone too. I don't remember what the difference with complete was |
| 13:11 | arohner | well, it looks like one of my issues is that contrib.shell has disappeared |
| 13:12 | raek | now that you mention it, I think clojure.java.shell has replaced it |
| 13:13 | arohner | raek: aha! thanks |
| 13:28 | jkdufair | anyone have a setup they're happy with for developing/deploying to GAE? |
| 13:29 | fliebel | jkdufair: I heard appengine-magic is nice |
| 13:29 | fliebel | amalloy: ping |
| 13:30 | amalloy | fliebel: pong |
| 13:30 | fliebel | amalloy: I wrote and benchmarked a few take-randnth functions :) |
| 13:31 | amalloy | exciting |
| 13:31 | jkdufair | ah! haven't heard of appengine-magic. will check it out. thx |
| 13:32 | fliebel | amalloy: https://gist.github.com/805747 |
| 13:33 | fliebel | So, there are the simple functions, which should be very bad, and then mine and yours, for the more complicated approach. |
| 13:33 | jkdufair | fliebel: wow! thank you |
| 13:34 | fliebel | amalloy: But as you can see in the graphs(linked), the first 2 do quite well. |
| 13:34 | amalloy | fliebel: neat, i'm looking now |
| 13:35 | fliebel | First graph is constant number of items from a growing vector, second is a growing number of items to take from a constant vector. |
| 13:35 | amalloy | did you check out https://gist.github.com/805546 and https://gist.github.com/805583, where i implemented it two more times myself? |
| 13:35 | fliebel | no... |
| 13:35 | amalloy | they're not that interesting really |
| 13:36 | fliebel | amalloy: Did you try them performance-wise? |
| 13:36 | amalloy | nope |
| 13:37 | amalloy | i don't expect them to be any better really |
| 13:37 | amalloy | one was a lazy-taking approach, and one was writing it with unfold |
| 13:39 | fliebel | the distinct one in my code is also lazy, but as you see in the second plot, it gets bad once n gets close to the length of coll. |
| 13:43 | fliebel | amalloy: How do you figure out this big o thing? |
| 13:44 | amalloy | fliebel: http://en.wikipedia.org/wiki/Big_O_notation#Example is a reasonable description |
| 13:48 | ohpauleez | Is Enrico Franchi in here? |
| 13:48 | amalloy | eg for take-rand3, (count coll) takes O(coll) time, (range nr) takes O(nr) time; each step in the reduces takes constant time, and there are coll + nr reduce steps, so the total algorithmic complexity is O(coll+nr) |
| 13:49 | amalloy | and the same is probably true of any similar implementation, including mine; the simple ones probably have smaller constant factors |
| 13:50 | amalloy | i think the main benefit of the complicated algorithm comes when (vec coll) is already passed in to you, so that you only have to do the O(nr) steps |
| 13:51 | amalloy | i'd be interested to see how that performs: create a large vector once, then call take-randnth on it many times. i dunno |
| 13:51 | fliebel | amalloy: What about nr 2? I can;t figure that one out. |
| 13:53 | amalloy | $source distinct |
| 13:53 | sexpbot | distinct is http://is.gd/9IzW0R |
| 13:54 | fliebel | amalloy: The problem is that we have to deal with the probability that rand-nth takes a duplicate. |
| 13:54 | fliebel | also, count on a vector seems to be constant. |
| 13:54 | amalloy | fliebel: yes, it gets murky |
| 13:54 | amalloy | and yeah, count is definitely constant there |
| 13:54 | amalloy | but in take-rand3, coll isn't a vec |
| 13:55 | fliebel | I pass it a vec... |
| 13:56 | amalloy | fliebel: i don't see that happening. plot-len and plot-take both pass it a (range foo), and the very first line of take-rand3 is (count coll) |
| 13:56 | amalloy | but it doesn't really matter, since there's an O(coll) step later anyway |
| 13:57 | fliebel | Oh, I didn't put that in the gist yet, but I do. |
| 13:57 | fliebel | where? |
| 13:57 | clojurebot | where is your source code |
| 13:58 | amalloy | fliebel: (reduce f (vec coll)) |
| 13:58 | amalloy | is going to have (count coll) steps |
| 13:59 | amalloy | er wait, those ->> forms confuse me |
| 13:59 | fliebel | amac: Wrong! Right! |
| 14:00 | fliebel | But still, there must be something that gets worse with coll, otherwise the first graph would be constant... |
| 14:00 | amalloy | $source vec |
| 14:00 | sexpbot | vec is http://is.gd/jXPZMI |
| 14:00 | ohpauleez | Is reduce lazy, in that it'll only realize the next element of a lazySeq? |
| 14:00 | amalloy | oh, of course that doesn't say anything useful |
| 14:00 | amalloy | ohpauleez: no |
| 14:00 | ohpauleez | amalloy: So it'll realize the full seq, just like apply? |
| 14:01 | fliebel | It goes down to RT, which calls LazilyPersistentVector |
| 14:01 | amalloy | fliebel: (vec coll) is O((count coll)) |
| 14:01 | fliebel | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LazilyPersistentVector.java |
| 14:01 | amalloy | thanks |
| 14:01 | fliebel | … I'm trying that |
| 14:02 | amalloy | fliebel: i've often wondered why (vec [1 2 3 4]) isn't a no-op |
| 14:02 | fliebel | yea... |
| 14:03 | amalloy | but either way, (count coll) and (vec coll) are both linear-time |
| 14:03 | amalloy | ohpauleez: i don't understand the question. realize which full seq? |
| 14:03 | fliebel | okay |
| 14:03 | jkdufair | is there some .emacs code i can use to start swank from within emacs (i.e. not have to launch another terminal)? |
| 14:04 | fliebel | amalloy: Bingo! removing the vec made 3 and 4 constant. |
| 14:04 | amalloy | fliebel: really? that's good, i think. can you link me to an updated gist? |
| 14:04 | technomancy | jkdufair: http://github.com/technomancy/durendal |
| 14:05 | fliebel | amalloy: You want updated plots as well? |
| 14:05 | amalloy | fliebel: if you want. i'm willing to take your word for it |
| 14:06 | jkdufair | technomancy: thank you! |
| 14:07 | fliebel | amalloy: https://gist.github.com/805747 http://yfrog.com/5r80779474p http://yfrog.com/mr42647628p |
| 14:07 | technomancy | no problem |
| 14:08 | amalloy | fliebel: excellent, just as we hoped |
| 14:10 | fliebel | amalloy: Still, picking and filtering random items, is faster for picking a small number of items from a larger vector. |
| 14:10 | amalloy | yeah |
| 14:10 | fliebel | uh, no, I mean… well |
| 14:10 | amalloy | fliebel: well, shuffling then picking |
| 14:11 | fliebel | right |
| 14:11 | amalloy | filtering is not so hot |
| 14:11 | fliebel | I was talking about the red line, which is… the shuffle one. |
| 14:12 | amalloy | as N approaches M, the filter solution is probably O(N!), but figuring out what it's like in the middle is too hard for me :P |
| 14:13 | fliebel | amalloy: I think some math person in here explained something related to me once... |
| 14:14 | fliebel | Something with birthdays and pigeonholes. |
| 14:14 | amalloy | yes, probably related to the birthday problem |
| 14:14 | amalloy | but more complicated i think |
| 14:15 | fliebel | So, it will be O(N!@#$%M^&) |
| 14:16 | amalloy | *laugh* indeed |
| 14:17 | fliebel | I'll update the gist to reflect that... |
| 14:17 | ejackson | fliebel: hilarious |
| 14:19 | fliebel | https://gist.github.com/805747 |
| 14:22 | jkdufair | technomancy: great tools. thx a bunch. |
| 14:32 | danlarkin | $4 |
| 14:38 | ieure | technomancy, What’s the accepted way of depending on a Java lib (with Leiningen) which isn’t in a public Maven repo? |
| 14:38 | ieure | I dropped it in lib/ and lein nukes it every time I run deps. |
| 14:41 | danlarkin | ieure: it has to be in a repo |
| 14:41 | danlarkin | your local .m2 cache is technically a repo |
| 14:41 | amalloy | ieure: you can install it to your local repo |
| 14:41 | ieure | Gross. |
| 14:42 | ieure | Okay. |
| 14:42 | ieure | Can I just cp it in there or what? |
| 14:42 | ieure | I don’t know fuck-all about the varied crazy Java build tools. |
| 14:43 | ldh | no, you've got to tell maven to install it. example: http://jeff.langcode.com/archives/27 |
| 14:45 | ohpauleez | I basically have to sum a comprehension, and I've timed a few approaches, two have similar times and so I want to understand how they differ. One is doing (reduce #(+ (op-on %1)) coll), another is doing (apply + (map #(op-on %1) coll)), but the apply is going to realize the entire collection, and I have a situation where that collection could be extremely large. (amalloy) |
| 14:47 | amalloy | ohpauleez: i think you made some kind of typo with your first example, but neither one of those will realize the whole collection at once |
| 14:47 | ohpauleez | oh really? I thought apply would |
| 14:48 | ohpauleez | amalloy: ^. Thanks though, I'll just go with which ever one is fastest then |
| 14:48 | amalloy | nah, it passes a lazy seq as the &rest arg |
| 14:48 | ohpauleez | ahh, cool |
| 14:48 | amalloy | &(apply + (range 1e6)) |
| 14:48 | sexpbot | ⟹ 499999500000 |
| 14:49 | ohpauleez | thanks amalloy |
| 14:50 | amalloy | &(= (doall (range 1e6))) |
| 14:50 | sexpbot | Too much is happening at once. Wait until other operations cease. |
| 14:50 | fliebel | amalloy: Why was your php code using 2 arrays? |
| 14:50 | amalloy | *blink* |
| 14:50 | amalloy | Raynes: ping |
| 14:50 | fliebel | Hm, I think sexpbot is having trouble with big numbers ;) |
| 14:51 | amalloy | $login |
| 14:51 | sexpbot | You've been logged in. |
| 14:51 | amalloy | $reload |
| 14:51 | sexpbot | Reloaded successfully. |
| 14:51 | amalloy | $logout |
| 14:51 | sexpbot | You've been logged out. |
| 14:51 | amalloy | &1 |
| 14:51 | sexpbot | ⟹ 1 |
| 14:51 | amalloy | fliebel: i suppose i could have done it with a single array |
| 14:52 | amalloy | use the below-i chunk of the array to store the return value, and then split it when it's time to return |
| 14:53 | fliebel | right, that is what my reduce thing is doing. made me feel real smart for a moment :) |
| 14:54 | amalloy | fliebel: ahh, is that what's going on. your reduce was too clever for me |
| 14:54 | fliebel | amalloy: Your iterate was to smart for me... |
| 14:55 | amalloy | fliebel: it's funny, because i knew the classic algorithm involved swapping a[i] with a[idx], but i couldn't remember why, so i just didn't do it |
| 14:59 | amalloy | fliebel: are you sure take-rand3 selects uniformly? |
| 14:59 | amalloy | (reduce #(conj %1 [%2 (rand-int %2 len)]) [] (range n)) looks like it will be biased towards higher numbers, though i still don't see how it all fits together |
| 14:59 | fliebel | uhm, no… but not less uniformly than your code I think… I just collapsed your separate vector inot the unused part of the first vector. |
| 15:00 | amalloy | oh, i think i get it |
| 15:00 | amalloy | okay, clever |
| 15:01 | fliebel | amalloy: You might have trouble with my ->>, I'm having trouble with your nesting. |
| 15:01 | amalloy | lol |
| 15:01 | amalloy | you create a list of swaps first, and then perform them all in a row on the coll? |
| 15:01 | fliebel | yea :) |
| 15:01 | tonyl | what gist is it? |
| 15:01 | amalloy | https://gist.github.com/805747 |
| 15:02 | amalloy | fliebel: i like ->> as much as the next guy, it's just harder to read other people's code :) |
| 15:03 | fliebel | yea, but I think I understand your code now. *phew* |
| 15:05 | amalloy | tonyl: your turn to write one |
| 15:05 | fliebel | tonyl: I second that :) |
| 15:05 | tonyl | I am working on one |
| 15:05 | fliebel | great :) |
| 15:05 | tonyl | are we looking for O(n) |
| 15:06 | fliebel | O(lean and mean) is what we want. |
| 15:06 | tonyl | right |
| 15:07 | fliebel | tonyl: Have you seen the plots? |
| 15:08 | tonyl | fliebel: I am looking at your post for that, are those the ones? |
| 15:08 | fliebel | yes |
| 15:10 | amalloy | fliebel: i love that immutability lets you write (assoc a i (a b) b (a i)) instead of needing a temporary swap area |
| 15:10 | fliebel | :) |
| 15:11 | fliebel | I wish update-in does that. or…. ##(doc update-in) |
| 15:11 | sexpbot | ⟹ "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created." |
| 15:11 | amalloy | fliebel: what for? isn't that what assoc is for? |
| 15:12 | fliebel | amalloy: Wouldn't it be great if you could update multiple nested values in one go? |
| 15:14 | fliebel | But yea, I am really starting to appreciate those little features. Same thing for map, equality and math operators. |
| 15:14 | amalloy | &(update-in {:a {:b 10 :c 5}} [:a] assoc :b 1 :c 2) is an approximation |
| 15:14 | sexpbot | ⟹ {:a {:b 1, :c 2}} |
| 15:14 | mfex | hi, can anyone point me to the slides for mark mcgranaghans conj talk? |
| 15:14 | amalloy | you can't easily operate on the existing values of :b/:c, afaik |
| 15:15 | amalloy | fliebel: i've wanted to be able to do that in the past, but someone convinced me it was a confused idea. if only i could remember why... |
| 15:15 | fliebel | hey, nr2 became O(M-ish) as well by removing the vec. |
| 15:16 | amalloy | fliebel: surely not if N ~= M? |
| 15:18 | fliebel | hmhm |
| 15:18 | fliebel | It just that the vec does not make it increase anymore. |
| 15:19 | fliebel | post updated |
| 15:21 | fliebel | I cant help seeing a patter like /// in the shuffle line. GC? Chunking? |
| 15:22 | technomancy | ieure: I recommend setting up a private archiva instance for private jars if you've got a team of more than 1 |
| 15:23 | technomancy | ieure: if you're solo then you can add the dependency to project.clj even if it's not in any remote maven repos and run lein deps; it will give you a line you can use to put the jar in m2 |
| 15:23 | amalloy | fliebel: gc i think. every one of the plots has those outliers |
| 15:24 | amalloy | shuffle probably feels the most impact because it's allocating a new M-sized array every time, even if you only need N elements out of it |
| 15:25 | fliebel | that's true... |
| 15:26 | fliebel | Although I would expect to see out-of-line dots, as with the others, but what I see is more like a gradual decline in speed, and then a drop again. |
| 15:27 | fliebel | tonyl: How are you doing? |
| 15:28 | tonyl | can't make it any better then m+n |
| 15:28 | tonyl | I need to learn more about clojure internals for this one |
| 15:29 | tonyl | it's puzzling me, but good thought and clojure-training exercise |
| 15:29 | fliebel | tonyl: http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html |
| 15:29 | fliebel | (shift the headers >) |
| 15:31 | fliebel | tonyl: When you're done, I'd love to see your code. |
| 15:32 | tonyl | thanks for the link, i have another idea. i will show the code for critique |
| 15:33 | bartj | I am looking for a soundex library and am thoroughly confused as to which I should pick |
| 15:33 | bartj | or even which is the most appropriate |
| 15:33 | bartj | because the soundex returned by the in-built mysql function |
| 15:35 | bartj | is different from that of Apache commons library - http://commons.apache.org/codec/apidocs/src-html/org/apache/commons/codec/language/Soundex.html#line.252 |
| 15:36 | amalloy | fliebel: oh, i see, you mean in the plot-take, not plot-len |
| 15:37 | fliebel | right |
| 15:37 | amalloy | yeah, that is interesting |
| 15:38 | amalloy | tonyl: you should certainly learn lein or cake. incanter is neat but i feel like i don't have enough uses for it to spend time learning it |
| 15:39 | tonyl | i've used a personal bash script to run my clj scripts, but now projects getting bigger or managing dependecies is getting to be a problem. |
| 15:39 | fliebel | tonyl: crash course: lein/cake deps, lein/cake repl, lein/cake uberjar. incanter: (view (xy-plot xs ys)) |
| 15:39 | amalloy | fliebel: don't forget lein/cake new |
| 15:39 | tonyl | so no big differences between lein and cake, besides cake having a persistent jvm? |
| 15:39 | amalloy | tonyl: mostly just different plugin frameworks |
| 15:40 | amalloy | lein has optional persistent jvm too |
| 15:40 | tonyl | oh ok |
| 15:40 | raek | they are very similar for basic tasks. their plugin/task features are more different, though |
| 15:40 | tonyl | I'll try lein first since it was the first one to come out |
| 15:40 | tonyl | then I'll test this code I have to see the scattering and time |
| 15:40 | tonyl | fliebel: I |
| 15:41 | tonyl | fliebel: I'll try not to keep you waiting to much for the code :) |
| 15:41 | shortlord | there is nothing like select-keys or find that takes a pred instead of fixed keys, is there? |
| 15:41 | tonyl | maybe some can help you there |
| 15:41 | fliebel | tonyl: I have tea :) so, if you do it within a hour, I'm fine :) |
| 15:41 | amalloy | shortlord: filter |
| 15:41 | fliebel | Otherwise I'll see you tomorrow. |
| 15:42 | shortlord | amalloy: but filter does not return a map, but a sequence, which requires some ugly stitching together afterwards |
| 15:42 | fliebel | meh, just (into {}) |
| 15:42 | amalloy | &(into {} (filter (comp even? key) {1 2, 4 3, 5 6 8 7})) |
| 15:42 | sexpbot | ⟹ {4 3, 8 7} |
| 15:43 | amalloy | fliebel: http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle is apparently what the shuffle algorithm is called |
| 15:43 | jkdufair | just want to say thanks to the whole clojure community. i got a production-ready GAE/slime/swank/clojure/cygwin setup together in a matter of hours and already have a hello world app on GAE |
| 15:48 | shortlord | fliebel, amalloy: thx, into {} together with some as the pred was exactly what I needed, great :) |
| 15:50 | raek | if you want to make it map type independent, you can do it like (into (empty m) (filter pred m)) |
| 15:57 | jweiss | anyone here use clojure.contrib.logging with java.util.logging? the method/line# logging doesn't work - it always prints "lojure.contrib.logging$impl_write_BANG_.invoke" |
| 15:57 | jweiss | rather "clojure.contrib.logging$impl_write_BANG_.invoke" |
| 16:06 | fliebel | tonyl: Done yet? My tea is done, and I'm soon going to bed ;) |
| 16:06 | tonyl | fliebel: I guess I'll bother you tomorrow then |
| 16:07 | fliebel | tonyl: Thanks :) |
| 16:09 | semperos | &(first "/") |
| 16:09 | sexpbot | ⟹ \/ |
| 16:09 | semperos | what's the right way to just have that char? |
| 16:10 | ieure | Ugh. |
| 16:10 | tonyl | semperos: it seems that you have it |
| 16:10 | ieure | What am I doing wrong here? https://gist.github.com/a9aeeb52bfe1514b7b55 |
| 16:10 | ieure | "No matching ctor found for class com.google.i18n.phonenumbers.Phonenumber" |
| 16:10 | ieure | No idea what that is supposed to mean. |
| 16:11 | semperos | tonyl: I do, but it seems a bit round-about to ask (first some-string) to "get" a single char |
| 16:11 | tonyl | ieure: means there is no constructor that just takes no arguments for that class |
| 16:11 | tonyl | &\/ |
| 16:11 | sexpbot | ⟹ \/ |
| 16:11 | semperos | tonyl: coulda sworn I tried that at the repl; thanks |
| 16:11 | tonyl | semperos: just prepend it with a \ ##\/ |
| 16:12 | bartj | ieure, I can help you |
| 16:12 | bartj | as a matter of great coincidence I am using the Phonenumber lib right now :) |
| 16:12 | semperos | same as with all char's, must have mistyped originally |
| 16:12 | ieure | bartj, Awesome. |
| 16:12 | bartj | ieure, let me look at gist |
| 16:13 | ieure | bartj, I guess I’m supposed to use PhonenumberUtil.getInstance() to get an instance back. |
| 16:13 | ieure | Fuckin’ Java. |
| 16:13 | bartj | oh, that is easy |
| 16:14 | bartj | (PhoneNumberUtil/getInstance) |
| 16:14 | bartj | here is how to format phone numbers: |
| 16:14 | bartj | (.format (PhoneNumberUtil/getInstance) phone com.google.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat/INTERNATIONAL) |
| 16:14 | bartj | where "phone" will be a number of course |
| 16:14 | ieure | Yeah. |
| 16:14 | bartj | this will return a Phonenumber class |
| 16:15 | ieure | Throws an exception, but I think I can thrash around from here. |
| 16:15 | bartj | you would have to use (PhoneNumberUtils/getInstance) |
| 16:16 | bartj | ok |
| 16:16 | amalloy | tonyl: sexpbot only evals ##code that starts with parens, to avoid annoying people in ##java and similar channels |
| 16:16 | tonyl | I figured it might be because of that |
| 16:16 | ieure | bartj, Is there a less insane way of saying "com.google.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat/INTERNATIONAL"? |
| 16:16 | bartj | ieure, yeah :) |
| 16:17 | bartj | (import-static com.google.i18n.phonenumbers.PhoneNumberUtil$PhoneNumberFormat INTERNATIONAL) |
| 16:17 | tonyl | aliasing it |
| 16:17 | bartj | and then |
| 16:17 | bartj | (.format (PhoneNumberUtil/getInstance) INTERNATIONAL) |
| 16:17 | bartj | I believe raek told me this a few days back |
| 16:17 | amalloy | bartj: sweet, i always forget we have import-static |
| 16:17 | ieure | Looks like that’s not an option with the `ns' macro, though. |
| 16:18 | amalloy | ieure: no, you have to do it separately |
| 16:18 | ieure | Is that a 1.3 feature? |
| 16:19 | ieure | Unable to resolve symbol: import-static in this context |
| 16:19 | ieure | On 1.2.x. |
| 16:19 | tonyl | it is in contrib |
| 16:19 | ieure | Ah, okay. |
| 16:19 | tonyl | http://clojuredocs.org/clojure_contrib/clojure.contrib.import-static/import-static |
| 16:19 | mattmitchell | ,(doc defn) |
| 16:19 | clojurebot | "([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any do... |
| 16:20 | amalloy | &(doc defn) |
| 16:20 | sexpbot | ⟹ "Macro ([name doc-string? attr-map? [params*] body] [name doc-string? attr-map? ([params*] body) + attr-map?]); Same as (def name (fn [params* ] exprs*)) or (def name (fn ([params* ] exprs*)+)) with any doc-string or attrs added to the var metadata" |
| 16:20 | markskilbeck | Deja vu. |
| 16:21 | mattmitchell | markskilbeck: funny :) |
| 16:25 | mattmitchell | hmm, i'm trying to add :doc and :arglists to a defn. but (doc my-func) doesn't show anything |
| 16:25 | mattmitchell | is this correct? (defn t #^{:doc "test"} [] (prn "t")) |
| 16:26 | tonyl | i think it is (defn ^{:doc "test"} t [] (prn "t")) |
| 16:27 | mattmitchell | tonyl: there we go thanks. |
| 16:27 | technomancy | mattmitchell: (defn t "test" [] (prn "t")) |
| 16:27 | ohpauleez | mattmitchell: also what technomancy ^ |
| 16:27 | ohpauleez | I think that's more widely used |
| 16:27 | amalloy | yes, for sure that is used most, but if you want to supply arglists you have to do it tony's way |
| 16:28 | ohpauleez | ahh, yes |
| 16:28 | brehaut | mattmitchell: the #^ is old style meta (pre 1.2) |
| 16:28 | mattmitchell | ok i thought i read that somewhere. |
| 16:32 | tonyl | gotta get some things done, nice talking to you guys |
| 16:33 | ieure | Is there a CSV library (or wrapper around a Java one) which will lazily read lines from *in*? |
| 16:34 | ieure | I found clojure-csv, but it seems to want the entire CSV to be read in as a string. |
| 16:34 | ieure | I guess I could parse one line at a time and always call first, but that seems somewhat ugly. |
| 16:34 | raek | (defn t "test" {:arglists '([foo bar])} [x y] ...) |
| 16:38 | ohpauleez | ieure: http://clojuredocs.org/clojure_core/clojure.core/line-seq |
| 16:38 | ohpauleez | &(doc line-seq) |
| 16:38 | sexpbot | ⟹ "([rdr]); Returns the lines of text from rdr as a lazy sequence of strings. rdr must implement java.io.BufferedReader." |
| 16:39 | ohpauleez | not sure how you'd make sure you were processing the csv correctly |
| 16:39 | ieure | ohpauleez, So, #1, this will not with with *in*, which is a LineNumberingPushbackReader, not a BufferedReader. And #2, I can already lazily read from *in*, it’s just that the clojure-csv semantics aren’t a good match. |
| 16:39 | ohpauleez | but you might be able to write a nice small DSL, using the existing functions in the library |
| 16:41 | ohpauleez | ieure: I was assuming you would just rebind *in*. Sorry for misunderstanding the question |
| 16:41 | ieure | No, I want to read from stdin. |
| 16:41 | ohpauleez | the answer is just see if the functions in the library are small enough for you to build up a lazy version of the DSL |
| 16:42 | ohpauleez | and then contribute the changes back to the project |
| 16:42 | ieure | Though it seems like I might be better off using with-open and/or line-seq. |
| 16:42 | ieure | I really don’t think I need to build up a DSL here. |
| 16:43 | ohpauleez | is this because you want to pipe the csv to it? |
| 16:43 | ieure | Yes. |
| 16:44 | amalloy | ieure: i think ohpauleez is using DSL to mean "library" here |
| 16:44 | ohpauleez | yes |
| 16:44 | ohpauleez | loosely using DSL |
| 16:48 | ieure | Well, I was hoping to avoid parsing command-line arguments, which was the main reason to use *in* |
| 16:48 | ieure | But this LineNumberingPushbackReader stuff that *in* uses seems crazy. |
| 16:49 | ieure | It’s way easier to just use (read-lines). |
| 16:49 | mattmitchell | is it common to use the :test meta key for embedding tests to your functions? |
| 17:05 | aamar | Missed connection: I saw a clojure package for couchdb, quite a bit more high-level than clojure-couchdb or clutch; more support for view handling etc. Anyone know of it? |
| 17:05 | aamar | Can't find it anymore |
| 17:11 | ohpauleez | aamar: eames, clojurize-couchdb, net.experimentalworks/couchdb ? |
| 17:11 | ohpauleez | there's also evil-couchdb |
| 17:12 | sritchie | hey all -- I'm reading about the various matrix packages in java, and I see references to "large" matrices, or really large vectors |
| 17:12 | sritchie | where would the "large" range start? |
| 17:12 | brehaut | dont forget https://github.com/mmcgrana/hammockdb |
| 17:12 | sritchie | I'd like to read in a 360x720 2d vector |
| 17:12 | sritchie | of floats |
| 17:15 | aamar | ohpauleez, brehaut: I bet it's one of those, I'll take a look. Thanks! |
| 17:15 | brehaut | aamar: its not hammock ;) |
| 17:17 | Leonidas | hi. I tried `binding' a variable from another namespace but that does not seem to be possible. any ideas what I could do? |
| 17:17 | ohpauleez | sritchie: I think it depends what you're doing with that matrix, but I'm not sure what qualify as "large" |
| 17:17 | ohpauleez | sritchie: typically in Clojure, large things are operated on lazily |
| 17:17 | ohpauleez | if possible |
| 17:18 | ohpauleez | Leonidas: http://clojuredocs.org/clojure_contrib/clojure.contrib.with-ns/with-ns |
| 17:18 | ohpauleez | you can use with-ns, and rebind |
| 17:18 | sritchie | ohpauleez: yeah, I've got these as lazy vectors, as of now -- I'm working on a cascalog operation that needs to return a sequence of float arrays |
| 17:19 | Leonidas | ohpauleez: that looks nice, so with-ns and binding. cool, will try that |
| 17:19 | sritchie | cascalog builds mapreduce jobs, so presumably these are going to get serialized by hadoop -- |
| 17:19 | raek | Leonidas: are you 1) using clojure 1.3 or 2) trying to rebing something in clojure.core= |
| 17:19 | ohpauleez | sritchie: and as long as it's using streaming underneath, you should be fine, right? |
| 17:20 | sritchie | ohpauleez: sounds like it |
| 17:20 | sritchie | ohpauleez: great, I'll test this out, then |
| 17:20 | ohpauleez | cool |
| 17:20 | raek | you should be able to rebind vars using binding without with-ns |
| 17:20 | ohpauleez | raek: really, even in other ns's? |
| 17:20 | raek | yes |
| 17:20 | dnolen | eames, not ready nor public yet. I really should get back to that :) |
| 17:21 | raek | (dynamic rebinding using 'binding') |
| 17:21 | ohpauleez | dnolen: :) |
| 17:21 | ohpauleez | I have a cassandra wrapper in a similar state |
| 17:21 | raek | the way you can rebing *in* and *out*, for instance |
| 17:22 | raek | 1) in clojure 1.3. only vars marked as :dynamic can be rebound, 2) some of the vars in clojure.core are special and cannot be rebindable. |
| 17:22 | ohpauleez | raek: ah yes, totally |
| 17:23 | ohpauleez | as long as you qualify correctly, I don't know what i was thinking |
| 17:23 | raek | yes. good point. the symbol used in 'binding' must of course resolve to the var in question |
| 17:25 | Leonidas | ohpauleez: uhm, now I can't access my formal parameters from inside the with-ns body. Whats the solution to that? |
| 17:26 | ohpauleez | Leonidas: you should scroll up and read what raek and I were saying on the subject |
| 17:26 | ohpauleez | let me know if that helps you |
| 17:28 | Leonidas | ohpauleez: oh sorry, I missed that somehow. |
| 17:28 | Leonidas | raek: no, I am on Clojure 1.2 and trying to rebind something that is defined in some other module of my software. |
| 17:29 | amalloy | sritchie: btw, "lazy vectors" is a contradiction. presumably you meant lazy sequences |
| 17:30 | sritchie | amalloy: yeah, sorry about that, I meant lazy sequences. I've got a byte-buffer, and I've written a function that returns a lazy sequence for a bytebuffer, by calling .getFloat |
| 17:30 | sritchie | amalloy: The next step is to use this lazy seq to create an array inside of incanter |
| 17:30 | raek | Leonidas: also, watch out for combining dynamic rebinding with lazy sequences (map, for, filter and friends) |
| 17:30 | sritchie | amalloy: so I'll have to realize the sequence eventually |
| 17:31 | Leonidas | raek: I am trying to rebind a boolean value. |
| 17:31 | raek | if you return a lazy sequence out of the binding form, the binding can revert before the lazy seq is forced |
| 17:31 | Leonidas | (def force-color false) |
| 17:31 | amalloy | Leonidas: whoa, that is not rebinding |
| 17:31 | Leonidas | in the one file and in the other (binding [force-color true] body) |
| 17:31 | raek | it is a convention to name rebindable variables with *earmuffs* |
| 17:32 | raek | (the naming shouldn't make any difference in 1.2, though) |
| 17:32 | Leonidas | oh, good point. I will adjust that. |
| 17:32 | amalloy | raek: or in 1.3, i'm pretty sure |
| 17:32 | Leonidas | I'd prefer to get this thing working first. |
| 17:32 | amalloy | Leonidas: that should work as long as force-color resolves to the same var as the one you're def-ing |
| 17:32 | ohpauleez | Leonidas: it needs to be (binding [the-ns/*force-color* true] body) |
| 17:32 | raek | ah, have they removed the automatic :dynamic on *earmuffs*= |
| 17:32 | amalloy | ie, you have a :use or :require for that ns |
| 17:33 | ohpauleez | Leonidas: what amalloy said |
| 17:33 | amalloy | raek: i'm not an authority by any means, but last i heard |
| 17:33 | raek | Leonidas: what does (resolve 'force-color) return? |
| 17:33 | raek | if it returns #'the-ns/*force-color*, then it should work |
| 17:34 | jweiss | how do i do this in clojure: x =1; try { doStuff(); x=2; } finally { System.out.println(x); } |
| 17:34 | Leonidas | ohpauleez: I thought the same and tried to :use my.namespace :only (force-color), is that enough or do I still need to prefix my.namespace/ to *force-color*? |
| 17:34 | raek | Leonidas: also, what does (binding [*force-color* :lala] *force-color*) return? |
| 17:34 | raek | Leonidas: the usual rules for symbol resolution applies |
| 17:35 | raek | ,(binding [*out* :lala] *out*) |
| 17:35 | clojurebot | :lala |
| 17:36 | raek | ,(binding [*out* :lala] (lazy-seq [*out*])) ; common gotcha |
| 17:36 | clojurebot | (#<StringWriter >) |
| 17:36 | Leonidas | raek: resolve returns nil, both before and inside the binding form |
| 17:37 | mefesto | Is it possible to extend a protocol to a byte array? |
| 17:37 | ohpauleez | Leonidas: can you paste up a gist for us? |
| 17:37 | raek | ,(resolve '*out*) |
| 17:37 | clojurebot | #'clojure.core/*out* |
| 17:37 | Leonidas | ohpauleez: sure. |
| 17:37 | ohpauleez | thanks! |
| 17:37 | amalloy | jweiss: (let [x (try (dostuff) 2 (catch Exception _ 1))] (println x)) |
| 17:38 | jweiss | amalloy: but i want a finally clause, not catch |
| 17:38 | raek | Leonidas: then either you should get an exception when trying to evaluate anything using *force-color*, or you have a let or function parameter shadowing it |
| 17:38 | jweiss | i want the printout whether an exception occurs or not |
| 17:38 | jweiss | do i have to rethrow? |
| 17:40 | raek | no, (try ... (finally (println x))) should work |
| 17:40 | Leonidas | ohpauleez: https://gist.github.com/806871 (it isn't actually running, I hope that's enough) |
| 17:40 | amalloy | jweiss: that or use some mutable/reference variable |
| 17:40 | amalloy | raek: but he needs x to be bound in the finally scope, and "changed" in the try scope |
| 17:40 | jweiss | so the finally clause can't know what the try clause returned? |
| 17:40 | jweiss | i guess not since it's inside the try :) |
| 17:40 | amalloy | jweiss: i don't think so |
| 17:41 | Leonidas | raek: yeah, I'm also surprised why I get nil but inside the (binding [force-color true] force-color) is still true. |
| 17:41 | ieure | You guys have invalidated my rule about IRC. |
| 17:41 | ieure | "All channels of the form #(programming-language) are useless." |
| 17:41 | ohpauleez | ieure: Which is? |
| 17:41 | Leonidas | ieure: what rule? |
| 17:41 | ieure | You guys are really helpful, and I appreciate it more than you know. |
| 17:41 | jweiss | this channel rocks |
| 17:41 | raek | ah. change. clojure does not allow that to locals. |
| 17:41 | ohpauleez | ah, thanks ieure |
| 17:41 | amalloy | ieure: only people with lots of vowels in their name are worth listening to? |
| 17:42 | ohpauleez | haha |
| 17:42 | raek | Leonidas: can you test evaling force-color and (binding [force-color :foo] force-color) at the repl? |
| 17:42 | amalloy | i guess with 3.5 of each i'm on the border |
| 17:42 | arohner | is defining multi-methods with #'foo as a dispatch function fully legal? |
| 17:43 | raek | after a (in-ns 'karmawhore.parser) |
| 17:43 | amalloy | arohner: yes |
| 17:43 | arohner | amalloy: it appears to give me a syntax error in 1.3-alpha4 |
| 17:43 | amalloy | gist? |
| 17:43 | arohner | one sec |
| 17:43 | Leonidas | raek: I get :foo back. |
| 17:43 | ohpauleez | Leonidas: is force-color originally bound to true? |
| 17:44 | Leonidas | ohpauleez: no, it is originally false |
| 17:44 | ohpauleez | and is it still false in that binding block? |
| 17:44 | Leonidas | raek: and (resolve 'force-color returns non-nil) |
| 17:45 | Leonidas | ohpauleez: no, it is true inside the block. But only to the block, the functions that I call (red) see it as false |
| 17:45 | jweiss | isn't there an alternative to swap! that just takes a value instead of a function? |
| 17:45 | raek | jweiss: reset! |
| 17:46 | jweiss | ah there you go. it's not mentioned here: http://clojure.org/atoms |
| 17:46 | Leonidas | #'karmawhore.color/force-color |
| 17:46 | jweiss | which i find strange |
| 17:46 | Leonidas | is what it resolves to. Looks fine to me |
| 17:46 | raek | Leonidas: can you paste the definition of 'red'? |
| 17:46 | Leonidas | but somehow the binding does not traverse over to inside karmawhore.color |
| 17:47 | raek | could be that you look up the value of force-color "in advance" |
| 17:48 | raek | for instance, (def foo force-color) will deref force-color and bind foo to the value it had at that point |
| 17:48 | sritchie | quick question on lazy seqs -- if I build a lazy seq with a generator, and want to return a lazy-seq of the first 1000 elements, say, os the way to do this with (def lazy-return (take 1000 lazy-generator)) |
| 17:48 | amalloy | jweiss: it's not exactly good practice. but it is mentioned in http://clojure.org/cheatsheet, at least |
| 17:48 | Leonidas | raek: the relevant bits: https://gist.github.com/806871#file_parser.clj |
| 17:49 | jweiss | amalloy: yeah, i left my paper cheatsheet copy at home :) |
| 17:49 | amalloy | sritchie: (take 1000 (lazy-generator)) |
| 17:49 | Leonidas | raek: erm, I mean https://gist.github.com/806871#file_color.clj |
| 17:49 | amalloy | ie, you should never bind a variable to the entire sequence, or none of it can be freed |
| 17:51 | sritchie | amalloy: ah, got it |
| 17:51 | sritchie | amalloy: how about (map %(take 1000 %) lazy-generators), where lazy-generators is a sequence of those lazy-gens? |
| 17:52 | brehaut | amalloy: caveat: the sequence is expensive to compute and you want to have it automemoized |
| 17:52 | raek | Leonidas: what does (binding [force-color true] (red "foo")) return? |
| 17:52 | amalloy | that's not lazy either |
| 17:52 | raek | I don't see any reason for why you code shouldn't work... |
| 17:52 | amalloy | because lazy-generators is itself holding the head of all the sequences |
| 17:53 | raek | Leonidas: so if force-color is true, then fill-color always returns ""? |
| 17:55 | sritchie | amalloy: okay, one more try. https://gist.github.com/806902 |
| 17:56 | sritchie | amalloy: I've got a large ByteBuffer, containing 24 (* 360 720) sized groups of floats. Every other group corresponds to a month, so i wrote extract-month, which returns another ByteBuffer, sized (* 360 720) |
| 17:56 | Leonidas | raek, ohpauleez: thank you both for your help. The problem was caused because of my own stupidity, missing a (not ...). |
| 17:57 | sritchie | so the idea is that this returns, back to hadoop, lazy sequences of floats |
| 17:57 | amalloy | sritchie: looks good to me |
| 17:57 | sritchie | amalloy: great, thanks for taking a look |
| 17:57 | amalloy | i'm not sure you want to hint it as HeapByteBuffer, though. probably just ByteBuffer? |
| 17:57 | arohner | where did c.c.java-utils/wall-hack-method go, in contrib 1.3? |
| 17:57 | raek | Leonidas: ok. glad you found the problem... :-) |
| 17:57 | Leonidas | but while at it, I might also try to learn something. What is with-ns for? I cannot access the enclosing namespace from it, so it seems quite limiting. |
| 17:59 | arohner | aha, c.c.reflect/call-method |
| 17:59 | raek | I think it's for evaling something in another namespace. I've never needed to use it |
| 18:00 | amalloy | sritchie: and you might actually want to use Channels or Streams, java's lazy constructs, instead of Buffers |
| 18:00 | amalloy | but i guess if you're returning a lazy seq of bytebuffers that's probably equivalent |
| 18:01 | sritchie | amalloy: I'm reading a binary file of floats written in little endian order -- I was just using bytebuffer as it was easy to set the byte order, so channels and streams might be better |
| 18:02 | raek | Leonidas: for future compability, you might as well add the :dynamic metadata: (def ^{:dynamic true} *force-color* false) |
| 18:02 | raek | in 1.3, only vars marked as dynamic will be reboundable |
| 18:02 | amalloy | sritchie: well, channels basically create buffers, or fill up existing buffers |
| 18:03 | mabes | If I have the string "inc" how would I get a hold of the var for that function? |
| 18:03 | amalloy | so it would reduce the amount of alloc/dealloc that needs to be done, but probably won't affect the amount of actual memory you use up |
| 18:03 | mabes | ,(symbol "inc") |
| 18:03 | clojurebot | inc |
| 18:03 | amalloy | ,(-> inc symbol resolve) |
| 18:03 | clojurebot | java.lang.ClassCastException: clojure.core$inc cannot be cast to java.lang.String |
| 18:03 | mabes | ah |
| 18:03 | sritchie | amalloy: sounds like a good way to tighten up this damned code |
| 18:03 | mabes | thanks amalloy |
| 18:03 | amalloy | ,(-> "inc" symbol resolve) |
| 18:03 | clojurebot | #'clojure.core/inc |
| 18:04 | sritchie | amalloy: once I get this working, I'll try out streams, I'm sure I'll shed a few lines |
| 18:04 | sritchie | amalloy: thanks for the help |
| 18:04 | amalloy | sritchie: welcome |
| 18:09 | Leonidas | raek: ok, will do. While renaming all my rebindable stuff to have *stars*. |
| 18:19 | brehaut | has anyone got any suggestions for a deployment management tool for small scale clojure powered websites hosted on a simple linux vps? |
| 18:20 | brehaut | (ie, something better than ducktape-and-string) |
| 18:22 | danlarkin | chef |
| 18:24 | zoldar | I know, that it's not clojure specific, but I have problem debugging code working in separate thread - code is ran by scheduled executor and I can see that at some moment it stops - probably due to some exception. Is there a way to get to the stacktrace when such problem occurs? |
| 18:26 | brehaut | danlarkin: cheers |
| 18:28 | danlarkin | chef definitely does have a learning curve, but I think once you "get" it then anything else seems like nonsense |
| 18:28 | technomancy | chef is probably overkill for a couple of servers |
| 18:28 | danlarkin | I disagree |
| 18:29 | brehaut | technomancy: i have one server and i doubt i'll outgrow it |
| 18:29 | technomancy | well if you are going to grow to 5+ then by all means take the time to learn it early, but if you'll never outgrow one it's a hard sell |
| 18:29 | technomancy | it also depends on how much you need to install that's not in apt |
| 18:30 | danlarkin | infrastructure as code |
| 18:30 | technomancy | danlarkin: you can write a hell of a lot of perfectly serviceable bash scripts in the time it takes to learn chef. |
| 18:30 | technomancy | whatever you use absolutely needs to be checked in of course |
| 18:31 | technomancy | I just can't see the setup of a single server being more than a couple pages of script |
| 18:31 | danlarkin | sure, but once you know chef, you know chef. writing your own almost-chef replacement is a wasted learning opportunity |
| 18:32 | danlarkin | which is not to say that writing things from scratch is never good, because it certainly is |
| 18:32 | danlarkin | but chef's story is pretty good |
| 18:34 | brehaut | im leaning towards the couple of pages of scripts i think |
| 18:34 | brehaut | ive got 1 uberjar to run and a directory of media for nginx |
| 18:34 | danlarkin | I'm going to take some artistic liberty and make this comparison, homegrown deploy script : chef :: homegrown vcs : git |
| 18:35 | danlarkin | why not just use a well-thought-out tool |
| 18:36 | brehaut | because i have a limited amount of spare time and i'd rather spend it learning other things? |
| 18:36 | technomancy | that is a pretty apt comparison because they both have huge learning curves and they both have small-scale situations where they're not appropriate |
| 18:36 | technomancy | I wouldn't tell my cousin to use git for his term papers, etc. |
| 18:38 | danlarkin | brehaut: I see why you would make that trade off, though I do not think it is correct |
| 18:39 | brehaut | there is no correct answer with a tradeoff; it wouldnt be a tradeoff otherwise |
| 18:40 | danlarkin | yes that's true |
| 18:40 | danlarkin | I'll rephrase then and just say I wouldn't make the same decision |
| 18:40 | brehaut | fair nuff |
| 18:41 | ieure | How do I figure out what index an elt exists at in a vector? |
| 18:44 | technomancy | ,(keep-indexed #(if (= :x %2) %1) [:w :x :y :z]) |
| 18:44 | clojurebot | (1) |
| 18:44 | technomancy | probably something better in contrib? |
| 18:46 | ieure | Hm… Maybe there’s a better approach to this. |
| 18:46 | technomancy | ieure: clojure.contrib.seq/positions, which is essentially what I have above packaged up nicer |
| 18:47 | technomancy | nicer but slightly slower |
| 18:47 | ieure | Given a strong "foo", can I generate a :foo symbol from that somehow? |
| 18:47 | brehaut | ,(keyword "foo") |
| 18:47 | clojurebot | :foo |
| 18:47 | hiredman | :foo is a keyword, not a symbol |
| 18:47 | ieure | brehaut, Perfect, thank you. |
| 18:48 | ieure | hiredman, Yeah, I don’t quite have the Clojure lingo down. |
| 18:50 | mefesto | is there a way to run clojure scripts using leiningen? something like: lein scripts/clean-db.clj ? |
| 18:50 | technomancy | mefesto: leiningen is for projects, so it only runs namespaces that are part of your project (using the run task) |
| 18:51 | ieure | technomancy, For whatever it’s worth, Python’s setuptools lets you define arbitrary entrypoints and creates wrapper scripts to invoke those. |
| 18:51 | ieure | I’ve found it useful. |
| 18:51 | brehaut | ieure: lets not use pythons package management as something to emulate |
| 18:51 | technomancy | ieure: yeah, I think that makes sense in Ruby too, but the JVM's limitations on the classpath call for different customs, I think. |
| 18:51 | ieure | brehaut, Tall words. |
| 18:52 | mefesto | technomancy: i see. these scripts are useful to the project while developing but aren't part of the end product... so do these go in test/ ? |
| 18:52 | technomancy | mefesto: sure. |
| 18:52 | mefesto | I'm think along the lines of: lein run -m test.namespace |
| 18:52 | technomancy | really simple stuff can just be new tasks in project.clj too |
| 18:54 | brehaut | ieure: why? i think most python programmers are willing to concede that package management is a weakpoint for the platform |
| 18:55 | technomancy | mefesto: if it's something that would be useful to multiple projects it should be a leiningen plugin though |
| 18:55 | mefesto | looks like there is one called lein-run |
| 18:56 | technomancy | I mean like a lein-db plugin |
| 18:56 | ieure | brehaut, Package management universally sucks, in my experience. But god knows the Java community has some seriously fucked up build/pakaging shit. |
| 18:56 | technomancy | surely your project is not the only one that would benefit from a task for cleaning the db =) |
| 18:57 | mefesto | technomancy: :) |
| 18:57 | technomancy | ieure: http://twitter.com/#!/derarthur/status/30434562785939456 =) |
| 18:58 | ieure | technomancy, Yeah. Leiningen is literally the only reason I try to hack Clojure. |
| 18:58 | technomancy | heh; nice |
| 19:02 | brehaut | technomancy: lein (sensibly) tells you off for trying to make a release that depends on a snapshot. is there a way to disable that? (eg because you depend on a project that only has snapshots on clojars) |
| 19:03 | technomancy | brehaut: depending on a numbered snapshot should do it |
| 19:03 | technomancy | foo/bar "1.0.0-20110128" instead of "1.0.0-SNAPSHOT" |
| 19:03 | technomancy | but also don't forget to get on their case about not doing proper releases! |
| 19:03 | brehaut | ah right. that makes sense |
| 19:03 | brehaut | :) |
| 19:04 | technomancy | *cough*enlive*cough* |
| 19:04 | brehaut | moustache too? |
| 19:07 | technomancy | let's all just stare at cgrand intently until we see stable releases |
| 19:07 | brehaut | excellent |
| 19:07 | brehaut | i'll just get my own crap in order first |
| 19:11 | brehaut | technomancy: if im browsing clojars, would i expect to see the date stamped snapshots there (eg in http://clojars.org/repo/clj-time/clj-time/), or would i need to work out the datestamp from the metadata? |
| 19:11 | technomancy | brehaut: they're in here http://clojars.org/repo/clj-time/clj-time/0.1.0-SNAPSHOT/ or you can look at the filename in lib |
| 19:12 | technomancy | ugh; wtf. all snapshots an no releases? |
| 19:12 | technomancy | bradfooooooooooord! |
| 19:12 | brehaut | yeah |
| 19:12 | brehaut | me thinks there needs to be some yelling and shouting to get this ship in order |
| 19:13 | hiredman | mutiny then |
| 19:13 | technomancy | this is spartaaaaaaaa |
| 19:15 | technomancy | dysinger is in SF right now, we should get him to do it. |
| 20:21 | jkdufair | which is more idiomatic? (defrecord inventory-log [foo bar]) or (defrecord InventoryLog [foo bar])? |
| 20:21 | brehaut | later; it creates a class |
| 20:22 | pdk | java conventions for class names capitalize each word |
| 20:22 | pdk | records are effectively creating classes |
| 20:23 | jkdufair | ok thx. wasn't sure in which Rome I was with defrecord |
| 20:25 | amalloy | jkdufair: though it is also idiomatic to (defn make-inventory-log [whatever args] (InventoryLog. some args)) |
| 20:32 | jkdufair | thx! |
| 20:46 | jkdufair | i'm a bit confused about namespaces. if have data.clj with (ns foo.data) at the top and i have core.clj with (ns foo.core (:use foo.data)) at the top. i can't seem to refer to foo.data.SomeRecord in core.clj |
| 20:47 | jkdufair | i can't refer to it as SomeRecord. but I *can* refer to it if i qualify it |
| 20:47 | brehaut | jkdufair thats correct |
| 20:47 | brehaut | because its a class, you need to import it |
| 20:47 | brehaut | (:import 'foo.data.SomeRecord) |
| 20:47 | jkdufair | ah! thank you |
| 20:47 | brehaut | approximately |
| 20:48 | brehaut | jkdufair: its common for people to write a constructor function (eg some-record) for consumers |
| 20:49 | jkdufair | ah ok. so you typically don't refer directly to the class defined in a defrecord? |
| 20:49 | jkdufair | if i do that, do i still need to import it? |
| 20:50 | brehaut | nope |
| 20:50 | jkdufair | super. thx so much |
| 20:51 | amalloy | brehaut: you don't need to quote imports |
| 20:51 | amalloy | (in or outside of the ns macro) |
| 20:51 | brehaut | oh. huh. |
| 20:51 | mattmitchell | if anyone knows the enlive html library -- is there any way to have classic template tags embedded in the html template? |
| 20:52 | brehaut | mattmitchell: you mean jamming clojure code into your markup? |
| 20:52 | mattmitchell | brehaut: well, i not necessarily. I'd be happy with simple placeholders like @title etc.. |
| 20:53 | brehaut | mattmitchell: place holders is done with elements |
| 20:53 | mattmitchell | trying to find a way to allow a cms user embed pre defined tags |
| 20:53 | brehaut | say you have a blog snippet, you might have <section class="blog"><h2>title</h2></section> |
| 20:55 | brehaut | you could then have a defsnippet with [:.blog :h2] (content title) |
| 20:56 | brehaut | and [:.blog :h2] (after content) |
| 20:56 | brehaut | (flying by memory there with after) |
| 20:56 | brehaut | (you might be better off with [:.blog] (append content) |
| 20:57 | brehaut | mattmitchell: the result is that instead of having magic text in your structured markup, you are using the classnames and whatever to achieve similar results. |
| 20:57 | mattmitchell | brehaut: yeah totally, that makes a lot of sense. your example looks nice. i think i'll just have to spend the night reading the enlive docs! |
| 20:58 | brehaut | mattmitchell: have you followed dnolen's tutorial? |
| 20:58 | mattmitchell | brehaut: not completely! maybe i'll finish that up first. |
| 20:59 | brehaut | its worth the effort IMO |
| 21:31 | mattmitchell | what is the main diff between an array map and a hash set? |
| 21:31 | brehaut | appart from one being a map and the other a set? |
| 21:33 | brehaut | ,[(hash-set :a 1 :b 2) (array-map :a 1 :b 2)] |
| 21:33 | clojurebot | [#{1 2 :a :b} {:a 1, :b 2}] |
| 21:34 | mattmitchell | brehaut: thanks. interesting. I think i'm confused because a hash in languages i've worked with are maps, so mixing hash and set together caused a little confusion. |
| 21:34 | brehaut | if that doesnt answer the question: a map is a mapping from keys to values, where a set is a group of things. the keys of a map form a set for instance |
| 21:35 | brehaut | the prefix tells you the implementation choice |
| 21:35 | brehaut | you dont need to care most of the time |
| 21:35 | brehaut | clojure also has ##(hash-map 1 2 3 4) |
| 21:35 | sexpbot | ⟹ {1 2, 3 4} |
| 21:35 | brehaut | both array-maps and hash-maps are persistentmaps |
| 21:36 | brehaut | and the system choses the implement based on the number of items and will change implementation silently as dictated by usage |
| 21:37 | mattmitchell | brehaut: that's really nice. good to know! |
| 21:46 | ieure | Aaaaaargh. Is there some non-horrible way to line-seq to read from *in* or System/in ? |
| 21:47 | ieure | This should be simple, but Java’s type system is fucking me in the ear. |
| 21:47 | ieure | Cannot create a BufferedReader from System/in. |
| 21:47 | ieure | Calling (reader System/in) returns an empty seq even when there’s stuff sent to sedin. |
| 21:47 | amalloy | &(class *in*) |
| 21:47 | sexpbot | ⟹ clojure.lang.LineNumberingPushbackReader |
| 21:48 | ieure | Er, (line-seq (reader System/in)) |
| 21:48 | amalloy | &(supers (class *in*)) |
| 21:48 | sexpbot | ⟹ #{java.lang.Readable java.lang.Object java.io.FilterReader java.io.PushbackReader java.io.Closeable java.io.Reader} |
| 21:48 | amalloy | ieure: it's a reader, so wrapping it in bufferedreader should work. are you trying to do this from slime? |
| 21:49 | ieure | amalloy, No, I can’t send anything to stdin there. It’s in my -main method in a Leiningen project. |
| 21:49 | brehaut | amalloy: line-seq *in* throws a classcastexception |
| 21:50 | brehaut | (use '[clojure.java.io :only [reader]]) (line-seq (io/reader *in*)) |
| 21:50 | ieure | (line-seq (reader *in*)) just gives me an empty list. |
| 21:50 | ieure | I wonder if this is a leiningen thing. |
| 21:50 | ieure | I’m using `lein run' and piping stuff to it. |
| 21:51 | ieure | Ugh, fuck. It is. |
| 21:51 | ieure | Works fine with `java -jar'. |
| 21:51 | devn | my coworker described namespaces as "state" -- what say you? |
| 21:52 | ieure | devn, Seems incorrect on its face. |
| 21:52 | pdk | that's |
| 21:52 | pdk | um |
| 21:52 | pdk | a unique way to interpret them |
| 21:53 | devn | i know it's ridiculous, but he makes an argument which i've never heard, which is that if you define the ns at the top of a file, it is ieffectively setting the context in which functions will be defined |
| 21:53 | devn | and therefore qualifies as state |
| 21:53 | devn | i dont agree with it, but im curious what other people have to say about it |
| 21:53 | brehaut | devn in the exact same way that any lexical scope is defined though surely? |
| 21:54 | brehaut | eg (let [foo 1] (defn add-foo [x] (+ x foo)) |
| 21:54 | brehaut | you wouldnt call foo state, but that seems to me to be no different than defining the namespace |
| 21:57 | devn | brehaut: he's never used clojure, so my assumption is that he saw that (ns ...) didn't wrap the (defn) that came later in the file and so on |
| 21:57 | devn | so he saw it as being a stateful thing |
| 21:57 | brehaut | would he agree that (def foo 1) (defn add-foo [x] (+ x foo)) is not state? |
| 21:58 | devn | i can ask him when he's done playing guitar hero |
| 21:58 | brehaut | state is context but not all context is state right? |
| 21:59 | phenom_ | what's the easiest way to run some defntest's I've got in a clj file ? |
| 21:59 | brehaut | phenom_: is it a lein (or presumably cake) project? |
| 22:01 | devn | brehaut: he has conceeded |
| 22:01 | brehaut | woo :) |
| 22:01 | devn | conceded* |
| 22:01 | phenom_ | brehaut: why do you presume cake? :P |
| 22:02 | devn | brehaut: it took me by surprise at first because yes, as you say, context is not state -- it depends on how you wish to define statefulness |
| 22:02 | brehaut | phenom_: im presuming cake behaves the same as lein in this instance |
| 22:02 | devn | you might say that a (let ...) is a state, but that would incorrect for most intents and purposes |
| 22:02 | ieure | Can someone point me to a clear example of how -> and ->> work? The documentation is completely inscrutable. I have no idea what they do or why I’d want to use them. |
| 22:03 | brehaut | ieure: they rewrite your forms. (-> a (b) (c)) becomes (c (b (a))) |
| 22:03 | brehaut | thats a terrible example |
| 22:03 | seancorfield | they are convenient when you want to apply a sequence of operations to the same thing, one after the other |
| 22:03 | amalloy | &(macroexpand-all '(->> (range) (filter even?) (take 100) (reduce +))) |
| 22:03 | sexpbot | java.lang.Exception: Unable to resolve symbol: macroexpand-all in this context |
| 22:03 | amalloy | &(use 'clojure.walk) |
| 22:03 | sexpbot | ⟹ nil |
| 22:03 | amalloy | &(macroexpand-all '(->> (range) (filter even?) (take 100) (reduce +))) |
| 22:03 | sexpbot | ⟹ (reduce + (take 100 (filter even? (range)))) |
| 22:03 | amalloy | ieure: ^ |
| 22:04 | brehaut | devn: i think if you are unfamiliar with pervasive immutability its reasonable to make that assumption i think |
| 22:04 | seancorfield | the difference is that -> puts the 'thing' as the first argument in each call and ->> puts the 'thing' as the last argument in each call |
| 22:05 | seancorfield | &(macroexpand-all '(-> x f g h)) |
| 22:05 | sexpbot | ⟹ (h (g (f x))) |
| 22:06 | ieure | Is macroexpand-all in -contrib somewhere? |
| 22:06 | seancorfield | &(macroexpand-all '(-> x (f a b) (g c d) (h e f))) |
| 22:06 | sexpbot | ⟹ (h (g (f x a b) c d) e f) |
| 22:06 | amalloy | ieure: you just saw me (use 'clojure.walk), right? |
| 22:06 | seancorfield | &(macroexpand-all '(->> x (f a b) (g c d) (h e f))) |
| 22:06 | sexpbot | ⟹ (h e f (g c d (f a b x))) |
| 22:07 | brehaut | devn my solution to that problem was to stop having coworkers |
| 22:07 | ieure | amalloy, I didn’t realize that the bot had persistent state like that. |
| 22:07 | devn | i think one unfortunate thing we need to really approach as a community is how we mention immutability in passing |
| 22:07 | devn | people hearing immutability and have no idea how to approach a world that looks like that |
| 22:07 | ieure | devn, It is incredibly daunting at first. |
| 22:08 | ieure | Then you play with it and realize that you don’t need nearly as much as you thought. |
| 22:08 | devn | ieure: it's taken me 2 years from 0 to lisp to "get" what was going on here |
| 22:08 | devn | i dont blame anyone |
| 22:08 | seancorfield | devn: true, when folks are used to writing for (x = 1; x < 10; ++x) doSomething(x); |
| 22:08 | ieure | devn, I make zero claims that I know what is going on here. :) |
| 22:08 | devn | it's just something that is so undervalued and misunderstood |
| 22:08 | brehaut | seancorfield: at my last job i wrote a nice little F# program. i had to rewrite it in VBS. |
| 22:08 | devn | ieure: i think that's funny |
| 22:08 | seancorfield | brehaut: my sympathies |
| 22:08 | devn | ieure: it's scary, but we're smart |
| 22:09 | brehaut | seancorfield: its not all bad. i got to write it in F# first ;) |
| 22:09 | devn | ieure: btw, thank you for your php-repl |
| 22:09 | devn | :X i hate to admit i used that at one time |
| 22:09 | ieure | devn, Ha, you’re welcome. |
| 22:09 | devn | but thank you :) |
| 22:09 | amalloy | ieure: oh, is that yours? i was using it just today |
| 22:09 | mattmitchell | php-repl? |
| 22:09 | devn | it's a repl, but you know, for a shitty language |
| 22:09 | ieure | mattmitchell, An attempt to make a REPL for PHP that wasn’t horrible. |
| 22:10 | mattmitchell | haha :) |
| 22:10 | mattmitchell | why not? |
| 22:10 | devn | either way, ieure is awesome |
| 22:10 | devn | everyone should remind him of how awesome he is more often |
| 22:10 | devn | IMO |
| 22:10 | ieure | Jesus, I had no idea I had a fan club. |
| 22:10 | devn | ieure: it's not a fan club *yet* :) |
| 22:11 | devn | im just happy to see you around these parts -- i hope you'll stick around |
| 22:11 | ieure | Oh, I’ve been meaning to get serious about Clojure for a long time. Still haven’t had much reason to do that, though. |
| 22:11 | seancorfield | brehaut: i often prototype something in clojure to make sure i understand the problem and have then been coding it in "language X" for production use |
| 22:11 | ieure | But I’ve been screwing around with it the last couple weeks when I felt like it. |
| 22:11 | seancorfield | but that will change... clojure is coming to production soon :) |
| 22:11 | mattmitchell | ieure is awesome. brehaut is too. i'm amazed at how i can ask dumb questions and get a serious answer here. very helpful. |
| 22:12 | devn | the thing that's missing big time in clojure ATM is a CRUD-like setup for web development |
| 22:12 | seancorfield | ieure: btw, did amalloy and i help answer the -> / ->> question? |
| 22:12 | brehaut | mattmitchell: i wouldnt say im awesome. ive just made the dumb mistakes before you did ;) |
| 22:12 | mattmitchell | brehaut: :) |
| 22:12 | devn | ieure: can i make a suggestion on -> and ->>? |
| 22:12 | ieure | devn, of course. |
| 22:12 | devn | ieure: https://github.com/tcrayford/clojure-refactoring |
| 22:12 | ieure | seancorfield, I do not fully understand it yet. But I don’t know if anyone can help me with that just yet. |
| 22:12 | seancorfield | devn: well, i plan to use clojure for the Model portion of an MVC web app with the VC portion written in CFML :) |
| 22:13 | ieure | I learn by doing. |
| 22:13 | devn | get that. play with thread-first and thread-last |
| 22:13 | devn | you can write some code and automatically refactor to -> and ->> |
| 22:13 | devn | it helps you see how it works and gives you insight into when to use it |
| 22:13 | devn | also ieure, another link: |
| 22:14 | brehaut | seancorfield: wait. cold fusion?! |
| 22:14 | seancorfield | yup, although it's been one word not two for a decade or so |
| 22:14 | devn | ieure: https://github.com/raganwald/homoiconic/blob/master/2008-10-30/thrush.markdown |
| 22:14 | seancorfield | i use the railo open source cfml engine (it's a jboss project) |
| 22:15 | ieure | Okay, I think I see what -> is doing now. |
| 22:15 | devn | ieure: -> and ->> are simply ways of reversing the order of computation |
| 22:15 | devn | so it reads left to right |
| 22:15 | brehaut | devn: ieure http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/ |
| 22:16 | devn | brehaut: great link |
| 22:16 | ieure | Yeah. So if I understand, I can use that to create with partial to create a nested function to map across a seq. |
| 22:16 | devn | ieure: id need a repl to test that because im not a magician or a god or anything when it comes to programming |
| 22:16 | brehaut | ieure: with thrush yeah; its a point-free operator |
| 22:17 | devn | but the basic idea if you get to switch up the order and read left to right |
| 22:17 | devn | i have a much more abstract idea of how it works i guess |
| 22:17 | devn | *shrug* |
| 22:18 | devn | btw, On explaining clojure to coworkers in an OOP mindset: Practical Clojure does an excellent job of covering the how and why |
| 22:19 | ieure | devn, I also found the introduction to Programming Clojure to be a good introduction. |
| 22:19 | devn | modularity, polymorphism, encapsulation, reusability |
| 22:20 | devn | "objects everywhere" really screws up the implementation of these ideas on their own |
| 22:20 | brehaut | devn Stuart Halloway's Clojure Conj presentation might also be good |
| 22:20 | devn | brehaut: i was there :) |
| 22:20 | devn | brehaut: is that online yet? |
| 22:20 | brehaut | lucky bastard :) |
| 22:20 | brehaut | it is |
| 22:20 | devn | link please! |
| 22:21 | devn | stuart -> pure awesome |
| 22:21 | devn | such a gracious host with a wonderful family and what i could only characterize as a heartfelt commitment to the community writ-large |
| 22:22 | brehaut | … taking longer to find this than i thought |
| 22:23 | seancorfield | http://clojure.blip.tv/?sort=custom;date=;view=archive;user=clojure;nsfw=dc;s=posts;page=1 is it here? |
| 22:23 | brehaut | not that i could see |
| 22:24 | devn | yeah i dont see it |
| 22:24 | devn | bummer -- i loved that talk |
| 22:24 | devn | perhaps he's witholding it given the beer that was involved |
| 22:25 | devn | probably need to edit out the label or something :D |
| 22:25 | brehaut | i know its on the web somewhere |
| 22:25 | brehaut | try http://www.infoq.com/presentations/Clojure-Java-Interop ? |
| 22:25 | seancorfield | stuart's talk... simplicity ain't easy? |
| 22:26 | devn | that's the topic |
| 22:26 | brehaut | sorry, ive got extrodinarily slow internet |
| 22:26 | devn | but i dont know of any video on it yet |
| 22:26 | seancorfield | i don't see it on blip.tv so it may not have been released yet |
| 22:27 | seancorfield | but these two talks might be useful for OO folks: http://clojure.blip.tv/file/982823/ and http://clojure.blip.tv/file/982957/ - clojure for java programmers parts 1 & 2 |
| 22:27 | devn | ive seen those |
| 22:27 | devn | id really like to see stuart's talk again, though |
| 22:27 | seancorfield | rich's preso to the NYC java study group |
| 22:27 | brehaut | https://github.com/downloads/stuarthalloway/clojure-presentations/Clojure-Simplicity.pdf thats the slides anyway |
| 22:27 | seancorfield | i had to miss the first conj but i am _not_ missing the second one!! |
| 22:28 | devn | :) |
| 22:28 | Scriptor | it's in NC, right? |
| 22:28 | devn | i refused to miss the first one |
| 22:28 | seancorfield | i may even bring one of my coworkers since he'll have had to learn clojure by then :) |
| 22:28 | brehaut | id like to not miss any of them, but unfortunately its the wrong hemisphere entirely |
| 22:28 | seancorfield | i was already committed to being in albuquerque and los angeles when the dates for the conj were announced :( |
| 22:29 | seancorfield | this year i'm keeping september and october free until the conj dates are finalized! |
| 22:29 | seancorfield | well, strangeloop is mid-september and javaone is early october... but other than that, i'm free... |
| 22:29 | Scriptor | wait, does anyone know where the 2nd conj will take place? |
| 22:29 | seancorfield | i expect it'll be the same place...? |
| 22:30 | Scriptor | so Durham again? |
| 22:30 | Scriptor | argh, I'll stick to the meetups here :) |
| 22:30 | seancorfield | according to alan dipert "Conj 2011 will most likely be in either Raleigh or Durham, North Carolina, and probably will happen around the same time of year as the |
| 22:30 | seancorfield | last Conj." |
| 22:31 | seancorfield | that's from his post to the clojure list on 12/27/10 |
| 22:31 | seancorfield | at least scala days is close to home for me :) |
| 22:32 | seancorfield | but i'm doing conferences in dallas, edinburgh (UK) and minneapolis in february, march, may so this year has a lot of travel in store |
| 22:32 | seancorfield | maybe one in kansas city, mo too in july |
| 22:33 | seancorfield | scala days in june (locally), strange loop in mid-september in st louis, javaone locally... and clojure conj :D |
| 22:55 | ieure | If someone feels like reviewing this code I wrote, I would greatly appreciate being told all the things I did wrong: https://gist.github.com/05f59e7b01f5b0d260f1 |
| 23:01 | brehaut | nothing obvious jumps out at me |
| 23:02 | amalloy | ieure: (apply hash-map (interleave foo bar)) is (zipmap foo bar) |
| 23:03 | amalloy | (partial get some-map) is the same as some-map |
| 23:04 | amalloy | #(first (parse-csv %)) is equivalent to (comp first parse-csv), which imo is more readable but tastes vary |
| 23:06 | amalloy | (. util format ...) is weird to read because it violates the usual "function first" style - i'd write (.format util ...) unless there's some reason you can't |
| 23:07 | ieure | amalloy, I have no major reason for doing most stuff there, except that it seems to mostly work. |
| 23:07 | ieure | I really appreciate the input. |
| 23:07 | amalloy | welcome |
| 23:10 | amalloy | oh, and (conj m {:k v}) is (assoc m :k v) |
| 23:10 | brehaut | amalloy wins |
| 23:11 | brehaut | amalloy: i should get you to pick apart my code some time ;P |
| 23:12 | amalloy | brehaut: do it. i generally enjoy review/editing |
| 23:13 | brehaut | amalloy: how about https://github.com/brehaut/clj-pingback/blob/master/src/clj_pingback/client.clj |
| 23:14 | ieure | amalloy, Excellent, this is significantly clearer. Thank you very much. |
| 23:14 | ieure | Any idea why if I change the (println …) to (print …), I get no output whatsoever? |
| 23:14 | amalloy | ieure: you need to flush the output stream |
| 23:15 | amalloy | \n automatically flushes by default |
| 23:15 | ieure | amalloy, Awesome, thank you. I’m used to Python, where it gets flushed on close/exit. |
| 23:16 | amalloy | ieure: i'd sorta expect it to get flushed on close too |
| 23:16 | amalloy | but if it doesn't, that's why :P |
| 23:16 | amalloy | brehaut: (when-let [[_ url] (...)] url) sounds a lot like (second (...)) |
| 23:17 | brehaut | huh so it is |
| 23:17 | amalloy | (fn [t] [t (foo t)]) == (juxt identity foo) |
| 23:19 | brehaut | true |
| 23:19 | brehaut | cheers :) |
| 23:20 | brehaut | and more point free :D |
| 23:20 | amalloy | hah, and you're importing your necessary-evil project as xml-rpc. i like it |
| 23:20 | brehaut | :) |
| 23:21 | brehaut | its the best name ive ever come up with for a project; pitty its wasted on such a lame protocol |
| 23:21 | amalloy | brehaut: what about using clojure.contrib.-?>> to replace the when-let/if-let construct? |
| 23:22 | brehaut | sorry, which function? |
| 23:22 | amalloy | that is, c.c.core/-?>> |
| 23:22 | brehaut | sorry, in the pingback code |
| 23:22 | amalloy | in discover-pingback-endpoint |
| 23:22 | brehaut | oh right |
| 23:23 | brehaut | i think i could replace it with or actually |
| 23:24 | amalloy | brehaut: i don't think so, cause you reuse url |
| 23:24 | brehaut | im not though, i accidentally masked it in the when-let |
| 23:25 | brehaut | which was replaced with (second ...) anyway |
| 23:25 | amalloy | ah |
| 23:27 | brehaut | so that if-let is now (or (get-in response [:headers "x-pingback"]) |
| 23:27 | brehaut | (second (re-find link-pattern (:body response)))) |
| 23:29 | brehaut | amalloy: i just pushed the changed code |