2010-03-12
| 00:15 | technomancy | slyphon: so am I going to see a docs patch for leiningen coming from you soon? =) |
| 00:16 | slyphon | uh, sure! |
| 00:16 | technomancy | you just mentioned a few concepts that were missing from the readme that I had just taken for granted |
| 00:17 | psykotic | joshua-choi: regarding your earlier question, what you need is a right fold, not a left fold like reduce. |
| 00:17 | joshua-choi | Yeah, I know. :) |
| 00:17 | technomancy | if you don't have time for a patch it would be great if you could just send something to the mailing list mentioning the things that weren't clear... while it's still fresh in your mind. |
| 00:17 | joshua-choi | The problem is with my parser, which is LL |
| 00:17 | joshua-choi | I had no problem with digits before decimal points |
| 00:18 | slyphon | technomancy: sure, i'll take a whack at it tomorrow or the next day |
| 00:18 | joshua-choi | I could just consume all the digits and then run a function on the whole sequence, but I want to minimize memory |
| 00:18 | joshua-choi | For demonstration purposes |
| 00:19 | technomancy | slyphon: no pressure, just thought it'd be good to get a fresh perspective |
| 00:19 | slyphon | sure |
| 00:19 | technomancy | easy to miss that when you're heads-down in the code for a while |
| 00:19 | psykotic | well, this function you want to compute is provably not computable that way. suppose you see 0.1.... and you want to compute the intermediate result. well, you do 0.1 + 0.1 * (recurse on the ...) |
| 00:19 | slyphon | i know how that is |
| 00:20 | psykotic | which is not a tail call |
| 00:21 | psykotic | here's one trick you can do if you know someone has already spent the memory on reading in the input string |
| 00:21 | psykotic | you scan forwards to the end of the decimal sequence and then scan backwards |
| 00:22 | psykotic | in that case you are not using extra memory on your own behalf, but you are using the memory already used by the caller in constructing the input string, etc |
| 00:22 | psykotic | but if you are reading from a lazy seq, you don't have that luxury |
| 00:22 | tomoj | why would you scan backwards? |
| 00:23 | psykotic | a right fold over the forward-direction sequence is the same as a left cold over the backward-direction sequence |
| 00:23 | psykotic | it's the usual foldl/foldr identity |
| 00:23 | psykotic | err, left fold, not cold :) |
| 00:24 | tomoj | and somehow that gives you a way to go from [3 5 2 1] to 0.3521? |
| 00:24 | psykotic | let me show you with an example |
| 00:26 | psykotic | here's the foldr version |
| 00:26 | psykotic | (letfn [(foldr [f val coll] (if (seq coll) (f (first coll) (foldr f val (rest coll))) val))] (foldr #(+ %1 (* 0.1 %2)) 0.1 [1 2 3 4])) |
| 00:26 | psykotic | ,(letfn [(foldr [f val coll] (if (seq coll) (f (first coll) (foldr f val (rest coll))) val))] (foldr #(+ %1 (* 0.1 %2)) 0.1 [1 2 3 4])) |
| 00:26 | clojurebot | 1.23401 |
| 00:27 | psykotic | here's the reverse/reduce version: |
| 00:27 | psykotic | ,(reduce #(+ %2 (* 0.1 %1)) (reverse [1 2 3 4])) |
| 00:27 | clojurebot | 1.234 |
| 00:28 | psykotic | sorry, for the earlier i meant |
| 00:28 | psykotic | ,(letfn [(foldr [f val coll] (if (seq coll) (f (first coll) (foldr f val (rest coll))) val))] (foldr #(+ %1 (* 0.1 %2)) 0 [1 2 3 4])) |
| 00:28 | clojurebot | 1.234 |
| 00:29 | psykotic | in any case, they use the same amount of memory in this case--it's just a question of whether it's in a data structure (the reverse) or on the call stack (the foldr) |
| 00:29 | psykotic | but the point is that if you already have something like a vector, then you can reverse with no extra storage overhead using rseq |
| 00:29 | psykotic | ,(reduce #(+ %2 (* 0.1 %1)) (rseq [1 2 3 4])) |
| 00:29 | clojurebot | 1.234 |
| 00:30 | tomoj | ok |
| 00:31 | tomoj | oh, by "scan forwards to the end of the decimal sequence", did you just mean that you find where it ends? |
| 00:31 | psykotic | yes |
| 00:31 | tomoj | ah, ok |
| 00:31 | psykotic | so then you know the slice, you slice it, then use rseq to reverse it |
| 00:31 | tomoj | I had thought you meant you should do both a foldr and a foldl |
| 00:32 | psykotic | well, you do foldl for the integral part and foldr (or foldl/rseq) for the fractional part |
| 00:33 | tomoj | I see |
| 00:44 | psykotic | alternatively... |
| 00:45 | psykotic | ,(/ (reduce #(+ %2 (* 10 %1)) 0 [1 2 3 4]) 1000.0) |
| 00:45 | clojurebot | 1.234 |
| 00:46 | tomoj | but then you have to count the sequence, right? |
| 00:46 | psykotic | that's right |
| 00:47 | psykotic | ,(reduce #(* %2 10) 1 [1 2 3 4]) |
| 00:47 | clojurebot | 40 |
| 00:47 | psykotic | ,(reduce #(* %1 10) 1 [1 2 3 4]) |
| 00:47 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--4943$fn |
| 00:47 | psykotic | heh |
| 00:48 | psykotic | but yeah, you can't escape what i said earlier about computing this function requiring a certain amount of space, either your own or someone else's |
| 00:49 | psykotic | in this case, the space is taken up by the integer |
| 00:49 | psykotic | for my technique to work in general, you'll need arbitrary-precision integers, like BigInteger, which aren't constant storage, so this technique is deceptive |
| 00:50 | psykotic | essentially, i'm just using the integer as a vector of digits |
| 00:50 | psykotic | better constant factor on the storage, but asymptotically the same |
| 00:58 | psykotic | ,(letfn [(parse-fraction [xs] (* 0.1 (/ (reduce #(+ %2 (* 10 %1)) 0 xs) (reduce (fn [x _] (* x 10)) 0.1 xs))))] (parse-fraction [1 2 3 4])) |
| 00:58 | clojurebot | 0.12340000000000001 |
| 01:04 | psykotic | incidentally, this is a good example of where folds can be fused using the tupling transform: |
| 01:04 | psykotic | ,(letfn [(parse-fraction [xs] (let [[m n] (reduce (fn [[a b] x] [(+ x (* a 10)) (* b 10)]) [0 0.1] xs)] (* 0.1 (/ m n))))] (parse-fraction [1 2 3 4])) |
| 01:04 | clojurebot | 0.12340000000000001 |
| 01:06 | psykotic | (letfn [(parse-fraction [xs] (let [[m n] (reduce (fn [[a b] x] [(+ x (* a 10)) (* b 10)]) [0 1.0] xs)] (/ m n)))] (parse-fraction [1 2 3 4])) |
| 01:06 | psykotic | ,(letfn [(parse-fraction [xs] (let [[m n] (reduce (fn [[a b] x] [(+ x (* a 10)) (* b 10)]) [0 1.0] xs)] (/ m n)))] (parse-fraction [1 2 3 4])) |
| 01:06 | clojurebot | 0.1234 |
| 01:14 | joshua-choi | Thanks to everyone's help, I've fixed my parser. You all rock. |
| 01:18 | psykotic | someone should do a tutorial that shows how easy it is to do undo in applications based on functional programming |
| 01:18 | psykotic | that's one of the really compelling use cases, imo |
| 01:19 | psykotic | every large application i've worked on has had some half-assed way of doing undo that did deep copies of the relevant parts of the object graph and shit like that |
| 01:19 | psykotic | it's super wasteful. persistent data structures makes it lightweight and easy. |
| 01:50 | zmila | ,,(doc every?) |
| 01:50 | clojurebot | "([pred coll]); Returns true if (pred x) is logical true for every x in coll, else false." |
| 01:51 | tomoj | ,,,,(doc every?) |
| 01:51 | clojurebot | "([pred coll]); Returns true if (pred x) is logical true for every x in coll, else false." |
| 01:51 | tomoj | weird |
| 01:51 | psykotic | i cry every time i type every? instead of all? :) |
| 01:51 | psykotic | two wasted characters, man, TWO! |
| 01:52 | psykotic | ,(doc some?) |
| 01:52 | clojurebot | Pardon? |
| 01:52 | psykotic | ,(doc any?) |
| 01:52 | clojurebot | Excuse me? |
| 01:52 | tomoj | ,(doc some) |
| 01:52 | clojurebot | "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)" |
| 01:52 | psykotic | oh right, it isn't necessarily boolean |
| 01:52 | tomoj | some returns booleany things |
| 01:52 | tomoj | yeah |
| 01:53 | tomoj | hmm "booleany" seems better than I thought at first |
| 01:53 | tomoj | because it really just returns any kind of thing |
| 01:54 | tomoj | isn't pred in that doc a bit misleading? |
| 01:54 | tomoj | since it might not be a predicate? |
| 01:54 | zmila | psykotic - lol! |
| 01:55 | psykotic | btw, a pet peeve about the name 'some' (aside from the fact that 'any' is one character shorter) is that it has the wrong connotations |
| 01:56 | psykotic | this goes back to some of aristotle's syllogisms actually. does 'some' imply that more than one member must satisfy the predicate? in human language, that's usually the case |
| 01:57 | psykotic | although you could say the same about every? in human language, if something is true for all members, it connotes that the set of members is nonempty, etc |
| 01:59 | tomoj | yes |
| 01:59 | tomoj | (any even? numbers) vs (some even? numbers) |
| 02:00 | tomoj | both of those are awesome, though |
| 02:00 | psykotic | btw, i'm not sure why every? isn't symmetric with some by returning the last logical true element, rather than 'true' |
| 02:00 | psykotic | that's a weird asymmetry |
| 02:00 | tomoj | bah |
| 02:00 | tomoj | and you'd call it every ? |
| 02:00 | psykotic | i suppose so. or all :) |
| 02:00 | tomoj | ah |
| 02:00 | tomoj | any/all is cool |
| 02:00 | psykotic | my point is that this would restore the symmetry with 'and' and 'or' |
| 02:01 | psykotic | right now there's a weird asymmetry |
| 02:01 | tomoj | but I don't think the last logical true element is ever useful... |
| 02:01 | tomoj | that seems a weird thing to return to me |
| 02:01 | psykotic | well, think about 'and' |
| 02:01 | tomoj | ooh shit |
| 02:01 | psykotic | it's the same thing |
| 02:01 | tomoj | yeah |
| 02:01 | psykotic | all is just 'and' folded over the sequence |
| 02:01 | tomoj | that sounds immensely useful, actually |
| 02:02 | tomoj | wait.. I think I was confused |
| 02:02 | tomoj | I know getting the first logical true value in a seq would be useful |
| 02:03 | psykotic | again, look at 'and'. it's the exact same thing. |
| 02:03 | tomoj | all would simultaneously check that all of them were logical true and also give you the last element? |
| 02:03 | psykotic | ,(and true 42) |
| 02:03 | clojurebot | 42 |
| 02:03 | zmila | last logical true = (apply and (map pred coll)) |
| 02:03 | psykotic | ,(and true 42 666 -1) |
| 02:03 | clojurebot | -1 |
| 02:03 | psykotic | zmila: except and is a macro, but yeah |
| 02:03 | tomoj | ,(and true 42 nil -1) |
| 02:03 | clojurebot | nil |
| 02:03 | tomoj | I don't often need that |
| 02:03 | tomoj | or maybe I do and just don't know it |
| 02:04 | psykotic | (and x y) is basically (when x y) |
| 02:05 | psykotic | that's pretty useful |
| 02:05 | tomoj | ok, so a list of things to do that can short-circuit, maybe? |
| 02:05 | psykotic | nah, not short circuit |
| 02:05 | psykotic | some doesn't short circuit either |
| 02:05 | tomoj | sure it does.. |
| 02:05 | psykotic | oh right, for lazy seqs |
| 02:06 | psykotic | anyway, every? presumably also short circuits |
| 02:06 | tomoj | yeah, so you could have a bunch of lazy seqs representing a calculation chain maybe? |
| 02:06 | psykotic | ,(every? identity [false (println "asdf")]) |
| 02:06 | clojurebot | asdf |
| 02:06 | tomoj | and at any point you can short-circuit and fail, otherwise you get the end result |
| 02:07 | psykotic | ,(every? identity (lazy-seq (cons false (lazy-seq (cons (println "asdf") nil))))) |
| 02:07 | clojurebot | false |
| 02:07 | psykotic | right |
| 02:10 | psykotic | and in any case, it's the aesthetic asymmetry that i don't like more than anything :) |
| 02:11 | tomoj | yes, it is strange |
| 02:11 | tomoj | but I figured maybe it's tied to actual use patterns |
| 02:11 | psykotic | if and was called and? and returned 'true' when operands were all logical true, i would be equally revolted |
| 02:12 | tomoj | as in, rich put it what he actually wanted |
| 02:12 | tomoj | but I don't place much confidence in my ability to imagine use cases for functions |
| 02:12 | psykotic | my preference would be any and all without any questionmarks and with the semantics i outlined. |
| 02:13 | psykotic | 1. they are short and symmetric in their names |
| 02:13 | psykotic | 2. they are symmetric in their semantics |
| 02:13 | psykotic | i think the every? and some? names come from scheme |
| 02:13 | tomoj | yes, I like it too |
| 02:13 | tomoj | but can you describe a simple use case for all ? |
| 02:14 | tomoj | perhaps I should adopt the backtick convention and ask about `all` |
| 02:15 | psykotic | you want to ensure that all elements have a certain property, and return some feature of the last element |
| 02:16 | psykotic | admittedly it's less common than wanting to know the first element satisfying some property |
| 02:16 | tomoj | right |
| 02:16 | tomoj | what I can't imagine is a typical feature that is also a property |
| 02:16 | psykotic | they don't have to be the same |
| 02:16 | psykotic | you can do (or (pred x) (feature x)) |
| 02:16 | tomoj | but with `all` ? |
| 02:17 | tomoj | (all identity ...) maybe |
| 02:17 | psykotic | ,(every? #(when (% < 10) (* % %)) (range 10)) |
| 02:17 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn |
| 02:17 | psykotic | okay, i clearly need to put on my prefix goggles :) |
| 02:18 | psykotic | ,((every? #(when (< % 10) (* % %)) (range 10)) |
| 02:18 | clojurebot | EOF while reading |
| 02:18 | tomoj | bad luck :( |
| 02:18 | psykotic | ,(every? #(when (< % 10) (* % %)) (range 10)) |
| 02:18 | clojurebot | true |
| 02:18 | tomoj | ok, so I see how that works |
| 02:18 | tomoj | but using when like that in a #() seems strange to me |
| 02:19 | tomoj | I can imagine it being useful though |
| 02:21 | psykotic | ,(letfn [(all [f xs] (reduce #(when-let [x (f %2)] x) nil xs))] (all #(when (< % 10) (* % %)) (range 10))) |
| 02:21 | clojurebot | 81 |
| 02:21 | tomoj | huh, you can't apply and |
| 02:21 | tomoj | that sucks |
| 02:21 | psykotic | it's a macro :) |
| 02:22 | tomoj | is that what you have to do to get around that? |
| 02:22 | tomoj | you've brought up an interesting area of my ignorance |
| 02:23 | tomoj | the fn there, #(when-let [x (f %2)] x) |
| 02:23 | tomoj | the body of the fn is a macro |
| 02:23 | tomoj | so at macro-time, this is expanded into only function and special forms, before being compiled into bytecode? |
| 02:23 | psykotic | it does a when test using the last binding in the [...] |
| 02:23 | tomoj | yeah, I can figure out how it works, just fuzzy on the actual runtime behavior |
| 02:24 | Chousuke | macros don't exist at runtime |
| 02:24 | Chousuke | well, unless you use eval |
| 02:24 | tomoj | right, so it's just special forms and fns that get compiled into bytecode for that #() ? |
| 02:24 | psykotic | ,(letfn [(and* [& xs] (reduce #(and %2 %1) xs))] (apply and* (range 1 10))) |
| 02:24 | clojurebot | 1 |
| 02:25 | psykotic | ,(letfn [(and* [& xs] (reduce #(and %1 %2) xs))] (apply and* (range 1 10))) |
| 02:25 | clojurebot | 9 |
| 02:25 | Chousuke | tomoj: well, yes, because the macro expands to those :) |
| 02:25 | tomoj | ok |
| 02:26 | tomoj | so the reader reads "some" and resolves that into a function object |
| 02:26 | Chousuke | no, the reader makes a symbol |
| 02:26 | tomoj | oh, then the evaluation happens after, right |
| 02:27 | Chousuke | the compiler resolves it into a var, and at runtime the value of the var is acquired and then called |
| 02:27 | tomoj | and syntax like "#{}" reads to a set, or evaluates to a set? |
| 02:27 | Chousuke | reads as a set, and evaluates into one |
| 02:27 | tomoj | aha |
| 02:27 | tomoj | ,(eval #{}) |
| 02:27 | clojurebot | DENIED |
| 02:28 | tomoj | er, of course |
| 02:28 | Chousuke | it reads as a set of symbols, but evaluates into a set of the values of the symbols |
| 02:28 | tomoj | but it's #{} |
| 02:28 | psykotic | the fact that it reads into a set can be tested using a macro |
| 02:28 | Chousuke | that is, if it had something in it. |
| 02:28 | tomoj | wow |
| 02:28 | tomoj | I don't think I ever fully grokked homoiconicity before |
| 02:28 | tomoj | in clojure's rich landscape at least |
| 02:29 | tomoj | no pun intended |
| 02:29 | psykotic | for shame, there is no letmacro :) |
| 02:30 | Chousuke | in Common lisp, a vector reads as a vector of symbols, but also evaluates into one |
| 02:30 | Chousuke | so if you want a vector of values, you need to do `#(,foo ,bar) |
| 02:31 | tomoj | seriously? |
| 02:31 | Chousuke | Well, as far as I know, yes. |
| 02:32 | psykotic | that is correct |
| 02:32 | tomoj | never saw that syntax before |
| 02:32 | psykotic | it's one of the things i hate about cl |
| 02:33 | psykotic | basically, it's intended to be symmetric with '(...) for constructing lists in the reader |
| 02:33 | Chousuke | huh. why wouldn't they just have #(foo bar) and '#(foo bar) then :P |
| 02:34 | psykotic | since vectors are not used to represent code in common lisp, that was a horrible idea |
| 02:34 | psykotic | i agree |
| 02:34 | psykotic | anyway, that is the explanation i heard. |
| 02:34 | psykotic | i'd love to read something like 'The Design and Evolution of C++' for Common Lisp that documents all the weird design decisions and trade offs for compatibility or coherence with the existing compilers and lisp variants out there at the time |
| 02:35 | psykotic | i picked up a few bits and pieces from reading cll over the years |
| 02:35 | gregh | You are in a maze of twisty parentheses, all alike. |
| 02:35 | gregh | You are eaten by a defun. |
| 02:36 | psykotic | nomnomnom |
| 02:58 | psykotic | i wonder who would win a longest-names contest--java or objective c programmers? |
| 02:58 | psykotic | java programmers are the usual whipping boys but i think objective c would win |
| 02:59 | Chousuke | It's not really fair for ObjC because parameters are interleaved |
| 03:00 | Chousuke | so while the name is longer, it's also much more readable than a shorter, but still long, name in java :P |
| 03:00 | psykotic | i'm referring to things like KeyAndValueArrayIndex for what a good programmer would call 'i' |
| 03:00 | psykotic | it makes code unreadable |
| 03:01 | Chousuke | I don't think I've ever seen things ike that :P |
| 03:01 | Chousuke | like* |
| 03:01 | psykotic | i was looking at some of wil shipley's code |
| 03:01 | psykotic | he's the guy who wrote delicious library, omniweb, etc |
| 03:02 | psykotic | he also admits to using proportional fonts for his code, so maybe i should just write him off as altogether demented :) |
| 03:02 | Chousuke | heh :P |
| 03:03 | tomoj | psykotic: stringByAddingPercentEscapesUsingEncoding |
| 03:03 | tomoj | that's what they call urlencode |
| 03:03 | tomoj | I did too |
| 03:03 | tomoj | thankfully they brought someone else in to do the iphone stuff :) |
| 03:04 | psykotic | when your identifiers are longer than the implementation... :) |
| 03:04 | tomoj | it's somewhat suprising to me |
| 03:05 | tomoj | that everything apple has made uses that shit |
| 03:05 | psykotic | i like names like i, x, y, when they are narrow scope and generic/non-specific. for example, in haskell flip (x,y) = (y,x) is perfect. the x and y have no meaning, they only there to convey structure. |
| 03:05 | psykotic | flip (firstValue, secondValue) = (secondValue, firstValue) is much less readable |
| 03:05 | tomoj | I dunno, maybe I can imagine finding those long names useful |
| 03:05 | tomoj | in an alternate universe where I'm a weirdo |
| 03:05 | psykotic | heh |
| 03:05 | hiredman | clojurebot: the evolution of lisp? |
| 03:05 | clojurebot | Lisp isn't a language, it's a building material. |
| 03:06 | psykotic | the case i usually here for something like KeyAndArrayValueIndex, etc, is that if you have deeply nested for loops, then you get confused about the meaning of i and j, etc |
| 03:06 | tomoj | like in the tool vs. language user debate |
| 03:06 | psykotic | at which point i want to say, don't do that |
| 03:06 | tomoj | obj-c is much toolier I guess, so maybe tool people like it |
| 03:06 | psykotic | i actually like objc as a language |
| 03:06 | psykotic | i'm less a fan of some of the conventions |
| 03:06 | tomoj | I hate it but I never did any C |
| 03:07 | Chousuke | psykotic: of course, the better solution in most cases is to use a foreach or something :P |
| 03:07 | gregh | mathematicians have been using single letter variable names for centuries, it works just fine :) |
| 03:07 | psykotic | Chousuke: indeed |
| 03:07 | Chousuke | indexes are silly |
| 03:07 | tomoj | yes |
| 03:07 | tomoj | javascript annoyed me the other day with that |
| 03:07 | Chousuke | gregh: not only that, but single letter names with various subscripts! |
| 03:08 | hiredman | http://interglacial.com/~sburke/pub/Evolution-of-Lisp.ps.gz is good, but not so detailed about common lisp as to go into why its vectors are the way they are |
| 03:08 | psykotic | Chousuke: when you need to mutate, they're useful, especially when you don't have pointers, or if the iterator/cursor isn't a pointer directly |
| 03:08 | gregh | Chousuke: and that's arrays :) |
| 03:09 | Chousuke | gregh: arrays, or some weird set of different but related values :P |
| 03:09 | psykotic | btw a trick i find useful in clojure and haskell is a sort of 'key path' that can be used as both a functional getter and a setter |
| 03:09 | psykotic | when used for lookup, it just reduces the keys over the initial input map |
| 03:09 | gregh | if only fortran supported subscripts! oh wait, that's in fortress now |
| 03:10 | Chousuke | It's often impossible to read maths unless they actually tell you what the variables are first |
| 03:10 | gregh | same with programs |
| 03:10 | hiredman | psykotic: have you seen update-in and get-in? |
| 03:10 | Chousuke | there's a lot of common knowledge of course |
| 03:10 | psykotic | hiredman: no? link? |
| 03:10 | hiredman | ,(doc update-in) |
| 03:10 | clojurebot | "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created." |
| 03:10 | psykotic | hiredman: doh, yeah that's exactly what i wrote myself |
| 03:11 | Chousuke | but if you take a random wikipedia article on abstract math, it's not going to be easy to understand ;/ |
| 03:11 | tomoj | also assoc-in |
| 03:11 | psykotic | it would be nice if this interoperated smoothly with clojure.zip |
| 03:11 | psykotic | right now i don't see a way of going from a zipper to a 'key path' |
| 03:12 | psykotic | not terribly difficult to code yourself, mind |
| 03:12 | tomoj | hmm, I haven't really used zippers much |
| 03:12 | tomoj | is there anything already there for using zip paths as getters/setters? |
| 03:13 | tomoj | haven't looked at it in a while so I don't really remember how it works |
| 03:13 | psykotic | zippers are useful when you want to do several updates in a batch a la these *-in functions |
| 03:13 | psykotic | oleg's page has a neat example of using a file system zipper for doing concurrent transactions |
| 03:13 | tomoj | sounds awesome |
| 03:14 | psykotic | clojure.zip is a 'one-hole context' zipper, oleg's can have an arbitrary number of holes, corresponding to concurrent users |
| 03:14 | tomoj | I think I saw a presentation about the file system built on zippers before |
| 03:15 | hiredman | ,(pl (↕map range $ 3 λx (inc x))) |
| 03:15 | clojurebot | (1 2 3) |
| 03:15 | hiredman | done with zippers |
| 03:15 | psykotic | ,(doc pl) |
| 03:15 | clojurebot | "([& forms]); replaces a $ b with (a b) walking right to left replaces a · b with (comp a b) left to right ⌽a with (uncurry a) left to right ↕a with (flip a) left to right" |
| 03:15 | hiredman | pl is a toy of mine |
| 03:16 | tomoj | does it map to something googleable? |
| 03:16 | hiredman | no |
| 03:16 | hiredman | source is around |
| 03:16 | hiredman | clojurebot: transform? |
| 03:16 | clojurebot | transform is http://github.com/hiredman/odds-and-ends/blob/8a84e6ddbad9d71f714ba16c3e1239633228a7eb/functional.clj |
| 03:16 | psykotic | tomoj: yeah, the file system talk is great |
| 03:17 | psykotic | when i first read it years ago, it also cemented the connection in my head between zippers and delimited control |
| 03:17 | tomoj | hiredman: you just made up the language? |
| 03:17 | hiredman | um |
| 03:17 | hiredman | ,(macroexpand '(pl (↕map range $ 3 λx (inc x)))) |
| 03:17 | clojurebot | (do ((flip map) (range 3) (fn [x] (inc x)))) |
| 03:17 | hiredman | I dunno that I would call it a language |
| 03:18 | tomoj | well, I mean, your choice of what these funky symbols do under the macro |
| 03:18 | tomoj | I figured "pl" was the name of some other language or theory of lambda calculus or something |
| 03:18 | hiredman | pointless |
| 03:18 | tomoj | ah |
| 03:19 | psykotic | lambdabot on #haskell has a @pl command for converting any term to pointless (and unreadable) form |
| 03:20 | psykotic | botfight! |
| 03:21 | hiredman | clojurebot: so and so likes haskell! |
| 03:21 | clojurebot | haskell is Yo dawg, I heard you like Haskell, so I put a lazy thunk inside a lazy thunk so you don't have to compute while you don't compute. |
| 03:22 | unfo- | lol :D |
| 03:23 | tomoj | psykotic: so what do you think should be done about literate clojure? |
| 03:23 | psykotic | hiredman: btw, regarding editing things functionally, have you read conal's blog posts on 'semantic editor combinators'? |
| 03:24 | tomoj | I saw that, pretty awesome |
| 03:24 | psykotic | http://conal.net/blog/posts/semantic-editor-combinators/ |
| 03:24 | tomoj | I'm barely touching true FP magic, I think |
| 03:24 | psykotic | some of them also apply to zippering |
| 03:24 | hiredman | psykotic: I have not |
| 03:26 | tomoj | psykotic: so are you suggesting we need a better clojure.zip, or clojure.contrib.general-zip or something? |
| 03:26 | hiredman | (but I will have soon) |
| 03:26 | psykotic | tomoj: well, i only started clojuring a few days ago, i figure i'll write my own stuff if need be |
| 03:26 | hiredman | clojure.zip could use more usage |
| 03:27 | psykotic | zippers are super nice but a little scary at first |
| 03:27 | psykotic | there's a great paper by norman ramsey on using zippers in combination with a few top-level ml-style refs (a la clojure) |
| 03:28 | psykotic | it's one of the few papers on real-world non-trivial uses of them |
| 03:28 | psykotic | http://www.cs.tufts.edu/~nr/pubs/zipcfg-abstract.html |
| 03:28 | psykotic | the refs are basically used for circularity |
| 03:29 | psykotic | that's one of the issues with zippers--they only work for acyclic data structures directly, so you need to 'break cycles' with something like references |
| 03:29 | psykotic | of course, they need not be mutable references--you can also just use labels that are resolved functionally through a top-level state map of some sort |
| 03:30 | hiredman | mmmm |
| 03:34 | tomoj | psykotic: it sounds to me like that could have applications in doing neural net calculations functionally, yeah? |
| 03:35 | psykotic | dunno, it seems like that is easily done using standard functional techniques? |
| 03:36 | psykotic | don't you generally evaluate those layer by layer? |
| 03:39 | tomoj | sometimes, yes |
| 03:39 | tomoj | but the kinds I am interested in are not easily layered |
| 03:40 | psykotic | i guess the standard c approach is queue-based for those? |
| 03:41 | psykotic | i.e. you evaluate some, if they trigger, you enqueue the targets, etc |
| 03:41 | tomoj | unless there is some way to go from a directed graph to a set of layers, even with cycles? |
| 03:41 | tomoj | ah, I see |
| 03:42 | tomoj | but don't you still end up with this awful complexity if all your edges are refs? |
| 03:43 | psykotic | it doesn't seem so bad. you're just associng once per candidate node |
| 03:44 | psykotic | where zippers shine is when you have really deep structures |
| 03:44 | psykotic | here you can just use a one-level labels to data map |
| 03:45 | psykotic | so, the data for a node would store any internal state, plus a list of (weight, label) pairs for outgoing connections |
| 03:45 | tomoj | ah, and then you look up the label in a ref'd map to get the node? |
| 03:45 | psykotic | it's not refed |
| 03:46 | tomoj | well, you've got an immutable map which contains ref values, then? |
| 03:46 | psykotic | no |
| 03:46 | psykotic | no refs anywhere. the labels serve the indirection purpose. |
| 03:46 | psykotic | you can think of them as functional refs, if you will, and this one-level map as the 'heap' |
| 03:46 | tomoj | ok, but where does the activation value go |
| 03:47 | tomoj | each node has a ref pointing to its internal state? |
| 03:47 | psykotic | {:node1 {:activation :outgoing [[:node2 12] [:node3 666]]} ...} |
| 03:47 | psykotic | that's your computation state |
| 03:47 | psykotic | err, :activation 42 |
| 03:48 | tomoj | and you just put the whole thing under one big ref? |
| 03:48 | psykotic | there's no ref! |
| 03:48 | tomoj | goddammit |
| 03:48 | psykotic | hehe |
| 03:48 | psykotic | or is the point to do this concurrently? |
| 03:48 | tomoj | I feel like descartes |
| 03:48 | tomoj | yes, concurrency would be nice |
| 03:49 | psykotic | well, let's just do it the obvious functional way first |
| 03:49 | psykotic | the point is that you have this map that represents the current state of your neural net |
| 03:49 | psykotic | each round you have a list of initial candidate nodes to examine for firing |
| 03:49 | tomoj | then an update step is just a function on the map, and you get the next state back? |
| 03:50 | psykotic | as you examine those, you update the state map by associng new data under the examined node labels, enqueue the connected nodes for examination, etc, until there are no more candidates, and at the end you got the final state for that round |
| 03:50 | psykotic | yes |
| 03:50 | psykotic | this is just the standard way of doing graphs functionally |
| 03:51 | tomoj | ok, so each update step itself would iterate through a function on a queue of candidates returning another queue? |
| 03:52 | psykotic | there would be a step function that takes a node label, the current state map, and returns a list of other nodes to examine, plus the new updated state map |
| 03:52 | psykotic | then there is an outer function that repeatedly pulls stuff off the front of a list of candidates, call this step function, conjs the returned list of nodes onto its work list, |
| 03:52 | psykotic | rinse and repeat until the work list is empty |
| 03:53 | psykotic | something like that. rather than approach this directly, try to wrap your head around how you implement graph algorithms functionally, it's really the same thing |
| 03:53 | psykotic | the only difference is that here we have some auxiliary data per node aside from the usual adjacency lists |
| 03:53 | tomoj | ok |
| 03:53 | tomoj | I will have to review graph algorithms, it's been a while |
| 03:54 | psykotic | try something simple like a BFS |
| 03:54 | psykotic | with special focus on how you deal with cycles |
| 03:54 | tomoj | will do |
| 03:55 | tomoj | but, do you think that in the concurrent case, zippers would help? |
| 03:55 | psykotic | not really |
| 03:55 | psykotic | the structure here is flat, zippers don't shine |
| 03:55 | tomoj | just curious, because following up on understanding the simple functional case will take me a while |
| 03:55 | psykotic | if you wanted to do this concurrently, you'd make the map go from labels to refs to data |
| 03:56 | psykotic | but don't worry about that now |
| 04:06 | psykotic | btw, regarding paths and zippers, one very useful thing is a function that takes a list of paths and factors them into common prefixes as much as possible |
| 04:06 | psykotic | it's the core function also used in the trie data structure |
| 04:06 | psykotic | once you have that, you can very efficiently take a list of paths and associated update functions and run them as a single 'transaction' using a zipper, very efficiently |
| 04:26 | Licenser_ | morning my lispy friends! |
| 04:34 | invis87 | Hi all |
| 04:34 | invis87 | Could you help me ? How can I write a function which print some message different times. Something like this: (defn my-hi [x] (while (not (zero? x)) ((println "hi") (dec x)))) |
| 04:35 | psykotic | ,(letfn [(say-hi [n] (dotimes n (println "hi")))] (say-hi 10) |
| 04:35 | clojurebot | EOF while reading |
| 04:35 | Chousuke | (dec x) doesn't actually decrease x :) |
| 04:35 | Chousuke | but if you don't want to cheat using dotimes, you need to use recursion |
| 04:36 | invis87 | how :) |
| 04:36 | Chousuke | something like (defn hi [x] (when-not (zero? x) (println "hi") (recur (dec x)))) |
| 04:37 | invis87 | So I cant use it like while in java ? |
| 04:37 | Chousuke | no. |
| 04:37 | invis87 | without recursion |
| 04:37 | invis87 | hmm, thanks |
| 04:37 | Chousuke | there is a while in Clojure, but it's for java interop mostly |
| 04:37 | Chousuke | most of the time you're dealing with immutable values, so while is completely pointless :) |
| 04:38 | Chousuke | because the condition of the while would be immutable too |
| 04:38 | Blkt | Chousuke: (dec 2) => 1 in repl |
| 04:38 | Chousuke | Blkt: yes, and that doesn't change 2 |
| 04:38 | Blkt | ah, rebinding |
| 04:38 | Blkt | true |
| 04:38 | invis87 | (def x 5) , => x |
| 04:38 | invis87 | 5 |
| 04:38 | invis87 | (dec x) |
| 04:38 | invis87 | 4 |
| 04:39 | invis87 | but |
| 04:39 | invis87 | x |
| 04:39 | invis87 | 5 |
| 04:39 | invis87 | :D |
| 04:39 | Chousuke | yes. |
| 04:39 | Blkt | yy |
| 04:39 | Chousuke | that's the point |
| 04:39 | Chousuke | it takes a while to wrap your brain around those semantics, but it makes many things a lot easier |
| 04:40 | Chousuke | if you program using immutable values, you never need to worry about someone else corrupting your data |
| 04:40 | invis87 | How I can write function like my-hi without while or like-while ? |
| 04:40 | Chousuke | you can pass your data structures wherever you want and just assume that they are not affected by it at all. |
| 04:41 | Chousuke | exactly because they are immutable. |
| 04:42 | Chousuke | invis87: well, the simplest way would of course be (dotimes [i 10] (println "hi")) |
| 04:42 | invis87 | hmm |
| 04:42 | invis87 | )) |
| 04:42 | Chousuke | or you can use the loop special form, but it's pretty much equivalent to the recursive function approach |
| 04:42 | bsteuber | invis87: when you really *want* to change something, there are vars, refs, atoms and agents - but most of the time you won't |
| 04:42 | invis87 | but dotimes is macro |
| 04:43 | Chousuke | invis87: yes, it expands to a loop |
| 04:43 | Chousuke | but loops in clojure are not like loops in java. They're recursive, which means you still can't modify things arbitrarily and need to use recur to "restart" the loop |
| 04:44 | invis87 | wow |
| 04:44 | invis87 | So there no loop without recursion ? |
| 04:44 | Chousuke | pretty much. |
| 04:44 | invis87 | it is like O_o |
| 04:44 | invis87 | for me |
| 04:44 | hiredman | ,(macroexpand '(dotimes [n 1e50M] (println n))) |
| 04:44 | clojurebot | (let* [n__5299__auto__ (clojure.core/int 1E+50M)] (clojure.core/loop [n (clojure.core/int 0)] (clojure.core/when (clojure.core/< n n__5299__auto__) (println n) (recur (clojure.core/unchecked-inc n))))) |
| 04:45 | Chousuke | but that's not a problem, since non-recursive loops don't make sense in a functional program anyway |
| 04:45 | hiredman | I can't say I care for that cast to int and the unchecked-inc |
| 04:45 | Chousuke | hiredman: it's optimised for speed and side-effects I suppose :P |
| 04:45 | hiredman | :/ |
| 04:46 | tomoj | psykotic: that sounds awesome |
| 04:47 | Chousuke | invis87: The key to functional programming is that you always need to capture the return value of things :) |
| 04:47 | psykotic | Chousuke: you can easily have both. you simply check on entry to the loop if the thing fits in an unboxed integer. |
| 04:48 | psykotic | you know the bound ahead of time |
| 04:49 | hiredman | ,(macroexpand-1 '(dotimes [n m] (println n))) |
| 04:49 | clojurebot | (clojure.core/let [n__5299__auto__ (clojure.core/int m)] (clojure.core/loop [n (clojure.core/int 0)] (clojure.core/when (clojure.core/< n n__5299__auto__) (println n) (recur (clojure.core/unchecked-inc n))))) |
| 04:50 | Chousuke | invis87: Because functions (ideally) have no side-effects, the only way they can communicate with the caller is by their return value. Clojure isn't pure though, so sometimes you write non-functional code where that doesn't apply, but that's another story |
| 04:50 | psykotic | when i say ahead of time, i obviously mean on entry to the loop--the termination condition isn't dynamically reevaluated with each iteration |
| 04:50 | psykotic | hence, you can just have two code paths |
| 04:50 | hiredman | sure |
| 04:50 | psykotic | at the very least it should throw an exception for bounds that don't fit in an unboxed integer |
| 04:51 | tomoj | like if you tried to pass a long in? |
| 04:51 | Chousuke | ,Integer/MAX_INT |
| 04:51 | clojurebot | java.lang.Exception: Unable to find static field: MAX_INT in class java.lang.Integer |
| 04:51 | Chousuke | hm, what's the field ;/ |
| 04:51 | tomoj | ,Integer/MAX_VALUE |
| 04:51 | clojurebot | 2147483647 |
| 04:51 | tomoj | soo... |
| 04:51 | psykotic | 2 billion isn't that many iterations |
| 04:51 | tomoj | wow |
| 04:52 | Chousuke | for side-effects I would say it is. :/ |
| 04:52 | hiredman | ,(int 1e100000M) |
| 04:52 | clojurebot | 0 |
| 04:53 | Chousuke | hm, that's not very good behaviour |
| 04:53 | hiredman | ,(int 1e1000M) |
| 04:53 | clojurebot | 0 |
| 04:53 | tomoj | ,(dotimes [i 1e1000M] (println "hello")) |
| 04:53 | clojurebot | nil |
| 04:54 | hiredman | … |
| 04:54 | Chousuke | I think that ought to be fixed :P |
| 04:55 | Chousuke | Could probably just throw an exception on more than MAXINT iterations. If you need more you can always write your own loop |
| 04:55 | tomoj | ,(int (inc (long Integer/MAX_VALUE))) |
| 04:55 | clojurebot | -2147483648 |
| 04:55 | hiredman | clojurebot: whose job is it to fix it? |
| 04:55 | clojurebot | who's job is it to keep hiredman in line? is <reply>That's my job |
| 04:57 | psykotic | hiredman: you wrote clojurebot? |
| 04:57 | hiredman | I guess |
| 04:57 | psykotic | i guess java makes it easy to jail something like a bot |
| 04:57 | psykotic | or the jvm rather |
| 04:58 | Chousuke | well, clojurebot's sandbox is far from perfect :P |
| 04:58 | hiredman | yes |
| 04:58 | Chousuke | I guess you can't take over the machine it runs on, but I'm sure there are ways to DoS clojurebot |
| 04:59 | gregh | ask him to evaluate the ackermann function for suitable inputs, for example |
| 05:00 | tomoj | wouldn't it time out? |
| 05:01 | gregh | time out or space out, whichever comes first :) |
| 05:01 | psykotic | does the jvm support 'jail compartments' for pieces of running within the same jvm? |
| 05:02 | hiredman | ,(apply trampoline (repeat 2 (fn a [x] #(x a)) ) |
| 05:02 | clojurebot | EOF while reading |
| 05:02 | psykotic | *pieces of code |
| 05:02 | hiredman | ,(apply trampoline (repeat 2 (fn a [x] #(x a)))) |
| 05:02 | psykotic | hiredman: speaking of which, have you considered auto-paren closing :) |
| 05:02 | clojurebot | Execution Timed Out |
| 05:02 | hiredman | psykotic: nope |
| 05:03 | gregh | I guess that's a pretty short timeout |
| 05:03 | hiredman | if I recall it is ten seconds |
| 05:04 | psykotic | btw, one thing i often wish for is a lazy print/println |
| 05:04 | psykotic | or at least chunky semilazy |
| 05:04 | hiredman | uh, what? |
| 05:04 | psykotic | as in, won't coerce to str directly but will doseq as a seq of chars |
| 05:05 | psykotic | maybe it's because i'm used to ghci |
| 05:05 | psykotic | it's nice to be able to println an infinite sequence and ctrl-c in the middle |
| 05:06 | psykotic | it would also mean you could have clojurebot print some prefix of an infinite sequence with ... after a certain point |
| 05:06 | gregh | it might be easiest to just write one whenever you need that |
| 05:06 | psykotic | and hack slime's repl to use mine, yeah |
| 05:09 | psykotic | right now all the print-method implementations print directly using .write |
| 05:10 | hiredman | ,(doc *print-level*) |
| 05:10 | clojurebot | "; *print-level* controls how many levels deep the printer will print nested objects. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum level to print. Each argument to print is at level 0; if an argument is a collection, its items are at level 1; and so on. If an object is a collection and is at a level greater than or equal to the value bound to *print-le |
| 05:11 | psykotic | that doesn't apply to a flat sequence |
| 05:12 | psykotic | anyway, the whole printer infrastructure is 1960s lisp |
| 05:12 | hiredman | ,(doc *print-length*) |
| 05:12 | clojurebot | "; *print-length* controls how many items of each collection the printer will print. If it is bound to logical false, there is no limit. Otherwise, it must be bound to an integer indicating the maximum number of items of each collection to print. If a collection contains more items, the printer will print items up to the limit followed by '...' to represent the remaining items. The root binding is nil indicating no limit." |
| 05:12 | psykotic | hiredman: useful |
| 05:12 | psykotic | it doesn't change the fact that the printer is ugly imperative style |
| 05:14 | psykotic | ,(binding [*print-length* 10] (println (repeat 42))) |
| 05:14 | clojurebot | (42 42 42 42 42 42 42 42 42 42 ...) |
| 05:14 | psykotic | by ugly imperative style i mean the fact that it doesn't separate the physical printing from the formatting |
| 05:15 | psykotic | for the simplest things like length and depth truncation, it's fortunate that top-down dynamic binding lets you do most of what you want |
| 05:16 | psykotic | hiredman: i guess you've read 'the design of a pretty printing library' by hughes? |
| 05:16 | psykotic | it's 15 years old at this point |
| 05:16 | psykotic | GHC has an updated version designed by simon peyton jones |
| 05:19 | psykotic | dumb question, for map destructuring patterns, is there a way to bind the unmatched remainder of the map? |
| 05:19 | psykotic | something like :rest to go with :as |
| 05:27 | triyo | Are there any technical papers available on Clojure implementation? |
| 05:29 | tomoj | psykotic: I don't think so |
| 05:30 | tomoj | you specifically want to drop the keys you explicitly pick out? |
| 05:30 | psykotic | if you think of a vector as a map from integers, then it's the same as & xs in vector binding patterns |
| 05:30 | psykotic | so yes |
| 05:31 | psykotic | obviously not too hard to call disj myself :) |
| 05:32 | tomoj | dissoc? |
| 05:36 | psykotic | typo, yes |
| 06:47 | powr-toc | Is there a way to use clojure.contrib.repl-ln with swank/slime? |
| 06:52 | Fossi | powr-toc: as in? you want a repl in emacs? |
| 06:54 | powr-toc | Fossi: No, I already have a swank repl... It's just repl-ln from contrib has better line number support... as the swank repl doesn't seem to display line numbers for snippets evaluated into swank... I was wondering if repl-ln might do the job, but I guess it wont work |
| 06:54 | Fossi | hmmm. i'd guess not |
| 06:55 | powr-toc | I just wish swank would track the line numbers for evaluated snippets when stack traces are thrown. |
| 06:56 | Fossi | never occured to me that would be useful |
| 06:58 | powr-toc | Fossi: well, during development I evaluate most of my programs inside Emacs/Swank, so when it blows up with a stacktrace, it'd be nice to know what lines it's referring to |
| 07:12 | cemerick | swank doesn't include line numbers when it eval's a file? |
| 07:14 | Fossi | can you easily extend a gen-classed class? you have to compile and then you can proxy it, right? |
| 07:14 | Fossi | damn, i guess i will need another gen-class though |
| 07:18 | Fossi | wow. my hands actually still know the paredit keys. that's cool. |
| 07:19 | Maddas | :-) |
| 08:28 | LauJensen | Anybody got a link to a solid study on the correlation between size of code-base and maintenance costs?' |
| 08:31 | caljunior | http://users.jyu.fi/~koskinen/smcosts.htm |
| 08:31 | caljunior | old and rather general but possibly helpful. |
| 08:40 | etate | ehh JDK doesn't include the server hotspot vm on 32bit windows?? |
| 08:42 | cemerick | etate: really? I seem to remember using -server successfully in 32-bit windows. |
| 08:43 | etate | cemerick: yeah i just installed the latest JDK, and no -server |
| 08:43 | cemerick | huh. Maybe that changed with 1.6? |
| 08:43 | cemerick | almost certain I ran -server with 1.5 |
| 08:44 | etate | cemerick: oh wait, no its there... just not in the right place |
| 08:44 | cemerick | oh, you mean the actual .dll |
| 08:45 | etate | cemerick: no i mean when i installed it it created 2 JREs, one in the jdk folder and one in program files |
| 08:45 | cemerick | oh, right |
| 08:45 | etate | cemerick: my system for some reason only knows about the one in program files, which is the wrong one |
| 08:46 | etate | cemerick: even though its not in path... i suspect system32 weirdness |
| 08:46 | cemerick | etate: well, for you :-) Client vm is far better for 90% of users. |
| 08:46 | etate | cemerick: whys that? |
| 08:46 | etate | cemerick: oh i see :) |
| 08:46 | cemerick | faster startup time and shorter gc pauses |
| 08:46 | cemerick | the selection of the java vm is driven by the registry, not the path |
| 08:48 | etate | cemerick: man i'm new to windows :( how can i change it in the registry? |
| 08:49 | cemerick | etate: regedit.exe, and have fun |
| 08:49 | cemerick | try to not break anything, tho :-) |
| 08:49 | etate | cemerick: am on windows 7 i think it works a bit different |
| 08:49 | cemerick | ah, can't help you there |
| 08:49 | cemerick | I think there's a java control panel where you can change it easily, but I'm nowhere near a windows box. |
| 08:50 | etate | lucky you |
| 08:50 | etate | things were so much easier in linux *sigh* |
| 08:51 | cemerick | I do touch windows for testing and such -- I generally ensure that I never install the consumer jre's, and then you're fine. |
| 08:51 | cemerick | if you set JAVA_HOME, that might resolve things for you simply |
| 09:05 | cemerick | fogus: a little crazy, huh :-) |
| 09:05 | fogus | Crazy yes |
| 09:06 | caljunior | LauJensen: http://sunset.usc.edu/csse/TECHRPTS/2008/usc-csse-2008-808/usc-csse-2008-808.pdf |
| 09:06 | LauJensen | caljunior: Thanks - I'll go have a look |
| 09:09 | etate | cemerick: JAVA_HOME is set to the right JDK :/ |
| 09:09 | cemerick | etate: it needs to be pointed at the JDK's jre |
| 09:09 | cemerick | not the JDK top level |
| 09:09 | etate | cemerick: oh i'll try that, i was just reading that apparently theres a java in system32 |
| 09:10 | cemerick | the 1.1.6 one, perhaps |
| 09:10 | cemerick | or a shim that bootstraps based on the registry settings |
| 09:12 | caljunior | the site seems to be a goldmine for software development cost modelling: csse.usc.edu/csse/research/COCOMOII/cocomo_papers.htm |
| 09:15 | LauJensen | Great! |
| 09:17 | sunny36 | This is probably a stupid question. What kind of app should I write to learn to learn clojure? I've been doing katas and it's starting to get bored. |
| 09:24 | etate | cemerick: wow this really sucks, i can't actually add a jre to the java config panel because it doesn't save my changes |
| 09:24 | zmila | sunny36 - try to solve project euler promblems :) |
| 09:25 | sunny36 | zmila: I've tried a number of those as well. Those are mostly math problems. |
| 09:26 | cemerick | etate: to back up a bit: why do you care what jre is used? Any dev tool with its salt will allow you to set JAVA_HOME and be done with it. |
| 09:27 | cemerick | used by default*, I mean |
| 09:29 | wthidden | how long does a paste.lisp.org take to arrive here? |
| 09:29 | cemerick | wthidden: that bot's been dead for a while, I think |
| 09:30 | wthidden | <sigh/> |
| 09:30 | The-Kenny | wthidden: If it's working, almost instantly |
| 09:30 | cemerick | ...which hasn't been true for weeks :-| |
| 09:30 | etate | cemerick: i want to be able to do java -server at the cmd line without it breaking |
| 09:31 | wthidden | ok... then i'll do it the hardway http://paste.lisp.org/display/96284 |
| 09:31 | cemerick | etate: OK, but why? Building up command line invocations by hand is generally a bad idea IMO, so surely you're using some tool to do it. |
| 09:31 | wthidden | i'm having issues with loading/finding a java static class |
| 09:31 | vy | fogus: IIRC, you were mentioning about a small script that parses Clojure source code to extract the API docs. What's the status of it? |
| 09:31 | wthidden | I see most of the classes just not the static sub-classes. |
| 09:32 | cemerick | otherwise, it's a windows sysadmin issue, and you know what I know in that dept. already :-) |
| 09:32 | etate | cemerick: when i load these commands in a bash script it has this issue too |
| 09:32 | etate | cemerick: sorry, a .bat script |
| 09:32 | rhickey | cemerick: saw your tweet - so, what are the big missing items or pain points for Clojure IDE users? (other than loneliness :) |
| 09:33 | etate | cemerick: i've fixed it anyhow by deleting the standard jre |
| 09:33 | cemerick | etate: ah, nuclear's always the best option :-D |
| 09:34 | cemerick | rhickey: ha |
| 09:34 | etate | cemerick: mwahaha :) |
| 09:34 | cemerick | rhickey: better put on your chasm-crossing suit |
| 09:34 | rhickey | cemerick: fwiw I'm sympathetic to your premise |
| 09:35 | ttmrichter | sunny36: Pick something you're interested in day-to-day. Make simple software to help automate it. |
| 09:35 | cemerick | rhickey: anyway, this is an entirely social problem. Maybe Eric has something different to say, but I don't think there's anything missing from clojure itself that would make a world-beating IDE out of reach. |
| 09:35 | icey | i'm pretty convinced that if someone repackaged emacs and called it "awesomeEd 0.2" or something appropriately web 2.0, that it would get a lot less pushback |
| 09:35 | cemerick | Really, I'd say enclojure (and, I hear, the intellij plugin) are getting pretty close in that regard. |
| 09:36 | etate | cemerick: enclojure is uber slow on my machine... dual core :/ |
| 09:36 | etate | cemerick: sorry i mean, netbeans |
| 09:37 | etate | cemerick: i think whats missing from enclojure is paredit |
| 09:38 | cemerick | rhickey: the biggest issues IMO are (a) initial contact with clojure right now is, more often than not, in conjunction with emacs, which is a *huge* warning flag for a super-supermajority of developers, (b) IDE options are generally not mentioned by clojure advocates, and (c) there is, shall we say, a certain smugness among emacs users towards even the concept of IDEs that is unproductive. |
| 09:39 | cemerick | etate: I'm in NB and enclojure all day, every day. Not sure what to say there. |
| 09:39 | etate | rhickey: well lispworks is basically emacs :> |
| 09:39 | cemerick | etate: um, wow, no :-) |
| 09:39 | etate | cemerick: it has the same keys, buffer concepts |
| 09:40 | cemerick | etate: bindings and buffers are both inconsequential |
| 09:40 | rhickey | etate: I never used the emacs bindings in LW |
| 09:40 | cemerick | NetBeans, Eclipse, and IntelliJ all have emacs bindings and buffers too, so that's clearly not the differentiating factor. |
| 09:41 | etate | i think paredit is the most important thing in any Lisp IDE |
| 09:41 | cemerick | anyway, the differences among editors is moot for this conversation IMO. I take it as a premise that people like the environments they like -- I just don't want that getting in the way of clojure adoption (or, at least, honest evaluation of it). |
| 09:41 | rhickey | cemerick: so, the dev who wants to try Clojure and not emacs at the same time - what are the hurdles IYO? |
| 09:42 | cemerick | rhickey: perception of the clojure community as accepting/supportive of *only* emacs as the development environment. |
| 09:44 | zmila | not only, i use Eclipse with CCW - it's buggy, but Eclipse is the IDE we use for other projects (java, html) |
| 09:44 | rhickey | cemerick: well you can't expect emacs fans to advocate for netbeans, and the numbers are there right now |
| 09:44 | etate | cemerick: i don't know, when i first came to clojure (yesterday), i thought there were more ide options than i expected. |
| 09:44 | rhickey | cemerick: maybe people like you need to write more articles about enclojure? |
| 09:45 | etate | cemerick: the biggest problem is the alpha tag attached to enclojure, a lot of devs would feel uncomfortable with this - and fwiw i think its less alpha than many beta open source projects |
| 09:45 | The-Kenny | Is there an article or a site which lists the ide-choices with screenshots etc.? |
| 09:45 | The-Kenny | Maybe a wiki |
| 09:47 | cemerick | rhickey: yeah, and I may do that. But then, I might do that once, or whatever. It's very hard to make a dent compared to those that are passionate about their environment (which one sorta has to be if one is to use emacs effectively). |
| 09:48 | LauJensen | rhickey: Is there an interest on your part in adopting something other than Emacs ? |
| 09:48 | sattvik | I am a long-tim Vim user. I tried out Emacs for some Lisp development, and I agree that it probably provides a better Clojure/Lisp development experience than Vim. However, trying to learn Emacs is a huge hurdle for someone for whom Vim is second-nature. I am fairly happy with VimClojure, though. It's not perfect or as nice as SLIME, but works well enough. |
| 09:48 | cemerick | Sometime next month, I'm going to be upgrading across the board, that'll be a good time to do a screencast or something about enclojure...and maybe see how far along the intellij plugin has come. |
| 09:49 | cemerick | If the latter is really good, that would be a big breakthrough -- having a commercial vendor behind a plugin like that would help a lot. |
| 09:51 | icey | Maybe if there was some *very short* documentation about the absolute basics in emacs people would be less scared of it |
| 09:52 | icey | i.e. "Open a file with C-x C-f", "Save with C-x C-s", "Paste with C-y" etc |
| 09:52 | icey | in other words, show them how it can be a regular old text editor first... then later they can figure out the cool parts |
| 09:53 | tr8dr | my 2 cents: the problem with emacs as an environment is that there is a lot more investment in IDEs for languages such as java. With clojure one may be in a multi-language environment. The investment in the last 10 yrs or more has been in IDEs |
| 09:53 | sattvik | icey: If it's a question of people who aren't used to vim or emacs, the tutorial that comes with emacs isn't bad. |
| 09:54 | Chousuke | tr8dr: emacs is actually capable of functioning as an IDE |
| 09:54 | cemerick | icey: sorry, educating the masses about emacs is a nonstarter. |
| 09:54 | icey | I guess I just don't see why; you're not talking about introducing people to emacs to do HTML |
| 09:54 | icey | (or PHP for example) |
| 09:54 | tr8dr | I've used emacs for many yrs, but IMO, is the best editor for sure, but poor relatively when it comes to the many facilities available in an IDE |
| 09:55 | Chousuke | tr8dr: and I don't just mean because it has tools and you can use them together. there's a library for implementing IDE features like refactoring, managing projects, and what have you. and then they have implementations of IDEs for C, C++ and Java at least :P |
| 09:56 | cemerick | icey: because software development is done in one of four environments, and I want the clojure community to grow without boiling the ocean of development environments. |
| 09:56 | Chousuke | in a way, emacs is like the JVM |
| 09:56 | Chousuke | a platform |
| 09:56 | icey | (fwiw I learned emacs specifically for Clojure about 6 months ago; I'm not an emacs pro or anything like that. I think the FUD seriously outweighs the difficulties of picking up the basics) |
| 09:57 | fogus | vy: Did I say that? |
| 09:57 | tr8dr | I'll admit that I switched over to IDEs 5-6 yrs ago, so the state of the art in emacs may have changed. I used to use IDE-like facilties for C++ and found them lacking |
| 09:57 | tr8dr | regardless of merit, most professional developers use IDEs. |
| 09:58 | tr8dr | and don;t want to muck around with elisp and other stuff to get a functional env |
| 09:58 | cemerick | tr8dr: +1 there |
| 09:58 | rhickey | A big argument for IDEs is that if people are already using them for Java, and want to integrate Clojure with their Java projects, asking them to move to emacs is a non-starter, ditto asking them to switch IDEs |
| 09:58 | LauJensen | I'm very fond of Emacs and didn't think it overly difficult to pick up - but are there valid reasons for switching to Enclojure et al ? |
| 09:59 | LauJensen | (except what Rich just said, in better Java integration) |
| 09:59 | Raynes | Not really. |
| 09:59 | tr8dr | the ideal for me would be a full emacs editor embedded in eclipse |
| 09:59 | cemerick | LauJensen: if you're happy with emacs, probably not. Maybe if you need to do a significant amt of java dev. |
| 09:59 | sattvik | tr8dr: That depends on the shop. I've been in many places where IDEs aren't used at all. In some cases where IDEs are used, it's because it is required. |
| 09:59 | LauJensen | k |
| 10:00 | vy | fogus: IIRC, you will be using it for the book and stuff. |
| 10:00 | Chousuke | for clojure work, my ideal would be an editor extensible in lisp, with vi-like editing controls, SLIME-style lisp integration and paredit |
| 10:00 | Chousuke | emacs fails at the vi-like editing :P |
| 10:00 | Chousuke | but otherwise it's good |
| 10:01 | cemerick | rhickey: switching IDEs isn't a big deal for, say, the top quarter of java devs -- who often use multiple IDEs in a week anyway. So, making it clear that there's a solid plugin for one of the three will ensure that they'll give clojure a whirl. |
| 10:01 | mattrepl | Chousuke: viper mode? |
| 10:01 | cemerick | make it seem like emacs is the only sane choice, and they'll just shrug and fiddle with scala/groovy/jruby/whatever some more |
| 10:01 | Chousuke | mattrepl: doesn't play nice with paredit |
| 10:01 | fogus | vy: Ah yes. That is still internal to chouser and myself and is pretty rough. It does what we need and only what we need, but after the book is done there might be some general value for others |
| 10:01 | Chousuke | mattrepl: and I won't write lisp without paredit :P |
| 10:02 | rhickey | cemerick: you seem to be asking for people to behave differently, which can't be a serious option |
| 10:02 | mattrepl | rightfully so |
| 10:02 | sattvik | Chousuke: Bingo. I want to like Emacs, but I'm hooked editing in vi mode. I use it everywhere: my shell, my browser, my editor, etc. |
| 10:02 | cemerick | rhickey: really? where? |
| 10:03 | etate | sattvik: viper-mode ? |
| 10:03 | Chousuke | sattvik: emacs actually can do vi-like editing very well if that's all you want, but it really causes problems, because many of the other emacs addons are not written with vi-like controls in mind |
| 10:03 | mattrepl | etate: see above, incompatible with paredit |
| 10:04 | licoresse | in a (proxy [JPanel MouseListener ....] ...) how do I override the constructor? |
| 10:04 | etate | mattrepl: can't you just rebind the paredit keys? :) |
| 10:04 | Chousuke | etate: you would need to rebind *viper* keys so that it calls paredit functions |
| 10:04 | mattrepl | dunno, not sure how viper-mode works (I'm quite happy using common emacs bindings when in emacs) |
| 10:04 | Chousuke | etate: one of the most apparent problems is dd deleting a whole line |
| 10:05 | Chousuke | etate: which is not good for lisp code, since it'll break the structure often |
| 10:05 | etate | Chousuke: can't you rebind dd so that it kills sexp instead of the actual line, actually ctrl-W also kills the structure |
| 10:05 | rhickey | cemerick: that the collective voice of CLojure users is making it seem like emacs is the only viable choice, mostly by not talking about other choices they don't use. Or are people actively saying emacs is the only viable choice? |
| 10:06 | etate | rhickey: I don't think its the only viable choice, theres enclojure, vim-clojure, ccw.. its just the best choice. :) |
| 10:07 | Chousuke | I think emacs is the most popular, and perhaps most mature, choice. |
| 10:07 | Chousuke | bestness depends on your needs, of course |
| 10:07 | mattrepl | even when developing mixed JVM-language projects I always go back to using emacs/slime. even if it means launching an app from Eclipse or IDEA with a swank socket open |
| 10:07 | Chousuke | :P |
| 10:07 | LauJensen | Last time I used Enclojure it certainly left me with the feeling that Emacs was the only viable pick - VimClojure is also quite good, but requires a fondness for Vim which I dont have |
| 10:07 | rhickey | cemerick: I know I've mentioned alternative environments for as long as they have existed, and presented from within Enclojure at JavaOne script bowl last year. http://clojure.org/getting_started seems fair |
| 10:08 | Chousuke | it might also be that many clojure programmers have lisp background and thus would favour emacs over Java IDEs |
| 10:08 | rhickey | cemerick: so, without putting words in your mouth, how do we improve the IDE story? |
| 10:09 | sattvik | etate: I tried it, but what I use is more than just movement and simple edit commands. There are other things such as switching between buffers, windows, and using other Vi plugins. I could probably spend a lot of time adapting to Emacs and playing with bindings, but it's not worth it to me. I have found tools that make Lisp/Clojure development in Vim good enough. |
| 10:11 | cemerick | rhickey: oh, I wouldn't suggest that emacs fans talk up enclojure or anything, but if one is interested in seeing clojure usage grow, one should not suggest to devs coming from a totally java background (for example) learn emacs as a first step. I've seen this happening, and intervened as well as I could, but I can't be everywhere. :-) |
| 10:12 | rhickey | cemerick: so a call to emacs fans to mention all the choices? |
| 10:12 | licoresse | looking for a rather complete example of proxy with overrides etc |
| 10:12 | cemerick | rhickey: yeah, I think what you've put out is great. I guess it all comes down to whether us non-emacs users can generate enough noise to counter the acolytes. ;-) |
| 10:12 | licoresse | my problem is that I get no error messages when the fn definitions are wrong |
| 10:13 | cemerick | rhickey: well, I suppose people need to decide whether they care about emacs or clojure more |
| 10:13 | cemerick | If the latter, one wouldn't reasonably suggest the former in many, many settings. |
| 10:14 | dcnstrct | cemerick, I was just about to ask a question about setting up swank/clime for clojure... what do you recommend instead of emacs ? |
| 10:14 | Chousuke | I can't honestly suggest IDE plugins to most people since I have no idea how well they work |
| 10:14 | Chousuke | I can at best say "There are IDE plugins, you might want to try them" |
| 10:14 | cemerick | Chousuke: that's honestly good enough |
| 10:14 | rsynnott | poor emacs! |
| 10:14 | rsynnott | No-one loves it |
| 10:15 | licoresse | I do! |
| 10:15 | cemerick | dcnstrct: enclojure for NetBeans is what I use all day, and it's very nice; I also hear good things about the intellij plugin |
| 10:15 | cemerick | rsynnott: inch wide, and miles deep, they do. :-) |
| 10:16 | rsynnott | I had a look at enclojure at some point; I found netbeans to be unreasonably slow |
| 10:16 | rsynnott | (though possibly it's the fault of my computer) |
| 10:16 | rsynnott | I'm an emacs person myself |
| 10:16 | cemerick | dcnstrct: you can poke into #enclojure for support with that, and there's a google group. I think there's forums for the intellij plugin. |
| 10:17 | dcnstrct | I was hoping you had some vi solution that works kind of like slime. I want something terminal based so I can make use of every pixel of resolution on this 10" netbook. |
| 10:17 | Chousuke | VimClojure supports swank somehow I think |
| 10:17 | dcnstrct | can enclojure do a "full screen" mode ? |
| 10:17 | dcnstrct | I'll check out VimClojure |
| 10:18 | Chousuke | or might not be swank, but an integrated repl anyway |
| 10:18 | cemerick | dcnstrct: netbeans has a nice full screen mode |
| 10:18 | Raynes | The only people who prefer Vi(m) over Emacs are just too afraid of change. /intentionalflamebait |
| 10:18 | Chousuke | :P |
| 10:18 | cemerick | :-( |
| 10:19 | Chousuke | I still navigate using arrows in emacs |
| 10:19 | sattvik | dcnstrct: VimClojure is pretty good. If you use screen or have two terminals open, you can run a REPL in one of them and Vim in the other. |
| 10:19 | Chousuke | I just can't learn the modifier key ways of emacs |
| 10:19 | Raynes | Chousuke: So do I. :> |
| 10:19 | Chousuke | though often I also use search to navigate |
| 10:19 | etate | sattvik: emacs doesn't play well with screen :( |
| 10:20 | Chousuke | which is faster than arrows or meta-whatever |
| 10:20 | Raynes | I'm ashamed to say that I use the scroll wheel and left mouse button more than I should. :( |
| 10:21 | Chousuke | heh |
| 10:21 | Chousuke | the scroll wheel in my mouse is broken, and I still haven't been bothered by that enough to buy a new one :P |
| 10:22 | Chousuke | I barely use it even when browsing |
| 10:22 | pjackson | Whilst I was trying to learn C-{n,p} etc. I bound the arrow keys to (insert "no"), or something equally annoying. |
| 10:22 | pjackson | I had it down within the day. |
| 10:23 | nuba | xmonad |
| 10:23 | dcnstrct | I will give both VimClojure and Enclojure(fullscreen) a shot before I circle back around to trying to fix slime/swank/emacs |
| 10:23 | nuba | and vimperator |
| 10:23 | nuba | Chousuke: will get you a long way mouseless |
| 10:23 | Raynes | XMonad is great for a while, but then it gets old. |
| 10:23 | Chousuke | nuba: yeah, I use vimperator |
| 10:23 | Chousuke | nuba: on OS X though |
| 10:23 | dcnstrct | I like Awesome for a window manager |
| 10:23 | Raynes | Probably not so much "fixing" as much as it is "doing it right". :p |
| 10:23 | nuba | Raynes: have you tried tiling window managers and then went back for the world of resize/move/etc. ? |
| 10:24 | Chousuke | nuba: the only app that really needs a mouse is the finder :( |
| 10:24 | Raynes | But "doing it right" is relative, because there are many different ways to do it right. |
| 10:24 | Raynes | nuba: Yes. Several. |
| 10:25 | Raynes | I used XMonad for several months, and Bluetile for about 1 and a half. |
| 10:25 | Raynes | I ended up full circle back at Metacity. |
| 10:25 | licoresse | A window manager I like a lot on OS X is SizeUp |
| 10:25 | sattvik | dcnstrct: With a proper classpath set up, you can run something like http://gist.github.com/330413 to set up nailgun and start a REPL. |
| 10:25 | nuba | Raynes: would you be willing to say more about it? I've switched to xmonad last month after trying stumpwm for a while and being a compiz whiz (scale and groups and etc) for some years before that |
| 10:26 | nuba | Raynes: i've grown tired of moving windows and resizing windows around |
| 10:26 | nuba | Raynes: and i'm pretty happy with xmonad atm. but a new perspective is always good to hear. |
| 10:26 | Raynes | I just got tired of the way things looked, and configuration to make it better was too much of a pain. That and a couple of bugs such as the infamous gray-swing-window bug and such. |
| 10:27 | nuba | Raynes: so you actually fine-tuned it with xmonad-contrib before giving up ? |
| 10:27 | Raynes | If you have one thing the size you need it, then nothing else on the screen is the size you need it, and changing the sizes takes longer for me with the keyboard. This is probably a side effect of a small monitor. |
| 10:27 | Raynes | I didn't do much 'fine tuning'. |
| 10:28 | Raynes | 'Fine tuning' to get things the way I wanted would have been more frustrating and time consuming then pkill xmonad && metacity -replace |
| 10:29 | Raynes | ;) |
| 10:29 | nuba | I can relate to that in a way, I use two screens, the notebook's large and high-res monitor and a smaller one, 15" LCD and 1024x768. its stellar on the larger and not quite so in the smaller one. |
| 10:29 | nuba | on the fine tuning, i saw a bunch of xmonad.hs then cooked up my own setup from that. and i'm pretty happy about it now. |
| 10:29 | nuba | but thanks for sharing! |
| 10:30 | Raynes | Bluetile was nice and I would have stuck with it, if not for general ugliness, inefficiency, and buggyness. |
| 10:30 | dcnstrct | http://awesome.naquadah.org/ <-- anyone who likes xmonad should at least glance at this project sometime if not try it. |
| 10:31 | Raynes | For example, if you have Firefox maximized over other not-maximized windows, then clicking on the area where the border of one of those windows is below firefox, IN Firefox, latches on and resizes the window below it. |
| 10:31 | Raynes | I use firefox as an example because it's usually maximized, but it applies to any window that overlaps other windows. |
| 10:36 | Mec | Is there a clearn/better/more idiomatic way to do any of this: http://go.pastie.org/866621 it seems a bit clumsy |
| 10:38 | psykotic | wow, i missed an emacs slug fest |
| 10:38 | LauJensen | What is the Weapon of Choice for non Emacers, Enclojure of IntelliJ ? I'm a little scared about the 'alpha' on Enclojure's website :) |
| 10:39 | Mec | I tried those two, gave up and went back to clojurebox |
| 10:39 | psykotic | i actually hope that attention on editor integration won't become too fragmented. frankly, slime integration still isn't that great--if enclojure, etc, isn't even up to that standard, it's a call to arms for us emacsers |
| 10:41 | psykotic | and regarding the 'identification' of a language with an editor, it didn't seem to hurt the uptake in ruby when rails hit the scene and was almost identical with use of textmate |
| 10:41 | psykotic | of course, textmate has a 'slightly' smoother learning curve |
| 10:41 | cemerick | psykotic: slightly? ;-) |
| 10:41 | psykotic | well, it's also a glorified version of notepad, so how hard could the learning curve possibly be? :) |
| 10:41 | cemerick | psykotic: I find enclojure very pleasant, FWIW. |
| 10:42 | cemerick | nah, that's not fair to textmate |
| 10:42 | psykotic | i hear it's improved; i haven't tried it around the time when rails came out and dhh's screencasts convinced me to look at it |
| 10:42 | psykotic | *since around the time |
| 10:43 | SynrG | i haven't used enclojure for anything serious, yet. just dabbling around. looks slick, tho. my big objection is it's overkill on my poor little eeepc |
| 10:43 | psykotic | cemerick: are there any clojure-related features of enclojure that aren't in slime? |
| 10:43 | cemerick | but regardless, emacs has a reputation (well-earned) that doesn't help clojure given the need to fight the lisp reputation in some circles (ill-earned IMO) |
| 10:43 | SynrG | resource usage probably isn't the worst part (i did put 2G ram in it). it wants a lot of screen real estate |
| 10:43 | cemerick | psykotic: probably not, but that's besides the point. |
| 10:44 | psykotic | cemerick: maybe besides your point, but i wanted to know :) |
| 10:44 | caljunior | I used textmate exclusively until Lau's screencasts helped me get started with emacs |
| 10:44 | cemerick | I've not used slime in years, so I'm not the one to comment on comparisons. |
| 10:44 | caljunior | the textmate clojure bundle has some serious issues though |
| 10:44 | cemerick | yeah, TM can't support anything lispy. |
| 10:45 | psykotic | on the flip side, if clojure had been identical with something like eclipse, me and a lot of other people might not have tried it :) |
| 10:45 | caljunior | well, paren support is actually quite good |
| 10:45 | psykotic | i think clojure's lisp roots helped its initial growth a lot |
| 10:46 | psykotic | emacs is part of that |
| 10:46 | SynrG | i tried to like emacs. maybe i just didn't try hard enough |
| 10:46 | Chousuke | paredit was what finally sold emacs to me |
| 10:46 | psykotic | not a big fan of paredit |
| 10:46 | Chousuke | and git, and org-mode, and the latex environment... :P |
| 10:46 | Chousuke | magit* |
| 10:46 | psykotic | i've had arguments with riastradh about this endlessly, heh |
| 10:47 | psykotic | org-mode on the other hand... <3 :) |
| 10:47 | Chousuke | psykotic: all the mismatched brackets I would have without paredit would drive me nuts |
| 10:47 | psykotic | paren pair highlighting is enough for me |
| 10:48 | Chousuke | Well, yeah, but if the editor can ensure that the parens are always matched, why not let it do that? |
| 10:48 | caljunior | I think textmate is actually a rather important gateway editor for new clojurians. Especially for those coming from dynamic languages. |
| 10:49 | psykotic | my problem with paredit and even more 'real' structure editors is that they don't allow you to go move between two valid states via invalid states |
| 10:49 | psykotic | they try to ensure that every step is structurally well formed |
| 10:49 | etate | psykotic: there aren't many invalid states to get into though (comments & ctrl-w being the main exceptions) |
| 10:50 | cemerick | caljunior: Interesting point. TM's bundle system isn't up to snuff for a lisp, tho. I wonder what could be done to get around that. |
| 10:50 | psykotic | i guess in general what i like about emacs is that it's a text editor, and i think a lot of this structural editing gets in the way of that, it's too confusing for me |
| 10:50 | zmila | just found waterfront - simple clojure ide, core written in java, the rest in clojure |
| 10:50 | LauJensen | Ok - So bottom line is that there is no viable alternative to Emacs ? |
| 10:50 | psykotic | EMACS WINS. FLAWLESS VICTORY! |
| 10:50 | etate | psykotic: once you get used to it it makes you much more productive with editing lisp code |
| 10:50 | cemerick | LauJensen: you forgot the ;-) at the end of that |
| 10:51 | LauJensen | cemerick: It was a serious question, trying to sum up your discussion above |
| 10:51 | etate | psykotic: i'd say paredit is actually the best reason to program in lisp |
| 10:51 | psykotic | etate: i gave it a fair shake a few years ago when i hung out on #scheme with riastradh, and it never grew on me |
| 10:51 | caljunior | cemerick: I actually don't agree. TM lisp support is sufficient. It's the classpath definitions that in the TM bundle that have issues. |
| 10:51 | cemerick | LauJensen: well, the above discussion is most emacs users talking. |
| 10:51 | etate | psykotic: it takes a while to get used to |
| 10:51 | LauJensen | I only use Emacs because its the best - if something better comes along, I'm not bound to any oath of loyalty |
| 10:51 | psykotic | LauJensen: turncoat! |
| 10:51 | Chousuke | psykotic: paredit is confusing initially, but once you realise that it's just doing what you would do manually anyway, it's great. :) |
| 10:52 | psykotic | okay, maybe i'll try it again |
| 10:52 | psykotic | btw, there are lots of emacs things i still haven't seen to the same extent elsewhere |
| 10:52 | psykotic | like... align.el |
| 10:52 | cemerick | caljunior: huh, last I looked at it, all of the parsing in TM bundles was regex-based. Makes things difficult. |
| 10:52 | psykotic | i hear there's an align extension for vim but i looked at the code and it's kind of pathetic |
| 10:52 | LauJensen | paredit is horrible - like crutches for text editing |
| 10:52 | Chousuke | crutches? :/ |
| 10:53 | psykotic | cemerick: for what it's worth, emacs's syntax tables are also regex based, and equally pathetic |
| 10:53 | Chousuke | LauJensen: you're not editing just text, you're editing lisp code |
| 10:53 | cemerick | interesting |
| 10:53 | psykotic | i hate emacs syntax tables |
| 10:53 | etate | LauJensen: paredit is a way of making parens disappear |
| 10:53 | LauJensen | etate: Routines handles that just fine |
| 10:53 | Chousuke | LauJensen: it has a certain structure, and paredit just enforces that structure and makes editing it more natural |
| 10:53 | psykotic | the few modes that do real parsing tend to be pretty extreme |
| 10:53 | The-Kenny | LauJensen: You're not editing text - You're editing threes based on parens |
| 10:53 | psykotic | like yegge's js2-mode |
| 10:53 | caljunior | key point is that paren support (highlighting etc) works well in textmate. |
| 10:53 | psykotic | or cedet/semantic |
| 10:54 | psykotic | semantic _completely_ reimplements lex and yacc in emacs lisp, on top of eieio, which is a clos reimplementation in elisp |
| 10:54 | caljunior | there is a nagging issue with compile step and path with spces |
| 10:54 | psykotic | it's... pretty insane |
| 10:54 | Chousuke | LauJensen: plain text editing *can* do what paredit does with lisp code, but it's more cumbersome :) |
| 10:54 | caljunior | spaces |
| 10:54 | psykotic | Chousuke: emacs already has sexp-based navigation without paredit |
| 10:54 | LauJensen | Chousuke: I've already tried it, so the sales-pitch is useless :) |
| 10:54 | etate | Chousuke: not always, i mean think about transposing sexps, removing the outer sexps, inserting inner sexps |
| 10:55 | The-Kenny | psykotic: But it doesn't support {} and [] |
| 10:55 | etate | Chousuke: that kind of thing takes time to do by hand |
| 10:55 | psykotic | etate: transpose-sexp has been in emacs forever, outside paredit |
| 10:55 | Chousuke | psykotic: it's not just navigating that paredit does. |
| 10:55 | psykotic | same with forward-sexp, mark-sexp, etc |
| 10:55 | psykotic | i know that some of the inside/outside stuff isn't in emacs by default |
| 10:55 | Chousuke | personally, I use the paren matching, barf and slurp |
| 10:56 | etate | psykotic: what about alt arrow up |
| 10:56 | psykotic | which one is that? |
| 10:56 | etate | psykotic: remove outer sexp |
| 10:56 | Chousuke | and those are enough to keep me addicted :P |
| 10:56 | Chousuke | oh, and kill-sexp as well |
| 10:56 | Chousuke | it's essential |
| 10:56 | psykotic | Chousuke: dude, that's also a default emacs feature |
| 10:57 | psykotic | lisp.el |
| 10:57 | psykotic | it also has up/down-list for inside/outside navigation |
| 10:57 | psykotic | what it doesn't have are things like kill outer sexp |
| 10:57 | Chousuke | psykotic: well, one less source of addiction for paredit then |
| 10:57 | psykotic | hehe |
| 10:58 | Chousuke | psykotic: but emacs still doesn't keep the structure sane by default |
| 10:58 | psykotic | right |
| 10:58 | psykotic | but like i said, i enjoy having the default editing be text editor like |
| 10:58 | psykotic | when i want to edit/navigate structurally, i'll use explicit commands |
| 10:59 | psykotic | but i'll use this opportunity to reevaluate paredit, so it's been useful to chat about it |
| 10:59 | etate | how do you find all the methods that are bound to a java interface from clojure? |
| 10:59 | Chousuke | I'm so used to paredit that I can't imagine myself wanting to edit lisp code as text. |
| 10:59 | psykotic | btw, i have some of my own code that i think is a million things nicer to use than transpose-sexp |
| 10:59 | psykotic | i call it drag-sexp (i have versions for words, lines, etc, as well) |
| 10:59 | psykotic | it acts like cell motion in org-mode |
| 10:59 | psykotic | for tables |
| 11:00 | Chousuke | hm, can you give an example? :/ |
| 11:00 | Chousuke | I haven't done any tables in org-mode |
| 11:00 | psykotic | basically you can drag 'units' (like sexps) around and it maintains intraunit point positioning |
| 11:00 | psykotic | i never liked emacs's transpose semantics, so maybe it's just me |
| 11:02 | psykotic | well, it's not just org mode tables that work like that, outline items work the same way |
| 11:02 | psykotic | when you drag them up/down, in/out, it maintains your point positoning within that outline element |
| 11:06 | psykotic | if you want to play around with it, i posted some of my code here: http://gist.github.com/328872 |
| 11:08 | neotyk | Hi * |
| 11:10 | The-Kenny | psykotic: Not just dragging. You can do the same with meta + arrow keys |
| 11:10 | The-Kenny | which is a feature I miss in *every* other writing application |
| 11:10 | psykotic | The-Kenny: you mean org-mode? |
| 11:10 | The-Kenny | psykotic: Yes ;) But more small things from org-mode. Like re-ordering outlines with just meta + arrow keys |
| 11:11 | psykotic | right |
| 11:11 | The-Kenny | A simple and fast way to restructure outlines |
| 11:11 | psykotic | using org-mode made me addicted to the 'kinetic' feel of moving things around |
| 11:11 | The-Kenny | Same for tables |
| 11:11 | psykotic | transpose-paragraphs, etc, is shit in comparison |
| 11:11 | psykotic | so that's why i wrote that code i posted |
| 11:11 | psykotic | i use it all the time now, whereas i never used transpose |
| 11:12 | psykotic | org-mode is pretty much a masterclass in awesomeness from beginning to end |
| 11:13 | psykotic | i know some emacs people dislike it because it's a bit aggressive with overriding emacs defaults, but it generally IMPROVES on those defaults |
| 11:14 | neotyk | how cool, I'm checking out orgmode.org |
| 11:15 | neotyk | thanks psykotic and The-Kenny |
| 11:15 | psykotic | i have an ongoing org-table hack that is nearing completion. have you ever seen http://cleanupdata.com/? |
| 11:15 | The-Kenny | neotyk: Also check out one or two screencasts about it. We told you almost nothing about it. |
| 11:15 | psykotic | anyway, i have a sort of emacs/org-mode equivalent of that in the works. what it basically does is record macros on org-mode table cells and replay them LIVE as you type on other rows |
| 11:15 | The-Kenny | neotyk: Oh, and it's integrated in emacs. You really need to fetch it, if you want the latest version |
| 11:15 | psykotic | it's mostly a novelty but it's pretty awesome |
| 11:16 | psykotic | the best intro i've seen is carsten dominik's google techtalk |
| 11:16 | psykotic | (he's the creator) |
| 11:17 | The-Kenny | psykotic: there's a new one by dominik which is good to |
| 11:17 | psykotic | oh? |
| 11:17 | The-Kenny | psykotic: wait a second |
| 11:18 | The-Kenny | hm... searching history just crashed my browser |
| 11:18 | psykotic | btw one of my favorite new org-mode things is mac-org-protocol |
| 11:18 | The-Kenny | ah, found it: http://emacsworld.blogspot.com/2010/03/new-org-mode-talk-from-carsten-dominik.html |
| 11:18 | psykotic | it lets you easily fire things to org-mode/remember with something liek quicksilver |
| 11:19 | The-Kenny | psykotic: Hm.. I tried getting mac-org-protocol, but all it did was open my finder :D |
| 11:19 | psykotic | it's set up to grab as much app context as possible, using applescript |
| 11:19 | psykotic | so for example if you use safari, it will grab the current url as context |
| 11:20 | psykotic | oh i see, that screencast is about org-protocol as well |
| 11:20 | The-Kenny | Huh, it is? |
| 11:21 | psykotic | sorry, haha, i was looking at a google search result |
| 11:21 | psykotic | http://www.mail-archive.com/emacs-orgmode@gnu.org/msg14279.html |
| 11:25 | triyo | with defmathod, how do I go about defining an optional method argument? |
| 11:25 | triyo | if possible |
| 11:29 | etate | hmm, this may sound silly but how do i ensure a value returned is of a specific type |
| 11:29 | etate | for example in Java you can do IClass class = meth(); |
| 11:30 | etate | in clojure just meth() is returning the wrong type |
| 11:30 | nuba | dont mess with meth |
| 11:30 | nuba | its dangerous |
| 11:31 | psykotic | fucks up your teeth |
| 11:32 | Raynes | inb4heynowdon'tbeusingfowllanguagewehostchildrenandadultsalike |
| 11:33 | psykotic | sorry, i'll be nice and church-like |
| 11:33 | Raynes | psykotic: I know. I find it silly as well. :( |
| 11:33 | dcnstrct | does anyone know what version of swank/slime will work properly with this guide ? http://riddell.us/tutorial/slime_swank/slime_swank.html or does anyone have a guide for installing swank/slime that works with the latest sources from git ? |
| 11:34 | psykotic | etate: i guess the easiest would be to write a simpler helper function that asserts on the class and otherwise returns the value |
| 11:34 | clojurebot | classpath is (System/getProperty "java.class.path") |
| 11:35 | etate | psykotic: i want to access the value as an IClass rather than as a native ref |
| 11:35 | dcnstrct | btw I tried enclojure... with the latest nebeans on ubuntu... massive fail.. the create project system pukes with some mysterious error I can't decipher :( |
| 11:35 | etate | psykotic: in Java its just IClass x = getValue() |
| 11:36 | SynrG | dcnstrct: latest netbeans on ubuntu? if it's based on the debian one it is ooold |
| 11:37 | SynrG | dcnstrct: i have given up waiting for packaging for netbeans. i just use upstream's installer. works fine on debian squeeze. |
| 11:37 | joshua-choi | I’m wondering something: Rich strongly states that we should always use (seq ...) instead of (not (empty? ...)). Why? |
| 11:38 | psykotic | etate: something like this? |
| 11:39 | dcnstrct | SynrG, 6.8 |
| 11:39 | psykotic | ,(letfn [(with-class [cls x] (assert (= (class x) cls)) x)] (with-class java.lang.Integer 42)) |
| 11:39 | clojurebot | 42 |
| 11:39 | dcnstrct | Synrg, I'll google for upstream's installer and try it |
| 11:39 | psykotic | ,(letfn [(with-class [cls x] (assert (= (class x) cls)) x)] (with-class java.lang.Integer "foo")) |
| 11:39 | clojurebot | java.lang.Exception: Assert failed: (= (class x) cls) |
| 11:39 | AWizzArd | joshua-choi: this is idiomatic in Clojure, I guess because it is shorter |
| 11:40 | SynrG | dcnstrct: i just mean the one from netbeans.org itself |
| 11:40 | psykotic | etate: you can wrap that around any call to check the class |
| 11:40 | SynrG | working fine with openjdk |
| 11:40 | psykotic | sorry, that's actually too strict, equality rather than isa |
| 11:40 | etate | psykotic: the thing is i know what the class is, the problem is its the wrong class :) |
| 11:41 | psykotic | what do you mean by the wrong class? |
| 11:41 | etate | psykotic: oh no wait its not... the error must come from something else |
| 11:42 | etate | psykotic: i just tried (class x) on the value and its the right class.. still crashes my jvm hmmm |
| 11:49 | sattvik | joshua-choi: I think it's from Clojure's Lisp roots. Booleans in Clojure, I believe, are an artifact of running in the JVM. |
| 11:50 | Chousuke | joshua-choi: using seq is an idiom, and (not (empty? ...)) needlessly goes against that idiom |
| 11:52 | Chousuke | they both convey the same information, but the former is more familiar to clojurians |
| 11:52 | psykotic | especially seeing that empty? is a macro for (not (seq ...)). every time you write that, i reaed it as (not (not (seq ...)) :) |
| 11:58 | Mec | Is there anything you can do when you want to use -> but sometimes the expression needs to go 2nd, last, or somewhere in the middle? |
| 11:58 | joshua-choi | Chousuke: seq creates a sequence object. Does empty? also create a sequence object? |
| 12:00 | lpetit | joshua-choi: it is idiomatic in the following piece of code : (if-let [s (seq smthing)]) versus (if (not (empty? smthing)) (let [s (seq smthing)] ...) I guess |
| 12:01 | joshua-choi | The former seems better, since if empty? creates a seq object, then the latter creates the same seq object twice. |
| 12:01 | joshua-choi | Oh, and it’s shorter. :) |
| 12:02 | lpetit | quite shorter :-) |
| 12:02 | psykotic | mec: i posted a macro for this a while ago. |
| 12:03 | psykotic | mec: http://gist.github.com/328830 |
| 12:03 | Mec | psykotic: thanks |
| 12:04 | Mec | on the off chance i need to include an anonymous function, does it have to be % as the placeholder? |
| 12:04 | psykotic | no, of course, just replace the '% with whatever placeholder |
| 12:05 | Mec | ah ok |
| 12:05 | psykotic | but it should work with anonymous functions |
| 12:05 | psykotic | try it. i call macroexpand-all on the arguments first, so anonymous function macros like that should have expanded away the %'s by the time i do my codewalking |
| 12:05 | Mec | ah i see |
| 12:05 | Mec | I'll play around with it |
| 12:18 | psykotic | so, i'm using paredit and i remember why i hate it. half of its commands beyond lisp.el are only needed because of paredit's bondage and discipline wrt structural consistency. |
| 12:18 | psykotic | serenity now |
| 12:20 | Chousuke | Does that matter? :/ |
| 12:20 | Chousuke | I use only about three paredit features |
| 12:21 | psykotic | i like C-k |
| 12:21 | psykotic | but i basically dislike the fundamental philosophy behind paredit. org-mode is the anti-paredit |
| 12:21 | Chousuke | yeah, that's my favourite, too. :P |
| 12:21 | psykotic | org-mode lets you type text as you want and it tries to make sense of it |
| 12:21 | psykotic | paredit is a cruel taskmaster |
| 12:21 | Chousuke | but they're for two purposes |
| 12:22 | Chousuke | org-mode accepts free-form text because that's how it's designed. but your lisp compiler won't accept free-form text |
| 12:22 | psykotic | i've known riastradh for years and i feel like he's standing over my desk, snapping a whip while yelling 'STRUCTURAL CONSISTENCY, SLAVE!' |
| 12:22 | Chousuke | or I guess I should say reader |
| 12:22 | psykotic | well, i know lisp syntax |
| 12:23 | psykotic | the point is that when i'm typing, i want to be the one in control |
| 12:23 | Chousuke | but what do you need to control? :/ |
| 12:23 | psykotic | my point is that a lot of things in paredit are only there because of the need for each intermediate state to be consistent |
| 12:23 | Chousuke | I've never found paredit actually obstructing what I need to do. |
| 12:23 | psykotic | e.g. barf/slurp |
| 12:24 | psykotic | bed time, later |
| 12:24 | Chousuke | the downside of manual control is that you have to track parentheses manually |
| 12:25 | Chousuke | highlighting helps, but with paredit the need disappears completely. |
| 12:25 | Knekk | what's the way to turn ((1 2) (3 4)) into (1 2 3 4) |
| 12:27 | Chousuke | in clojure or in paredit? :P |
| 12:27 | Chousuke | you can apply concat for flattening one level, or use flatten |
| 12:27 | Knekk | sorry, clojure :) |
| 12:27 | Knekk | flatten is a contrib? |
| 12:28 | dnolen | clojure.contrib.seq-utils I think |
| 12:28 | Knekk | thank you |
| 12:29 | S11001001 | Knekk: remember that strings aren't sequential, but they are seq-able |
| 12:30 | Knekk | S11001001: I will try to remember, even tho it doesn't have a bearing on my current problem :) |
| 12:31 | Knekk | is S11001001 a bot? |
| 12:33 | S11001001 | Knekk: it's unlikely |
| 12:35 | hiredman | clojurebot: whose job is it to enforce the turing test? |
| 12:35 | clojurebot | latest is 1382 |
| 12:35 | hiredman | :/ |
| 12:38 | hiredman | clojurebot: latest? |
| 12:38 | clojurebot | latest is 1382 |
| 12:39 | hiredman | clojurebot: forget latest is 1382 |
| 12:39 | clojurebot | I forgot latest is 1382 |
| 12:39 | hiredman | clojurebot: latest? |
| 12:39 | clojurebot | latest is 1382 |
| 12:39 | hiredman | LIAR |
| 13:01 | slyphon | technomancy: hey, just sent you a message on github |
| 13:01 | slyphon | re: leiningen notes |
| 13:03 | technomancy | slyphon: awesome; thanks |
| 13:03 | slyphon | sure, i hope it's useful |
| 13:58 | etate | is there something obvious i'm missing here wrt to gen-class.. (ns foo.bar (:gen-class)) then calling (foo.bar.) gives me a class not found exception |
| 13:58 | S11001001 | etate: only works when compiling file |
| 13:59 | etate | S11001001: with (compile "foo.bar.clj") > |
| 13:59 | etate | ? |
| 13:59 | hiredman | that is not right |
| 13:59 | etate | because that doesn't work either: string cannot be cast to clojure.lang.Named |
| 13:59 | hiredman | did you read the docstring for compile? |
| 14:00 | hiredman | have you read the compile documentation on clojure.org? |
| 14:00 | etate | no i kindof assumed ctrl-c ctrl-c compiled the code : |
| 14:00 | etate | :/ |
| 14:00 | hiredman | there is compiling and then there is aot compiling |
| 14:01 | hiredman | ,(doc compile) |
| 14:01 | clojurebot | "([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath." |
| 14:01 | hiredman | ~compiling |
| 14:01 | clojurebot | Excuse me? |
| 14:01 | hiredman | clojurebot: compile? |
| 14:01 | clojurebot | the unit of compilation in clojure is the namespace. namespaces are compiled (not files). to compile a namspace the namespace needs to be on the classpath and so does ./classes/ (and the directory needs to exist) because clojure writes the class files to that directory. http://clojure.org/compilation |
| 14:02 | hiredman | and your file name and namespace don't match up, so aot compilation won't work, regardless |
| 14:02 | hiredman | ~namespace |
| 14:02 | clojurebot | namespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it |
| 14:03 | etate | hiredman: by single segment namespaces, does that mean i shouldn't have just one dir with lots of .clj files in it? |
| 14:03 | hiredman | huh? no |
| 14:04 | hiredman | why would you think that? |
| 14:05 | hiredman | as long as your namespaces are all dir.filename having one directory full of files is no problem |
| 14:05 | etate | hiredman: because if a segment of a namespace corresponds to a directory in a classpath, having it just one level deep is a single segment? |
| 14:05 | etate | hiredman: oh okay |
| 14:05 | hiredman | etate: "they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj" |
| 14:05 | hiredman | it does not say they correspond to directories |
| 14:07 | etate | in other words if i add /clojure/ to classpath, and it contains ./foo/file.clj within it, the namespace correspondence will be foo.file? |
| 14:07 | hiredman | yes |
| 14:07 | etate | okay, sorry for the mild stupidity |
| 14:15 | etate | hmm still doesn't work |
| 14:15 | etate | :( |
| 14:15 | hiredman | have you read the compile documentation on clojure.org? |
| 14:17 | etate | hiredman: yes |
| 14:18 | etate | hiredman: i created a folder c:\clojure\foo, with a file c:\clojure\foo\bar.clj |
| 14:19 | etate | hiredman: then i created a folder c:\clojure\classes and c:\clojure\foo\classes, then i added c:\clojure\, c:\clojure\foo and c:\clojure\classes, c:\clojure\foo\classes to the class path |
| 14:19 | rads | is there any difference between (declare *foo*) and (def *foo*)? |
| 14:19 | etate | hiredman: then i did (compile 'foo.bar) -> error cannot find foo__init.class |
| 14:20 | etate | sorry bar__init.class |
| 14:20 | hiredman | why do you have a c:\clojure\foo\classes? |
| 14:20 | Mec | rads: declare is for when you want to use a var in a definition before it is defined, and then later defined with def |
| 14:20 | etate | hiredman: i was checking to see if it helped |
| 14:20 | SynrG | ,(doc def) |
| 14:20 | clojurebot | DENIED |
| 14:20 | hiredman | etate: why do you think it would help? |
| 14:20 | SynrG | oh, so you're like that, are you? |
| 14:21 | etate | hiredman: because the other classes folder didn't |
| 14:21 | nteon | clojurebot: def? |
| 14:21 | clojurebot | That is the one thing Clojure can not do. |
| 14:21 | nteon | heh |
| 14:22 | StartsWithK | etate, http://paste.pocoo.org/show/188909/ |
| 14:22 | hiredman | etate: and how are you compiling? |
| 14:24 | etate | hiredman: (compile 'foo.bar) |
| 14:25 | hiredman | and how did you set your classpath? |
| 14:25 | etate | StartsWithK: I can't really see what i'm missing from that paste, the differences are that you're using a src folder in your classpath whereas i'm using the base c:\clojure folder |
| 14:25 | etate | StartsWithK: also you have a lib with clojure in it which i don't have, clojure is found elsewhere |
| 14:26 | hiredman | etate: "found elsewhere" is not a good idea |
| 14:26 | StartsWithK | etate, just start from this and expand to your use case, so you can see when things fail |
| 14:26 | etate | hiredman: I used (add-to-list 'swank-clojure-classpath dir) |
| 14:26 | hiredman | … |
| 14:27 | hiredman | and what does (System/getProperty "java.class.path") say? |
| 14:28 | etate | hiredman: i can't really paste it because its too long, but it includes those dirs... however what i notice is that the other classpaths that work point to .jar files |
| 14:28 | SynrG | hmm, does clojurebot just not like me, or did i ask it a naughty question? |
| 14:28 | SynrG | ,(def declare) |
| 14:28 | clojurebot | DENIED |
| 14:28 | etate | hiredman: all the ones that point to dirs don't seem to work |
| 14:28 | hiredman | jar files in a classpath are the same as a directory containing the contents of a directory |
| 14:28 | SynrG | i guess it's just me :) |
| 14:29 | SynrG | oops |
| 14:29 | SynrG | ,(doc declare) |
| 14:29 | clojurebot | "([& names]); defs the supplied var names with no bindings, useful for making forward declarations." |
| 14:29 | hiredman | are you using relative or absolute paths? |
| 14:29 | SynrG | but to: |
| 14:29 | etate | hiredman: absolute, with a trailing slash |
| 14:29 | SynrG | ,(doc def) |
| 14:29 | clojurebot | DENIED |
| 14:29 | SynrG | my repl says: |
| 14:29 | SynrG | Special Form Please see http://clojure.org/special_forms#def |
| 14:30 | SynrG | so why is repl (1.1.0) smarter than clojurebot? |
| 14:30 | hiredman | etate: and what if you don't use slime? |
| 14:30 | etate | hiredman: could not locate foo/bar__init.class |
| 14:31 | hiredman | that is from the repl? |
| 14:31 | hiredman | (clojure.main, not slime) |
| 14:32 | Fossi | SynrG: clojurebot is just locked up, so nobody takes control of it or crashes it |
| 14:34 | etate | hiredman: i get a different error now |
| 14:35 | etate | hiredman: the system cannot find the path specified |
| 14:35 | hiredman | how are you starting clojure? |
| 14:35 | etate | hiredman: i start it with clojure box and a modified default.el |
| 14:35 | hiredman | 11:31 hiredman : etate: and what if you don't use slime? |
| 14:35 | etate | hiredman: if i don't use slime i get the file not found error whilst writing the class |
| 14:36 | hiredman | ,(doc *compile-path*) |
| 14:36 | clojurebot | "; Specifies the directory where 'compile' will write out .class files. This directory must be in the classpath for 'compile' to work. Defaults to \"classes\"" |
| 14:36 | hiredman | the compile-path defaults to a relative path |
| 14:38 | etate | hiredman: the compile path was set to "classes" which i thought was correct, i tried using an absolute path to the classes dir in c:\\clojure\\ and same error |
| 14:38 | hiredman | etate: what do you mean "tried" |
| 14:38 | hiredman | you changed *compile-path*? |
| 14:38 | etate | hiredman: as in i added "c:\\clojure\\classes\\" to class-path |
| 14:38 | etate | hiredman: no, should i do that? |
| 14:39 | hiredman | *compile-path* and classpath have no connection, except for compilation to work the directory specified in the former must be in the latter |
| 14:40 | hiredman | doing things with the classpath does not effect *compile-path* at all |
| 14:41 | etate | hiredman: well the basedir c:\\clojure\\ is on the classpath and contains a dir named "classes" which is empty |
| 14:41 | hiredman | so? |
| 14:42 | etate | so if *compile-path* is set to "classes" and its relative to the classpath, then that should be correct right? |
| 14:42 | psykotic | no |
| 14:42 | StartsWithK | etate, relative to "user.dir" property |
| 14:42 | psykotic | there's a million directories on the class path |
| 14:42 | hiredman | etate: how would having the output directory be relative to the classpath possibly work? |
| 14:43 | hiredman | ^- what psykotic said |
| 14:43 | etate | hmm good point |
| 14:45 | etate | in other words i should find a way to add to the *compile-path* |
| 14:45 | hiredman | there is one compile-path |
| 14:45 | hiredman | it is not like the classpath, again, how would it work if it had multiple paths? |
| 14:45 | hiredman | you can change the compile-path a few ways |
| 14:47 | Drakeson | 1. is it possible to use build.xml and project.clj together? or, 2. are there any examples for porting build.xml to project.clj? |
| 14:47 | hiredman | if you are at the repl you can use binding or maybe set! to change it |
| 14:48 | hiredman | Drakeson: no and no |
| 14:49 | etate | hiredman: is that wise though? because the clojure classes dir contains a lot of clojure specific code |
| 14:49 | hiredman | etate: um |
| 14:50 | Drakeson | hiredman: I see. |
| 14:50 | hiredman | etate: your project should not be in the same directory as clojure |
| 14:50 | hiredman | you should build a clojure jar and put that on your classpath |
| 14:51 | etate | hiredman: right, but when java starts its relative to the clojure dir i believe |
| 14:51 | etate | hiredman: or maybe not |
| 14:51 | Drakeson | hiredman: do you happen to know a project using project.clj that also compiles some java sources? |
| 14:51 | hiredman | Drakeson: there is a lein plugin that does java compilation |
| 14:52 | hiredman | clojurebot: lein-java |
| 14:52 | clojurebot | Huh? |
| 14:52 | hiredman | clojurebot: google lein-java |
| 14:52 | clojurebot | First, out of 362000 results is: |
| 14:52 | clojurebot | antoniogarrote's lein-javac at master - GitHub |
| 14:52 | clojurebot | http://github.com/antoniogarrote/lein-javac |
| 14:52 | Drakeson | hiredman: thanks :) |
| 14:52 | psykotic | no, it's relative to the current working directory at the time of execution... |
| 14:52 | psykotic | it doesn't matter where the clojure jar is. how could it? |
| 14:53 | hiredman | well, it matters for the classpath |
| 14:53 | psykotic | sure |
| 14:53 | psykotic | i'm talking about user.dir |
| 14:54 | hiredman | sure |
| 14:54 | psykotic | etate: iirc, the getting started page has a good overview of this stuff. |
| 14:54 | etate | psykotic: i think its the swank-clojure that starts java |
| 14:54 | etate | i just downloaded clojure box so i have no idea where the java process is starting |
| 14:55 | psykotic | that's the problem with bundles like that |
| 14:55 | psykotic | anyway, i still don't understand why you're putting all your code in the clojure dir |
| 14:56 | etate | psykotic: i'm not... my code is in c:\\clojure\\ but the clojure dir is under c:\\cygwin\\... |
| 14:56 | psykotic | ah, i see what you're getting at |
| 14:56 | etate | but yeah theres nothing in the default site-lisp that says anything about starting the java process, mmy guess is swank-clojure starts it |
| 14:56 | hiredman | then why would you care about the classes directory the clojure build process uses? |
| 14:57 | psykotic | i guess because the user.dir is in the clojure directory |
| 14:57 | etate | hiredman: i'm just trying to figure out where this relative "classes" dir is lol |
| 14:57 | hiredman | I doubt it |
| 14:57 | etate | or supposed to be |
| 14:57 | hiredman | etate: it doesn't have to be relative, you can change it |
| 14:57 | hiredman | (System/getProperty "user.dir") |
| 14:58 | etate | OMG |
| 14:58 | etate | IT WORKS |
| 14:58 | psykotic | high five :) |
| 14:58 | etate | are there any side effects to me changing *compile-path*? apart from the set! i mean |
| 14:59 | The-Kenny | Maybe (binding ...) works |
| 14:59 | hiredman | any classes you generate using compile will go in that directory |
| 15:00 | etate | hiredman: is there a way of having different projects generate in different classes directories without having to start a different process |
| 15:00 | etate | user.dir is == c:\\windows\\system32 anyway :/ |
| 15:00 | hiredman | etate: is there a real reason you need to aot compile? |
| 15:01 | etate | hiredman: AOT = ahead of time? |
| 15:01 | hiredman | yes |
| 15:01 | hiredman | what compile does |
| 15:02 | etate | hiredman: yeah i'm trying to extend a java class |
| 15:03 | etate | hiredman: and i don't want to do it dynamically with proxy for efficiency reasons |
| 15:03 | hiredman | what version of clojure are you using? |
| 15:03 | hiredman | do you really need a stable name? I would look at reify |
| 15:04 | technomancy | etate: you should probably write it in proxy first and get it working, then switch to gen-class once you have profiled it and determined that it's an actual bottleneck |
| 15:04 | technomancy | because it's probably not |
| 15:04 | StartsWithK | gen-class is not realy fast |
| 15:04 | StartsWithK | it may even be slower than a proxy |
| 15:04 | hiredman | right |
| 15:04 | hiredman | gen-class generates a stub that calls out to the clojure functions |
| 15:04 | hiredman | similar to proxy |
| 15:06 | etate | technomancy: its not just for efficiency, its also to be able to have static methods, a main etc |
| 15:06 | hiredman | I really recommend against tieing yourself to aot (as it is largly a deadweight) |
| 15:06 | etate | hiredman: a deadweight? what do you mean? |
| 15:06 | hiredman | it will drag you to the bottom and you will drown |
| 15:07 | etate | haha |
| 15:07 | hiredman | I mean for the pain it causes it gives you relatively little |
| 15:07 | StartsWithK | but there is a catch :) |
| 15:07 | StartsWithK | how do you start a clojure app |
| 15:07 | StartsWithK | hihihi |
| 15:08 | hiredman | java -cp whatever foo.clj |
| 15:08 | StartsWithK | you can or :gen-class to get main |
| 15:08 | hiredman | er |
| 15:08 | StartsWithK | or yes yes |
| 15:08 | hiredman | java -cp whatever clojure.main foo.clj |
| 15:08 | StartsWithK | and now you have a problem |
| 15:08 | StartsWithK | your ide will eval foo.clj |
| 15:08 | etate | so proxy is the same as gen-class but easier to use? |
| 15:08 | etate | and gen-class provides main but thats the only benefit? |
| 15:08 | hiredman | StartsWithK: only if your ide sucks |
| 15:08 | StartsWithK | as your 'main' is outside of any function in that case |
| 15:08 | StartsWithK | hiredman, all ides suck |
| 15:09 | hiredman | java -cp whatever clojure.main -e "(use 'foo.bar) (go-web-go)" |
| 15:09 | StartsWithK | :) |
| 15:10 | hiredman | etate: oh, you can do other things with it, and if you really really need to generate classes with a stable name for some brain dead java |
| 15:10 | etate | the problem i was having was that i couldn't easily see how to extend java classes which extend other classes and call static methods etc from a proxy |
| 15:10 | hiredman | how do static methods matter in this? |
| 15:11 | hiredman | clojure has better "static methods" than java, they are called fns |
| 15:11 | etate | take a look at this java code: http://www.jmonkeyengine.com/wiki/doku.php/tutorial_1_-_learning_jme_2 |
| 15:12 | etate | to me it makes it easier to think about a gen-class extending the simplegame class than a proxy |
| 15:12 | hiredman | I don't see any static methods |
| 15:12 | Apage43 | ... I don't see what's so difficult about that |
| 15:12 | Apage43 | main() isn't pulled off SimpleGame |
| 15:12 | Apage43 | only simpleInitGame() is, no probs proxying that |
| 15:12 | etate | Apage43: main isn't but rootNode & ConfigShowMode etc are |
| 15:13 | Apage43 | those are static? |
| 15:13 | etate | no |
| 15:13 | hiredman | ugh |
| 15:14 | etate | bare in mind i've been in clojureland 2 days, so i basically suck |
| 15:14 | hiredman | I think you will need to use reflection to get rootNode in anycase |
| 15:14 | Apage43 | probably.. |
| 15:15 | Apage43 | bleh.. that's a kind of icky API. |
| 15:15 | etate | yeah its hard to make sense of it for me |
| 15:15 | hiredman | this seems like one of those "here is a simple thing for newbies to use, no one will seriously use it, so we'll just do it badly" kind of things |
| 15:15 | etate | lol |
| 15:16 | etate | the best part is that the java doc link is broken |
| 15:17 | hiredman | :/ |
| 15:19 | etate | hiredman: yesterday i got to the root of the JVM crash btw, it turned out that in one of the ogre4j functions, it returns a RenderList that upon access crashes the JVM. |
| 15:19 | etate | hiredman: i tried all the methods on it and most crash :( |
| 15:19 | hiredman | fun |
| 15:20 | etate | hiredman: so one 3d rendering lib has a bad API, the other is really unstable :( |
| 15:20 | Apage43 | does whatever library do 3d? |
| 15:20 | Apage43 | Have you considered just using JOGL/JSR-231? |
| 15:21 | Apage43 | or what all libs have you looked at |
| 15:21 | duncanm | la la la |
| 15:21 | etate | Apage43: jogl / lwjgl involve writing an engine from scratch |
| 15:22 | etate | Apage43: other than that i've looked at the jmonkey and ogre4j |
| 15:22 | Apage43 | what's that going to manage for you, moving stuff around? |
| 15:22 | Apage43 | Collisions? |
| 15:22 | etate | Apage43: skeletal animation, collisions, easy shaders, access to d3d or opengl |
| 15:23 | etate | etc etc |
| 15:23 | hiredman | I think Lua did some work with jme |
| 15:24 | etate | hiredman: i was looking mainly at doing something in clojure |
| 15:24 | hiredman | not the language |
| 15:24 | hiredman | LauJensen |
| 15:24 | hiredman | he is, uh, some german guy? |
| 15:25 | chouser | Denmark |
| 15:25 | hiredman | some dane |
| 15:25 | hiredman | wait |
| 15:25 | hiredman | thats not right either |
| 15:26 | etate | hiredman: hmm it looks like the basegame class has a nicer api |
| 15:26 | chouser | oh, you're right. Netherlands |
| 15:27 | hiredman | clojurebot: lua? |
| 15:27 | clojurebot | Excuse me? |
| 15:27 | hiredman | clojurebot: LauJensen is some dane |
| 15:27 | clojurebot | You don't have to tell me twice. |
| 15:27 | chouser | Well, european mainland anyway. Close enough. |
| 15:29 | Apage43 | etate: it looks like it's BaseSimpleGame where all those static bits are set up |
| 15:30 | etate | Apage43: theres also BaseGame, which is i think where i'll start |
| 15:30 | etate | http://www.jmonkeyengine.com/wiki/doku.php/starter:simplegame |
| 15:30 | Apage43 | http://code.google.com/p/jmonkeyengine/source/browse/branches/2.0/src/com/jme/app/BaseSimpleGame.java <-- Here's what all SimpleGame does for you |
| 15:31 | SynrG | Fossi: i figurede as much. but i don't know what it was about my request that made it objectionable is all. it seemed rather strange. |
| 15:31 | SynrG | Fossi: the ,(doc def) request, that is |
| 15:31 | etate | Apage43: nice thanks ! :) |
| 15:32 | Fossi | SynrG: i bet def is blocked in any form |
| 15:32 | Apage43 | You could write a java class that extends it and toss in some getter methods for the fields you want |
| 15:32 | Apage43 | Or reflection -is- an option |
| 15:33 | etate | Apage43: would it not be simpler to just use gen-class, as in why do i need reflection? |
| 15:33 | hiredman | you could use clojure.asm to generate bytecode directly :D |
| 15:33 | Apage43 | using clojure.contrib.reflect, from within a proxied method, you should be able to get rootNode with (get-field (.getClass this) "rootNode" this) |
| 15:33 | etate | hiredman: theres a clojure.asm? :D |
| 15:34 | Fossi | etate: crystalspace 4 the win |
| 15:34 | Fossi | only has a swig api though |
| 15:34 | hiredman | it's the ASM bytecode engineering library |
| 15:34 | hiredman | it is what clojure uses to generate jvm bytecode |
| 15:35 | etate | Apage43: in baseclass rootNode gets created by a Node class. Can i use reflection whilst using gen-class? |
| 15:35 | Apage43 | rootNode is a field on the base class of type Node. |
| 15:36 | Apage43 | get-field gets the current value of the field |
| 15:36 | SynrG | Fossi: ah. i hadn't considered that possibility. makes sense. |
| 15:36 | Fossi | SynrG: well, it's overly protective, but better safe than sorry :) |
| 15:36 | Apage43 | I also don't know how you get at the "this" object using gen-class |
| 15:36 | Apage43 | in proxy, its passed implicitly as a fn arg. |
| 15:37 | etate | Apage43: i think you get to it when defining a method (defn x [this]) |
| 15:37 | Apage43 | ah |
| 15:37 | Apage43 | then it should work then |
| 15:38 | etate | Apage43: also are you sure rootNode is a field on the baseclass? |
| 15:38 | Apage43 | as long as you make the call to get-field after rootNode has been set |
| 15:38 | Apage43 | etate: rootNode is defined on BaseSimpleGame.java |
| 15:38 | Apage43 | which SimpleGame extends. |
| 15:38 | etate | Apage43: right, but if i extend BaseGame instead of SimpleGame, I don't have to use reflection anymore right ? :D |
| 15:39 | Apage43 | Course, since there's no rootNode to get at |
| 15:40 | rads | is there a way to add a class path to leiningen project without replacing one of the existing ones? |
| 15:40 | etate | hmm ConfigShowMode however is defined on AbstractGame which BaseGame extends |
| 15:40 | etate | but its an enum, not a class |
| 15:41 | Apage43 | that.. is an enum |
| 15:41 | Apage43 | hmm |
| 15:42 | etate | maybe i can just skip create a class that doesn't use any of these base classes, and use that as the base game class |
| 15:43 | Apage43 | enum shouldn't be a problem since they are static. |
| 15:43 | etate | ah |
| 15:43 | robwolfe | rads: no, but why do you want to do that? |
| 15:44 | etate | Apage43: so a java enum with the fields NeverShow, AlwaysShow etc, what is the equivalent in clojure of static fields? |
| 15:44 | etate | Apage43: i don't mean Config/StaticField, i mean how can i create one that is exactly the same as the java enum, without using that enum |
| 15:45 | Apage43 | you want to create a new enum? |
| 15:46 | etate | Apage43: right, but that corresponds exactly to a Java enum |
| 15:47 | Apage43 | I don't think you're going about this the right way =P |
| 15:49 | etate | Apage43: lol, okay i'll try extending the base class instead of trying to write the abstract class by hand, that will probably be easier |
| 15:49 | Apage43 | com.jme.app.AbstractGame.ConfigShowMode/NeverShow is a problem? |
| 15:50 | etate | Apage43: no that will most probably work :) |
| 15:51 | Apage43 | er |
| 15:51 | Apage43 | Might have to be AbstractGame$ConfigShowMode/NeverShow |
| 15:51 | Apage43 | since ConfigShowMode is a subclass |
| 15:58 | Fossi | are you guys making a game? |
| 15:58 | etate | Fossi: trying to get a renderer working first :D |
| 15:59 | chouser | sweet. compile-time infinite recursion. |
| 16:00 | hiredman | stack blowing or just looping? |
| 16:01 | Fossi | etate: well, that's one part :) |
| 16:01 | Fossi | etate: i'm currently making a game for android, so maybe you guys wanna share some insight with functionally programming a renderer |
| 16:02 | rads | robwolfe: for a config directory |
| 16:02 | remleduff | OK, two days later I guess I give up on vimclojure again :( |
| 16:02 | chouser | stack blowing. |
| 16:03 | chouser | looks a lot like (defmacro foo [] `(foo)) |
| 16:03 | remleduff | What are the current best instructions for installing emacs? |
| 16:03 | remleduff | I mean clojure in emacs |
| 16:03 | remleduff | On windows |
| 16:04 | etate | Fossi: sure, i'll share once i can get something running :D |
| 16:04 | jave | is there a .info version of the clojure reference doc? |
| 16:05 | Fossi | etate: as said, i guess i could provide some insight into crystalspace, but i never used it from java. you using ogre? |
| 16:05 | robwolfe | rads: there is "resources" directory meant for that purpose |
| 16:05 | jave | so info-lookup-symbol can be used in emacs? |
| 16:05 | etate | Fossi: no, i tried ogre yesterday but it crashes the JVM so i'm using jmonkeyengine now, to see if that works better |
| 16:06 | Fossi | ah, never used it, but heard some stuff |
| 16:06 | Fossi | actually using CS from clojure would be worth a shot for fun |
| 16:07 | Fossi | but well, too many projects, not nearly enough time ;D |
| 16:08 | etate | Fossi: why crystal space? |
| 16:11 | Fossi | etate: because it's a good engine and i've been around (and a bit of contributing) for about 7 years or such ;) |
| 16:12 | etate | Fossi: i'll check it out :) |
| 16:16 | Fossi | could somebody point me to a more sane AOT compile example than the one in the docs? |
| 16:17 | hiredman | eh? |
| 16:17 | hiredman | what is wrong with the one in the docs? |
| 16:18 | Fossi | wasn't there some way of calling the compiler directly? |
| 16:18 | hiredman | what do you mean? |
| 16:18 | hiredman | (compile 'clojure.examples.hello) looks pretty direct to me |
| 16:19 | Fossi | sorry, from the commandline |
| 16:20 | Fossi | ah, -e is what i was looking for |
| 16:26 | Fossi | i'm too stupid to get this stuff compiled ;D |
| 16:26 | Fossi | my emacs can't write to 'classes' and from the commandline i can't seem to get the classpath right ;D |
| 16:28 | Fossi | ah, is that alive and kickin' |
| 16:28 | Fossi | last time i did some clojure that was still wip |
| 16:29 | Fossi | then again, i need ant to compile the stuff for android, so i should most likely add another target to it |
| 16:30 | hiredman | android doesn't have a jit or a good gc |
| 16:31 | hiredman | (well it has a jit now, but it is not on by default) |
| 16:31 | Fossi | oh, clojars <3 |
| 16:31 | Fossi | that's a good deed |
| 16:31 | Fossi | hiredman: i know |
| 16:31 | hiredman | clojure leans hard on the jit and the gc |
| 16:31 | Fossi | hiredman: i'm still doing this ;p |
| 16:32 | Fossi | the gc is absolutely killing it |
| 16:32 | Fossi | then again, i can't really get myself to do this in java. i just wait until the gc gets better |
| 16:32 | Fossi | it's not really bareable for java either |
| 16:32 | hiredman | I know technomancy is looking at duby for android developement |
| 16:33 | seangrove | Hey all, how can I take a sequence of strings and combine them into one string with spaces separating them? |
| 16:33 | Fossi | plus i want to fiddle with the dexer again some time again and finally make that faster |
| 16:33 | seangrove | Map won't work because that will of course return another string |
| 16:33 | seangrove | I suppose I could just do it recursively |
| 16:33 | Fossi | so that might be a way to get a faster repl |
| 16:33 | Fossi | (and hopefully swank/slime) |
| 16:33 | headius | yay duby |
| 16:33 | hiredman | ,(reduce (partial str " ") ["a" "b" "c"]) |
| 16:33 | clojurebot | " abc" |
| 16:34 | hiredman | bleh |
| 16:34 | hiredman | ,(reduce (partial partial format "%s %s") ["a" "b" "c"]) |
| 16:34 | clojurebot | #<core$partial__5034$fn__5044 clojure.core$partial__5034$fn__5044@1d26ddd> |
| 16:34 | hiredman | :/ |
| 16:35 | hiredman | ,(reduce #(format "%s %s" % %2) ["a" "b" "c"]) |
| 16:35 | clojurebot | "a b c" |
| 16:35 | The-Kenny | ,(reduce #(str %1 (partial " " %2)) [1 2 3]) |
| 16:35 | clojurebot | "1clojure.core$partial__5034$fn__5036@17c814dclojure.core$partial__5034$fn__5036@10cf661" |
| 16:35 | The-Kenny | ,(reduce #(str %1 (str " " %2)) [1 2 3]) |
| 16:35 | clojurebot | "1 2 3" |
| 16:36 | hiredman | ,(reduce (comp (partial apply format "%s %s") list) ["a" "b" "c"]) |
| 16:36 | clojurebot | "a b c" |
| 16:36 | seangrove | Heh |
| 16:38 | hugod | ,(reduce str (interpose " " ["a" "b" "c"])) |
| 16:38 | clojurebot | "a b c" |
| 16:39 | joshua-choi | I’ve been actually trying developing with the REPL now. I get it now; it’s really nice; much better than running tests repeatedly. JLine also helps a *lot*. |
| 16:39 | hiredman | hugod: use apply in that case |
| 16:40 | Fossi | str-join ;D |
| 16:40 | hiredman | Fossi: write a stack lisp that compiles to bytecode without needing a runtime |
| 16:40 | Fossi | thought about it |
| 16:40 | Fossi | too crazy though |
| 16:40 | Fossi | i wouldn't finish in ages |
| 16:41 | nteon | ,(reduce (fn [a b] (str a " " b) ["a" "b" "c"]) |
| 16:41 | clojurebot | EOF while reading |
| 16:42 | nteon | ,(reduce (fn [a b] (str a " " b)) ["a" "b" "c"]) |
| 16:42 | clojurebot | "a b c" |
| 16:42 | nteon | hugod: yours is better :) |
| 16:48 | stacktracer | is there a way to allow a lambda to be called with more args than it uses? |
| 16:48 | stacktracer | for example: |
| 16:48 | stacktracer | ,(#(print %) "Hello, world!") |
| 16:48 | clojurebot | Hello, world! |
| 16:48 | stacktracer | ,(#(print "Goodbye") "Hello, world!") |
| 16:48 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--5579$fn |
| 16:49 | stacktracer | can I make the second one work without doing (fn [_] ...) ? |
| 16:49 | hiredman | ,(#(do %& (print :a)) :b :c :d) |
| 16:50 | clojurebot | :a |
| 16:50 | hiredman | in short, no |
| 16:50 | stacktracer | okey dokey -- thanks hiredman |
| 17:07 | etate | OMFG FINALLY... ogre4j starting to work :) |
| 17:39 | rem7 | is there a way to set the repl to print really big numbers not truncated? |
| 17:45 | remleduff | How can I tell if elpa has successfully downloaded swank-clojure and if it's active correctly after restarting? |
| 17:46 | hiredman | M-x slime |
| 17:46 | remleduff | That says, "[No match]" |
| 17:47 | remleduff | I have this in my *Messages* though: File mode specification error: (file-error "Cannot open load file" "swank-clojure-autoload") |
| 17:58 | remleduff | Any ideas how I get past: swank-clojure.el:48:1:Error: Cannot open load file: swank-clojure-autoload when trying to M-x package-install swank-clojure ? |
| 18:06 | remleduff | Any ideas why "M-x slime" doesn't do anything at all? :| |
| 19:05 | miltondsilva | about memoize, kotarak and cgrand have posted some very nice aditions to it but, shouldn't the caching be done on the JVM side? Souldn't high-level languages abstract you from memory managment? What am I missing? |
| 19:11 | nteon | is there a way to specify a method signature for a static method/function on a gen-class namespace? |
| 19:16 | Chousuke | miltondsilva: memoize is not memory management, it's a caching "decorator" for functions |
| 19:26 | slyphon | so, what's the idiomatic way to throw exceptions in your code? I'm used to defining a root exception for my project and subclassing that, but that seems like it would be very cumbersome in clojure |
| 19:27 | hiredman | (throw (RuntimeException. "blah blah stuff happened")) |
| 19:27 | slyphon | so just use RuntimeException? |
| 19:28 | hiredman | or don't throw exceptions |
| 19:28 | hiredman | clojurebot: exceptions? |
| 19:28 | slyphon | hrm |
| 19:28 | clojurebot | http://paste.lisp.org/display/74305 |
| 19:28 | hiredman | you could just pick one |
| 19:28 | slyphon | ok |
| 19:29 | slyphon | rhickey: is the "ants" demo and talk a good place to learn about how to structure code to take advantage of STM? |
| 19:30 | slyphon | i'm starting to work on a video encoding task management engine in clojure, and i'm a little confused at what level i should be using ref/atom/agent |
| 19:30 | rhickey | slyphon: It's a good start, but all situations are different, so not a fixed model |
| 19:32 | rhickey | slyphon: try to find the 'identities' in your problem space - these should get the refs in the first cut at a model. e.g. if a person was an entity in your domain, his arm wouldn't be an identity |
| 19:32 | slyphon | THANKS, SPRINT! |
| 19:32 | rhickey | slyphon: try to find the 'identities' in your problem space - these should get the refs in the first cut at a model. e.g. if a person was an entity in your domain, his arm wouldn't be an identity |
| 19:32 | rhickey | have you read http://clojure.org/state ? |
| 19:34 | slyphon | i'm sort of modeling an RDBMS row as a struct-map, and it seems that the row will have columns that are immutable and others that are mutable, the mutable ones seem to me to be a natural fit with refs |
| 19:35 | slyphon | "If this struct was a part of an index of this collection of structs, i wouldn't want to have to change the whole collection just because i'm going to update *blah* on this 'row'" |
| 19:35 | slyphon | rhickey: i'll just read that page again |
| 19:36 | hiredman | how big are your rows? |
| 19:36 | miltondsilva | Chousuke: the problem is, I'm now at a point where I need to memoize a great number of functions in order to optimize my program. so shouldn't this be done automatically? |
| 19:36 | hiredman | bleh |
| 19:36 | hiredman | that is not the question |
| 19:36 | slyphon | hiredman: about 17 cols |
| 19:37 | hiredman | how often will you mutate multiple columns in a row? |
| 19:37 | slyphon | fairly often |
| 19:37 | hiredman | hmm |
| 19:38 | slyphon | it's keeping track of the state of an encoding job as it gets taken by an encoder and processed |
| 19:38 | slyphon | including progress updates, timestamps to indicate how long it's been running for, how long it waited to get picked up, etc. |
| 19:38 | slyphon | right now we have it in a mysql db, but it's causing all sorts of issues, because using the db as a queue is "doing it wrong" |
| 19:39 | slyphon | gah, he're my train stop |
| 19:39 | slyphon | i'll bbialb |
| 19:45 | rhickey | what's the current Clojure textmate bundle? |
| 19:47 | rhickey | this http://github.com/nullstyle/clojure-tmbundle looks pretty old |
| 19:53 | Chousuke | miltondsilva: you can't automatically memoize functions |
| 19:53 | Chousuke | miltondsilva: it only works for pure ones |
| 19:55 | miltondsilva | Chousuke: I know.... but being lazy as I am, I was hoping there was a switch called memoize-all-pure-fns |
| 19:55 | Chousuke | well, you can write a small wrapper macro that defines and memoizes a function |
| 19:56 | miltondsilva | Chousuke: if not that than something like defn-memoized |
| 19:58 | miltondsilva | I could if I knew how to write macros... ah well guess this is a good time to learn ;) |
| 20:01 | Chousuke | start with writing out the code you want manually |
| 20:01 | Chousuke | then write a *function* that produces that code. ie. a list. |
| 20:01 | Chousuke | then change defn to defmacro :P |
| 20:03 | miltondsilva | thanks but as I said I'm lazy and I'm also lucky contrib has a defn-memo ^^ |
| 20:03 | Chousuke | heh |
| 20:14 | nathanmarz | any tips on writing unit tests for code that uses agents? |
| 20:14 | nathanmarz | "lein test" just hangs when the tests finish |
| 20:14 | krumholt_ | how can i predict how many elements of a lazy-seq will be realised? for example i don't want the following to fail |
| 20:14 | krumholt_ | ,(first (lazy-seq [(/ 1 2) (/ 1 2) (/ 1 0)])) |
| 20:14 | clojurebot | java.lang.RuntimeException: java.lang.ArithmeticException: Divide by zero |
| 20:18 | tomoj | krumholt_: I don't think it works that way |
| 20:19 | tomoj | ,(first (lazy-seq (cons (/ 1 2) (lazy-seq (cons (/ 1 0) nil))))) |
| 20:19 | clojurebot | 1/2 |
| 20:20 | tomoj | ,(lazy-seq (cons (/ 1 2) (lazy-seq (cons (/ 1 0) nil)))) |
| 20:20 | clojurebot | java.lang.ArithmeticException: Divide by zero |
| 20:20 | tomoj | ,(doc lazy-seq) |
| 20:20 | clojurebot | "([& body]); Takes a body of expressions that returns an ISeq or nil, and yields a Seqable object that will invoke the body only the first time seq is called, and will cache the result and return it on all subsequent seq calls." |
| 20:21 | tomoj | your body is that vector, so your call to lazy-seq returns a LazySeq which, when realized, evaluates that vector |
| 20:21 | tomoj | evaluating that vector causes the divide by zero error |
| 20:21 | krumholt_ | tomoj, ok |
| 20:21 | tomoj | to get lazy-seqs you would normally use the seq library |
| 20:22 | krumholt_ | is that from contrib or in clojure.core? |
| 20:22 | tomoj | well, it's not a specific library really |
| 20:22 | tomoj | lots in core, some stuff in contrib |
| 20:22 | tomoj | just in general functions which return lazy seqs |
| 20:23 | tomoj | e.g. |
| 20:23 | tomoj | ,(map / (reverse (range 1 5))) |
| 20:23 | clojurebot | (1/4 1/3 1/2 1) |
| 20:23 | tomoj | that's lazy |
| 20:23 | tomoj | so this blows up |
| 20:23 | tomoj | ,(map / (reverse (range 5))) |
| 20:23 | clojurebot | java.lang.ArithmeticException: Divide by zero |
| 20:23 | tomoj | ,(first (map / (reverse (range 5)))) |
| 20:23 | clojurebot | 1/4 |
| 20:24 | tomoj | but that works |
| 20:24 | krumholt_ | ok |
| 20:24 | tomoj | if you need to build a lazy-seq manually using the `lazy-seq` function, the pattern I've seen most is (lazy-seq (cons ... ...)) |
| 20:25 | tomoj | or sometimes lazy-cat |
| 20:26 | krumholt_ | tomoj, ok i thought that (lazy-seq [1 2 3]) would do that |
| 20:27 | tomoj | no, vectors aren't lazy, so |
| 20:27 | krumholt_ | tomoj, ah ok i understand |
| 20:27 | krumholt_ | thanks |
| 20:27 | krumholt_ | ,(seq? [1 2 3]) |
| 20:27 | clojurebot | false |
| 20:27 | tomoj | if you've already got [1 2 3] no reason to turn it into a lazy seq |
| 20:27 | tomoj | on the other hand, you might have a macro which reads a vector and lazily evaluates its members... but that seems strange |
| 20:28 | tomoj | ,(doc macrolet) |
| 20:28 | clojurebot | Pardon? |
| 20:29 | tomoj | ,(require '[clojure.contrib.macro-utils :as macro-utils]) |
| 20:29 | clojurebot | nil |
| 20:33 | krumholt_ | i think it is because of chunked sequences |
| 20:36 | tomoj | chunking can cause problems, yes |
| 20:36 | tomoj | are you doing side-effects? |
| 20:37 | tomoj | ,(take 5 (map #(do (println %) %) (range 10))) |
| 20:37 | clojurebot | (0 1 2 3 4) |
| 20:38 | tomoj | well, it prints out 0-10 as well |
| 20:38 | krumholt_ | tomoj, no side effects |
| 20:39 | krumholt_ | just calculations that might fail |
| 20:39 | tomoj | ah |
| 20:39 | krumholt_ | but if they do i don't want that to happen before it's there turn to execute |
| 20:39 | Licenser | harr harr harr |
| 20:40 | tomoj | krumholt_: are you using `take` to grab some results off the seq of calculations? |
| 20:40 | krumholt_ | no just first |
| 20:40 | tomoj | ah, same problem there |
| 20:40 | tomoj | ,(first (map #(do (println %) %) (range 10))) |
| 20:40 | clojurebot | 0 |
| 20:40 | clojurebot | 0 1 2 3 4 5 6 7 8 9 |
| 20:40 | krumholt_ | ,(first (lazy-seq (cons (/ 1 2) (cons (/ 3 4) (cons (/ 1 0) (cons (- 1 2) nil)))))) |
| 20:40 | clojurebot | java.lang.RuntimeException: java.lang.ArithmeticException: Divide by zero |
| 20:41 | tomoj | you need more lazy-seqs :) |
| 20:41 | krumholt_ | i think it is because of chunks but its not that bad |
| 20:42 | krumholt_ | i'll wrap the statements in delays |
| 20:52 | tomoj | ,(macro-utils/macrolet [(lazy-vec [v] (when (seq v) `(lazy-seq (cons ~(first v) (lazy-vec ~(next v))))))] (first (lazy-vec [(/ 2) (/ 1) (/ 0)]))) |
| 20:52 | clojurebot | java.lang.Exception: No such var: sandbox/lazy-vec |
| 20:52 | hiredman | uh |
| 20:53 | hiredman | krumholt_: lazy-seq does not reach into cons and make it lazy |
| 20:53 | hiredman | your lazy-seq there returns a strict list |
| 20:53 | tomoj | lazy-vec doesn't :) |
| 20:53 | tomoj | but, I have no idea why you'd want lazy-vec, really |
| 20:53 | hiredman | lazy-seq basicly makes a thunk |
| 20:53 | hiredman | that has nothing to do with chucnks |
| 20:54 | pdk | if you did (lazy-seq (cons (...))) then it would have to evaluate the cons before it could pass it as an argument to lazy-seq |
| 20:54 | remleduff | Wow, rebooting fixed swank! |
| 20:54 | remleduff | Does anyone know the magic to make [] work with paredit? |
| 20:54 | hiredman | pdk: lazy-seq is a macro, so that is not true |
| 20:55 | tomoj | remleduff: https://gist.github.com/15c936da860edf2fa016 |
| 20:55 | tomoj | remleduff: you probably don't need all of that |
| 20:55 | remleduff | Hehe, thanks tomoj :) |
| 20:56 | tomoj | oh, also |
| 20:56 | tomoj | you should be using paredit-beta.el |
| 20:56 | krumholt_ | hiredman, i thought lazy-seq qould take my seq and make it lazy |
| 20:56 | tomoj | http://mumble.net/~campbell/emacs/paredit-beta.el |
| 20:56 | tomoj | vectors aren't seqs |
| 20:57 | tomoj | lazy-seq doesn't really do that for seqs either |
| 20:57 | hiredman | krumholt_: you don't have a seq, you have a list |
| 20:57 | krumholt_ | (seq? (list 1 2 3)) |
| 20:57 | krumholt_ | ,(seq? (list 1 2 3)) |
| 20:57 | clojurebot | true |
| 20:58 | hiredman | ok, you don't have a list, you have a function call that returns a non-lazy list |
| 20:58 | tomoj | ,(first (lazy-seq (list 1 2 (/ 0)))) |
| 20:58 | clojurebot | java.lang.RuntimeException: java.lang.ArithmeticException: Divide by zero |
| 20:58 | tomoj | the list is a seq, yes, but lazy-seq can't just magically make it a lazy seq |
| 20:58 | hiredman | ,(first (lazy-seq 1 (lazy-seq (/ 0)))) |
| 20:58 | clojurebot | java.lang.RuntimeException: java.lang.ArithmeticException: Divide by zero |
| 20:58 | tomoj | lazy-seq just lazily evaluates its body, which in my example is (list 1 2 (/ 0)) |
| 20:58 | tomoj | evaluating that throws an error |
| 20:58 | hiredman | ,(first (lazy-seq (cons 1 (lazy-seq (/ 0))))) |
| 20:58 | clojurebot | 1 |
| 20:59 | tomoj | yeah, need a string of lazy-seqs if you're doing this manually |
| 20:59 | hiredman | if you look at the definition for lazy seq producing functions they are recursive |
| 20:59 | krumholt_ | ok i think i get it |
| 20:59 | krumholt_ | thanks all |
| 21:00 | tomoj | though my lazy-vec above is an attempt to evaluate a vector lazily through a macro |
| 21:00 | tomoj | so (first (lazy-vec [(/ 1) (/ 0)])) returns 1 |
| 21:00 | etate | man i just made the best color-theme evar |
| 21:01 | hiredman | ,(letfn [(map’ [f [x & xs]] (when x (lazy-seq (cons (f x) (map’ f xs)))))] (map’ inc (range 3))) |
| 21:01 | clojurebot | (1 2 3) |
| 21:01 | tomoj | etate: are you sharing? |
| 21:01 | etate | tomoj: sure if you want it |
| 21:01 | tomoj | I made my own too but don't really like it |
| 21:01 | etate | tomoj: i just spent the last 40 mins making this one :) |
| 21:02 | etate | tomoj: the region highlighting kind of sucks but i'll paste it |
| 21:02 | tomoj | thanks |
| 21:03 | etate | http://gist.github.com/331038 |
| 21:03 | etate | tomoj: let me know what you think |
| 21:05 | tomoj | etate: looks pretty nice |
| 21:05 | tomoj | didn't cover everything mine did so remnants are left :( |
| 21:05 | etate | tomoj: yeah its not complete yet :) |
| 21:06 | tomoj | I think some of the near-whites are too bright for me, but I like your basic idea better than my weird combination of a bunch of colors that don't go together |
| 21:07 | etate | tomoj: as in the strings or functions? |
| 21:08 | etate | tomoj: i think you're right though there are some subtle inconsistencies... i'll continue hacking it :) |
| 21:08 | tomoj | just in general the colors are too similar to me |
| 21:08 | tomoj | I look like http://tomojack.com/stuff/sshots/color.png |
| 21:09 | etate | tomoj: thats not my theme, thats yours? |
| 21:10 | tomoj | yeah |
| 21:10 | tomoj | comparatively I have lots of different colors |
| 21:11 | etate | tomoj: yeah i think too many colours makes it look inconsistent personally |
| 21:11 | tomoj | yeah, I didn't like picking them and am not satisfied |
| 21:11 | etate | tomoj: i try and choose a palette and go for pastel colours |
| 21:13 | tomoj | next time maybe I'll try using a palette, good idea |
| 21:15 | etate | tomoj: :) i'm just hacking mine now i'll paste the next version :D |
| 21:16 | hiredman | tomoj: have you tried rainbox parens? |
| 21:17 | hiredman | rainbow |
| 21:26 | remleduff | What's the "correct" way to turn on paredit mode now actually? I'm a little confused with all the seemingly different documentation |
| 21:30 | etate | remleduff: either M-x paredit-mode, or set it in .emacs |
| 21:32 | etate | remleduff: to set it in .emacs you use (add-to-list 'load-path "/path/to/paredit/"), then (autoload 'paredit-mode "paredit") .. then add hooks to your modes so: (add-hook 'clojure-mode-hook (lambda () (paredit-mode +1))) |
| 21:33 | etate | tomoj: got a new version which is much more colourful |
| 21:33 | remleduff | estate: OK, I'm trying to stick to ELPA as much as possible and thought I was doing too much manually |
| 21:34 | etate | remleduff: o, i can't really comment since i don't know how ELPA works |
| 21:34 | etate | tomoj: http://gist.github.com/331058 |
| 21:39 | etate | is there a clojure-indent ? |
| 21:45 | tomoj | hiredman: I haven't |
| 21:57 | psykotic | remleduff: with ELPA, you don't need to worry about adding it to the path or autloading, but you still need to activate it where appropriate, either manually or with mode hooks |
| 22:06 | remleduff | psykotic: Thanks, I think I understand |
| 22:07 | psykotic | (autoloading is 'lazy loading'. it creates a stub function that loads the .el file the first time it is called) |
| 22:08 | remleduff | What I have now is: (require 'paredit) (add-hook 'clojure-mode-hook (lambda () (paredit-mode +1))) and then the magic to make [] and {} work as well |
| 22:10 | remleduff | Where is swank-clojure.jar supposed to come from? I've been searching clojars for something to add to project.clj but am I missing something? |
| 22:11 | psykotic | you don't need to require it |
| 22:11 | psykotic | elpa adds autoloads and things like that for you automatically |
| 22:13 | remleduff | Hmm, if I didn't require it, I get errors when I try to do: (define-key paredit-mode-map (kbd "M-[") 'paredit-wrap-square) |
| 22:14 | psykotic | ah yeah. for defining keys you need more than the autload |
| 22:14 | hiredman | tomoj: there is a rainbow-paren-mode that colors parens based on nesting depth |
| 22:14 | psykotic | the usual way people do that is add a hook to paredit-mode itself |
| 22:14 | hiredman | it's very colorful |
| 22:14 | psykotic | ie they have a lambda which on load of paredit fixes up the mode map |
| 22:15 | psykotic | that way it's deferred, and by the time the lambda body executes, it will actually have been loaded, and variables like paredit-mode-map, etc, will exist |
| 22:16 | psykotic | look at this guy's .emacs: http://www.freebsd.org/doc/en/books/developers-handbook/emacs.html |
| 22:17 | psykotic | particular the my-lisp-mode-hook |
| 22:17 | psykotic | do something similar for paredit |
| 22:17 | psykotic | then you don't need the require and the autoload will do |
| 22:20 | slyphon | hrm |
| 22:21 | slyphon | it'd be interesting if you could coordinate updates between STM and say, an RDBMS |
| 22:21 | remleduff | Isn't C-k supposed to do something, even though I'm in paredit mode? |
| 22:21 | slyphon | yeah, it kills the sexp, without destroying the delicate balance of sexps |
| 22:22 | slyphon | http://www.emacswiki.org/emacs/PareditCheatsheet |
| 22:22 | slyphon | "paredit-kill" |
| 22:22 | remleduff | I typed: (defun awesome-p () t) |
| 22:22 | kwertii | Is there a Clojure time/date library, or some other way to avoid using the obscene GregorianCalendar stuff from Java? |
| 22:22 | remleduff | I put the point after the paren, and hit C-k |
| 22:22 | psykotic | kwertii: i think a lot of people using jota |
| 22:22 | slyphon | after which paren? |
| 22:22 | remleduff | But it deleted the following line, I thought it was supposed to delete the sexp |
| 22:22 | remleduff | I can't get it to delete any sexps :) |
| 22:23 | kwertii | psykotic: Joda? |
| 22:23 | kwertii | psykotic: cool, thanks |
| 22:24 | psykotic | kwertii: yes, sorry, all this java stuff is new to me |
| 22:24 | kwertii | psykotic: found it, looks good |
| 22:24 | remleduff | psykotic, after either paren, for the first (), it does nothing. At the end of the line, it deletes the following newline |
| 22:25 | remleduff | Hmm, maybe I'm misunderstanding the tutorial I'm reading |
| 22:26 | psykotic | if it behaves differently than normal C-k, then it's working :) |
| 22:28 | psykotic | always read the docs. it's pretty explicit about what happens. C-h k C-k |
| 22:29 | psykotic | basically, if you've got a sexp spread over multiple lines, then C-k doesn't gobble up everything in one go, it acts like normal C-k |
| 22:29 | psykotic | if you want to kill the whole multi-line sexp, i think you need to put the cursor on the opening bracket |
| 22:46 | remleduff | Any idea why M-x swank-clojure-project might just sit there polling slime.5548 forever? |
| 22:46 | icey | remleduff: that's happened to me before when my swank server didn't start properly |
| 22:46 | somnium | remleduff: probably no swank-clojure.jar in ./lib, but check *inferior-lisp* for more info |
| 22:47 | icey | i'm trying to think back to what caused it, but i think i was missing something on my classpath |
| 22:47 | remleduff | somnium: I'm pretty sure that's my problem, but where do I get swank-clojure.jar? |
| 22:47 | somnium | remleduff: [swank-clojure "1.1.0"] |
| 22:48 | remleduff | Great, I've been searching for that for a while, thanks. swank-clojure doesn't come up if you search on clojars |
| 22:51 | somnium | hmm, swank alone gets a hit. but yeah, thats a bit confusing |
| 22:51 | remleduff | Yay, it worked! |
| 22:56 | psykotic | you're launching with lein swank, right? |
| 22:57 | remleduff | No, M-x swank-clojure-project for the moment |
| 22:57 | psykotic | ah right |
| 22:59 | remleduff | Is the completion style when I hit <TAB> configurable when there are multiple matches? |
| 22:59 | remleduff | I'd rather get something like ido instead of a big buffer listing all the completions available |
| 23:01 | hiredman | there is something called autocomplete which will popup a sort of overlay for completions |
| 23:02 | psykotic | hiredman: with slime? |
| 23:04 | psykotic | ah this, http://www.emacswiki.org/emacs/AutoComplete |
| 23:04 | remleduff | Do you know if slime-fuzzy-complete-symbol will work? |
| 23:04 | psykotic | iirc slime's fuzzy complete is not done in emacs but host-side |
| 23:04 | psykotic | but someone reimeplemtned the algorithm in emacs separately, so you could probably hook that in |
| 23:06 | remleduff | There seems to be something called "company-mode" in ELPA, I'll see if that will work |
| 23:06 | remleduff | "company = complete anything". It also is rough to google for |
| 23:08 | psykotic | if you don't know any emacs lisp, hooking these things up to slime might not be that easy |
| 23:09 | somnium | auto-complete rocks -- typing more than 3 chars feels like a chore |
| 23:12 | psykotic | it's pretty crazy that it uses overlays, haha |
| 23:12 | psykotic | i guess it creates one for each row of the completion box |
| 23:13 | psykotic | and presumably it has to temporarily pad lines with spaces if the box extends beyond some given line's contents, etc |
| 23:16 | remleduff | Is autoinstall something that existed pre-ELPA, or some competitor or... ? |
| 23:16 | psykotic | preeexisted |
| 23:16 | psykotic | actually, it might not, now that i think about it |
| 23:17 | remleduff | I feel like I'm asking too much emacs stuff here, sorry people who want to hear about clojure |
| 23:18 | kwertii | can you set JVM command-line arguments in Leiningen (to enable remote debugging)? |
| 23:18 | somnium | emacs digressions are fairly common in this channel |
| 23:18 | tomoj | kwertii: for what, lein-swank? |
| 23:18 | tomoj | I mean, how are you starting the jvm? |
| 23:18 | tomoj | guess it doesn't matter, I don't know the answer :( |
| 23:19 | kwertii | tomoj: yeah, or anything, really. I'm starting with lein swank, but I imagine it would be the same for lein repl or whatever |
| 23:23 | kwertii | Not what I had in mind, but you can set the JAVA_OPTS env variable to affect the JVM launched by Leiningen... |
| 23:23 | psykotic | there's something called eval-in-project |
| 23:24 | psykotic | it takes a handler arg that's called on the java task before execution, and it can set jvm args |
| 23:25 | psykotic | but there don't appear to be hooks for the existing eval-in-project uses |
| 23:26 | psykotic | kwertii: is that a general java thing? |
| 23:26 | kwertii | psykotic: yep, at least with the Sun JVM |
| 23:26 | psykotic | oh, i see, it's in the lein shell script |
| 23:27 | remleduff | The only thing I see is the JAVA_OPTS environment variable |
| 23:27 | kwertii | ahh, so it is |
| 23:27 | remleduff | I wonder why lein-repl is implemented in the shell script rather than using eval-in-project |
| 23:28 | psykotic | it would be nice if eval-in-project used some *special-vars* for jvm args, etc |
| 23:28 | psykotic | the current handler approach is nice if you are in control of the eval-in-project invocation, but it doesn't help you much if you want to alter existing eval-in-project uses elsewhere |
| 23:30 | psykotic | remleduff: i avoid using lein repl, it doesn't seem to work very well |
| 23:31 | remleduff | Yeah, the current way it's implemented means it gets leiningen's classpath rather than the project's |
| 23:32 | remleduff | Well, that's oversimplifying, it adds everything in lib as well |
| 23:33 | remleduff | So I guess it's basically the project's classpath |
| 23:39 | Mec | What font do you guys like best for code? |
| 23:39 | arbscht | inconsolata |
| 23:42 | Apage43 | I am pretty partial to Inconsolata |
| 23:43 | Apage43 | use Consolas at work though, next best since it ships with office 07. |
| 23:43 | Mec | I dont think i have that one |
| 23:44 | hiredman | I prefer Consolas to Inconsolata, but mostly use DejaVu Sans Mono because it has the best unicode coverage |
| 23:45 | Mec | i do have that one |
| 23:52 | Mec | hey lookie there, emacsW32 where have you been all my life |
| 23:58 | remleduff | somnium: Now that I have autocomplete installed, how do I get it to work with clojure? |
| 23:59 | psykotic | consolas looks like garbage with a non-windows font renderer |
| 23:59 | psykotic | monaco looks good on a mac, imo |
| 23:59 | icey | psykotic: yeah i use monaco and like it |