2015-03-06
| 04:09 | stardiviner | test |
| 04:11 | godd2 | 1 line run; 1 failure; 0 successes |
| 04:34 | TEttinger | wow, sleepy in here today. I see two messages in my scrollback |
| 04:34 | chiffr | TEttinger: Friday daze ;) |
| 04:57 | zot | i have a midje test that triggers a parked thread, blocking my tests. is there any way short of restarting repl to manage/handle this case? |
| 05:08 | noidi | you could do the operation in a future and deref it with a timeout |
| 05:14 | schmir | what's the best clojure book for clojure newbies? |
| 05:16 | mnngfltg | schmir, I like this one: http://shop.oreilly.com/product/0636920013754.do |
| 05:18 | schmir | mnngfltg: LOL 'No, Parentheses Actually Won’t Make You Go Blind' |
| 05:23 | schmir | mnngfltg: Thanks. I'll buy that for my new coworker... |
| 05:31 | mnngfltg | schmir, you're welcome |
| 05:31 | zot | noidi: that's what i ended up doing, copying a macro to handle it. it's not perfect, but for testing, won't be too evil as long as the contents don't spawn tooooo many orphanable threads :) |
| 06:16 | noncom|2 | i am working in a repl, but i have to change java code frequently. is there a way to reload a java class? |
| 06:52 | noncom|2 | wow, it is so friday here :) |
| 06:57 | jballanc | noncom|2: more likely it's just too early in negative-UTC-offset-world |
| 06:57 | noncom|2 | right, could be! |
| 06:57 | noncom|2 | it is about 7 am in new york i guess |
| 06:58 | jballanc | yup |
| 07:02 | ordnungswidrig | how can I wait for a list of channels to unblock in core.async? (map <!! list-of-channels) ? |
| 07:06 | hyPiRion | Pretty sure you want something that's not lazy for that |
| 07:06 | hyPiRion | like, (dolist [ch list-of-channels] (<!! ch)) |
| 07:08 | ordnungswidrig | hypririon: ok, now assume I have an error channel where which I will read alternatively. i.e. if there's a val in the error channel then use that, else the list returned. |
| 07:09 | ordnungswidrig | I tried something like (alts!! [err-chann (async/map <!! list-of-chans)]) |
| 07:18 | agarman | having an issue with cider & nREPL --> https://www.refheap.com/98150 ... any chance someone has an idea of what I borked? |
| 07:19 | the_frey | I find that when I hit the cider and write clojure it all goes tits up too |
| 07:20 | agarman | this is recent issue for me. I was doing Java stuff for a couple months and now back to Clojure and made the mistake of updating emacs-live and my lein profiles.clj |
| 07:34 | wizzo | hi. is there a way to get just a section of a byte-array. like just from byte 5 to 10 or whatever |
| 07:39 | muhuk | wizzo: you can convert it to a seq, or you can copy those elements to a new array. |
| 07:41 | wizzo | muhuk: it is 12mb i wasn't sure if it was a good idea to make it a seq or not |
| 07:41 | wizzo | i'll probably just not read the whole thing in memory if that's an insane idea |
| 07:44 | Glenjamin | wizzo: possible a combination of (byte-array) and a (for) |
| 07:46 | wizzo | glenjamin: do you have an example of that working? i'm not really getting it from the docs |
| 07:47 | Glenjamin | ,(let [b (byte-array (range 100))] (byte-array (for [i (range 10 20)] (aget b i)))) |
| 07:47 | clojurebot | #<byte[] [B@418700a3> |
| 07:47 | Glenjamin | something along those lines |
| 07:48 | wizzo | thank you! i'll have a play around with it |
| 08:09 | sandbags | anyone know how to shut up the "cljx no longer provides Leiningen hooks; please use :prep-tasks in your project.clj instead" messages every time you run a lein command with cljx installed? Esp. annoying when I do use :prep-tasks |
| 09:14 | profil | Hey guys, I am building a tcp server and I want to use PING/PONG messages just like irc. Right now I use a loop inside a future to send ping messages every Nth second. Would it be better to use core.async's go block instead? The future macro will create a new thread which I think may a bit heavy for this case. Any ideas? |
| 09:16 | sujeet | profil, if you're doing aio, use aio |
| 09:16 | sujeet | you don't need to thread it |
| 09:16 | profil | sujeet: I am using aleph and just mapping over the stream, how would I fit my ping loop inside that? |
| 09:49 | ocharles_ | does anyone know if it's possible to use s/check (prismatic schema) on a record, where the schema was defined with s/defrecord? |
| 09:49 | ocharles_ | Right now, I get "not (instance? type)" which is valid, but I only want to valid the underlying map against the same schema |
| 09:49 | whidden | /msg NickServ identify pegasus |
| 10:16 | matthewwest | I'm aiming to be a part of GSOC this year, and I'm especially interested in maybe adapting clojure/tools.reader to be able to run on a JS runtime such as Node.js. |
| 10:16 | matthewwest | I'm looking to understand why it currently doesn't work, but not how to get started.\ |
| 10:17 | matthewwest | Does anyone know if clojure currently uses clojure/tools.reader to read in sourcecode? |
| 10:17 | Glenjamin | matthewwest: jvm clojure currently doesn't use tools.reader |
| 10:17 | Glenjamin | but clojurescript does |
| 10:18 | Glenjamin | it doesn't currently run on Node.js because there's a bunch of JVM-specific things in the codebase |
| 10:18 | matthewwest | Alright, that's helpful. |
| 10:18 | Glenjamin | there's some WIP on tools.reader here: https://github.com/nasser/tools.reader/tree/nodejs |
| 10:18 | Glenjamin | i dunno how far along it is |
| 10:18 | matthewwest | Is it an eventual language target to use tools.reader for the JVM? |
| 10:19 | Glenjamin | certainly none of the tests are ported |
| 10:19 | Glenjamin | no idea, i suspect not but Bronsa will know more if he's around |
| 10:20 | matthewwest | Alright, I'll just need to poke around and figure out what's going on. |
| 10:21 | matthewwest | Once my academic term ends I'll have a bit more time to devote (at least until the next one starts) |
| 10:22 | Bronsa | Glenjamin: matthewwest no, no plans to make t.reader the default Clojure reader |
| 10:23 | matthewwest | Is that because since it's a hosted language anyway, there's no purpose in bootstrapping? |
| 10:26 | Bronsa | a number of reasons, since clojure is not self-hosted there's no point in using a slower reader just for the sake of having it written in clojure |
| 10:26 | Bronsa | also there would be bootstrapping issues |
| 10:30 | matthewwest | Thanks |
| 10:40 | Ven | hi -- people using the cursive plugin here? It's completly failing to resolve defn, ns, defmacro and the others :). I have a sdk configured |
| 10:43 | kras | Exception in thread "main" java.lang.UnsupportedClassVersionError: clj_antlr/ParseError : Unsupported major.minor version 51.0 |
| 10:43 | kras | why do I get this error when I "lein run"? |
| 10:44 | kras | something to do with the JRE version? |
| 10:55 | profil | sujeet: How do you mean use aio? I can use manifolds periodically, but how do I get it to stop executing when the stream is closed? And how do I create a periodic loop without using either clojure's future or manifold.deferred's future? |
| 11:25 | octe | i'm listening to modification events for files with inotify, and when a file is completly written i want to do something. to ensure it's completly written i want to wait a few seconds after the last modify event for each file and then do something |
| 11:25 | octe | what would be a good way to do that? |
| 11:30 | muhuk | octe: Thread/sleep ? |
| 11:30 | justin_smith | octe: sounds like you want a debounce |
| 11:31 | octe | justin_smith, yeah |
| 11:31 | Glenjamin | https://gist.github.com/loganlinn/4719107#file-debounce-clj-L12 |
| 11:31 | octe | it's pretty easy to do in javascript since it's single threaded |
| 11:31 | octe | cool, thanks |
| 11:31 | Glenjamin | there's an mildly annoying lack of license on that gist |
| 11:32 | justin_smith | debounce should be in clojure.core, or at least in core.async |
| 11:32 | justin_smith | and I think it can be done without two atoms |
| 11:39 | timvisher | is there anything that's more 'battle tested' than loom as far as nice clojure libraries for dealing with graphs |
| 11:55 | justin_smith | octe: Glenjamin: this one is public domain. Since you always want the last bounce's time when debouncing, it doesn't need atoms. Maybe it should have a locking block for the odd case where two bounces were waiting on the same time stamp? https://www.refheap.com/98153 |
| 11:56 | justin_smith | another difference is that each debounce call can provide its own args, only the args for the last one before the timeout are used |
| 11:57 | justin_smith | *each call to the debounced function |
| 11:57 | justin_smith | need coffee |
| 11:58 | octe | why an array? |
| 11:58 | justin_smith | octe: because it is mutable |
| 11:59 | justin_smith | I guess any Box would have worked though |
| 12:00 | justin_smith | *any mutable Box |
| 12:01 | justin_smith | octe: so each attempt puts its timestamp in the box, and only runs the function if after waiting the required time its timestamp is still in the box |
| 12:02 | justin_smith | since the timestamp is intentionally "last writer wins", it is fine to just let the calls race |
| 12:04 | octe | hm, it doesn't seem to work the same |
| 12:05 | octe | i'll try to see how |
| 12:05 | justin_smith | octe: mine runs in the thread that calls it |
| 12:05 | justin_smith | so you can choose to put a call in a future, or to just wait for it to complete / cancel in your own thread |
| 12:06 | justin_smith | (that may not be the only difference) |
| 12:07 | octe | yes, that was one thing |
| 12:08 | vas | justin_smith how do you take your coffee? *carries out tray with spoons and variegated sundries* |
| 12:08 | octe | i think that in the first, while the debounced function is running, further calls to it doesnt run it multiple times |
| 12:08 | octe | if you see |
| 12:08 | justin_smith | vas: black |
| 12:08 | vas | well then *pitches tray out window* |
| 12:09 | justin_smith | octe: nor should mine (unless you mean after the debounce period, mine will run multiple times, but with a debouncing interval enforced) |
| 12:11 | justin_smith | eg. one use of debouncing is to have a debounced message handler or channel, where you want repeated invocation, but constraining the rate with the debounce logic |
| 12:12 | octe | well, i only want one to run for each file so it's better to ignore further invocations while it's actually being processed |
| 12:12 | octe | which is a property the first implementation seems to have |
| 12:13 | justin_smith | yeah, if you want one-shot logic that could be tacked onto my version, but isn't inherent to it |
| 12:13 | octe | how would i do that? :) |
| 12:16 | justin_smith | octe: simplest version I can think of is to close over a delay with the function - (let [status (delay (f status)) final-status (debounce #(deref status))] ...) |
| 12:16 | justin_smith | in that manner, the delay only does the work the first time, it's cached afterward |
| 12:16 | justin_smith | I missed the wait arg for the debounce there of course |
| 12:33 | lvh | Is there something cool in Clojure for wrapping POJOs that are basically just data containers? |
| 12:34 | lvh | e.g. I have this class with ctor GroupConfiguration(String name, int cooldown, int minEntities, int maxEntities, Map<String,String> metadata); I'd be nice if I could autogenerate something that knew how to turn a map with the appropriate keys into one of those things. Preferably automagically with introspection run once at compile time :-) |
| 12:34 | justin_smith | lvh: for accessing them or creating them? for the latter we just use hashmaps |
| 12:34 | lvh | justin_smith: I'm interfacing with an existing Java API, I want to use hashmaps on the clj side but I can't; the Java API really wants this POJO |
| 12:40 | Glenjamin | (doc bean) |
| 12:40 | clojurebot | "([x]); Takes a Java object and returns a read-only implementation of the map abstraction based upon its JavaBean properties." |
| 12:41 | Glenjamin | i dunno about the reverse though |
| 12:48 | justin_smith | lvh: it would be easy enough with deftype, except for the fact that you can only implement methods that are in an interface, so you would need to define a custom protocol or interface for the type that had the standard get/set methods |
| 12:49 | justin_smith | lvh: it's one of the places where clojure's opinionated nature starts to show |
| 12:51 | puredanger | I wrote a macro that can take a map and call the appropriate setters on a Java object here: |
| 12:51 | puredanger | http://stackoverflow.com/questions/27308061/whats-the-idiomatic-way-to-do-this-java-function-in-clojure/27308254#27308254 |
| 12:51 | justin_smith | puredanger: interesting, I think something very much like that is used by a c3p0 wrapper I use |
| 12:52 | Glenjamin | "unbean" would be a fun name for that :) |
| 12:52 | lvh | puredanger: Thanks for the pointer :-) This POJO does have one thing going for it: it's immutable ;-) |
| 12:52 | justin_smith | Glenjamin: texas-style |
| 12:52 | lvh | so I guess some ctor inspection is in my future |
| 12:52 | puredanger | lvh: well that's good :) |
| 12:52 | Glenjamin | https://github.com/arohner/unbean |
| 12:52 | puredanger | the downside of a positional constructor is of course needing to know the positions |
| 12:52 | puredanger | but certainly seems like something you could abstract |
| 12:53 | Glenjamin | i guess bean isn't quite accurate, as this is contructor in, getters out |
| 12:53 | lvh | puredanger: right. But I should be able to do all of that introspection at compile time, right? |
| 12:53 | octe | justin_smith, cool, that works! the delay i mean |
| 12:54 | puredanger | sure, if you use reflection. and assuming there is some standard mapping from param names to map fields |
| 12:54 | puredanger | actually, do you get param names in reflection? |
| 12:54 | puredanger | I know this was an old problem, not sure of current state |
| 12:54 | iamjarvo | is there a way to update an atom asynchronously> |
| 12:54 | lvh | iamjarvo: reset! |
| 12:55 | puredanger | that's not asynchronous |
| 12:55 | lvh | Huh, it's not? |
| 12:55 | justin_smith | (future (swap! a f)) |
| 12:55 | justin_smith | no need to deref the future if you don't care about the return value |
| 12:55 | puredanger | swap! and reset! guarantee that the change is complete when they return |
| 12:55 | lvh | ah |
| 12:56 | puredanger | agent send is asynchronous |
| 12:56 | puredanger | or wrapping in future |
| 12:56 | iamjarvo | lvh thanks |
| 12:56 | puredanger | although the cost of wrapping in future is likely significantly higher than the reset! |
| 12:56 | lvh | iamjarvo: Don't thank me, I gave the wrong answer ;) |
| 12:56 | iamjarvo | ha i was just reading about ti |
| 12:56 | iamjarvo | it* |
| 12:56 | justin_smith | yeah, if you want async update, you may want an agent instead of an atom anyway |
| 12:57 | iamjarvo | thanks all |
| 13:12 | lvh | puredanger: So, this class does have a Builder nested class, which probably makes the macroing a lot simpler |
| 13:15 | bcham | Hey I have a question about hash-maps and their potential key values. It's very straight forward. |
| 13:15 | bcham | http://www.codeshare.io/rg0vn |
| 13:16 | bcham | why is it, in that code that lines 14 and 15 print nil? |
| 13:18 | hiredman | keywords are not numbers |
| 13:19 | hiredman | you map has a number as a key, you are looking up the value for a keyword, there is no value, so nil |
| 13:19 | bcham | You mean that keywords cannot be numbers? Because shouldn't the (str ) wrap make it into a string and thus can be turned into a keyword? |
| 13:20 | justin_smith | bcham: keyword is not the same as key |
| 13:21 | bcham | justin_smith: There's my issue I need (name )? |
| 13:21 | bcham | it seems |
| 13:21 | hiredman | no |
| 13:21 | hiredman | look, your map doesn't have keyword keys |
| 13:21 | hiredman | a map can have keys that are of any type |
| 13:21 | hiredman | keys are not always keywords |
| 13:22 | justin_smith | (get {{"apple" "red"} "fruity"} {"apple" "red"}) |
| 13:22 | justin_smith | ,(get {{"apple" "red"} "fruity"} {"apple" "red"}) |
| 13:22 | bcham | Gotcha, now I understand. My misunderstanding was that "keyword" was doing what "name" actually does. Because the code " (@hash-links (name "112785")) ; nil" |
| 13:22 | bcham | works |
| 13:22 | clojurebot | "fruity" |
| 13:22 | justin_smith | ,(= (name "112785") "112785") |
| 13:22 | clojurebot | true |
| 13:23 | bcham | thank you for humoring my learning. |
| 13:23 | justin_smith | bcham: notice in the above silly example with the apple, I use a hash-map as the key in a hash-map |
| 13:24 | oskarth | Does anyone know of any good alternative to cljs-ajax? |
| 13:24 | bcham | justin_smith: yeah I see that! Thanks |
| 13:29 | sritchie | oskarth: what’s wrong with cljs-ajax? |
| 13:30 | oskarth | sritchie: tired of all these different places params end up, there's a key called :params on client side, but it can end up in either body, params or query-params depending on various things |
| 13:30 | sritchie | oskarth: that’s not cljs-ajax’s fault - |
| 13:30 | sritchie | oskarth: that’s the middleware stack on the clojure side |
| 13:30 | oskarth | aware, but it complicates things |
| 13:30 | sritchie | each middleware that intercepts params merges them into its own key, then merges all of them into :params |
| 13:30 | sritchie | oskarth: my pt is you’ll have that problem if you hit your server w/ curl |
| 13:31 | sritchie | nothing to do with cljs-ajax |
| 13:31 | oskarth | for example, ring-edn and query-params (with format edn) using non-edn format |
| 13:32 | oskarth | just asking for an alternative :) disagree with the diff behaviors for GET/POST etc, don't believe it's necessary |
| 13:40 | lvh | So, I'm doing (.. (Something/whatever) (aMethod (:some-key some-map))) a bunch of times. Is there a neat way to only call those methods when (:some-key some-map) isn't nil? Example: https://gist.github.com/lvh/bd35d7506bc0f127cbb9 |
| 13:41 | lvh | I tried to do it with ->> and when-let but I can't get it to work |
| 13:42 | cfleming | Ven: How did you set up your project? With Lein? |
| 13:42 | Ven | cfleming: yes |
| 13:42 | lvh | Maybe something like (->> (LaunchConfiguration/builder) (when-let [v (:load-balancers lc)] apply #(.loadBalancers))) ? |
| 13:42 | Ven | cfleming: a long time before I set up cursive, though :) |
| 13:43 | cfleming | Ven: Are your files under a source root? (blue folder in the project view)? |
| 13:43 | Ven | cfleming: src/ isn't a blue dir, an in "project settings" there's "excluded" but no way to mark as source |
| 13:44 | cfleming | Ven: Right click the folder and you can mark as source |
| 13:44 | cfleming | Ven: But if you set your project up with lein the problem is that your src folder isn't configured in your project.clj |
| 13:44 | lvh | Except of course (apply #(.someMethod) ..) doesn't really do what you want |
| 13:45 | Ven | cfleming: do you have a doc link on how I should configure it in project.clj? |
| 13:45 | Ven | cfleming: also I see no link to make it a source folder |
| 13:46 | cfleming | Ven: Right click the folder in the project view->Mark directory as->Source folder |
| 13:46 | Ven | cfleming: found project.cj config |
| 13:47 | cfleming | Ven: Source paths are taken from :source-paths, :resource-paths, :java-source-paths |
| 13:47 | cfleming | Ven: Assuming this is Clojure and not CLJS |
| 13:47 | Ven | cfleming: alright, much better! it now finds my own defs. but still, any other external defs, even "defn", "ns" and so on so forth are unrecognized |
| 13:48 | mgaare | lvh: is .. what you want? you might be looking for doto |
| 13:48 | cfleming | Ven: Do you have a Clojure jar attached to your project? |
| 13:48 | lvh | mgaare: I'm currently using .., but that doesn't let me express the when-let part |
| 13:48 | lvh | mgaare: I don't want to call the method at all when (nil? (:k m)) |
| 13:48 | Ven | cfleming: if the jar is indeed "clojure-complete", then yes -- but intellij did warn me about not recognizing the jar |
| 13:49 | mgaare | lvh: you could take a look at cond-> |
| 13:49 | cfleming | Ven: Under External Libraries in the Project view, you should have one saying Leiningen: org.clojure/clojure:<some version> |
| 13:50 | Ven | cfleming: ah, I don't |
| 13:50 | Ven | that's definitely it |
| 13:50 | mgaare | in your case it'll be somewhat duplicative |
| 13:50 | cfleming | Ven: Do you have clojure as a dep in your project.clj? |
| 13:50 | Ven | cfleming: no |
| 13:50 | Ven | cfleming: actually! [org.clojure/clojure "1.6.0"] |
| 13:51 | lvh | mgaare: Cool! that is kind of what I want; also my current when-let thing seems to work: (when-let [v (:load-balancers lc)] apply #(.loadBalancers % v)) |
| 13:51 | mgaare | lvh: I've occasionally written utility functions that handle this kind of thing too |
| 13:51 | cfleming | Ven: That is very strange. Try refreshing your project (open the Leiningen toolwindow, Refresh) |
| 13:52 | cfleming | Ven: I have to go, sorry, I'll be around later on probably |
| 13:52 | Ven | cfleming: it does say "there are no lein project to display" |
| 13:52 | lvh | yeah, I think this is going to have to be a macro, unless there's a thing that does what the (.method) special form does except where method is given as a string |
| 13:52 | Ven | alright, thanks anyhow :) |
| 13:52 | Ven | that'll do it, definitely |
| 13:52 | cfleming | Ven: Oh - Right click on project.clj, add as lein project |
| 13:52 | Ven | I just did :) |
| 13:52 | Ven | thanks! |
| 13:52 | cfleming | NP - good luck! |
| 13:53 | Ven | cfleming: amazing :) |
| 14:12 | sritchie | oskarth: for sure - |
| 14:12 | sritchie | oskarth: I was just confused as to why you thought an alternative for cljs-ajax would do anything about your params issue |
| 14:12 | sritchie | oskarth: since the “problem” is on the ring side, nothing to do with cljs-ajax |
| 14:12 | sritchie | oskarth: an alternative is to use jquery: http://api.jquery.com/jquery.ajax/ |
| 14:12 | sritchie | oskarth: but it won’t help |
| 14:13 | oskarth | sritchie: I think it's just some edge case with edn as transport, resolved it by reverting to json |
| 14:13 | oskarth | the problem is not on the ring side |
| 14:14 | sritchie | oskarth: the ring-edn middleware adds :edn-params and merges them into :params |
| 14:14 | oskarth | nope :) |
| 14:14 | oskarth | not in this case |
| 14:14 | oskarth | was about GET and query-params non-edn format |
| 14:15 | oskarth | anyway, have to go. If I were to run into problems again I think I'll go with just a thin wrapper over xhr, seems like the most transparent abstraction to me |
| 14:16 | oskarth | a la https://github.com/swannodette/om-sync/blob/master/src/om_sync/util.cljs#L34 or https://github.com/hackerschool/community/blob/master/client/src/community/util/ajax.cljs |
| 14:29 | lvh | I wrote a macro that tries to call some methods on a POJO, but there's always a space between the dot and the method name e.g. (. x) instead of (.x), which fails because that name doesn't exist |
| 14:29 | lvh | https://gist.github.com/lvh/bd35d7506bc0f127cbb9 |
| 14:29 | lvh | kw-to-sym is a simple function that turns :some-keyword-name into 'someKeywordName |
| 14:39 | aperiodic | lvh: you can't concatenate symbols in a macro in the way you seem to be trying to with #(.~m ...) |
| 14:40 | muhuk | lvh: you need to join them as strings, then convert. |
| 14:40 | muhuk | lvh: (str "." m) |
| 14:40 | Bronsa | or just use the . form |
| 14:40 | aperiodic | lvh: you can, however, use the dot special form |
| 14:41 | aperiodic | (. object method) |
| 14:41 | aperiodic | method doesn't need to have a dot at the front there |
| 14:41 | Bronsa | (. % ~m ..) |
| 14:41 | muhuk | which is a better idea IMO |
| 14:41 | aperiodic | http://clojure.org/java_interop#Java%20Interop-The%20Dot%20special%20form |
| 14:48 | ARM9 | what's the data structure behind defrecord |
| 14:48 | ARM9 | does it just use something basic like a c struct? or is it a hash map |
| 14:49 | Bronsa | ARM9: for it stores declared fields in class slots, for extra keys it uses a hashmap |
| 14:52 | ARM9 | class slots, is that a java thing |
| 14:52 | ARM9 | so it stores the data the way java does for a class? |
| 14:52 | Bronsa | ARM9: i mean, as regular class fields yes |
| 14:53 | ARM9 | alright cool, thanks |
| 14:54 | jcromartie | what would cause this type of error? |
| 14:54 | jcromartie | java.lang.ClassCastException: foo.Bar cannot be cast to foo.Bar, compiling:(foo.clj:28:3) |
| 14:54 | jcromartie | sorry it's anonymized |
| 14:54 | jcromartie | this is during aot |
| 14:54 | stuartsierra | jcromartie: Protocols and records. |
| 14:54 | jcromartie | with a defrecord that implements a protocol |
| 14:54 | jcromartie | yes |
| 14:54 | jcromartie | so |
| 14:54 | jcromartie | what are we doing wrong? |
| 14:54 | stuartsierra | It can happen if you reload the a namespace which has already been AOT-compiled. |
| 14:57 | jcromartie | this happens during lein uberjar |
| 14:57 | jcromartie | literally |
| 14:57 | jcromartie | lein clean && lein uberjar |
| 14:57 | jcromartie | (sorry I'm not trying to be obtuse on purpose) |
| 15:03 | stuartsierra | Something is getting compiled / loaded twice. Sorry, can't be more specific. |
| 15:11 | jcromartie | is there a way to see what's being compiled and loaded? |
| 15:12 | jcromartie | is (:gen-class) unnecessary? |
| 15:15 | the_danko | mr. cfleming, does cursive offer an "organize imports" functionality for java classes? like eclipse does |
| 15:18 | stuartsierra | jcromartie: `:gen-class` is unlikely to be the issue. |
| 15:22 | jcromartie | I'm trying to create a minimal test case to reproduce |
| 15:22 | jcromartie | it's very strange |
| 15:24 | stuartsierra | Some of the AOT loading issues may have been fixed in Clojure 1.7. |
| 15:28 | puredanger | is Bronsa here? |
| 15:43 | jcromartie | stuartsierra: got it... |
| 15:43 | jcromartie | we had an app that depended on a lib |
| 15:43 | jcromartie | the lib called protocol functions at load time |
| 15:43 | jcromartie | as part of a (def ...) |
| 15:44 | jcromartie | the app that required the lib had :profiles {:uberjar {:main whatever :aot :all}} |
| 15:44 | jcromartie | and the main namespace had (:gen-class) |
| 15:45 | jcromartie | moving to {:main ^:skip-aot whatever :profiles {:uberjar {:aot :all}} fixed it |
| 15:46 | stuartsierra | wow |
| 15:48 | amalloy | clojurebot: :gen-class is likely to be the issue |
| 15:48 | clojurebot | 'Sea, mhuise. |
| 15:48 | justin_smith | ~aot |
| 15:48 | clojurebot | aot was so ahead of its time |
| 15:49 | justin_smith | well, he's not wrong |
| 15:58 | cfleming | the_danko: Not in Clojure code, unfortunately - lots of people have requested that though, there's an issue in the tracker |
| 16:10 | the_danko | cfleming thanks |
| 16:15 | ToxicFrog | Argh |
| 16:15 | lvh | How do I do lookahead assertions in regexes? I was hoping (re-matcher #"[a-z]+(?=[A-Z]|$)|[A-Z][a-z]*" "anABCMethod") might work, but, no luck. |
| 16:16 | ToxicFrog | Just wasted an hour debugging an issue caused by the fact that map always returns a list, rather than returning the same type it was passed |
| 16:16 | amalloy | lvh: (?=) works in clojure. if it doesn't do what you want, your regex is broken |
| 16:16 | ToxicFrog | So (map foo [x y z]) is a list rather than a vector and the two behave very differently in maros |
| 16:16 | ARM9 | isn't it technically a sequence |
| 16:16 | ARM9 | a lazy one at that |
| 16:16 | SagiCZ | it is a sequence |
| 16:16 | SagiCZ | ,(type (map inc (range 5))) |
| 16:17 | clojurebot | clojure.lang.LazySeq |
| 16:17 | amalloy | it looks like you don't want lookahead at all though, and you're just grouping things wrong |
| 16:17 | lvh | amalloy: Hm. Okay. So maybe my regex is broken. I was expecting that regex to match at the very least "abc", since the first part is 1-or-more lowercase chars, and the second part is zero-or-more Capitalized groups |
| 16:17 | SagiCZ | you can get a vector this way |
| 16:17 | SagiCZ | ,(mapv inc (range 5)) |
| 16:17 | clojurebot | [1 2 3 4 5] |
| 16:17 | lvh | amalloy: Instead, I'm getting no matches at all. |
| 16:17 | amalloy | #"[a-z]+(?:[A-Z][A-Za-z]*)" looks like more what you meant |
| 16:17 | amalloy | er, #"[a-z]+(?:[A-Z][A-Za-z]*)?" |
| 16:17 | amalloy | forgot the ? |
| 16:18 | lvh | I think that would parse someABCMethod differently |
| 16:19 | lvh | ("some" "ABC" "Method") vs ("some" "A" "B" "C" "Method"); if that makes any sense |
| 16:19 | amalloy | sure, but so what? you don't have any capturing groups |
| 16:19 | amalloy | i can't tell from your malformed regex what you want to capture in some future version of the regex |
| 16:20 | amalloy | anyway, mine "parses it like", if such a thing can really be usefully said, ("some" "A" "BCMethod") |
| 16:21 | Frozenlock | Any library suggestion to work with SQL? (sqlingvo, korma?) |
| 16:22 | amalloy | clojure.java.jdbc |
| 16:23 | Frozenlock | amalloy: I'll immediately look at it, thanks! |
| 16:24 | lvh | amalloy: Sorry, yes; I am trying to capture them. I'm trying to turn a bunch of Java variable names into Clojure-looking keywords. |
| 16:25 | amalloy | then i would say the most obvious thing wrong with your original regex is that you seem to believe [A-Z][a-z]* is the same as [A-Za-z]* |
| 16:26 | lvh | That's why I care how it would match; I'm going to (join "-" (map lower-case bits)) afterwards. |
| 16:37 | SagiCZ | lvh: have you heard of regexpal.com ? its really easy, like zero learning curve and helps me with my pathetic regex atempts |
| 16:42 | Frozenlock | There's also re-builder in emacs http://www.masteringemacs.org/article/re-builder-interactive-regexp-builder |
| 16:58 | AeroNotix | Does :java-source-paths affect how lein finds clojure classes with :gen-class? |
| 16:58 | AeroNotix | I seem to not be able to properly compile things when I have a repo with java |
| 16:58 | creese | How do you tell clj-http not to throw exceptions for 40x, 50x, errors? |
| 16:59 | AeroNotix | creese: use http-kit :L) |
| 16:59 | creese | is that project more current? |
| 16:59 | AeroNotix | probably |
| 16:59 | hiredman | read the readme and do what it says? |
| 17:00 | creese | it says to use :throw-exceptions false, but that has no effect |
| 17:01 | creese | I'm inside a go block, I wonder if that's breaks certain assumptions |
| 17:01 | pipi | k |
| 17:01 | hiredman | well 1. do do io in a go block 2. why do you think it has no effect? |
| 17:01 | hiredman | don't do |
| 17:01 | clojurebot | Pardon? |
| 17:02 | creese | the io happens in a callback |
| 17:02 | creese | it has no effect because I always get a traceback even if I try to catch |
| 17:03 | lurkOnTheWall | I'm trying to get fireplace working, and I have the leiningen plugin, but I can't seem to connect to the nREPL server. |
| 17:03 | lurkOnTheWall | I'm getting errno 111 connection refused. |
| 17:03 | AeroNotix | when I add :java-source-paths and then use the java package in a :gen-class then try to compile+import the gen-class'd joint, it complains about some classes missed. |
| 17:04 | AeroNotix | missing* |
| 17:04 | AeroNotix | any ideas? |
| 17:04 | hiredman | creese: so the clj-http option definitely works, if you think you are setting the option and it is not working, that is because you are failing to set it for some reason |
| 17:05 | hiredman | either you are doing io in a go block or you are not, you say "I am inside a go block" |
| 17:05 | creese | definately in a go block |
| 17:05 | creese | the exception comes from the callback |
| 17:05 | hiredman | creese: and how are you passing the option to clj-http? |
| 17:06 | lurkOnTheWall | hmmm... I may have installed cider-nrepl, but not cider |
| 17:06 | hiredman | what callback? |
| 17:06 | hiredman | clj-http is synchronous, no callbacks |
| 17:06 | creese | I know |
| 17:06 | creese | clj-http is called from a go block |
| 17:07 | AeroNotix | I am inside a cupboard |
| 17:07 | AeroNotix | am I doing io? |
| 17:07 | hiredman | then you are doing io in a go block |
| 17:07 | creese | what's wrong with that? |
| 17:08 | hiredman | blocking io blocks, and go blocks all share a threadpool |
| 17:09 | hiredman | (bounded) |
| 17:10 | creese | the exception is coming from thread "async-dispatch-2", can I assume that means it's within a go block? |
| 17:10 | hiredman | how are you trying to catch the exception? |
| 17:11 | creese | I want clj-http to not throw it at all |
| 17:11 | creese | but :throw-exceptions false has no effect |
| 17:11 | hiredman | creese: so how are you tell in to not throw? |
| 17:13 | hiredman | I know that setting the options works, I don't know how you are trying to set them that it doesn't work, you could be putting the option in the wrong place in the map |
| 17:13 | creese | (client/post url {:body (json/write-str data) :content-type :json :accept :json} {:as :json :throw-exceptions false}) |
| 17:14 | creese | ok |
| 17:14 | hiredman | or since core.async is at play, you could have spun off code running in a go loop or something, that is printing errors, fixed it in in your code, and never stopped the go-loop so you still see errors from the old code running |
| 17:15 | joegallo | pretty sure that's supposed to just be one map... |
| 17:15 | hiredman | yeah |
| 17:16 | creese | ok, that did it |
| 17:16 | creese | I read the docs wrong |
| 17:16 | creese | cool |
| 17:16 | joegallo | no worries, it happens |
| 17:17 | hiredman | (and stop doing io in a go block) |
| 17:20 | lurkOnTheWall | I'm not sure that lein's target/repl-port is being set correctly. How could I check that? |
| 17:23 | ToxicFrog | I think this may be a new, horrible record, at least for me: https://gist.github.com/ToxicFrog/2a24438134717968158d |
| 17:23 | ToxicFrog | 117 lines of compiler crash vomit to scroll through to get to the error message. |
| 17:24 | lurkOnTheWall | idk what happened, but it's working now. |
| 17:24 | AeroNotix | when I add :java-source-paths and then use the java package in a :gen-class then try to compile+import the gen-class'd joint, it complains about some classes missing. |
| 17:30 | puredanger | ToxicFrog: the first line of the message tells you the problem and location doesn't it? there is no reason the tool (lein) has to show you the stack trace here. |
| 17:30 | ToxicFrog | puredanger: no reason at all! And yet it does. |
| 17:42 | iamjarvo | is there a recommended way to use jars with clojure? |
| 17:42 | iamjarvo | articles im finding are older |
| 17:42 | puredanger | just put them on the classpath :) |
| 17:43 | iamjarvo | hrm i read that gets difficult. any experience with this? https://github.com/kumarshantanu/lein-localrepo |
| 17:43 | iamjarvo | im also new to java so im exploring |
| 17:44 | puredanger | the easiest way to deal with jars etc is to use Leiningen and let it manage them for you in your local Maven cache |
| 17:44 | puredanger | if you are experimenting, "lein try" is pretty handy https://github.com/rkneufeld/lein-try |
| 17:45 | iamjarvo | thanks |
| 17:57 | iamjarvo | turns out this was already available with lein deps org.apache.poi/poi |
| 18:25 | timothyw | Hey all, quick q. |
| 18:25 | timothyw | For emacs cider (https://github.com/clojure-emacs/cider) |
| 18:25 | timothyw | How can I get ac-cider working ? (https://github.com/clojure-emacs/ac-cider) |
| 18:25 | timothyw | The given instructions don't work (not showing completions on my system) |
| 18:42 | paxan | clojure.core.match question. Is it possible to specify a clause with pattern dynamically? Two examples coming… |
| 18:42 | paxan | (match [{:yo 123}] [{}] :yes :else :no) ; => :yes |
| 18:42 | paxan | (let [p {}] (match [{:yo 123}] [p] :yes :else :no)) ;=> :no |
| 18:43 | amalloy | no |
| 18:43 | timothyw | … Nevermind. I just had to reboot my VM for some reason :) |
| 18:43 | timothyw | probably just a zombie process or something |
| 18:57 | paxan | I've grokked how to use core.match with dynamic clauses… |
| 18:57 | paxan | (eval (let [v {:yo 123} p (read-string "{:yo _}")] `(match [~v] [~p] :yes :else :no))) ;=> :yes |
| 18:57 | paxan | (eval (let [v {:abc 123} p (read-string "{:yo _}")] `(match [~v] [~p] :yes :else :no))) ; => :no |
| 18:58 | paxan | the above demonstrates a pattern, p, obtained, say, from a command line arg. |
| 18:58 | martinklepsch | ,(let [a #{:a :b} b #{:c :a}] (clojure.set/difference (clojure.set/union a b) (clojure.set/intersection #{:a :b} #{:c :a}))) |
| 18:58 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: clojure.set, compiling:(NO_SOURCE_PATH:0:0)> |
| 18:59 | martinklepsch | is there a more elegant way of doing that? |
| 19:00 | amalloy | martinklepsch: this is computing the symmetric difference, right? |
| 19:01 | amalloy | i'd say it's easier to understand when written as (union (difference a b) (difference b a)), but of course that's the same number of operations |
| 19:06 | martinklepsch | amalloy: ah neat, didn't know how do describe it. |
| 19:07 | martinklepsch | amalloy: thanks |
| 19:24 | lvh | Hm. |
| 19:25 | lvh | I have a nested enum inside some other class. Is Outer$Inner/CONST_NAME not how I access those? |
| 19:25 | lvh | I figured it's a static field, and Outer$Inner is how you do nested classes, right? |
| 19:25 | amalloy | it is |
| 19:25 | amalloy | did you forget to import Outer$Inner? |
| 19:26 | lvh | Ah; I didn't import it separately :) |
| 19:26 | lvh | Thanks! |
| 19:27 | amalloy | remember, inner classes are a fiction of javac. it's really just an ordinary class with a funny name, and if you want to use it you have to import it (or refer to it fully-qualified), just like any class |
| 19:28 | lvh | Right, makes sense. I guess I was hoping for those imports to be automatically resolved, or something. |
| 19:29 | lvh | But given how it's all lies anyway, it makes sense :) |
| 19:39 | vas | How do you switch a handler from "dev" to "production" (so that stack traces just return a 404 instead)? |
| 20:54 | jcromartie | what does "lein clean" do if it doesn't clean out target/ |
| 20:56 | TEttinger | jcromartie: maybe the output dir isn't target? |
| 20:56 | jcromartie | maybe |
| 20:57 | jcromartie | this is a brand-new "lein new app" |
| 21:02 | TEttinger | so what's in target ? |
| 21:04 | jcromartie | target/uberjar/classes etc. |
| 21:05 | jcromartie | seems like target/uberjar is preserved during "lein clean" |
| 21:11 | TEttinger | jcromartie, is the uberjar running? it might be locked |
| 21:13 | jcromartie | the effect is that "lein uberjar" doesn't actually compile the code again |
| 21:14 | jcromartie | "rm -r target && lein uberjar" will compile the namespaces again |
| 21:14 | TEttinger | that's odd |
| 21:14 | jcromartie | yah |
| 21:14 | jcromartie | Leiningen 2.5.0 on Java 1.7.0_75 Java HotSpot(TM) 64-Bit Server VM |
| 21:15 | TEttinger | lein uberjar won't recompile if the sources haven't changed |
| 21:15 | TEttinger | so there's that |
| 21:18 | jcromartie | well anyway, this is tangential to what I'm trying to do |
| 21:18 | jcromartie | I'm trying to narrow down this issue with AOT and defrecord |
| 21:26 | creese | What's the best way to debug a macro? |
| 21:27 | jcromartie | (macroexpand-1 |
| 21:27 | jcromartie | ,(macroexpand-1 '(when true :foo)) |
| 21:27 | clojurebot | (if true (do :foo)) |
| 21:36 | amalloy | creese: also, strive to write macros simple enough that you don't have to debug them |
| 21:54 | TimMc | amalloy: Arbitrarily small pieces of code can require debugging. :-) |
| 21:55 | amalloy | TimMc: did i say small? |
| 21:57 | TimMc | heh |
| 21:57 | TimMc | I think my point still stands. |
| 21:59 | amalloy | of course, "don't write bugs" is not trivially-followable advice, but it's still useful advice. a lot of people who need help writing macros are building this giant thing, most (or all) of which shouldn't be a macro at all |
| 22:01 | TEttinger | this piece of code could be entertaining to debug http://www.ioccc.org/1984/mullender.c |
| 22:01 | TEttinger | valid C code, for a certain kind of machine |
| 22:02 | justin_smith | what a silly way to write machine code |
| 22:02 | TimMc | Oh, yes -- I think you have to pass a compiler flag to avoid a warning, though? |
| 22:02 | amalloy | and run a machine older than the stones |
| 22:03 | amalloy | is that the right idiom? it doesn't feel right. older than the ____ |
| 22:04 | amalloy | the hills |
| 22:05 | TEttinger | TimMc, it was an entry in 1984, I doubt compilers cared much |
| 22:05 | justin_smith | I think "older than amalloy" is the accepted hyperbole |
| 22:15 | justin_smith | actually, "old as dirt" is the version I always heard in rural Vermont at least |
| 22:15 | justin_smith | or "old as the hills" |
| 22:16 | amalloy | you're probably right, old as the hills sounds best to me |
| 22:17 | justin_smith | there's also "older than the stars", which is a book, and has a nice ring to it |
| 22:19 | TEttinger | old as time, old as memory, old as AOL CDs in the mail... |
| 22:20 | justin_smith | older than the cue cat™ |
| 22:21 | xemdetia | is there a better tarball out there right now that has a file index |
| 22:21 | justin_smith | ? |
| 22:22 | xemdetia | When you do tar -tf on a 14 GB file it takes a while :) |
| 22:22 | justin_smith | oh, so a replacement for tar with faster file index? |
| 22:22 | xemdetia | well, with a file index. The reason why it is so slow is that tar does not have a file index since it is designed for tape |
| 22:22 | justin_smith | right |
| 22:23 | xemdetia | I was writing one for fun a while ago |
| 22:23 | xemdetia | I forget what happened to that |
| 22:23 | justin_smith | tar = TApe ARchive |
| 22:23 | TEttinger | taar |
| 22:23 | justin_smith | TEttinger: for some reason everyon started spelling it wrong |
| 22:23 | TEttinger | heh |
| 22:35 | andyf | xemdetia: Zip ? |
| 22:36 | xemdetia | andyf, maybe I will have to check if it does perms like tar |
| 22:36 | xemdetia | I don't know I am just waiting for like 300 GB to process from a silly command and I dream of something else |
| 22:36 | andyf | Compression only occurs independently between files, I believe, not across files like tar.gz or whatever compression you use |
| 22:38 | xemdetia | yeah it's not the compression as much as just getting a good ol' manifest quick |
| 22:38 | andyf | I 'm surprised wikipedia's comparison of archive formats page doesn't mention that property, nor whether they maintain unix file permissions |
| 22:44 | TimMc | gfredericks: We still haven't figured out a name for the kid! So far I'm leaning towards mysql_escape_baby |
| 22:45 | justin_smith | TimMc: for bonus points, name the next kid mysql_real_escape_baby |
| 22:45 | justin_smith | to encourage healthy sibling rivalry |
| 22:46 | TimMc | Oh, that is a much better name, yes! |
| 22:46 | nuwanda_ | robert');drop table students :) |
| 22:46 | gfredericks | ,(format "baby-%04d" (rand-int 10000)) |
| 22:46 | clojurebot | "baby-2226" |
| 22:46 | TimMc | :-D |
| 22:46 | justin_smith | gfredericks: well, you could just make their social security number part of their name |
| 22:46 | xemdetia | andyf, I agree. I believe rar has an index but that's patent-hard |
| 22:46 | TimMc | justin_smith: They don't have one ye. Deadlock. |
| 22:47 | andyf | Looks like info-zip should maintain unix permissions, from what I have read, not personal testing |
| 22:47 | justin_smith | TimMc: well, you could get around that with a delay |
| 22:47 | justin_smith | or a promise |
| 22:47 | gfredericks | TimMc: you could also consider some contrived manner of having the baby determine its own name |
| 22:48 | gfredericks | or also you could use "Gary Fredericks" |
| 22:48 | TimMc | I think the state needs a string, not a reference. |
| 22:49 | TimMc | gfredericks: Gurgle Psffwtt McCormack |
| 22:49 | TimMc | the Hic'th |
| 22:49 | justin_smith | TimMc: I think the future is in ungoogleable names |
| 22:50 | justin_smith | things like "boobs" or "free ipad" that are totally impossible to google search for |
| 22:50 | justin_smith | thus guaranteeing privacy |
| 22:50 | TimMc | I've thought of that. |
| 22:50 | justin_smith | "mail order viagra, esquire" |
| 22:51 | TimMc | I did some NLP work so I know how to fool some of the algorithms. |
| 22:51 | gfredericks | also "Barack Obama" |
| 22:51 | TimMc | Fnu The |
| 22:52 | TimMc | A name-placeholder + a stopword. |
| 22:52 | justin_smith | foo |
| 22:53 | justin_smith | that one has a built in scheme for naming all the kids |
| 22:53 | justin_smith | foo, bar, baz, quux |
| 23:00 | TEttinger | could just name him Lil' Satan |
| 23:00 | gfredericks | or node.js |
| 23:01 | TEttinger | oh! |
| 23:01 | TEttinger | unicode snowman |
| 23:01 | gfredericks | not even the unicode character just the two words "Unicode Snowman" |
| 23:01 | TEttinger | "please sign your name in cursive." "...uh... ☃" |
| 23:02 | TimMc | U+2028 LINE SEPARATOR |
| 23:02 | TEttinger | hahaha |
| 23:02 | TEttinger | U+FEFF BOM |
| 23:05 | gfredericks | U+20FG |
| 23:05 | justin_smith | "unbreakable space" would be a pretty kickass name |
| 23:06 | TEttinger | ,\u20fg |
| 23:06 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Invalid digit: g> |
| 23:06 | TEttinger | agh |
| 23:06 | TEttinger | ,\u20ff |
| 23:06 | clojurebot | \ |
| 23:06 | TEttinger | heh |
| 23:06 | andyf | Base 17 is hard |
| 23:07 | gfredericks | security by obscurity |
| 23:07 | TEttinger | ,17r20fg |
| 23:07 | clojurebot | 10097 |
| 23:07 | TEttinger | ,(Integer/toString 10097 16) |
| 23:07 | clojurebot | "2771" |
| 23:07 | TEttinger | alternatively |
| 23:07 | TEttinger | ,(char 10097) |
| 23:07 | clojurebot | \❱ |
| 23:07 | TEttinger | huh |
| 23:07 | TEttinger | that's nice |
| 23:08 | gfredericks | how on earth do they track unnamed kids at the hospital |
| 23:08 | TEttinger | then again, you don't know if it's base 17 or up to base 36, or even base64 |
| 23:08 | TEttinger | "wiggly one" |
| 23:08 | gfredericks | I guess they can't rely on just names in general anyhow |
| 23:10 | TEttinger | "one of the 15 with the parents who say no vaccines, it doesn't matter, they'll be headed to the morgue in a few years anyway" |
| 23:10 | justin_smith | speaking of babies and systems, the craziest thing was that idea in the US of making one number that is simultaneously a unique identifier and also an authentication secret |
| 23:10 | TEttinger | heh |
| 23:10 | justin_smith | like, did they spend more than an hour or two thinking about the consequences of that? |
| 23:12 | gfredericks | was it designed to be an auth secret? |
| 23:12 | justin_smith | gfredericks: yeah, that may have just been a thing that ended up happening |
| 23:12 | TEttinger | kinda like Sony's authentication scheme for PS3 releases. scheme singular, they used the same phrase to authenticate any software for PS3, so the moment it was cracked anyone could bypass the hardware hypervisor |
| 23:12 | justin_smith | haha |
| 23:12 | justin_smith | TEttinger: you'd think with security practices like that they'd get hacked eventually or something |
| 23:13 | TEttinger | lol |
| 23:13 | TEttinger | this was long before the sony pictures hack, but it seems like security was not exactly on the mind of anyone at sony |
| 23:13 | clojurebot | Gabh mo leithscéal? |
| 23:27 | TimMc | gfredericks: Well, she's currently registered at the pediatrician's office as "Baby Girl Thorn" :-/ |
| 23:28 | TimMc | gfredericks: http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/ #40 |
| 23:29 | justin_smith | oh, there's a unicode character for "thorn" Þ |
| 23:29 | TimMc | yup |
| 23:29 | justin_smith | People’s names fit within a certain defined amount of space. |
| 23:29 | justin_smith | haha |
| 23:30 | amalloy | my name is infinite, because it includes by reference all experiences i have had up to the current instant in my life, including a recitation of my name |
| 23:31 | metellus | good thing you thought up that handy nickname |
| 23:33 | justin_smith | http://i.imgur.com/lJrFq.jpg |
| 23:59 | vas | justin_smith: what if i require a floating point quantity of ladies? |