2009-11-23
| 00:57 | gilbertleung | hi |
| 00:58 | gilbertleung | i'm trying to use wall-hack-method, which requires a list of params to be passed in |
| 00:59 | gilbertleung | if the param is of string class, then i just pass in java.lang.String |
| 00:59 | gilbertleung | so... what if the param is of String[] ? |
| 01:00 | hiredman | ,(-> "foo" vector into-array .getClass) |
| 01:00 | clojurebot | [Ljava.lang.String; |
| 01:00 | hiredman | ,(Class/forname ""[Ljava.lang.String;"") |
| 01:00 | clojurebot | EOF while reading |
| 01:01 | hiredman | ,(Class/forName "[Ljava.lang.String;") |
| 01:01 | clojurebot | [Ljava.lang.String; |
| 01:01 | gilbertleung | hmm |
| 01:02 | hiredman | it is less than ideal, but most things dealing with classes of arrays are |
| 01:04 | gilbertleung | interesting |
| 01:04 | gilbertleung | hiredman: thx |
| 01:06 | hiredman | ,(-> "foo" vector into-array class) |
| 01:06 | clojurebot | [Ljava.lang.String; |
| 02:23 | mrSpec | hello |
| 05:41 | ordnungswidrig | anybody using leiningen on w32? |
| 05:42 | Bjering | is there a function to list all my variables so I can run test on those that have :test metadata? |
| 05:45 | ordnungswidrig | Bjering: all vairables or all functions? |
| 05:46 | liwp | Bjering: you can look up the vars in a namespace I think |
| 05:46 | Bjering | all variables that holds functions |
| 05:47 | liwp | so you could iterate over all the vars exported by a ns and see if they have :test metadata on them or not |
| 05:47 | Bjering | What I am really after the best way to manage my unittests, I have no java legacy its a new project. I am new to Clojure. |
| 05:47 | Bjering | yes that was my idea |
| 05:47 | liwp | Bjering: you should look into the clojure test framwork: clojure.test I think |
| 05:49 | liwp | ,(doc clojure.test) |
| 05:49 | clojurebot | java.lang.ClassNotFoundException: clojure.test |
| 05:49 | liwp | or not... |
| 05:50 | Bjering | ,(doc test) |
| 05:50 | clojurebot | "([v]); test [v] finds fn at key :test in var metadata and calls it, presuming failure will throw exception" |
| 05:50 | Bjering | Thats all the doc I find |
| 05:51 | liwp | ,(doc clojure.test-is) |
| 05:51 | clojurebot | java.lang.ClassNotFoundException: clojure.test-is |
| 05:51 | liwp | grr |
| 05:52 | Bjering | now I am reading "the book" now, and it describes the test-is library. I just wanted to go with the core test first, until it was proven to me it wasnt enough. Maybe I already reached that point? |
| 05:53 | liwp | AFAIK clojure.contrib.test-is got moved to clojure.test and it's used e.g. in writing tests for core |
| 05:53 | liwp | I haven't used it myself, but there's an oldish article about it at http://stuartsierra.com/2009/01/18/tests-are-code |
| 05:54 | liwp | seems straight forward enough, i.e. I don't think you need to worry about it being overkill for you needs |
| 05:54 | Bjering | thank you, I'll read that |
| 06:15 | cypher23 | VimClojure question: The keybindings don't seem to work, is there anything I need to do to activate them? |
| 06:57 | rhickey | heh, potential JDK syntax for function expressions? #() :) http://www.jroller.com/scolebourne/entry/closures_in_jdk_7 |
| 06:59 | _ato` | :D |
| 07:53 | Bjering_ | I want to rotate a vector, like this: |
| 07:53 | Bjering_ | (reduce conj (subvec v n) (subvec v 0 n))) |
| 07:54 | Bjering_ | is there a way todo this O(1) ? |
| 08:02 | ordnungswidrig | Bjering_ Rotate by one element? What about concat? (concat (subvec v n) (subvec v 0 n)) |
| 08:02 | ordnungswidrig | ,(let [v [1 2 3 4] n 3] (concat (subvec v n) (subvec v 0 n))) |
| 08:02 | clojurebot | (4 1 2 3) |
| 08:02 | ordnungswidrig | ,(let [v [1 2 3 4] n 1] (concat (subvec v n) (subvec v 0 n))) |
| 08:02 | clojurebot | (2 3 4 1) |
| 08:06 | Bjering_ | ornungswidrig: Ah perfect, now it would be great if concat was listed among "related functions" ner vector at http://clojure.org/data_structures |
| 08:07 | ordnungswidrig | Bjering_ yes, the api is very large and dynamic typing makes it hard to browser for matching functions. |
| 08:08 | Bjering_ | I understand |
| 08:10 | Bjering_ | hmm, concat destroys the "vectorness" though, its a lazy-seq |
| 08:10 | ordnungswidrig | Bjering_: but is O(1) I suppose :-) |
| 08:11 | Bjering_ | As long as I dont want to use it as a vector later. |
| 08:11 | ordnungswidrig | Bjering_: you mean random access? |
| 08:11 | Bjering_ | yes, such as subvec |
| 08:11 | Bjering_ | ,(= [1 2 3 4 5 6] (concat [1 2 3] [4 5 6])) |
| 08:11 | clojurebot | true |
| 08:12 | Bjering_ | one is a seq, one is a vec still they are equal? |
| 08:12 | ordnungswidrig | Bjering_: you'd better ask somebody who is more familier with clojure's datastructurs. I don't know them very well. |
| 08:16 | ordnungswidrig | ,(let [v [1 2 3 4] n 3] (vec (subvec v n) (subvec v 0 n))) |
| 08:16 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: core$vec |
| 08:17 | Bjering_ | Well, I can make my rotate return a vector by using the vec-ctor, sure, but I assume the vec call is O(n) |
| 08:19 | ordnungswidrig | Bjering_: basically you need sth. like concat for vectors which is O(1) |
| 08:21 | Bjering_ | yes but this doesnt exist? |
| 08:27 | chouser | ,(into [1 2 3] [4 5 6]) |
| 08:27 | clojurebot | [1 2 3 4 5 6] |
| 08:27 | chouser | That's roughly O(n) where n is the length of the second vector |
| 08:28 | rhickey | Bjering: there is no constant-time vector rotate in Clojure |
| 08:28 | Bjering_ | ok, thats the best possible? |
| 08:28 | Bjering_ | ok |
| 08:29 | rhickey | so, in playing with callsites I've added the ability to more-statically link to defn-ed vars you know won't change (e.g. clojure.core), for significant perf boost in some situations, thinking about how best to expose/express this option |
| 08:30 | rhickey | could be at the var or lib levels, property of the author or consumer... |
| 08:31 | chouser | hm, fun... |
| 08:32 | rhickey | seems to give 20% perf boost easily, and can be many times that when a small work unit gets inlined |
| 08:32 | chouser | that's a bit better than I saw going from vars to letfn in finger tree |
| 08:32 | rhickey | you would never need letfn for perf again |
| 08:32 | chouser | yay |
| 08:33 | rhickey | the tradeoff is, no dynamic rebinding, no redef without reloading deps (not a restart though) |
| 08:34 | rhickey | I found few cases of dynamic rebinding of fns, one in test itself, some in a mock and trace lib |
| 08:35 | rhickey | so, this ad hoc capability is costing everyone, even when not used, but can be tricky to determine granularity of expressing static/non |
| 08:36 | chouser | producer could provide a "hint" and a consumer could still override that, right? |
| 08:37 | rhickey | it's notthat simple when you think of libs that might dynamically rebind something expecting that to be in effect for called code that statically linked |
| 08:37 | rhickey | that's a made-up but possible case |
| 08:39 | chouser | ah, right. like a trace applied to someone else's code |
| 08:40 | djork | is there a standard way to create a fully-qualified symbol from a "base" symbol and a namespace? |
| 08:40 | rhickey | so there are a few division points - this fn was designed to be rebound, this lib is done/static, this code is under dev/dynamic, this lib superimposes dynamism on things it doesn't own |
| 08:40 | djork | ,(namespace 'foo/bar) |
| 08:40 | clojurebot | "foo" |
| 08:40 | djork | should I just do it with strings |
| 08:41 | djork | ,(str "some-ns/" (name 'foo)) |
| 08:41 | clojurebot | "some-ns/foo" |
| 08:41 | rhickey | for the latter case there could just be a 'turn off direct linking' option, back to old semantics |
| 08:42 | rhickey | but if on consumer side, :requires in different libs could have conflicting directives re this |
| 08:42 | durka42 | ,(symbol "foo" "bar") |
| 08:42 | clojurebot | foo/bar |
| 08:43 | djork | ah, thanks a lot durka42 |
| 08:46 | djork | hmm, can't use private fns in a macro that's used somewhere else... |
| 08:47 | chouser | is it possible to get a warning if you try to rebind something that has direct linking? |
| 08:55 | Bjering_ | the seq returned by (seq (vector 1 2 3)) is lazy I presume? |
| 08:59 | Bjering_ | this paste-webpage I have seen you use, how do I use it? |
| 09:01 | rhickey | chouser: I guess if it was a property of the var in the first place - I haven't gone there yet, but on the todo is a more varied set of vars, with/without rebind e.g., and 'constant' vars |
| 09:02 | rhickey | but while linkage could be a global property, it need not be, since it is really a property of each fn how strongly it links to the vars it references |
| 09:07 | rhickey | one consuming fn could say - I'm happy with the current def indefinitely, another that is wants to see changes |
| 09:08 | rhickey | of course, #' does the latter right now |
| 09:11 | chouser | Bjering_: just go to http://paste.lisp.org/new/clojure and fill out the form |
| 09:11 | Bjering_ | chouser: Thank you |
| 09:13 | lisppaste8 | Bjering_ pasted "fast-drop" at http://paste.lisp.org/display/90945 |
| 09:14 | rhickey | also on the table this weekend was putting protocol fn defs right into deftypes, and having protocols auto-generate interfaces. The desire is to hide the interfaces, which really are an implementation detail, but not have deftype + interfaces be more convient than deftype + protocols, and not have there be any code munging required to move an extend impl to an interface-based one |
| 09:14 | Bjering_ | Is there a reason (other then deemed unimportant) why this kind of optimization isn't in? |
| 09:14 | rhickey | but protocols-autogenerate-interfaces has the problems of gen-and-load-interface :( |
| 09:17 | rhickey | Bjering: special handling of particular data structures would bloat all of the standard fns, and how to decide which to special-case? When the standard fns are protocol-based, this kind of optimization will be easy, natural, and extensible |
| 09:18 | Bjering_ | rhickey: Where can I learn about "protocol-based"? |
| 09:18 | rhickey | https://www.assembla.com/wiki/show/clojure/Protocols |
| 09:19 | Bjering_ | Thank you |
| 09:19 | chouser | Bjering_: currently clojure's core fns and datatypes don't use protocols, but there are plans to move in that direction. |
| 09:20 | mikem` | Hi, I have a call to map like this: (map (fn [x] (list (keyword (first x)) (second x))) (some-seq)) -- instead of (fn ...) I tried to use #('((keyword (first %)) (second %))) but that throws java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn. what am I missing? |
| 09:22 | chouser | mikem`: #(foo) is (fn [] (foo)) not (fn [] foo) |
| 09:23 | chouser | mikem`: so you're trying to eval something like ('(a b)) |
| 09:23 | chouser | but a list is not a function, so you get an error. |
| 09:24 | mikem` | ok. so can I write a function like with #() that returns a list based on the argument it receives? |
| 09:24 | rhickey | (fn [x] (anything x)) ==> #(anything %) |
| 09:25 | chouser | mikem`: #(list (keyword (first %)) (second %)) |
| 09:26 | mikem` | ok, thanks! it's working. |
| 10:48 | djork | are there any catches to using defmulti/defmethod across namespaces or files? |
| 10:52 | chouser | not really. a defmulti can be extended by a defmethod in any file or namespace |
| 11:05 | hamza` | ~memoize |
| 11:05 | clojurebot | Gabh mo leithscéal? |
| 11:05 | hamza` | how did we get the url to source for a function? |
| 11:07 | jweiss | bah. paredit. doesn't do what i want in clojure. anyone here gone thru this already? (paredit in emacs) |
| 11:07 | chouser | ~def memoize |
| 11:07 | hamza` | ool thanks.. |
| 11:07 | hamza` | * cool |
| 11:08 | liwp | jweiss: I have |
| 11:08 | liwp | jweiss: I had problems with {} I think |
| 11:08 | jweiss | liwp: ok, for instance, i want the slurp/barf to work within square braces. how do i do that |
| 11:09 | jweiss | btw i love that they named it 'barf' |
| 11:09 | liwp | jweiss: huh? what happens at the moment? |
| 11:09 | liwp | jweiss: slurp / barf are paredit functions? |
| 11:09 | jweiss | liwp - that command does nothing if i run it withing square braces |
| 11:09 | jweiss | liwp: paredit-forward-slurp-sexp |
| 11:10 | liwp | jweiss: what happens in your case? |
| 11:11 | liwp | ~paste |
| 11:11 | clojurebot | lisppaste8, url |
| 11:11 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 11:11 | jweiss | liwp - nothing happens. if i have this (let [a b | ] c) where | is the point, and i run that command, i want it to give me (let [a b c]) . but it does nothing. |
| 11:13 | liwp | jweiss: IIRC you have to hack paredit source to understand [] and {}. Let me see if I can figure out what I changed... |
| 11:14 | jweiss | liwp: maybe just diff your paredit.el with the orig |
| 11:14 | jweiss | or create patch :) |
| 11:14 | liwp | jweiss: have a look in paredit.el:667 |
| 11:15 | liwp | jweiss: you should see a bunch of (define-paredit-pair) forms |
| 11:15 | jweiss | liwp: yeah |
| 11:15 | liwp | do you have forms for all these: () [] {} <>? |
| 11:15 | jweiss | liwp yes |
| 11:16 | liwp | jweiss: uhh, must have been something else that I changed then... |
| 11:16 | jweiss | round, square, curly, angled. |
| 11:16 | liwp | yeah |
| 11:16 | jweiss | liwp: just run diff from http://mumble.net/~campbell/emacs/paredit.el to your file |
| 11:18 | jweiss | liwp, or better just just pastebin your file and i'll use that :) |
| 11:18 | jweiss | s/just just/yet just/ |
| 11:18 | liwp | jweiss: yeah, let's try that for starters |
| 11:18 | the-kenny | I fell asleep two times in a row watching "Clojure Data Structures - Part 1". Sorry :( |
| 11:18 | jweiss | we should probably post this somewhere maybe on github for other people |
| 11:19 | liwp | jweiss: I'd love to figure out what I changed first :-) |
| 11:19 | liwp | uhh, "paste too large" |
| 11:19 | jweiss | liwp: i'll diff it for ya if you like |
| 11:19 | jweiss | liwp: maybe try the non-lisp pastebin |
| 11:20 | jweiss | http://pastebin.com/ |
| 11:21 | liwp | jweiss: apparently my paredit.el is identical to the one on the above url... |
| 11:21 | liwp | this isn't really helping :-( |
| 11:21 | jweiss | liwp. so you didn't change anything? |
| 11:21 | jweiss | that is... odd |
| 11:22 | liwp | jweiss: I distinctly remember changing something. IIRC I wasn't able to type in curly braces with the default paredit.el |
| 11:23 | jweiss | liwp, for what it's worth, i CAN slurp in the next item if it's an sexp |
| 11:23 | liwp | jweiss: ahh, I think there's some magic in clojure-mode.el for paredit |
| 11:24 | liwp | jweiss: can you pastebin some code that doesn't work for you |
| 11:24 | jweiss | liwp, ok, hm |
| 11:24 | liwp | jweiss: my clojure-mode say this: ./clojure-mode/clojure-mode.el:225: ;; Enable curly braces when paredit is enabled in clojure-mode-hook |
| 11:24 | jweiss | liwp: yeah i think i have that too |
| 11:24 | jweiss | this is on the REPL by the way |
| 11:25 | liwp | ahh, I don't have paredit enabled on slime repl |
| 11:25 | jweiss | liwp: (interpose [|] :a [1 2 3]) |
| 11:25 | jweiss | where the cursor is at the | |
| 11:25 | jweiss | i want to slurp in the :a |
| 11:26 | liwp | jweiss: I get this after a slurp: (interpose [| :a] [1 2 3]) |
| 11:26 | liwp | let me try that in the repl |
| 11:27 | jweiss | liwp: works for me in a clojure file |
| 11:27 | jweiss | not the repl tho |
| 11:27 | liwp | jweiss: yep, works there as well |
| 11:27 | liwp | jweiss: is that a slime repl or the inferior-lisp buffer? |
| 11:27 | jweiss | liwp, slime-repl |
| 11:28 | jweiss | ok i think i have a problem in my .emacs, let me see if i can fix liwp |
| 11:28 | liwp | jweiss: seems to work for me everywhere, sorry I can't help :( |
| 11:32 | mattrepl | any active contributors know if it's fine to self-assign an open ticket in assembla? |
| 11:34 | Chousuke | mattrepl: I don't think the assigment system is used for anything other than tracking who's working on the issue |
| 11:35 | mattrepl | Chousuke: thanks |
| 11:35 | liwp | mattrepl: I think so. If you think that you can fix something, go for it. The patch will go through verification before it's applied in any case. |
| 11:38 | jweiss | liwp: ok i figured it out. had to enable clojure-mode in the repl, and then enable paredit-mode in the repl. |
| 11:38 | Joreji | Hey guys, how can I dispatch a multimethod on a & rest param? (e.g.: (defmethod [:one :two LazySeq] [one two & rest] nil) ) |
| 11:38 | liwp | jweiss: good job |
| 11:38 | jweiss | liwp: i am not sure how to get this to happen in my .emacs file tho, any suggestion |
| 11:39 | liwp | jweiss: let me see what I do to get slime going... |
| 11:41 | Joreji | jweiss: (add-hook 'slime-repl-mode-hook (lambda()(progn(clojure-mode 1)(paredit-mode 1)))) ? |
| 11:41 | jweiss | Joreji: letme try that |
| 11:41 | liwp | jweiss: it seems that I don't have clojure-mode enabled in my slime-repl (I don't know why paredit seems to work for in that case). But I'm sure you can use some mode hook to enable clojure-mode |
| 11:42 | liwp | Joreji: yeah, something like that |
| 11:44 | jweiss | Joreji: didn't work, i get a strange message when i run slime: |
| 11:45 | jweiss | bah, it won't even paste because it has multibyte chars |
| 11:45 | jweiss | Joreji: error in process filter: progn: Wrong number of arguments: #[nil (and then bunch of list items) |
| 11:47 | liwp | jweiss: try it without the progn, i.e.: (add-hook 'slime-repl-mode-hook (lambda () (clojure-mode 1) (paredit-mode 1))) |
| 11:48 | Joreji | Hmm strange |
| 11:49 | jweiss | liwp: Joreji, nope, same err |
| 11:49 | Joreji | I doubt the problem lies with the top level progn |
| 11:50 | Joreji | then again, I've just activated clojure-mode inside my repl, and I must say that I don't see the use for it. |
| 11:50 | Joreji | You can't have the repl-mode and clojure-mode be activated at the same time. |
| 11:51 | jweiss | Joreji: hm, i can't get paredit to work right unless i activate clojure-mode |
| 11:51 | the-kenny | jweiss: Just add a hook to slime-repl-mode |
| 11:51 | jweiss | the-kenny: um, i'm an emacs newb, how do i do that |
| 11:52 | Joreji | jweiss: You already tried that. |
| 11:52 | the-kenny | (add-hook 'slime-mode-hook (lambda () paredit-mode +1)) |
| 11:52 | jweiss | the-kenny: i don't think that's it. clojure-mode does something to make paredit work right. |
| 11:52 | the-kenny | jweiss: It's working for me. |
| 11:53 | liwp | Joreji: yeah, you're right, enabling clojure-mode disables repl-mode |
| 11:53 | jweiss | the-kenny: in the REPL? |
| 11:53 | the-kenny | jweiss: Yes |
| 11:53 | the-kenny | paredit doesn't have anything to do with paredit |
| 11:53 | ordnungswidrig | whoohoo. chatting at the train with my g1 |
| 11:53 | the-kenny | Ew.. I mean clojure-mode |
| 11:53 | jweiss | the-kenny: try this: (interpose [|] :a) where | is the cursor, and hit C-[rightarrow] |
| 11:53 | jweiss | see if it slurps in the :a |
| 11:54 | jweiss | the-kenny: yes it does, i think. clojure-mode's code has some paredit stuff in it |
| 11:55 | the-kenny | jweiss: Hm.. you're right. It adds functionality for { |
| 11:55 | the-kenny | But that works for me in my REPL without extra changes |
| 11:55 | jweiss | the-kenny: crap |
| 11:56 | ordnungswidrig | the-kenny paredit doesn't work on { for me. |
| 11:56 | the-kenny | ordnungswidrig: Oo strange |
| 11:56 | jweiss | i can't seem to surround a list with [] in the repl |
| 11:56 | the-kenny | Maybe it works because I've opened a buffer in clojure-mode *before* I started the repl? |
| 11:57 | jweiss | nor slurp the list into empty [] |
| 11:57 | ordnungswidrig | when i insert a { no } is inserted. the rest works as expected... deleting etc. |
| 11:57 | jweiss | ordnungswidrig: yeah i don't get any curly brace love on the repl either |
| 11:58 | jweiss | the-kenny: i didn't realize it mattered where you start slime from |
| 11:58 | jweiss | it opens a new buffer for me |
| 11:58 | ordnungswidrig | jweiss: in the clojure buffer i do not get it neither |
| 11:59 | jweiss | ordnungswidrig: oh yea, me neither |
| 11:59 | liwp | you don't get {} in a clojure buffer? |
| 11:59 | jweiss | liwp: no |
| 11:59 | liwp | jweiss: I do |
| 11:59 | ordnungswidrig | liwp: no insert of { after } |
| 12:00 | liwp | If I type '{' I get '{}' and the point is in between the braces |
| 12:00 | ordnungswidrig | liwsp: tr/{}/}{/ |
| 12:00 | jweiss | liwp, doesn't work for me |
| 12:00 | ordnungswidrig | strange stuff |
| 12:00 | liwp | jweiss: I think this is exactly what clojure-mode fixes in paredit.el |
| 12:00 | jweiss | liwp: so what's going wrong then |
| 12:01 | jweiss | loaded in the wrong order or something? |
| 12:01 | ordnungswidrig | must i enable paredit by clojure-mode? |
| 12:01 | liwp | I don't think that should make any difference... |
| 12:01 | ordnungswidrig | ...let enable... |
| 12:02 | liwp | I autoload paredit first and the require clojure-mode |
| 12:02 | ordnungswidrig | hmm. i'm on debian unstable. does the clojure-mode version matter? |
| 12:02 | liwp | ordnungswidrig: possibly, I think most people get it directly from github |
| 12:03 | liwp | I gotta run, good luck! |
| 12:03 | ordnungswidrig | iirc I use clojure installed by elpa-cl-swank |
| 12:03 | ordnungswidrig | yes, will keep trying. good to know that it can work fine. |
| 12:04 | Chousuke | elpa should have a recent enough clojure-mode I think |
| 12:05 | jweiss | i installed it thru elpa as well |
| 12:05 | jweiss | but if i put (require 'clojure-mode) in my .emacs it won't start correctly |
| 12:06 | jweiss | my clojure mode is udner my ~/.emacs.d/elpa |
| 12:08 | jweiss | aha, had to move the elpa stuff to the top of .emacs |
| 12:15 | Bjering_ | What is the idiomatic way to check for the empty list? #(= '() %) |
| 12:17 | stuartsierra | Bjering_: seq or empty? |
| 12:17 | Bjering_ | thank you |
| 12:50 | jweiss | if i have a little mini function i want to call a couple times within a defn, but i don't need the mini function anywhere else, is it ok to just define it in a let? or will this waste memory each time the larger function is called? i would hope it's the same as any place you use #() |
| 12:51 | the-kenny | jweiss: Let is fine.. |
| 12:51 | the-kenny | I think there is also letfn or so |
| 12:52 | the-kenny | jweiss: You're on the JVM. The JIT does a good job in optimizing such things |
| 12:58 | stuartsierra | Each instance of (fn ...) or #(...) creates a single Java class. A new instance of that class is created each time you evaluate the fn/#() form. |
| 12:59 | hiredman | each time you compile |
| 13:00 | hiredman | (which is what eval does, but saying it happens each time you compile the form sounds less threatening) |
| 13:00 | the-kenny | ,(time (dotimes (_ 100000) (let [foo (fn [] nil)] (foo)))) |
| 13:00 | clojurebot | java.lang.IllegalArgumentException: dotimes requires a vector for its binding |
| 13:00 | the-kenny | ,(time (dotimes [_ 100000] (let [foo (fn [] nil)] (foo)))) |
| 13:00 | clojurebot | "Elapsed time: 56.972 msecs" |
| 13:00 | hiredman | the-kenny: what will only compile the function once |
| 13:01 | hiredman | that |
| 13:01 | the-kenny | hiredman: That compiles only once? Very good :) |
| 13:03 | bgs100 | ,(map .toUpperCase ["a" "b" "c"]) |
| 13:03 | clojurebot | java.lang.Exception: Unable to resolve symbol: .toUpperCase in this context |
| 13:03 | hiredman | bgs100: java methods are not first class values |
| 13:03 | bgs100 | Oh |
| 13:04 | hiredman | ,(map (fn [x] (.toUpperCase x)) ["a" "b" "c"]) |
| 13:04 | clojurebot | ("A" "B" "C") |
| 13:04 | the-kenny | ,(map (memfn toUpperCase) ["a" "b" "c"]) |
| 13:04 | clojurebot | ("A" "B" "C") |
| 13:04 | hiredman | ,(map #(.toUpperCase %) ["a" "b" "c"]) |
| 13:04 | clojurebot | ("A" "B" "C") |
| 13:19 | defn | hiredman, S. Halloway's book, eh? :) |
| 13:19 | defn | errr, nvm, didn't notice the-kenny interjected there |
| 13:20 | defn | it should be noted that memfn is less favorable |
| 13:20 | the-kenny | defn: Why is memfn not favorable? |
| 13:20 | defn | It came from when Clojure didn't have anonymous functions |
| 13:20 | defn | anonymous functions are the preferred way of using Java calls |
| 13:21 | the-kenny | ah ok.. got it. |
| 13:49 | krukow | Anyone up for an emacs/slime classpath question? |
| 13:51 | the-kenny | krukow: Just ask. meta-questions are just time consuming |
| 13:51 | krukow | sure: I can use add-classpath to dynamically a to the classpath, yes? |
| 13:51 | krukow | for example: |
| 13:52 | the-kenny | krukow: You could, but it's discouraged. |
| 13:52 | krukow | (add-classpath "file:////Users/krukow/emacs/enlive/enlive.jar") |
| 13:52 | krukow | (add-classpath "file:////Users/krukow/emacs/enlive/enlive.jar") |
| 13:52 | krukow | yes, just for a repl session |
| 13:53 | krukow | following the enlive tutorial I am adding enlive.jar and tagsoup-1.2.jar |
| 13:53 | krukow | this works fine. However adding: (add-classpath "file:////Users/krukow/emacs/enlive/src") |
| 13:54 | krukow | doesn't seem to work for me |
| 13:54 | krukow | at least it can't see a file located in the src directory |
| 13:55 | krukow | it works with java -cp<paths here> clojure.main |
| 13:56 | KirinDave | Enlive looks nice. |
| 13:56 | KirinDave | I am glad the culture of sexp->html is not deeply rooted in the clojure community. It's such a tiresome practice to dispel. |
| 13:58 | krukow | noone on the emacs classpath q? |
| 14:00 | the-kenny | krukow: Which question? |
| 14:00 | krukow | I was wondering why seems to be able to see the html file in enlive/src with java -cp<paths here> clojure.main |
| 14:01 | krukow | but not when using add-classpath file:////Users/krukow/emacs/enlive/src |
| 14:01 | krukow | inside emacs |
| 14:02 | the-kenny | Because add-classpath is buggy ;) |
| 14:02 | krukow | oh ;-) |
| 14:02 | hiredman | ~add-classpath |
| 14:02 | clojurebot | add-classpath is Fraught with Peril! |
| 14:02 | krukow | which is why it is discouraged :-) |
| 14:02 | the-kenny | hiredman: Is ~ a shortcut for ,(doc name)? |
| 14:03 | hiredman | ~ is a shortcut for clojurebot: |
| 14:03 | clojurebot | for is not used enough |
| 14:03 | hiredman | clojurebot: add-classpath |
| 14:03 | clojurebot | add-classpath is Fraught with Peril! |
| 14:04 | michaeljaaka | hi |
| 14:04 | michaeljaaka | I have question |
| 14:04 | michaeljaaka | http://gist.github.com/241284 |
| 14:05 | michaeljaaka | are these sequences whole consumed? |
| 14:05 | michaeljaaka | or only first element is evaluated |
| 14:05 | michaeljaaka | and removed as filter wants |
| 14:06 | hiredman | michaeljaaka: those sequences are not lazy, so it makes no difference |
| 14:06 | michaeljaaka | but if those were lazy? |
| 14:06 | michaeljaaka | how to check this in future |
| 14:06 | hiredman | only the first |
| 14:06 | michaeljaaka | I will have sequences from file |
| 14:06 | hiredman | check what? |
| 14:06 | michaeljaaka | is there any simple way to ensure |
| 14:07 | michaeljaaka | that sequences are not evaluated? |
| 14:07 | hiredman | "sequences from a file" is pretty vague |
| 14:09 | michaeljaaka | if the filter computes after checking only first element from each seq, then it is ok |
| 14:09 | michaeljaaka | thanks |
| 14:13 | Chousuke | michaeljaaka: note that functions that transform or consume sequences may consume more than is strictly necessary. first doesn't though, so in this case it's safe. |
| 14:14 | michaeljaaka | ok, thanks |
| 14:24 | esj | any way of seq'ing an integer ? Doing an Euler problem where I want to treat a number as seq, and turning it into a string first seems a bit wasteful. |
| 14:25 | Chousuke | you can devise another method of extracting the digits from an integer I suppose. |
| 14:26 | rhickey | add-classpath is not buggy, it just can't make the added classpath visible to all classloaders, thus, not that useful and to be avoided |
| 14:27 | krukow | ok, interesting. can you explain why adding a jar seems to work while adding a directory does not? |
| 14:27 | esj | Chousuke: sure I could do it numerically or via the string, but seems roundabout |
| 14:29 | rhickey | krukow: don't use add-classpath, I'm going to remove it at some point. Use regular classpaths |
| 14:30 | rhickey | I don't see a reason why jars and dirs would be different if the dir has the same structure |
| 14:31 | krukow | ok, but it's still a nice feature to dynamically extend a repl session |
| 14:31 | krukow | except that it doesnt work of course :-) |
| 14:32 | rhickey | I wish there was a standard way to extend the root classpath, but there isn't |
| 14:33 | rhickey | if you are using JDK 6 you can add a wildcard dir to your classpath, then dynamically drop jars there |
| 14:34 | krukow | cool, didn't know that |
| 14:34 | rhickey | my classpath ends with :/Users/rich/dev/ext/* and everything I put there is visible |
| 14:35 | the-kenny | Does this really work? I remember problems with that |
| 14:35 | rhickey | it's quite painless |
| 14:35 | krukow | I think I'll add something similar to my swank-clojure-extra-classpaths |
| 14:36 | krukow | thanks |
| 14:36 | rhickey | the-kenny: java.ext.dirs can be tricky, but the wildcard isn't afaict |
| 14:37 | chouser | With some effort I've gotten java.ext.dirs to work pretty consistently. I should probably try the wildcard instead. |
| 14:37 | the-kenny | hm.. so should "java -cp classes/*:lib/*:src/* my.class" work? |
| 14:37 | chouser | the-kenny: probably "classes:lib/*:src" if you've got a "normal" layout |
| 14:38 | the-kenny | hm... does the order matter? |
| 14:38 | chouser | the-kenny: if there are two classes with the same name in different places, yes. |
| 14:39 | rhickey | wildcards are for dirs containing jars only |
| 14:39 | chouser | the-kenny: but I was pointing out that 'classes' and 'src' are usually each the root of a classpath, with dirs named like 'com' and 'org' in them. |
| 14:39 | chouser | while 'lib' is usually a directory full of .jar files. |
| 14:39 | the-kenny | chouser: Yes, that's my layout. |
| 14:40 | rhickey | hrm, claspath wildcards are not dynamic, guess I never really needed that |
| 14:41 | rhickey | at least they keep you from ever-expanding classpath args |
| 14:41 | rhickey | http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html |
| 14:41 | the-kenny | I just started using `echo lib/*.jar|sed -e 's/ /:/g'` some minutes ago |
| 14:41 | krukow | ok |
| 14:42 | jweiss | can someone point me to an example of using callbacks/listeners in clojure? I am trying to implement something like TestNG in clojure. testng is java, and to add a listener to it you implement one of their interfaces, and it calls your listener when certain events happen. |
| 14:43 | the-kenny | ,(doc proxy) |
| 14:43 | clojurebot | "([class-and-interfaces args & fs]); class-and-interfaces - a vector of class names args - a (possibly empty) vector of arguments to the superclass constructor. f => (name [params*] body) or (name ([params*] body) ([params+] body) ...) Expands to code which creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns. A single class, if provided, must be first. If not provid |
| 14:44 | chouser | jweiss: 'proxy' is the best way to implement an interface |
| 14:44 | chouser | jweiss: there are examples in contrib and you can probably google for more. |
| 14:44 | jweiss | ok |
| 14:44 | hiredman | http://clojure.org/jvm_hosted has an actionlistener example |
| 14:45 | jweiss | proxy is not what i'm looking for though, i don't need to interact with testng, just do a clojure-only version of it |
| 14:45 | chouser | oh! |
| 14:45 | chouser | then you just write a high-order function. |
| 14:45 | chouser | 'map', for example, essentially calls the "callback" you give it, right? |
| 14:46 | jweiss | chouser: yeah i know how to call a single function, but how to group them together like in java's interface? |
| 14:46 | jweiss | i suppose i could just make a map |
| 14:46 | jweiss | of keywords to fn's |
| 14:47 | chouser | jweiss: ah. In the "new" branch, defprotocol. but yes, a map would be perfectly acceptible. |
| 14:47 | chouser | actually, depending on your use cases a map might be best even if defprotocol were available. |
| 14:47 | jweiss | i don't know if i'm ready to mess up my new emacs dev environment with the new branch :) i'll try maps |
| 14:48 | the-kenny | jweiss: "new" is very stable in my opinion.. never had a crash |
| 14:49 | jweiss | the-kenny: yeah i'm more worried about getting it working with swank-clojure |
| 14:49 | the-kenny | jweiss: Works without any problems here. |
| 14:50 | jweiss | hm. so i just h ave to replace the jar i build in the swank-clojure emacs.d dir? |
| 14:50 | the-kenny | "git co new; ant clean; ant build" and the same for clojure-contrib was enough :) |
| 14:50 | the-kenny | jweiss: Hm.. Maybe you have to recompile the jar. |
| 14:50 | jweiss | the-kenny: swank-clojure jar? |
| 14:50 | the-kenny | Yes |
| 14:51 | jweiss | k, i'll give it a shot in a bit |
| 14:51 | krukow | krukow:~/emacs/clojure/clojure$ git checkout new |
| 14:51 | krukow | error: pathspec 'new' did not match any file(s) known to git. |
| 14:51 | the-kenny | Yeah, you have to add the remote branch.. wait |
| 14:54 | jweiss | git checkout --track -b new origin/new |
| 14:54 | jweiss | ? |
| 14:54 | the-kenny | yeah, something like this |
| 14:56 | krukow | great :-) really gotta read up on git soon... |
| 15:01 | kzar | yea me too krukow, submitted a patch the other day and it was pretty easy but I want to learn a lot more about it |
| 15:03 | krukow | same here, I read a bit of theory about it but I don't know many actual commands besides git clone :-) |
| 15:04 | the-kenny | git is really cool :) |
| 15:04 | chouser | http://www.newartisans.com/2008/04/git-from-the-bottom-up.html |
| 15:04 | krukow | thx - reading it now |
| 15:04 | chouser | that helped me a bit. I should probably read it again, actually. |
| 15:04 | kzar | oo thanks I'll read that later too |
| 15:08 | kzar | Is this kind of code OK or is it bad form to redefine stuff like this with let? (let [example "hello", example (take 3 example)] example) |
| 15:08 | stuartsierra | kzar: that's ok |
| 15:09 | stuartsierra | although it may be more readable to use different names |
| 15:09 | chouser | kzar: but it's good you're asking. :-) |
| 15:09 | krukow | I would have guessed that would result in an error, but it runs fine |
| 15:09 | kzar | Heh cool, it makes more sense in my actual code but I wanted to make sure it's not a taboo or something heh |
| 15:10 | krukow | why is that ok - I would consider it bad style |
| 15:10 | hiredman | let performs sequential binds so its like (let [example 1] (let [example 2] example)) |
| 15:10 | krukow | ah |
| 15:10 | hiredman | generally it's kind of icky |
| 15:10 | hiredman | but I do it all the time :P |
| 15:10 | chouser | it's no worse than using the same local variable to mean a couple different things in any other language. |
| 15:10 | rhickey | me too |
| 15:11 | krukow | can someone give a compelling example? |
| 15:11 | hiredman | usually it means I mean incrementally mucking with a function |
| 15:11 | hiredman | I have been |
| 15:11 | fogus_ | krukow: I do it when I coerce |
| 15:12 | chouser | mm, yes (fn [x] (let [x (int x)] ...)) |
| 15:12 | hiredman | http://github.com/hiredman/clojurebot/blob/master/hiredman/clojurebot/code_lookup.clj#L66 |
| 15:12 | hiredman | started out as google being the google url |
| 15:13 | hiredman | then clojure moved from google svn to github |
| 15:13 | kzar | krukow: (I'm having a go at changing my tetris to be functional like a few articles I read. So I have signals being passed and I'm setting the signals to be the result of routing the signals, then setting the signals to be the result of routing the input signals. So I could call them signals, signals after processing, input-signals, input-singals-after-processing ... but I rather just keep 'changing' something called |
| 15:13 | kzar | signals) |
| 15:13 | hiredman | so I wrote a transform to turn the google svn url into a github url |
| 15:13 | chouser | I guess I'd say it's a matter of taste. If you're *realy* rather say (fn [x-obj] (let [x (int xobj)] ...), then go ahead. But it hardly seems clearer. |
| 15:14 | hiredman | code_lookup is icky anyway |
| 15:14 | chouser | nearly all code that actually does anything seems to be icky in the end |
| 15:14 | krukow | LOL |
| 15:15 | kzar | chouser: At least all the code I've received money for has been |
| 15:15 | krukow | can I quote that? ;-) |
| 15:15 | chouser | that's one nice thing about projecteuler type problems. You can write tidy little solutions that you can feel good about. |
| 15:15 | chouser | krukow: :-P sure |
| 15:15 | hiredman | sometimes it has a brutalist beauty |
| 15:16 | chouser | hiredman: that's true. the beauty of a good hack. |
| 15:19 | esj | chouser: you don't mean to tell me that once I've learn't clojure through PE my mercenary coding won't suddenly be beautiful. *crestfallen* |
| 15:20 | hiredman | http://gist.github.com/184831 <-- I still like this |
| 15:21 | hiredman | ~ticket search Keyword |
| 15:21 | clojurebot | ("#154: (keyword \"a/b\") => ns nil, name a/b; should be ns a, name b" "#154: (keyword \"a/b\") => ns nil, name a/b; should be ns a, name b" "#154: (keyword \"a/b\") => ns nil, name a/b; should be ns a, name b" "#64: GC Issue 61: \t Make Clojure datatype Java Serializable" "#174: Make c.l.Keyword Serializable" "#6: GC Issue 1:\t:validator as keyword arg for ref/atom/agent" "#174: Make c.l.Keyword Serializable" "#200: Exte |
| 15:21 | stuartsierra | yowza |
| 15:22 | chouser | hiredman: I'm pretty sure I wrote zip-filter exactly so I wouldn't have to write code like that. :-P |
| 15:23 | hiredman | ~ticket #64 |
| 15:23 | clojurebot | {:url http://tinyurl.com/kv5v3t, :summary "GC Issue 61: Make Clojure datatype Java Serializable", :status :new, :priority :low, :created-on "2009-06-17T19:38:52+00:00"} |
| 15:26 | krukow | people don't like me at work anymore because of clojure... |
| 15:27 | tmountain | krukow: why is that? |
| 15:27 | jweiss | i'm guessing because clojure is greek to them |
| 15:27 | krukow | because I've started programming my Java more functionally, I think |
| 15:27 | zaphar_ps | krukow: yeah we want to know |
| 15:27 | mauritslamers | question: is it possible to create arrays of primitives inside clojure for use in calling Java functions? |
| 15:28 | chouser | ,(into-array Integer/type [1 2 3 4]) |
| 15:28 | clojurebot | java.lang.Exception: Unable to find static field: type in class java.lang.Integer |
| 15:28 | chouser | ,(into-array Integer/TYPE [1 2 3 4]) |
| 15:28 | clojurebot | #<int[] [I@1738d88> |
| 15:28 | tmountain | krukow: when every variable in your class begins with final, you know you've drank the koolaid ;-) |
| 15:28 | krukow | it does, but it's not just that |
| 15:28 | jweiss | ick, can't imagine trying to force java's square peg into that round hole |
| 15:29 | stuartsierra | ,(int-array [1 2 3 4]) |
| 15:29 | clojurebot | #<int[] [I@13bb93a> |
| 15:29 | mauritslamers | chouser: when I call my function with that, it returns a ClassCastException |
| 15:29 | chouser | stuartsierra: so much better! |
| 15:29 | stuartsierra | but I think that creates an array, not convert |
| 15:29 | stuartsierra | ,(doc int-array) |
| 15:29 | clojurebot | "([size-or-seq] [size init-val-or-seq]); Creates an array of ints" |
| 15:29 | mauritslamers | stuartsierra: checking out :) |
| 15:29 | stuartsierra | nope, it converts to an array too |
| 15:32 | mauritslamers | stuartsierra: it seems to return the correct array, but when I call my function with the result, it still throws an ClassCastException |
| 15:32 | krukow | anyway, I find myself mimicking clojure constructs in the code |
| 15:32 | chouser | mauritslamers: are you sure the method you're calling wants an array of primitive int? |
| 15:32 | mauritslamers | public byte[] convertDoubleArrayToByte(double[] incoming){ |
| 15:32 | hiredman | int[] is not double[] |
| 15:32 | stuartsierra | That's a double array you want, then. |
| 15:32 | jweiss | hehe |
| 15:33 | mauritslamers | of course :) |
| 15:33 | mauritslamers | (def heletoonsarray (double-array heletoonsbuffer)) |
| 15:33 | mauritslamers | in which heletoonsbuffer is a list of floating point values |
| 15:33 | krukow | it's really quite facinating... I've never tried this with a language before |
| 15:33 | mauritslamers | doubles to be exact |
| 15:33 | chouser | krukow: using clojure idioms in Java? |
| 15:34 | mauritslamers | calling the function with: (.convertDoubleArrayToByte dsp heletoonsbuffer) |
| 15:35 | chouser | mauritslamers: you're saying that's what you've been doing and you still get the exception? Can you paste the whole stack trace somewhere? |
| 15:35 | mauritslamers | how do I get the whole stack trace? |
| 15:35 | mauritslamers | the only message I get is: user=> (.convertDoubleArrayToByte dsp heletoonsbuffer) |
| 15:35 | mauritslamers | java.lang.ClassCastException (NO_SOURCE_FILE:0) |
| 15:36 | stuartsierra | (.printStackTrace *e) |
| 15:36 | chouser | (.printStackTrace *e) if you're at a plain terminal repl |
| 15:37 | mauritslamers | the stack trace only contains clojure stuff and sun.reflect et |
| 15:37 | mauritslamers | *Etc |
| 15:37 | chouser | you can often get a better message too if you type-hint the first arg. (.methodOfFoo #^Foo dsp arg2 etc) |
| 15:37 | mauritslamers | chouser: http://gist.github.com/241351 |
| 15:38 | rhickey | urk, looks like pprint rebinds core fns |
| 15:38 | hiredman | :( |
| 15:38 | chouser | really!? which ones? |
| 15:38 | chouser | pprint is rather ambitious |
| 15:38 | hiredman | mauritslamers: can you pastebin your code? |
| 15:39 | mauritslamers | hiredman: which code exactly? |
| 15:39 | rhickey | looks like pr |
| 15:39 | mauritslamers | it is quite a lot :) |
| 15:39 | krukow | chouser: at least thinking much more in terms of identities and values |
| 15:39 | hiredman | mauritslamers: the code that produces the exception |
| 15:39 | hiredman | like a small test case |
| 15:39 | chouser | mauritslamers: did you try the type hint? |
| 15:40 | mauritslamers | chouser: when I do: (.convertDoubleArrayToByte #^ml.mesic.dsp.DSP dsp heletoonsbuffer) |
| 15:40 | mauritslamers | java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to [D (NO_SOURCE_FILE:0) |
| 15:40 | chouser | ah, now we're getting somewhere. |
| 15:40 | hiredman | mauritslamers: you are running map or something over the array at some point |
| 15:41 | hiredman | so it is no longer an array |
| 15:41 | mauritslamers | it shouldn't... |
| 15:41 | mauritslamers | moment. checking... |
| 15:41 | mauritslamers | ah... oops ... |
| 15:41 | chouser | :-) |
| 15:41 | chouser | the best words in a debugging session |
| 15:41 | mauritslamers | *shame* |
| 15:41 | chouser | naw, that's what debugging is all about |
| 15:42 | mauritslamers | it ain't gonna work if I keep feeding it with the wrong argument ... :\ |
| 15:42 | mauritslamers | anyway: thanks a lot :D |
| 15:43 | chouser | I wonder why the error message is different for dynamic method calls |
| 15:43 | krukow | if the bug isn't there it's because it is somewhere else |
| 15:43 | hiredman | http://hsivonen.iki.fi/rdf-competition/ |
| 15:44 | rhickey | so, that's a good example - some lib like pprint wants to redefine something like pr for everyone. Leaving all those hooks open means slowing everyone else down... |
| 15:45 | rhickey | aargh - (deftest dotrace-on-core ...) |
| 15:53 | mauritslamers | interesting... my function written in java is much much MUCH faster than the one in clojure... |
| 15:55 | mauritslamers | For those interested: http://gist.github.com/241366 |
| 15:55 | mauritslamers | the clojure code takes at least half a second |
| 15:57 | KirinDave | The JVM is pretty notoriously bad at byte-level manipulation. |
| 15:57 | mauritslamers | but why is the java code faster than the clojure code :) |
| 15:58 | stuartsierra | mauritslamers: The difference in this case comes from the overhead of Clojure's persistent data structures. |
| 15:58 | stuartsierra | Every call to your float-to-two-bytes creates a persistent vector as an intermediate value. |
| 15:58 | mauritslamers | so for this type of conversions it is better to write stuff in java |
| 15:58 | mauritslamers | and create a clojure wrapper |
| 15:59 | rhickey | hrm, mocking is in obvious conflict with direct linking... |
| 15:59 | stuartsierra | Also, Clojure's bit-shifting operations are not well-optimized. |
| 15:59 | stuartsierra | mauritslamers: you would get closer to Java performance by writing a single function using loop/recur and Java arrays instead of reduce/mapcat |
| 16:00 | stuartsierra | But you will probably not be able to match Java performance on bit twiddling (yet). |
| 16:00 | rhickey | only failures in clojure and contrib with direct linking are now in the mocking stuff |
| 16:00 | mauritslamers | stuartsierra: which is not really a problem, since I have to do other java stuff anyway :) |
| 16:01 | mauritslamers | I need the bit twiddling to be as fast as possible |
| 16:01 | mauritslamers | thanks! |
| 16:01 | stuartsierra | rhickey: what's this mocking/linking? |
| 16:01 | mauritslamers | tty all later! |
| 16:02 | KirinDave | It'd be cool if Clojure had optimized binary pattern matching like erlang. :) |
| 16:02 | rhickey | stuartsierra: I now can do direct-linking of call sites. For code you are not going to be changing at runtime, nor rebinding (e.g. core, etc) you can get much faster perf by limiting dynamism and directly hooking up the callee. The mocking is just the contrib library, the only thing left in contrib that doesn't work with direct linking |
| 16:03 | stuartsierra | I see. |
| 16:03 | stuartsierra | I like. |
| 16:03 | wtetzner_ | how do i use the clojure printer from java? |
| 16:03 | wtetzner_ | i found the reader in LispReader.class |
| 16:03 | wtetzner_ | but i can't find the printer |
| 16:04 | stuartsierra | wtetzner_: You can invoke the clojure.core/print function directly. |
| 16:04 | stuartsierra | RT.var("clojure.core", "print").invoke(...) |
| 16:04 | wtetzner_ | oh |
| 16:04 | wtetzner_ | cool |
| 16:04 | wtetzner_ | thanks |
| 16:04 | hiredman | prn |
| 16:04 | hiredman | I imagine you'll want prn |
| 16:04 | wtetzner_ | so you can call any clojure functions that way? |
| 16:05 | rhickey | stuartsierra: fyi, test/report was another problem area |
| 16:05 | wtetzner_ | hiredman: yeah, actually prn-str |
| 16:05 | stuartsierra | Oh, yeah. |
| 16:05 | rhickey | but now test/report and pr are marked {:dynamic true} |
| 16:05 | krukow | rhickey: why are these problematic? |
| 16:05 | rhickey | so test and pprint work |
| 16:05 | stuartsierra | rhickey: Ok. |
| 16:05 | rhickey | krukow: they are being dynamically rebound by design |
| 16:06 | krukow | ok so just marking them is fine |
| 16:06 | stuartsierra | rhickey: So does this mean that any var which is dynamically rebound must be declared {:dynamic true}? |
| 16:06 | rhickey | krukow: I've been testing all of clojure and contrib with direct linking |
| 16:06 | KirinDave | Or can we enable an optimization by saying {:dynamic false} |
| 16:06 | krukow | what kind of speed up are you expecting from direct linking? |
| 16:06 | rhickey | stuartsierra: just vars that are invoked, so not your normal *foo* stuff |
| 16:07 | stuartsierra | rhickey: Ok, that's good. |
| 16:07 | stuartsierra | Functions, in other words. |
| 16:07 | rhickey | functions |
| 16:07 | rhickey | right |
| 16:07 | chouser | you get an error? when? |
| 16:08 | rhickey | krukow: it can be quite substantial, depending on what the function does, but overall you can see 20% easily, some specific calls might be several times faster |
| 16:09 | rhickey | chouser: what error? |
| 16:10 | chouser | if you try to dynamically bind a static fn |
| 16:10 | chouser | do you get an error or just the root binding behavior? |
| 16:10 | rhickey | chouser: no error, just won't be dynamic |
| 16:10 | chouser | hm |
| 16:10 | KirinDave | So you'd try to rebind it and it'd fail for some calls? |
| 16:11 | rhickey | as I was saying before, direct linking is a property of the caller, not the callee |
| 16:11 | rhickey | one caller could directly link and another not |
| 16:11 | KirinDave | Ah |
| 16:11 | stuartsierra | even better |
| 16:11 | stuartsierra | So which is declared {:dynamic true}? The caller or the callee? |
| 16:12 | krukow | I guess that could give some strange behaviour with binding core fns |
| 16:12 | rhickey | a directly linked caller will see the original value forever (or until they themselves are re-evaluated) |
| 16:12 | rhickey | krukow: that's the question - who's binding core fns and why? |
| 16:12 | rhickey | there was only one case in all of contrib - pprint |
| 16:13 | rhickey | none in core |
| 16:13 | rhickey | trivial functions can be 10x faster with direct linking |
| 16:14 | rhickey | so, it's important, to me at least |
| 16:14 | krukow | I was just thinking of an example on the web: |
| 16:14 | stuartsierra | I assume direct linking allows the JVM to inline the function as well? |
| 16:14 | rhickey | but the general question is, how do we want to talk about this, at what granularity, with what defaults |
| 16:14 | rhickey | stuartsierra: yep |
| 16:14 | krukow | cant find it right now, but I think it was about using binding to create som AOP like feature |
| 16:15 | rhickey | krukow: one option could be - I never want direct linking |
| 16:16 | stuartsierra | rhickey: I feel I should mention that it feels like features keep getting added, pushing a 1.1 release farther into the future. |
| 16:16 | rhickey | that is the simplest story for ad hoc whatever |
| 16:16 | stuartsierra | I mean, they're cool features, no question, but have you thought about where you're going to stop? |
| 16:16 | hiredman | stuartsierra: 2.0 :P |
| 16:17 | krukow | actually it sounds very cool to me - just immediately trying find an example it would break :-) |
| 16:17 | rhickey | stuartsierra: none of this is going into 1.1. I would love it if someone would come up with a punch list for calling what we've got 1.1, producing some release candidates etc. I've added a new field in the tickets - bug/enhancement - I'd like to see all tickets categorized |
| 16:17 | stuartsierra | Would that include deftype/defprotocol? |
| 16:18 | rhickey | stuartsierra: nothing from new is going in 1.1, so no deftype/defprotocol |
| 16:18 | spuz | In Clojure, if a variable is not actually variable... then what do we call it? |
| 16:18 | hiredman | spuz: a binding |
| 16:18 | rhickey | It came up the other day that chunked seqs might be controversial - we need the broader community trying master |
| 16:18 | krukow | rhickey: when do you expect deftype/protocol? |
| 16:19 | spuz | hiredman: funny how I could read a whole book about clojure and not get that... |
| 16:19 | stuartsierra | If it's any help, I've been using master for months without any problem. |
| 16:19 | rhickey | krukow: soon after 1.1, at least with 1.1 out it can move into master and get more hands on it. But it is still a work in progress |
| 16:20 | krukow | really looking forward to it, btw :-) |
| 16:20 | rhickey | stuartsierra: right, and yet, I think hiredman and AWizzArd were both troubled by it the other night, as it can change full lazy semantics. And we don't have a seq1 to force dribbling |
| 16:21 | hiredman | spuz: I was just looking over the chapter on lexical bindings in essentials of programming languages |
| 16:21 | rhickey | I'd love to know how the community breaks down as far as which release/branch they use |
| 16:21 | stuartsierra | rhickey: Ah, ok, hadn't considered that. |
| 16:22 | rhickey | so, 1.1. is a matter of - no new enhancements, tidy up anything unfinished, produce release candidates and get broader feedback, cut a release when ready |
| 16:23 | rhickey | the new branch work will follow 1.1 |
| 16:23 | krukow | diff 1.1 1.0? |
| 16:23 | rhickey | but I am fully (like 10 hrs a day) occupied with the new branch, so people that want 1.1. have to step up and volunteer |
| 16:24 | krukow | I want the new branch :-) |
| 16:24 | rhickey | krukow: right, but we want releases of things that are relatively stable, as is master right now |
| 16:24 | krukow | I'm not sure if it is my object oriented mind kicking in but I am missing deftype |
| 16:25 | krukow | sure - I value stability highly |
| 16:25 | stuartsierra | rhickey: I'm volunteering. :) |
| 16:25 | rhickey | but yes, deftype/protocols fill an important gap |
| 16:25 | rhickey | stuartsierra: great! |
| 16:26 | stuartsierra | I'll start by making a which-release-are-you-using survey |
| 16:26 | hiredman | clojurebot: stuartsierra is volunteering |
| 16:26 | clojurebot | c'est bon! |
| 16:27 | stuartsierra | rhickey: What do you want to know, besides http://spreadsheets.google.com/viewform?formkey=dFJSd1p4YXh0d0VxV0xjdk42MTU5RkE6MA |
| 16:28 | chouser | what's a SNAPSHOT release? |
| 16:28 | spuz | is there a command to reset the state of the REPL? |
| 16:28 | stuartsierra | The maven repositories take snapshots of master roughly every 24 hours |
| 16:28 | rhickey | is that from hudson? |
| 16:28 | chouser | is that just some version of master we've chose ourselves, vs. "github master" being continuouly upgrading? |
| 16:28 | chouser | ah |
| 16:29 | the-kenny | What are chunked sequences? :) |
| 16:29 | stuartsierra | chouser: I was thinking keeping it up to date regularly. |
| 16:30 | twbray | Wondering why if-let only lets you do one binding... I have two or three bindings to do and some forms to run, but only if the first binding is non-nil. Why would that be wrong? |
| 16:31 | chouser | stuartsierra: ok. I recently switch our work code from 1.0 to some a recent 1.1-snap, but probably won't change it again until 1.1.0. wasn't sure which answer I'd pick for that. |
| 16:31 | rhickey | stuartsierra: question 1 is good enough for me. Maybe asking people if they know how to get from github or maven. But if we do release candidates we can make that just a download for everyone |
| 16:32 | chouser | twbray: some people that ask for mutliple if-let bindings only want the "true" case if all the bindings are true. you're asking for something different? |
| 16:32 | rhickey | twbray: if if-let did multiple bindings, it would be unclear as to which would be involved in the conditional |
| 16:32 | KirinDave | twbray: It's probably just historical. This is why we have macros and -contrib. |
| 16:33 | twbray | Hmm... I read the docs and assumed it would key off the first binding. |
| 16:33 | spuz | yes, what are chunked sequences? :) |
| 16:33 | twbray | chouser: Yep... I can see the ambiguity. |
| 16:34 | krukow | spuz http://blip.tv/file/2301367 |
| 16:34 | chouser | http://www.assembla.com/wiki/show/clojure/Chunked_Seqs |
| 16:34 | chouser | hm, that's pretty thin |
| 16:34 | twbray | So I'm left with (let [x (some complex fun)] (if x (let [bunch of other bindings]. Not terrible I guess. |
| 16:34 | stuartsierra | ok, changed the questions a bit: http://spreadsheets.google.com/viewform?formkey=dFJSd1p4YXh0d0VxV0xjdk42MTU5RkE6MA |
| 16:35 | hiredman | twbray: you can still use if-let |
| 16:36 | spuz | krukow: thanks, it says "Rich Hickey, inventor of Clojure, talks about the new "chunked seq" architecture which allows first-order Clojure functions such as map to as fast (or faster) than hand-coded loops." why would that be a bad thing? Why ask the question in the questionnaire? |
| 16:36 | KirinDave | twbray: Why not try and get a macro into contrib? I'm sure people would use it. It sounds useful. |
| 16:36 | spuz | (obviously, I still need to watch the video, but just incase it's not obvious...) |
| 16:36 | rhickey | stuartsierra: I recently made another milestone - Approved backlog - into which we can move things from Next Release that aren't going in, in order to use Next Release as a punch list |
| 16:36 | stuartsierra | ok |
| 16:37 | hiredman | spuz: it can alter the lazy nature of seqs |
| 16:37 | spuz | ah I see |
| 16:37 | hiredman | because chunked seqs are processed in 32 item chunks |
| 16:37 | rhickey | http://clojure.googlegroups.com/web/chunks.pdf |
| 16:38 | twbray | hiredman: Right... (if-let [x (some complex func)] (let [ other bindings] ... |
| 16:38 | chouser | twbray: that's not an uncommon pattern in my code, fwiw. |
| 16:41 | falkor2 | hi, why is there clojure.lang.PersistentList$1 ? My question regards the $1, I seem to see it inside macros... |
| 16:41 | chouser | falkor2: that's normal Java naming for a anonymous inner class |
| 16:42 | twbray | chouser: Thanks, that's the kind of thing a n00b likes to hear. |
| 16:42 | falkor2 | yep, I know, but sometimes it is not therre |
| 16:42 | rhickey | looks like there are a dozen or so patches waiting in backlog, but they should probably wait until after 1.1 unless trivial |
| 16:43 | falkor2 | (println (type '(1)) -gives persistentlist (no $1) |
| 16:44 | hiredman | falkor2: some annonymous subtype of plist |
| 16:44 | falkor2 | `(println (type ~lst)) [Note in macro], gets $1 |
| 16:44 | hiredman | implementation detail |
| 16:44 | hiredman | ignore it |
| 16:44 | chouser | ,(class clojure.lang.PersistentList/creator) |
| 16:44 | clojurebot | clojure.lang.PersistentList$1 |
| 16:45 | falkor2 | The problem is that I am doing type inspection (probably not in the best way...) |
| 16:45 | chouser | PersistentList$1 is a function, not a list |
| 16:45 | hiredman | falkor2: don't |
| 16:46 | chouser | falkor2: lst may not be what you think it is, or may be being misused. |
| 16:46 | stuartsierra | rhickey: any more questions for the survey, before I post it to the group? |
| 16:46 | falkor2 | I am doing macros (newbie) and I think I am being bitten by some confusion still lingering in my head... |
| 16:47 | rhickey | stuartsierra: the whole 'reliability' part of it seems a little weird |
| 16:47 | stuartsierra | What do you want to know? |
| 16:47 | stuartsierra | I thought that was the point. |
| 16:47 | chouser | falkor2: seems plausible. maybe paste somewhere your macro that's includes the `(println (type ~lst)) ? |
| 16:48 | rhickey | I think we get the reliability reports on the group etc, I really want to know if they are using master yet |
| 16:48 | stuartsierra | ok, I'll drop that question. |
| 16:48 | rhickey | i.e. are we close to 1.1. from a community feedback perspective, or have most of them never tried the master code, and we'll be seeing a lot of new reports once we do a release candidate |
| 16:48 | stuartsierra | And the "Describe any reliability problems..." question. |
| 16:49 | stuartsierra | ok, just 3 questions now |
| 16:49 | rhickey | it used to be, most people were on trunk, so when the bug reports eased, we were good to go. Now, I'm unsure what the ratios are, and with more, and more conservative, users, we might need a decent beta period |
| 16:50 | KirinDave | So where is the right place to get the most current stable clojure? |
| 16:50 | KirinDave | The github? |
| 16:50 | stuartsierra | KirinDave: define stable :) |
| 16:50 | stuartsierra | There is one official release, 1.0. |
| 16:50 | KirinDave | stuartsierra: Well, usable. |
| 16:50 | KirinDave | yes, but no one seems to use that. :D |
| 16:50 | KirinDave | They want the new features. |
| 16:50 | chouser | well the 'master' features at least, if not the 'new' ones. |
| 16:51 | falkor2 | chouser: I think I have to do a bit more self-investigation before I pester you guys ;) |
| 16:51 | stuartsierra | All the major new features (reify, deftype, defprotocol) are on the "new" branch. |
| 16:51 | stuartsierra | The "master" branch seems to be quite stable. |
| 16:51 | KirinDave | So are people going builds from http://github.com/richhickey/clojure:master? |
| 16:51 | chouser | falkor2: ok, that's up to you. Don't get too frustrated though before asking. |
| 16:51 | stuartsierra | But "master" doesn't have any whiz-bang new features. |
| 16:51 | chouser | falkor2: and if it's about a macro, we have a form to help ask the question well. |
| 16:52 | chouser | ~macro help |
| 16:52 | clojurebot | macro help is http://clojure-log.n01se.net/macro.html |
| 16:52 | rhickey | it's all usable, that's always been the Clojure way. some of the very latest features are works in progress, but you won't have existting code that a) uses them, or b) will be broken by them |
| 16:52 | KirinDave | Cool, so it's relatively safe to run off new then? |
| 16:52 | rhickey | if you use the latest features, you are helping me define them with your feedback |
| 16:52 | chouser | stuartsierra: that's just an age thing. master has futures, chunked seqs -- good stuff! |
| 16:52 | falkor2 | I have to say, coming from Prolog, that evaluation in lisp is made a bit complex and convuluted |
| 16:52 | stuartsierra | chouser: Oh, I thought futures were in 1.0 |
| 16:53 | rhickey | KirinDave: master is the best choice unless you are really interested in the new features and testing |
| 16:53 | chouser | stuartsierra: hm, I may be thinking of promises |
| 16:53 | stuartsierra | chouser: promises, promises |
| 16:53 | chouser | exactly |
| 16:53 | rhickey | there are a ton of new things in master, we're all just used to them already |
| 16:53 | chouser | exactly |
| 16:54 | stuartsierra | We're blase' |
| 16:54 | rhickey | nice |
| 16:54 | chouser | anyone want to bet on survey results? |
| 16:54 | stuartsierra | ok, ready to go? http://spreadsheets.google.com/viewform?formkey=dFJSd1p4YXh0d0VxV0xjdk42MTU5RkE6MA |
| 16:54 | chouser | I say <20% of responders on 1.0 |
| 16:54 | rhickey | stuartsierra: sure - we'll know more than we do now! Thanks |
| 16:54 | stuartsierra | no problem |
| 16:55 | rhickey | stuartsierra: wanna stick a logo on it? |
| 16:55 | hiredman | you should stick a picture of a wallaby on it |
| 16:55 | chouser | if you like it you should stick a ring on it |
| 16:55 | rhickey | hiredman: because? |
| 16:56 | chouser | um. nevermind. |
| 16:56 | hiredman | they're cute |
| 16:56 | stuartsierra | rhickey: don't know how to do that on GDocs. |
| 16:56 | hiredman | chouser: ha ha |
| 16:56 | rhickey | stuartsierra: ok |
| 16:56 | stuartsierra | and I already emailed it to the lists |
| 16:57 | chouser | the url doesn't change when you edit the doc |
| 16:57 | chouser | oh, inlined. nevermind |
| 16:58 | rhickey | it's fine |
| 16:58 | falkor2 | There are other ways to get clojure, BTW: I mostly use whatever comes in enclojure.... |
| 16:58 | technomancy | like leiningen. =) |
| 16:59 | chouser | stuartsierra: care to share the results url? |
| 16:59 | chouser | so that I can obsessively reload it? |
| 17:00 | stuartsierra | technomancy: ok, added "IDE/Package manager" as an option. |
| 17:00 | stuartsierra | chouser: yes, hang on |
| 17:00 | chouser | while you're fixing things, typo on "the help me" |
| 17:01 | stuartsierra | chouser: thanks, fixed |
| 17:02 | rhickey | looks like 2 how do you get questions now |
| 17:03 | stuartsierra | yes |
| 17:03 | stuartsierra | from the early responses |
| 17:03 | stuartsierra | oops, ok, fixed |
| 17:06 | stuartsierra | Results link: http://spreadsheets.google.com/ccc?key=0AuEMlyQZQkUMdFJSd1p4YXh0d0VxV0xjdk42MTU5RkE&hl=en |
| 17:06 | chouser | stuartsierra: thanks |
| 17:07 | stuartsierra | "Form-> Show summary" gives you pie charts. |
| 17:07 | zaphar_ps | one question is shown twice |
| 17:07 | stuartsierra | zaphar_ps: fixed now |
| 17:07 | stuartsierra | Oh, in the results? yes, that's a leftover |
| 17:07 | zaphar_ps | ahh ok |
| 17:08 | zaphar_ps | github is obviously the most frequent method to get clojure shown so far |
| 17:09 | chouser | "in early results" |
| 17:09 | zaphar_ps | which probably features the early adopter type crowd |
| 17:09 | chouser | with less than 2% of precincts reporting... |
| 17:09 | zaphar_ps | :-) |
| 17:09 | stuartsierra | Ok, that's my contribution for the day, got to go. |
| 17:09 | chouser | I can't choose the "form" menu |
| 17:10 | chouser | (to see the pie charts) |
| 17:10 | stuartsierra | huh |
| 17:10 | zaphar_ps | me either |
| 17:10 | stuartsierra | Are you logged in with a Google acct? |
| 17:10 | chouser | stuartsierra: don't worry about it. go do what you need to do. |
| 17:10 | chouser | yeah |
| 17:11 | stuartsierra | Don't know how to fix that. |
| 17:13 | chouser | heh. I "made a copy" of the spreadsheet, and there I can choose form->show summary, but it says 0 responses |
| 17:14 | hiredman | clojurebot: ~logs |
| 17:14 | clojurebot | logs is http://clojure-log.n01se.net/ |
| 17:17 | falkor2 | OK, I think a more clever question would be: Is is possible to know, in a macro, the type of an object without executing it? Say, I do (mymacro (1 2 3) (println 3) ) And are able to see the type of both lists, and execute the 2nd? |
| 17:17 | hiredman | the type of what? |
| 17:17 | hiredman | the datastructure passed to the macro? |
| 17:17 | falkor2 | Whatever I pass to the macro... |
| 17:18 | hiredman | the type of the result of calling eval on the datastructure? |
| 17:18 | falkor2 | so in this case, There are 2 lists |
| 17:18 | falkor2 | no, not the result |
| 17:18 | falkor2 | but I would like to inspect the objects without executing them |
| 17:18 | hiredman | why are you interested in concrete types? |
| 17:19 | falkor2 | mainly in seeing the first element and do a decision on how to proceed |
| 17:19 | hiredman | falkor2: have you looked at multimethods? |
| 17:19 | falkor2 | I need something a bit more general |
| 17:19 | hiredman | … |
| 17:19 | falkor2 | let me explain |
| 17:19 | hiredman | then you haven't looked at multimethods |
| 17:20 | hiredman | multimethods let you define a dispatch function |
| 17:20 | hiredman | that is about as general as you can get |
| 17:20 | funkenblatt | i think he wants to decide whether to evaluate based on the car of each list |
| 17:20 | falkor2 | I have, and I have code with mm on github |
| 17:20 | falkor2 | let me explain |
| 17:20 | hiredman | funkenblatt: very doable |
| 17:21 | falkor2 | I want to be able to do something like this ((new StringBuffer "bla") (add "ble") (add "bli")) |
| 17:21 | falkor2 | The result being a SB "blablebli" |
| 17:21 | the-kenny | falkor2: doto? |
| 17:21 | falkor2 | maybe, let me reread doto |
| 17:21 | hiredman | ,(doto (StringBuilder.) (.add "a") (.add "b")) |
| 17:21 | clojurebot | java.lang.IllegalArgumentException: No matching method found: add for class java.lang.StringBuilder |
| 17:22 | hiredman | bah |
| 17:22 | hiredman | ,(doto (StringBuffer.) (.add "a") (.add "b")) |
| 17:22 | clojurebot | java.lang.IllegalArgumentException: No matching method found: add for class java.lang.StringBuffer |
| 17:22 | the-kenny | ,(doto (StringBuilder.) (.append "a") (.append "b")) |
| 17:22 | clojurebot | #<StringBuilder ab> |
| 17:22 | hiredman | right |
| 17:22 | the-kenny | ,(.getString (doto (StringBuilder.) (.append "a") (.append "b"))) |
| 17:22 | clojurebot | java.lang.IllegalArgumentException: No matching field found: getString for class java.lang.StringBuilder |
| 17:22 | the-kenny | ... |
| 17:22 | hiredman | the-kenny: toString |
| 17:22 | hiredman | or just str |
| 17:22 | the-kenny | ,(.str (doto (StringBuilder.) (.append "a") (.append "b"))) |
| 17:22 | clojurebot | java.lang.IllegalArgumentException: No matching field found: str for class java.lang.StringBuilder |
| 17:22 | hiredman | the-kenny: str is not a method |
| 17:23 | funkenblatt | well in any case looks like my interpretation of what he wanted was completely wrong |
| 17:23 | hiredman | http://gist.github.com/222974 |
| 17:23 | the-kenny | hm.. I think falkor2 knows what we mean |
| 17:23 | falkor2 | I think doto is probably enough. Newbie questions, sorry |
| 17:24 | falkor2 | My objective is to be able to create tree like structures in an easy fashion |
| 17:24 | falkor2 | (think lots of swing components embedded in one another) |
| 17:25 | the-kenny | Maybe something like clojure.zip? |
| 17:25 | the-kenny | (I'm not sure what you want to do) |
| 17:26 | hiredman | swing is very imperative |
| 17:26 | hiredman | I don't you want to use zippers for interacting with it |
| 17:26 | hiredman | doubt |
| 17:27 | the-kenny | hiredman: I thought about creating and traversing the tree structure with zippers |
| 17:27 | falkor2 | Mainly I am trying to construct tree like structure of Java objects in an easy way (think a JFrame which contains a Menubar, which contains menus, and so on and so forth) |
| 17:27 | falkor2 | Trying to devise a way with little boillerplate code |
| 17:27 | hiredman | the-kenny: zippers are a functional tree editing construct |
| 17:28 | hiredman | there would be a significant mismatch for bidirectional swing<->zipper |
| 17:31 | falkor2 | I am going to research doto, thanks. My final objective is to have a dynamic way to construct Java tree-like structures easily. |
| 17:32 | hiredman | you migh do some kind of batched convert to zipper, edit, update ui |
| 17:34 | falkor2 | I am going to have a look, thanks for the tips. |
| 17:42 | cow-orker | ,char? |
| 17:42 | clojurebot | java.lang.Exception: Unable to resolve symbol: char? in this context |
| 17:42 | cow-orker | why is this so....? |
| 17:43 | hiredman | because the function does not exist |
| 17:43 | the-kenny | cow-orker: My repl doesn't lnow this function either. |
| 17:43 | KirinDave1 | Man I updated lein and broke it |
| 17:43 | cow-orker | sure, but why? |
| 17:43 | KirinDave1 | I spend like 5x as much time futzing with lein as I do actually coding. |
| 17:43 | cow-orker | ,integer? |
| 17:43 | clojurebot | #<core$integer_QMARK___5623 clojure.core$integer_QMARK___5623@78fac9> |
| 17:43 | cow-orker | ,vector? |
| 17:43 | clojurebot | #<core$vector_QMARK___4488 clojure.core$vector_QMARK___4488@346801> |
| 17:43 | hiredman | cow-orker: no one has bothered to write it |
| 17:43 | cow-orker | etc etc .... but no char? |
| 17:43 | cow-orker | ok, fair enough :) |
| 17:44 | hiredman | (partial instance? Character) |
| 17:44 | KirinDave1 | Is "lein new _name_" or "lein help" broken for everyone or just me? |
| 17:45 | hiredman | ,((partial instance? Character) \a) |
| 17:45 | clojurebot | true |
| 17:45 | hiredman | ,((partial instance? Character) 1) |
| 17:45 | clojurebot | false |
| 17:45 | technomancy | KirinDave1: help is broken due to a Clojure bug if lein has been AOT'd. |
| 17:45 | KirinDave1 | technomancy: Same deal for new? |
| 17:45 | technomancy | KirinDave1: not that I know |
| 17:46 | KirinDave1 | technomancy: "Could not locate leiningen/new__init.class or leiningen/new.clj on classpath", you know? |
| 17:46 | cow-orker | hiredman: thanks. Was looking at core.clj and just wondered if there was something special wrt characters. Guess not :) |
| 17:46 | technomancy | KirinDave1: you're on 1.0.0-SNAPSHOT and have updated your bin script? |
| 17:47 | technomancy | (new didn't exist in 0.5.0) |
| 17:47 | KirinDave1 | Oh, well |
| 17:47 | KirinDave1 | When i pulled from the url in your repo |
| 17:47 | KirinDave1 | i got 0.5.0 |
| 17:50 | KirinDave1 | technomancy: Following the directions in the mailing list seems to work better. :) |
| 17:52 | Chousuke | technomancy: good work with leiningen btw. It seemed to me to appear out of thin air and now I see mentions of it everywhere :P |
| 17:52 | technomancy | KirinDave1: right; the readme points to with the stable branch |
| 17:52 | technomancy | Chousuke: thanks! it's obvious now that it's addressing pain that a lot of people feel. |
| 17:52 | Chousuke | now Clojure itself needs to start using it. |
| 17:53 | Chousuke | :P |
| 17:53 | technomancy | chicken, meet egg. |
| 17:56 | funkenblatt | delicious delicious egg |
| 17:56 | funkenblatt | man now i'm hungry |
| 17:59 | KirinDave1 | Man, I just have no luck with lein. |
| 18:09 | technomancy | KirinDave1: I'm a bit busy right now, but there's a mailing list for leiningen: http://groups.google.com/group/leiningen |
| 18:45 | ambient | clojure-mode from ELPA is telling me that clojure-install is deprecated. what should I use instead? |
| 18:48 | technomancy | ambient: M-x slime should download Clojure if swank-clojure is installed. |
| 18:49 | ambient | nvm, i was a bit reading impaired. technomancy.us/swank-clojure seems to be the way |
| 18:50 | ambient | technomancy: ok, ty |
| 18:52 | ambient | it installed version 1.0.0 :( |
| 18:53 | ambient | and i dont even know where to |
| 18:53 | technomancy | ambient: sounds like you want option 2 then |
| 18:53 | _ato` | ambient: ~/.swank-clojure |
| 18:55 | _ato` | I also had to move swank.jar into ~/.clojure to get M-x swank-clojure-project to work :\ |
| 18:59 | KirinDave1 | Man, too much time spent trying to get this to work. :\ |
| 18:59 | KirinDave1 | I am just gonna go back to lein 0.5.0 |
| 18:59 | KirinDave1 | Good thing I have lots of time today with my 800000 installs of windows. |
| 19:00 | _ato` | KirinDave1: yeah, best to stick with stable version unless you want to hack on lein itself. |
| 19:01 | KirinDave1 | _ato: Probably should remove the .jar tho |
| 19:01 | KirinDave1 | It seems completely broken. |
| 19:01 | KirinDave1 | Referring to a method that does not exist at invocation, etc. etc. :) |
| 19:02 | _ato | yeah, you probably know but they're installed under: ~/.m2/repository/leiningen/leiningen/ |
| 19:02 | KirinDave1 | Yes. |
| 19:02 | KirinDave1 | The 1.0.0-SNAPSHOT invokes main when I think it means to invoke "-main" |
| 19:04 | technomancy | no, it got renamed to "main" in master; that's correct. we're no longer gen-classing. |
| 19:23 | tomoj | is there something wrong with "java -cp lib/* clojure.main" in a swank-clojure-project-style project? |
| 19:23 | qed | wow I need to learn Java |
| 19:23 | tomoj | oh, yes, of course |
| 19:23 | tomoj | needs to be quoted |
| 19:24 | qed | I've been secretly hoping this whole time learning clojure that I'd be able to completely ignore Java |
| 19:24 | qed | but it looks like a dirty necessity |
| 19:24 | tomoj | yup :/ |
| 19:24 | qed | To what extent seems to be the question |
| 19:24 | tomoj | they taught me java here at school, luckily. but I still haven't forced myself to learn ant or maven or.. |
| 19:25 | _ato | KirinDave1: ah.. I just realised what the problem is, technomancy's snapshot is 4 days out of date |
| 19:26 | tomoj | packaging seems to be the dirtiest part to me, maybe new clojure tools will help hide that from us :) |
| 19:27 | qed | it'll get better |
| 19:27 | technomancy | _ato: I guess I should put a note that self-install should not be relied upon for snapshot versions |
| 19:28 | technomancy | it's so easy to get out of sync |
| 19:28 | _ato | technomancy: yeah, probably a good idea to chuck a check in the lein script as well that spits out a warning if the version ends in snapshot |
| 19:28 | qed | i do all of my clojure/swank/slime setup manually |
| 19:28 | qed | it just seems cleaner that way, no offense technomancy |
| 19:32 | ambient | this bothers me, to use clojure efficiently there still remains a significant threshold for not-so-smart people |
| 19:33 | tomoj | isn't there clojurebox or something? |
| 19:34 | ambient | certainly. i'm just lamenting that in my view, there's no "perfect" development environment yet, in which i would feel comfortable in, without wanting some random feature or convenience |
| 19:34 | ambient | i could make emacs such, but in my experience, it becomes with a significant burden |
| 19:43 | chouser | I'm hopeful. Lisp was not an acceptable lisp, and then came clojure. |
| 19:43 | chouser | emacs is not an acceptable emacs, but maybe something will come along. |
| 19:44 | technomancy | lexical scoping and threading in emacs 24! |
| 19:44 | chouser | hm |
| 19:44 | chouser | really? |
| 19:44 | technomancy | chouser: there's talk of it |
| 19:45 | chouser | with those, it might make an acceptable clojure compilation target. |
| 19:45 | technomancy | possibly coroutines instead of threads; that's fine w/ me |
| 19:45 | technomancy | chouser: I've thought about that, believe me. =) |
| 19:46 | hiredman | best to start now |
| 19:46 | hiredman | clojure subset to elisp compiler |
| 19:46 | hiredman | "translator" |
| 19:46 | technomancy | might be fun to compile directly to elisp bytecode |
| 19:47 | hiredman | that would be even better |
| 19:47 | chouser | no point in starting pre-cinc |
| 19:47 | hiredman | I wasn't aware there was elisp bytecode |
| 19:47 | hiredman | chouser: not a full clojure port |
| 19:47 | hiredman | more like code gen guided by feed in clojure forms |
| 19:47 | technomancy | hiredman: someone ported a destructuring version of let already; it's pretty nice |
| 19:48 | hiredman | emacs :( |
| 19:48 | qed | gah I get so confused at this Creating & Compiling Java Classes in Clojure section of Stuart's book |
| 19:49 | _ato | qed: with anything in particular? |
| 19:49 | funkenblatt | i thought emacs has had destructuring bind in the 'cl package for a while |
| 19:49 | qed | i worked through this section last night _ato -- im going to try my luck again. If i have an issue ill ask though, thanks :) |
| 19:51 | qed | is the (.. class-or-inst form & forms) special form kind of like (->)? |
| 19:51 | _ato | yes |
| 19:52 | technomancy | funkenblatt: not with hashes |
| 19:52 | funkenblatt | ah |
| 19:52 | _ato | qed: it came from before the (.foo obj) notation was introduced IIRC. Better to do (-> obj (.foo) (.bar)) rather than (.. obj (foo) (bar)), as you can also use clojure functions with -> |
| 19:53 | qed | ok _ato -- here's where I get confused, and this might just be my java ignorance, but the (proxy class-and-interfaces super-cons-args & fns) is scary to me |
| 19:53 | qed | ah right _ato that makes sense |
| 19:53 | _ato | hehe it is scary! |
| 19:53 | _ato | class-and-interfaces = classes and interfaces you are subclassing/implementing with proxy |
| 19:54 | _ato | super-cons-args = arguments to the superclass' constructor, so if you're subclassing class Foo and need to pass in some args like: (Foo. 1 2 3) this is where you'd put them |
| 19:55 | _ato | both of them should be vectors |
| 19:55 | qed | okay so far so good |
| 19:55 | _ato | and fns is jus the fns you want to override. So if you want do override. (.foo obj 1 2 3), you'd put (foo [x y z] ...) there |
| 20:08 | qed | _ato: i think what is confusing me is...and this might sound ridiculous...but...why? |
| 20:08 | qed | like...what are we doing essentially by using proxy |
| 20:09 | tomoj | qed: are you totally new to java? or you know a bit? |
| 20:09 | qed | I know some Ruby, I took some AP Java in high school, a semester of it |
| 20:10 | tomoj | well in ruby you can make a subclass and override some methods |
| 20:10 | qed | MyController < ApplicationController |
| 20:10 | qed | something like that? |
| 20:11 | tomoj | yeah, but.. |
| 20:11 | tomoj | I guess it's sortof like a ruby singleton class maybe |
| 20:11 | tomoj | you just get a single instance of this new class |
| 20:12 | tomoj | so like if you want to make a JFrame instance but override some methods, instead of creating a new class MyJFrame and instantiating it, like you would in java, you can just proxy JFrame |
| 20:12 | tomoj | you get an instance of an anonymous subclass with your overridden methods |
| 20:12 | qed | oh okay okay, i think i see where this is going |
| 20:13 | hiredman | (except extending JFrame like every java gui tutorial does is a horrible idea) |
| 20:13 | qed | (def print-element-handler (proxy [DefaultHandler [] (startElement [uri local qname atts] (println (format "Saw element: %s" qname))))) |
| 20:13 | _ato | yeah |
| 20:14 | qed | so we are making an anonymouse instance of DefaultHandler and overriding startElement? |
| 20:14 | hiredman | you are missing a ] |
| 20:14 | qed | ah yeah, so i am |
| 20:14 | _ato | qed: it's basically because many java libraries force you to subclass one if their types in order to use their API |
| 20:14 | hiredman | _ato: if you are lucky, one of their interfaces |
| 20:15 | qed | so what is [uri local qname atts] |
| 20:15 | hiredman | the arguments to the method |
| 20:15 | _ato | it's the arguments passed to .startElement |
| 20:15 | qed | do they need to be named exactly like the the method names them? |
| 20:15 | hiredman | proxy generates a class |
| 20:15 | hiredman | qed: nope |
| 20:15 | qed | so i could just do q1 q2 q3 q4 |
| 20:15 | _ato | no, it's just like (defn startElement [uri local qname attrs] ...) |
| 20:15 | _ato | yeah |
| 20:16 | _ato | except that it creates a java method |
| 20:16 | _ato | instead of a clojure function |
| 20:16 | qed | sure, okay |
| 20:16 | _ato | (method meaning it's attached to a class instead of being "global" like a function) |
| 20:16 | hiredman | proxy stubs out the java methods in the generated class, and just passes the arguments off the to clojure fn created from the proxy form |
| 20:16 | qed | thanks guys, im gonna get back to playing with this -- just for fun, does anyone have an easy example of a Java class/method I could use proxy on? |
| 20:16 | hiredman | ACtionListener |
| 20:16 | qed | im gonna try to write a couple of them |
| 20:16 | hiredman | ActionListener |
| 20:17 | hiredman | FileFilter? |
| 20:19 | tomoj | hiredman: got disconnected, was the verdict horrible or not horrible? |
| 20:19 | qed | like: (def action-performed (proxy [ActionListener] [] (actionPerformed [event] (println (format "Performed %s" event))))) |
| 20:20 | tomoj | I think the only time I've ever used proxy was for a KeyListener |
| 20:21 | hiredman | tomoj: verdict on? |
| 20:21 | tomoj | which overrode keyPressed to call a handler-fn on the event |
| 20:21 | hiredman | qed: are you familiar with java's anonymous classes? |
| 20:21 | tomoj | oh, is proxying swing classes always horrible? |
| 20:21 | tomoj | or did you just mean JFrame in particular |
| 20:21 | qed | hiredman: im familiar with Ruby's |
| 20:22 | hiredman | does ruby hava anonymous classes? |
| 20:22 | qed | the "ghost" class, singleton class, eigenclass, uniclass, etc. |
| 20:22 | tomoj | ruby has anonymous classes? |
| 20:22 | qed | yes |
| 20:22 | tomoj | oh, that's sorta like proxying but backwards I think |
| 20:22 | tomoj | when you proxy you make an anonymous class and then instantiate it once |
| 20:22 | hiredman | http://blog.jayfields.com/2008/02/ruby-creating-anonymous-classes.html |
| 20:23 | tomoj | with the singleton class you've got an instance of some class and then you can stick your overridden methods in for just that instance, so, same effect I guess |
| 20:23 | hiredman | anyway |
| 20:23 | hiredman | yeah, proxy creates an instance of an anonymous class |
| 20:23 | tomoj | in ruby proxy'ing would be unnecessary since we don't have to dance around to satisfy java's type system anyway |
| 20:24 | hiredman | well, it creates an anonymous class, and then returns an instance |
| 20:25 | qed | so it creates this anon class, and then an instance of it with my overridden methods, i guess im still struggling to see applicable scenarios not having worked with Java much at all |
| 20:25 | qed | that's really where im really trying to get clarification, some examples of this in action |
| 20:25 | tomoj | well, for example, swing wants you to give it a KeyListener to listen to key events in the GUI |
| 20:25 | _ato | qed: java doesn't have first class functions |
| 20:25 | _ato | you can't pass a function to another function in java |
| 20:26 | tomoj | I don't want to make a java class which subclasses KeyListener, so I just proxy it |
| 20:26 | _ato | so you basically use anonymous classes or subclasses instead |
| 20:26 | tomoj | yeah, in clojure I'd just be able to pass a fn to call on the key event I suppose |
| 20:27 | tomoj | Runnable too, eh? |
| 20:27 | qed | Callable/Runnable yeah |
| 20:27 | qed | _ato: when you say fn in java, you mean method, no? |
| 20:28 | qed | we're essentially creating an anonymous function from some Java method? |
| 20:28 | _ato | yeah, it doesn't have functions and it's methods aren't first class, they don't exist as objects themselves. You can't pass them around. It doesn't even have function pointers. (leaving aside reflection, which doesn't really count) |
| 20:29 | tomoj | eh |
| 20:29 | tomoj | I think we're essentially doing some little dance to make up for the fact that java can't do that |
| 20:29 | qed | so we're sort of creating an abstract version of a java method |
| 20:29 | qed | so we can use it all over the place in clojure |
| 20:30 | tomoj | where you would pass a fn in clojure, you instead pass a singleton of some anonymous class |
| 20:31 | tomoj | java code you're interoping with wants some object which extends/implements certain classes/interfaces - it doesn't care that clojure is dynamic |
| 20:31 | qed | is there a way to get the methods for a Java class in my REPL? |
| 20:31 | tomoj | so you use proxy to make a one-off subclass/implementation |
| 20:31 | tomoj | c.c.repl-utils has show |
| 20:32 | tomoj | if you're using slime you should be able to use the slime inspector as well |
| 20:32 | tomoj | like C-c I Math |
| 20:32 | qed | awesome, that's a big help |
| 20:33 | qed | okay okay, this is starting to make real sense now |
| 20:33 | _ato | What I find really funny is a lot of java folks have been against adding closures/lambda expressions to java because they're "too complex". So instead you've got to do to this annoying subclass / anonymous class dance which actually turns out to be harder and more complex. |
| 20:34 | tomoj | I remember really enjoying learning about anonymous/inner classes because they seemed so esoteric |
| 20:34 | qed | We're just making some version of a Java method which implements a Class/Interface, so we can fake Java into talking to our version of it which we create with a proxy |
| 20:34 | _ato | qed: exactly |
| 20:34 | tomoj | I guess maybe they're much easier to implement in java, though? |
| 20:34 | qed | tomoj: yeah i really enjoyed the ruby metaprogramming stuff |
| 20:34 | qed | very fun |
| 20:36 | tomoj | I had heard rumors about closures coming to java, though |
| 20:37 | qed | okay so I have (def get-month (proxy [Date] [] (getMonth [month] (println (format "The month is %d" month))))) |
| 20:37 | qed | what am i doing wrong there? |
| 20:40 | tomoj | getMonth doesn't take a parameter |
| 20:41 | tomoj | so "month" is not what you think it is, I think |
| 20:43 | tomoj | ,(.getMonth (proxy [Date] [] (getMonth [] (println "foo") 3))) |
| 20:43 | clojurebot | java.lang.RuntimeException: java.lang.IllegalStateException: Var null/null is unbound. |
| 20:44 | tomoj | ,(import 'java.util.Date) |
| 20:44 | clojurebot | java.util.Date |
| 20:44 | tomoj | ,(.getMonth (proxy [Date] [] (getMonth [] (println "foo") 3))) |
| 20:44 | clojurebot | java.lang.RuntimeException: java.lang.IllegalStateException: Var null/null is unbound. |
| 20:44 | tomoj | huh. |
| 20:44 | qed | there we go |
| 20:44 | tomoj | well, that works fine for me, prints foo and returns 3 |
| 20:44 | tomoj | though that's a pretty strange example :) |
| 20:45 | qed | (def print-crazy-date (proxy [Date] [] (toString [] (str (. (java.util.Random) nextInt))))) |
| 20:45 | qed | (. print-crazy-date toString) |
| 20:45 | qed | err forget a . after Random |
| 20:46 | qed | forgot* |
| 20:46 | tomoj | crazy indeed |
| 20:46 | qed | hehe |
| 20:49 | qed | okay this is making more and more sense.. (.start (Thread. (proxy [Runnable] [] (run [] (println "I ran!"))))) |
| 20:50 | qed | Thread. wants something that is Runnable, so we're giving it what it wants |
| 20:51 | tomoj | yep |
| 20:51 | hiredman | http://groups.google.com/group/clojure/browse_thread/thread/4303a1a0bc4bdfa5?hl=en <-- good question |
| 20:51 | tomoj | though I think agents make all that unnecessary in clojure, luckily |
| 20:51 | tomoj | but maybe if you're interoping with some library that wants Runnables.. |
| 20:51 | hiredman | clojure Fns are Runnable |
| 20:51 | qed | #() |
| 20:52 | qed | and Callable |
| 20:52 | hiredman | ,(ancestors (class #())) |
| 20:52 | clojurebot | #{java.lang.Object clojure.lang.IMeta clojure.lang.AFunction clojure.lang.Obj java.io.Serializable clojure.lang.AFn java.util.concurrent.Callable java.lang.Runnable java.util.Comparator clojure.lang.IFn clojure.lang.Fn :clojure.contrib.generic/any clojure.lang.IObj} |
| 20:52 | tomoj | well then I guess all that is unnecessary no matter what |
| 20:52 | qed | (.call #(println "foo")) |
| 20:52 | qed | ,(.call #(println "foo")) |
| 20:52 | clojurebot | foo |
| 20:53 | tomoj | (.start (Thread. #(println "foo"))), nifty |
| 20:53 | qed | yeah definitely |
| 20:53 | hiredman | (future (println "foo")) |
| 20:54 | qed | ,(future (println "foo")) |
| 20:54 | clojurebot | #<core$future_call$reify__7719@624159: nil> |
| 20:54 | qed | ,(seq (future (println "foo"))) |
| 20:54 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.core$future_call$reify__7719 |
| 20:54 | tomoj | I still have never used future |
| 20:55 | qed | ,(future-call #(println "foo")) |
| 20:55 | clojurebot | #<core$future_call$reify__7719@1937976: :pending> |
| 20:55 | tomoj | ,(let [the-future (future (println "foobar"))] [@the-future @the-future]) |
| 20:55 | clojurebot | [nil nil] |
| 20:56 | tomoj | guess clojurebot doesn't want to print that |
| 20:56 | qed | why two calls to @the-future? |
| 20:56 | tomoj | but it only prints once :) |
| 20:56 | qed | it gives me nil twice |
| 20:57 | tomoj | because it still only prints once |
| 20:57 | tomoj | yeah, but only prints once |
| 20:57 | tomoj | (println returns nil) |
| 20:58 | qed | (let [the-future (future (str "foo!"))] [@the-future @the-future]) |
| 20:58 | qed | ,(let [the-future (future (str "foo!"))] [@the-future @the-future]) |
| 20:58 | clojurebot | ["foo!" "foo!"] |
| 20:59 | qed | ,(let [the-future (future (str "foo!"))] [@the-future the-future]) |
| 20:59 | clojurebot | ["foo!" #<core$future_call$reify__7719@19c1908: "foo!">] |
| 21:02 | tomoj | ,(time (let [the-future (future (Thread/sleep 1000) "foo")] [@the-future @the-future @the-future])) |
| 21:02 | clojurebot | ["foo" "foo" "foo"] |
| 21:02 | clojurebot | "Elapsed time: 1030.109 msecs" |
| 22:11 | arohner | I have on the order of 1000 instances of clojure maps that I scan through, looking up values. If I convert that to a deftype that implements IPersistentMap, will things get faster? |
| 22:12 | chouser | the clojure maps all have the same keys? |
| 22:12 | chouser | if so, you should see a substantial speedup |
| 22:15 | arohner | chouser: yes, they all have the same keys, and do no assoc/disassoc |
| 22:15 | arohner | thanks |
| 22:19 | chouser | yeah, you should get an inlinable java method call instead of the hashmap algorithm implementation |
| 22:35 | arohner | oh, but they don't implement IFN, so I can't do (instance key) |
| 22:36 | arohner | is that planned/ a good idea? |
| 23:01 | cark | arohner : did you try (keyword instance) ? |
| 23:01 | arohner | cark: yes, that works |
| 23:01 | arohner | but my existing code uses (instance keyword) everywhere. I was hoping a deftype that implemented IPersistentMap would be a drop in replacement |
| 23:03 | cark | but wouldn't you loose the performance characteristics if this was done this way ? |
| 23:04 | cark | ohwell anyways i don't have this version of clojure installed yet =P |
| 23:05 | cark | oh i see your post |
| 23:07 | _ato | cark: (keyword instance) is actually faster for deftypes |
| 23:08 | _ato | it's as fast as a java field access |
| 23:08 | qed | You know I just realized that all of this channel is logged and my stupidity will forever be cast in stone.l |
| 23:09 | _ato | yeah, isn't it great. In 5 years time when you're an almightly Clojure god you can look back and think... "ah... how I have improved!" :-) |
| 23:10 | cark | mhh but if you include the IPersistentMap interface in your deftype, doesn't it behave like a struct-map ? |
| 23:10 | qed | _ato: haha you are by far the most positive person I've met in here -- I have to say I really appreciate your patience |
| 23:10 | kzar | qed: Yea I asked a question in here the other day, then I googled the problem and found what I said in the results.. |
| 23:10 | qed | kzar: ahahaha |
| 23:11 | kzar | "Sweet this guy has the same problem... oh wait" |
| 23:11 | qed | To the internet: If you come to IRC and ask _ato, you will learn. |
| 23:12 | _ato | cark: hmm, you could well be right. I'm not sure, I haven't played with that enough |
| 23:12 | cark | looks like i might have to test it too =) |
| 23:13 | qed | And on top of that, _ato is humble, he didn't even take the opportunity to toot his horn. |
| 23:13 | qed | God damnit, _ato. What are you made of, man? |
| 23:14 | kzar | I bet you are the same person, you just opened up bitchx in a shell and started bigging yourself up |
| 23:14 | _ato | hahaha |
| 23:14 | qed | hahahaha |
| 23:14 | _mst | outed! |
| 23:14 | _mst | I'm _ato and so's my wife :P |
| 23:14 | qed | i am really offended you would think I'd use BitchX |
| 23:14 | qed | wtf is it, 1997? |
| 23:15 | cark | hey i'm using mirc ! |
| 23:15 | qed | that's right, get the shame you feel out into the open |
| 23:15 | qed | you can only learn from this experience |
| 23:15 | _mst | another one for the IRC logs :) |
| 23:16 | qed | actually something ive taken to showing my future employers -- or at least mentioning in interviews is that if you google me you will find me, at age 13, on the vuln-dev mailing list |
| 23:17 | qed | asking if it is "okay" to extort money from a local ISP for a hole I found in their system |
| 23:17 | qed | that shit is never going away |
| 23:18 | qed | in fact, they mirrored it...twice |
| 23:18 | qed | and vuln-dev takes precedence over my crappy blog, so my 13 year old extortion scheme still reigns supreme in my google results |
| 23:23 | _ato | heh, if you google my name, which seems to be fairly common you will get: "The father of brainstorming" and "like Jesus, except I'm not dead." |
| 23:25 | qed | there's another guy in my state who is a drug addict and got arrested for statutory |
| 23:26 | qed | i need to be very clear on my middle initial |
| 23:59 | KirinDave1 | I'm writing a program and I feel like I'm doing it wrong. |