2010-09-24
| 00:07 | technomancy | grrr... using ant as a library is like building a castle out of sand |
| 00:07 | ninjudd | tell me about it |
| 00:08 | technomancy | apparently it just plain ignores the spawn option on the subprocess launching |
| 00:08 | ninjudd | which task? Javac. |
| 00:08 | technomancy | "Look ant, I need you to fork a subprocess that outlasts the parent." / "Cool story bro. Listen, I'm gonna do my own thing over here..." |
| 00:08 | technomancy | just plain Java |
| 00:10 | ninjudd | hmm |
| 00:11 | ninjudd | isn't that what you use to fork your project jvm? |
| 00:11 | technomancy | well normally I don't want the forked process to outlast the parent |
| 00:12 | technomancy | but I realized it wouldn't be hard to have it start a background server |
| 00:12 | technomancy | err--it wouldn't be hard if ant behaved as advertised |
| 00:12 | ninjudd | are you writing a persistent jvm. |
| 00:13 | technomancy | I'm expanding the repl server to work in the background |
| 00:13 | technomancy | I guess so? |
| 00:13 | ninjudd | you have fork=true and spawn=true, right? |
| 00:13 | technomancy | right |
| 00:13 | technomancy | but the parent JVM just quits and takes the child with it |
| 00:14 | ninjudd | and you aren't using any of the other opts that aren't compatible with spawn? |
| 00:15 | technomancy | right; I had failOnError set, but I turned that off when it complained |
| 00:16 | ninjudd | i could swear I got that working before I decided to launch both jvms from ruby |
| 00:17 | technomancy | maybe it's fixed in a newer ant |
| 00:17 | Bahman | Hi all! |
| 00:17 | ninjudd | perhaps. docs say it doesn't work with input, output, error, result and timeout... |
| 00:21 | ninjudd | could you use Runtime.exec directly? |
| 00:22 | technomancy | according to the ant mailing list they had to work around a hell of a lot of edge cases in Runtime.exec |
| 00:23 | technomancy | of course, apparently they missed at least one |
| 00:23 | ninjudd | hehe |
| 00:24 | ninjudd | I use ant 1.8.1. you may want to try that |
| 00:27 | technomancy | oh, I thought 1.7.1 was the latest... will try that |
| 00:28 | ninjudd | I think there is 1.8.2 |
| 00:28 | ninjudd | not sure why I'm not using it though |
| 00:34 | TheBusby | I've actually had a lot of trouble with Java process spawning recently. Final solution ended up being using JNI. |
| 00:56 | technomancy | at least with smalltalk you could forgive it for pretending like Unix didn't exist because it was so old |
| 00:57 | technomancy | that excuse really doesn't work for the JVM |
| 01:04 | sandGorgon | hi guys... wanted to prototype a document store like functionality in clojure. basically a clojure server would be running on a remote machine, I request for a (guaranteed) unique filename and it returns a one-time URL that I can retrieve the files from. Later I'm gonna bolt on authentication and all that stuff |
| 01:04 | sandGorgon | I'm confused on the first step - to build the clojure "server" would I have to use a web framework like compojure ? |
| 01:06 | amalloy | sandGorgon: i'm not an expert here (so don't take my advice!), but you certainly don't have to. if you wanted, you could instantiate the java.net.ServerSocket yourself |
| 01:07 | sandGorgon | amalloy, true - I was kinda hoping one layer of abstraction above it. my first thought was compojure, then I thought of ring, now I'm thinking of something using Aleph/Netty. But wanted to get idead |
| 01:07 | sandGorgon | s/idead/ideas/ |
| 01:07 | sexpbot | <sandGorgon> amalloy, true - I was kinda hoping one layer of abstraction above it. my first thought was compojure, then I thought of ring, now I'm thinking of something using Aleph/Netty. But wanted to get ideas |
| 01:09 | amalloy | somewhere around here i have a copy of my first clojure program, which was a simple chat server. compojure or ring or something is almost certainly better, but i don't have experience with any of them |
| 01:09 | TheBusby | technomancy: I fought with the JVM's processing spawning for quite a bit before going JNI. The worst part is what works for one platform doesn't work for another, hence the JNI route... |
| 01:10 | technomancy | TheBusby: yeah... honestly I only bothered because it looked like it would be really easy |
| 01:11 | technomancy | I'm not sure it's worth the hassle at this point just to be able to do TDD outside swank |
| 01:11 | sandGorgon | amalloy, actually the reason why it might be a bit different is that it might well be a multi-gigabyte file. So you dont want to drop down to socket level and have to deal with fillng up of posix buffers and all that. |
| 01:11 | technomancy | maybe someone who doesn't use swank could implement it. =) |
| 01:13 | TheBusby | I think it took me about 20 minutes to implement what I needed, but I had some skeleton code (using fork and execvp) to work with. |
| 01:15 | amalloy | github gist |
| 01:15 | amalloy | argh. wrong window :P |
| 01:18 | amalloy | sandGorgon: anyway http://gist.github.com/594895 if you want to use it as a comparison vs ring or some other tool |
| 01:19 | sandGorgon | amalloy, hey thanks!! |
| 01:20 | technomancy | (re-pattern (format "(?:^|/)%s/" pat)) <= what's all that punctuation about? |
| 01:23 | amalloy | technomancy: ^ indicates start of line, and / is a literal. they're separated by |, which is OR; those are wrapped in (?:) to get proper grouping - the ?: prevents it from stomping on your capturing groups |
| 01:24 | technomancy | amalloy: ah, thanks. I hadn't seen ?: before; handy. |
| 01:24 | amalloy | so it looks to be matching "foo/" or "anything/foo", but not "myfoo" |
| 01:25 | nroot7 | clojure documentation mentions many functions to be side effect free. How does the compiler verify that ? Is it just a convention ? |
| 01:25 | amalloy | technomancy: http://www.regular-expressions.info/tutorial.html is a superb resource for learning both basics and nuances, if you're getting into a lot of regexes |
| 01:25 | amalloy | nroot7: just convention. the compiler has no idea |
| 01:25 | sandGorgon | amalloy, ah.. I was thinking that the ? was for a non-greedy match |
| 01:27 | amalloy | heh. ? means about a hundred things depending on where in the regex it is |
| 02:07 | Bahman | Hi all! |
| 03:07 | LauJensen | Good morning all |
| 03:10 | amalloy | silly europeans, claiming it's morning |
| 03:12 | LauJensen | clojurebot: UGT? |
| 03:12 | clojurebot | ugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html |
| 03:12 | LauJensen | silly uneducated americans, thinking I was referring to time |
| 03:14 | nlogax | also, there's no timezone exclusive to europe |
| 03:24 | Raynes | It's morning in the USA. |
| 03:24 | Raynes | At least, my clock says AM. |
| 05:18 | fliebel | morning |
| 05:18 | mrBliss | morning fliebel |
| 05:19 | fliebel | What is the usual path to follow when lein deps is missing something? |
| 05:19 | fliebel | (junit 4.7 in this case I believe) |
| 05:20 | mrBliss | make sure your dependency vector is correct: http://jarvana.com/jarvana/archive-details/junit/junit/4.7/junit-4.7.jar |
| 05:22 | fliebel | It's not exactly my vector, rather the Overtone one. And even then, it is a dependency of a dependency, because Overtone itself does not depend on junit. |
| 05:23 | mrBliss | fliebel: good luck :) |
| 05:24 | fliebel | mrBliss: Thanks :( I guess I'll just ask on the Overtone mailing list, after I tried some more. |
| 05:59 | fliebel | mrBliss: Deleting .m2 fixed it for some reason :-| |
| 06:11 | Hoornet | Hello |
| 06:12 | Raynes | Hi. |
| 06:14 | esj | wotcha |
| 06:21 | esj | was it something I said ? :( |
| 07:53 | LauJensen | Anybody here living in London ? |
| 07:58 | mccraig | LauJensen: i work there |
| 08:08 | esj | I live up the way in Cambridge |
| 08:13 | LauJensen | esj: Im in priv with mccraig trying to extract some information :) |
| 08:13 | esj | All you need to know is that London is big and smell :) |
| 08:14 | LauJensen | I don't remember any specific smell, just that its huge and difficult to get around in |
| 08:18 | esj | yes, I served a two year term there, happily I am now paroled. |
| 08:25 | bobo_ | is there any good tutorial on testing your java code with clojure? setting up the project and so on? |
| 09:11 | fliebel | Hey, what are naming conventions in Clojure? I figured out dashed-style is preferred and question-mark? is used for booleans, but how about *stars and -dashes? |
| 09:12 | esj | fliebel: I think *ear-muffs* are often for dynamic vars, and -dashes for private functions |
| 09:13 | fliebel | esj: -main has a dash, and in java that's public static void main IIRC. |
| 09:13 | chouser | never seen a leading star. trailing star is like a "prime tick" in math -- foo is something, foo* is related but different. sometimes a macro vs. a function that does something similar |
| 09:13 | fliebel | chouser: Yea, I meant things like fn* |
| 09:13 | chouser | yes, *ear-muffs* are for vars -- things that are meant to be rebound using (binding ...) |
| 09:14 | chouser | leading dash is for functions that are acting as methods for genclass. Note (defn- foo ...) is for a private foo which is different than (defn -foo ...) which is likely a public method of a class. |
| 09:15 | chouser | fliebel: yeah fn* is the real special operator, related to fn which is a macro |
| 09:16 | fliebel | okay… so, recap: *changable-var* low-level-stuff* -java-method bollean? |
| 09:16 | esj | -dashes.... yes I'm confusing myself with defn-. Apologies. |
| 09:17 | AndChat- | . |
| 09:17 | esj | or rather: predicate? |
| 09:17 | fliebel | esj: Yea, nicer word :) |
| 09:17 | chouser | I use ? for boolean locals too. I think that's ok. |
| 09:18 | chouser | as in (let [inside? (< low x high)] ... (if inside? ...)) |
| 09:18 | fliebel | Talking about private functions, why would you want to do that? Except for keeping the ns clean and for "setters" |
| 09:19 | esj | chouser: cool. |
| 09:21 | chouser | fliebel: I think "ns clean" is too dismissive. A public API carries weight -- it should be clean yes but also documented, slow to change, conceptually aligned with how users are supposed to think about the problem space, free of implementation-specific details, etc. |
| 09:21 | chouser | private functions don't need to meet any of those criteria, so it's worth being clear about which is which. |
| 09:22 | fliebel | chouser: Right… I'll think about making my bad ass macro a bit more friendly. |
| 09:22 | chouser | note they're not even as private as Java private methods -- you can always get at a private var from another ns if you know its name. |
| 09:22 | chouser | actually, you can discover it's name easily too. |
| 09:23 | fliebel | chouser: I did that to Ring the other day… I needed something in their lower levels. |
| 09:23 | chouser | fliebel: right, good, and you're aware of the risks involved. |
| 09:23 | fliebel | chouser: Probably not… Only thing I can think of is that they change it becasue it's private anyway. |
| 09:24 | chouser | fliebel: right, that's it. |
| 09:24 | chouser | it's behavior, name, interface may change without notice |
| 09:25 | chouser | if you think your use of it is legit I'd recommend asking for it to be made public. |
| 09:25 | fliebel | I'm not using it anymore |
| 09:26 | fliebel | My use was completely unrelated to Ring, it just happend to contain the exact thing I needed. |
| 09:28 | fliebel | Huh, am I allowed to do this? (defn a [] (defn b [])) |
| 09:29 | fliebel | That'd mean I don't need to make a macro at all to define some crazy function. |
| 09:30 | fliebel | I'm trying to do this badd ass macro in a proper way: http://github.com/pepijndevos/utterson/blob/develop/src/utterson/compile.clj#L55 |
| 09:34 | lpetit | fliebel: I really don't understand your problem with (defn a [] (defn b [])) which could be solved by a macro. |
| 09:34 | lpetit | can you repeat slowly for me please ? :-) |
| 09:34 | chouser | def-anything inside a fn is generally not a "proper way" |
| 09:34 | fliebel | lpetit: The point is that I though one wa supposed to use a macro for this, but evaluating that just yieald b |
| 09:35 | fliebel | chouser: Right... |
| 09:35 | chouser | fliebel: you won't be able to give the name of 'b' from an argument of 'a' |
| 09:35 | lpetit | I can't see why (defn a [] (defn b [])) could be useful at all |
| 09:35 | fliebel | chouser: I also realized that... |
| 09:35 | chouser | you could try using intern, though. |
| 09:36 | fliebel | I'll just do it the normal way and break it up in fns and a macro for defining it. |
| 09:36 | chouser | (defn a [tname] (intern *ns* tname (fn ...))) |
| 09:37 | chouser | but .. looking at your defgen I doubt that'll work for you either. |
| 09:39 | fliebel | chouser: So what do you suggest, if anything? |
| 09:43 | fliebel | I think I'll split it up in 3 functions and one macro |
| 09:44 | chouser | yeah, I'd try to have the macro emit as little code as possible. |
| 09:45 | pjstadig | ,36r16 |
| 09:45 | clojurebot | 42 |
| 09:45 | chouser | looks like it'll need markdown# to redefine your template# a couple times |
| 09:45 | pjstadig | 1r2 |
| 09:45 | pjstadig | ,1r2 |
| 09:45 | clojurebot | Radix out of range |
| 09:45 | pjstadig | ,3r16 |
| 09:45 | clojurebot | For input string: "16" |
| 09:45 | pjstadig | :-( |
| 09:46 | pjstadig | ,2r1 |
| 09:46 | clojurebot | 1 |
| 09:46 | fliebel | chouser: Yea, I need to come up with a decent plan to spread the data to the right places across those fns |
| 09:46 | chouser | and maybe put your template of ~@others in a local fn. |
| 09:46 | pjstadig | hmm i guess the radix comes first? |
| 09:47 | pjstadig | ,3r12 |
| 09:47 | clojurebot | 5 |
| 09:47 | chouser | so then the body of the let you emit can just be (gen* markdown# template# othersfn#) |
| 09:56 | fliebel | chouser: Would it be good style to define some fo those functions in a lot, so they can access common data? |
| 09:56 | fliebel | *let |
| 09:57 | chouser | fliebel: not sure exactly what you mean, but it doesn't sound bad. :-) |
| 09:57 | fliebel | chouser (let [common data] (defn a []) (defn b[])) |
| 09:58 | chouser | that'll only work if common data is entirely global |
| 09:58 | fliebel | true |
| 10:15 | chouser | would it be dumb to have a pom.xml editor? perhaps an emacs mode or a little command-line utility that wraps up common configurations? |
| 10:15 | technomancy | lein includes a sexp->pom.xml translator, in essence |
| 10:16 | chouser | yeah, I guess I'm thinking something two-way |
| 10:16 | hugod | it would be great not to maintain seperate project.clj and pom files |
| 10:16 | chouser | in case you use an IDE to adjust the pom.xml or something. |
| 10:16 | technomancy | hugod: if you need something in pom.xml that project.clj currently doesn't support it should be easy to add |
| 10:17 | technomancy | I've been thinking about adding a maven plugins section so you can do "lein pom && mvn myplugin:action" easily |
| 10:17 | chouser | lein is happy to depend on projects that provide pom.xml but not project.clj, right? |
| 10:17 | technomancy | chouser: definitely |
| 10:18 | technomancy | once something is on clojars, project.clj is not even taken into account; the pom is the only thing that matters |
| 10:18 | hugod | technomancy: there is rather a lot I fear http://github.com/hugoduncan/pallet/blob/master/pom.xml |
| 10:18 | technomancy | hugod: eh; it wouldn't be too much work to add |
| 10:19 | hugod | technomancy: good to hear :) |
| 10:19 | technomancy | profiles, plugins, and developer lists; it's all just a matter of adding the appropriate .addProfile etc. calls to the maven java API |
| 10:19 | Raynes | My eyes! |
| 10:20 | technomancy | though I'm really not sure of the purpose of the latter |
| 10:20 | chouser | btw, lein cake and maven all feel less superfluous to me since I've started thinking of them as classpath management tools rather than "build" tools |
| 10:21 | hugod | technomancy: I tend to agree with you on that |
| 10:21 | chouser | superfluous isn't quite the right word |
| 10:22 | shoover | chouser: I'm curious how you manage dependencies without those tools. Do you download jars the old fashioned way and stash them somewhere? |
| 10:23 | shoover | Or write everything from scratch depending only on clojure.jar? ;) |
| 10:23 | chouser | shoover: essentially yes. Well, I've got two different "systems", neither very impressive. |
| 10:23 | technomancy | chouser: indeed; "building" a jar is the trivial part |
| 10:23 | technomancy | classpath management is the #1 faq for newbies coming in |
| 10:24 | chouser | for work we already have an extensive build system using cmake (do not recommend), so I plugged clojure into that. The generated makefiles fetch dependencies and then we have a shell script that sets up the classpath and launches the appropriate Java class. |
| 10:24 | raek | http://clojure.github.com/clojure/ <-- what happened to clojure.test and friends? |
| 10:25 | chouser | for my own hacking around, I had started working up a system of jar directories, one per clojure major version plus a "common" one. So to start using a jar I'd just download it into the appropriate dir, launch the appropriate clojure repl version, and go. |
| 10:26 | chouser | of course this is both too complex and too simplistic. |
| 10:26 | Raynes | chouser: Insanity. |
| 10:26 | shoover | chouser: I see |
| 10:27 | chouser | shoover: but you're right -- I tend to depend on few libs in practice. java core, clojure core, and contrib covers 90% of what I play with. |
| 10:27 | chouser | dabbling with ring was painful with my setup. I definitely need to use one of these dep management things. |
| 10:27 | anonymouse89 | j git |
| 10:27 | anonymouse89 | oops |
| 10:27 | shoover | chouser: oh yeah, lots of little jars in the http world |
| 10:28 | chouser | so maybe after finger trees... |
| 10:29 | chouser | but see after that I'm likely to be messing around with clojure-in-clojure stuff, and then maybe clojurescript, etc. None of these have deps outside of clojure. |
| 10:29 | technomancy | chouser: so right after I give my lein talk at the conj then? nice timing =) |
| 10:29 | chouser | technomancy: yep. and maybe I'll look at eclipse right after lpetit is done talking... |
| 10:29 | chouser | clojure-conj fascilitates my laziness |
| 10:30 | AWizzArd | When I have a :gen-class'ed namespace, and :state s, and want somewhere in that file/NS to access .s then I get a reflection warning. Exists there a way to type-hint it? |
| 10:30 | chouser | AWizzArd: sure, just hint it to the class you're gen'ing |
| 10:31 | shoover | chouser: I can't imagine doing anything not involving a couch and a tv after writing a book |
| 10:31 | AWizzArd | chouser: that would be the NS itself. |
| 10:31 | chouser | AWizzArd: no, the namespace is not a class |
| 10:32 | chouser | though they are generally named similarly, yes. |
| 10:32 | AWizzArd | chouser: to AOT that class I used a (:gen-class ...) in the (ns my-ns) form. |
| 10:35 | AWizzArd | chouser: one sec, I will post an example |
| 10:36 | cemerick | man, there was a nasty little locals-clearing bug in 1.1.0 :-/ |
| 10:37 | AWizzArd | http://paste.lisp.org/display/114852 |
| 10:37 | AWizzArd | When I try to compile this I get a ClassNotFoundException: bar.Foos |
| 10:37 | AWizzArd | without the type hint I get two reflection warnings |
| 10:40 | chouser | AWizzArd: you have to compile for :gen-class to work |
| 10:41 | chouser | also, why are you using gen-class to implement intefraces instead of deftype or reify? |
| 10:41 | chouser | interfaces |
| 10:41 | AWizzArd | This is just a demo |
| 10:41 | chouser | ok |
| 10:41 | chouser | so yeah, you have to use compile. when I (compile 'bar.Foos) it works fine |
| 10:41 | chouser | giving only a reflection warning for the .s you didn't hint. |
| 10:44 | AWizzArd | okay good |
| 10:44 | AWizzArd | I was confused because I got those warnings in Emacs, when loading this NS. |
| 10:45 | chouser | yes, I understand emacs can be confusing. |
| 10:45 | chouser | sorry, couldn't resist. bad chouser! |
| 10:46 | AWizzArd | chouser: *g* |
| 10:47 | rfgpfeiffer_ | can a deftype type have static methods? |
| 10:49 | chouser | rfgpfeiffer: no, just use regular clojure functions for that |
| 10:58 | technomancy | hmmm... might be time to drop test-is support in the next leiningen release. =) |
| 10:58 | fliebel | Given the fact that Clojure-in-Clojure is possible, it is thus possible to define lazy seqs. Would it also be possible to define a lazy seq where the 0th element is actually in the middle of an infinite lazy seq extending in both ways? so like (iterate inc) with negative number included :) |
| 10:59 | technomancy | you can't rebind a dynamically-referenced var, can you? |
| 10:59 | technomancy | I mean, without evaling a binding call |
| 11:00 | chouser | fliebel: ISeq only provides an API for walking forwards. You'd need a different interface for walking the other direction. |
| 11:02 | fliebel | chouser: Hrm :( that means I'll be unable to use with with existing functions, right? |
| 11:04 | chouser | fliebel: well, what existing function do you intend to call to get item before 'first'? |
| 11:04 | fliebel | chouser: Dunno… I mean, if I'm not using ISeq, I can;t even use first, right? |
| 11:05 | chouser | well, your theoretical bidirectional lazy seq could implement ISeq for going forward |
| 11:05 | fliebel | chouser: Oh wait, Java, so I can implement ISeq and add my own interface and fns for going the other way. |
| 11:07 | fliebel | chouser: How about this… you define a lazy seq like iterate but with 2 fns, for going in either direction. then you call spin on it to change which direction you're seqing over :) |
| 11:08 | fliebel | so spin = reverse for lazy seqs |
| 11:08 | chouser | hm, interesting. |
| 11:09 | chouser | I don't see why not. |
| 11:09 | fliebel | chouser: So, what Clojure bits do I need to implement that? |
| 11:10 | chouser | a deftype and ... a function? |
| 11:10 | fliebel | *looks up deftype* |
| 11:17 | chouser | actually, just a deftype would do, though it's not quite as pretty. |
| 11:17 | fliebel | chouser: I don't think I get it. |
| 11:18 | chouser | (rseq (rest (drop 10 (IterBi. 0 inc dec)))) ;=> (5 4 3 2 1 0 -1 -2 -3 -4 -5 ...) |
| 11:18 | anonymouse89 | I'm having trouble with this: |
| 11:18 | anonymouse89 | ,(let [add '(+)] (apply (first add) (range 10))) |
| 11:18 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (10) passed to: Symbol |
| 11:18 | anonymouse89 | I would like it to be equivalent to (apply + (range 10)) |
| 11:18 | chouser | anonymouse89: try (list +) instead of '(+) |
| 11:19 | anonymouse89 | chouser: nice |
| 11:19 | chouser | ,(class (first '(+))) |
| 11:19 | clojurebot | clojure.lang.Symbol |
| 11:19 | chouser | ,(fn? (first '(+))) |
| 11:19 | clojurebot | false |
| 11:19 | chouser | ,(fn? (first (list +))) |
| 11:19 | clojurebot | true |
| 11:20 | anonymouse89 | I thought '(0 1 2) could be thought of as an unevaluated sequence not as a symbol |
| 11:20 | chouser | it is an unevaluated sequence, but the contents are unevaluated as well |
| 11:20 | chouser | so + in that case is just a symbol. |
| 11:21 | anonymouse89 | chouser: that makes sense, thanks |
| 11:21 | chouser | if you want to look up what function + refers to, you have to evaluate the symbol |
| 11:22 | chouser | fliebel: so that's what you wanted, right? intersting idea. |
| 11:22 | fliebel | chouser: I understand how I can do without the fn, but I don't understand deftype. |
| 11:22 | chouser | actually, you don't need deftype either. you could use reify or proxy if you prefer, and a normal function. |
| 11:23 | fliebel | chouser: I never worked with those 1.2 things before. So it's going to be a lot of learning… :) |
| 11:24 | chouser | fliebel: so... how shall we proceed? You want to see my code or should I try to drop hints or ask leading questions? |
| 11:24 | fliebel | the later one :) extended with my guessing and reading |
| 11:25 | fliebel | chouser: So I basically need to look up the ISeq interface and overwrite a few methods? |
| 11:25 | chouser | ok, so how would you use deftype or reify to implement an ISeq that just repeats the same value over and over |
| 11:25 | chouser | ? |
| 11:26 | fliebel | Where can I find the ISeq interface? |
| 11:26 | chouser | I do (show clojure.lang.ISeq) |
| 11:26 | fliebel | Unable to resolve symbol: show in this context |
| 11:26 | edw | I'm a longtime Emacs user and Scheme programmer and I'm trying to get Emacs set up to play nice with Clojure (1.2) and I the best guide I can find is a mailing list message from Constantine Vetoshev and I get an error when following along with that. Is there a definitive SLIME/Clojure guide out there somewhere? |
| 11:26 | chouser | fliebel: :-( rhickey took my 'source' fn, but not my 'show' |
| 11:27 | chouser | fliebel: show is clojure.contrib.repl-utils/show |
| 11:27 | fliebel | chouser: Ah, I use source quite often, but that doesn't work on Java stuff I guess. |
| 11:27 | dnolen | edw: http://www.assembla.com/wiki/show/clojure/Getting_Started_with_Emacs |
| 11:27 | edw | dnolen: Thank you! |
| 11:28 | chouser | fliebel: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/ISeq.java |
| 11:28 | edw | Oh gawd, it uses ELPA?! I didn't have good luck with that! |
| 11:28 | dnolen | edw: the trick is that you only need to install swank-clojure |
| 11:29 | Raynes | ELPA is the standard way of setting this stuff up to work for Clojure. It's all tested and known to work. |
| 11:29 | dnolen | edw: the main trouble you might run into is if you have existing Lisp configurations |
| 11:29 | edw | dnolen: Ah. I was getting all sorts of dependency errors when installing slime using it. Should I clean out any existing SLIME installations? |
| 11:30 | dnolen | edw: I would. Don't bother installing anything but swank-clojure, ignore slime, slime-repl, clojure-mode. There's a bug in the install process. installing swank-clojure will grab everything you need. |
| 11:31 | fliebel | chouser: I guess it'd be (reify clojure.lang.ISeq (first [this] 1)) but that fails |
| 11:31 | dnolen | edw: you will need to wipe anything clojure related from your .emacs.d/elpa before installing swank-clojure |
| 11:31 | fliebel | ah wait |
| 11:31 | edw | dnolen: Thanks again. Cleaning out my .emacs (and .emacs.d) right now. |
| 11:32 | fliebel | chouser: Do I need to implement all of them? Or can I just use a concrete subclass of ISeq? |
| 11:33 | dnolen | edw: np |
| 11:33 | chouser | fliebel: just implment the ones you need for now. What happens when you call 'first' on your reify there? |
| 11:33 | chouser | Then when happens when you call 'next'? |
| 11:34 | fliebel | chouser: I get java.lang.AbstractMethodError when defining it, because ISeq is an abstract interface. |
| 11:34 | fliebel | (i think) |
| 11:34 | chouser | fliebel: are you sure that's why? |
| 11:34 | chouser | did you try (first (reify ...)) ? |
| 11:35 | fliebel | chouser: Hm, that works, but just defining it fails. |
| 11:35 | fliebel | chouser: Ah, repl evaluates |
| 11:36 | chouser | yep, and after E is P |
| 11:36 | fliebel | ? |
| 11:36 | chouser | REPL |
| 11:36 | fliebel | ah |
| 11:36 | chouser | and printing a seq means walking it an printing each of the items. we're not ready for that. |
| 11:37 | fliebel | I see |
| 11:37 | chouser | so, (first ...) works. what about (next ...)? |
| 11:37 | fliebel | let me try.. |
| 11:39 | fliebel | (next [this] this) |
| 11:39 | fliebel | Okay, but I have no idea what more and cons are about. |
| 11:40 | chouser | fliebel: ignore them for now. |
| 11:40 | chouser | so, (first ...) and (first (next ...)) work now, right? |
| 11:40 | fliebel | yea, but not doing second on it still gives me the error. |
| 11:41 | chouser | it's a shame it doesn't tell you the specific method it's trying to call that fails. |
| 11:41 | chouser | you can discover it by looking up the line of source code it mentions and seeing what method it's calling. |
| 11:42 | fliebel | It doesn't even give a line or file: |
| 11:42 | fliebel | java.lang.AbstractMethodError |
| 11:42 | fliebel | ( |
| 11:42 | fliebel | that's all |
| 11:42 | chouser | yeah |
| 11:42 | chouser | oh, (.printStackTrace *e) or (pst) on clojure 1.3.0 alpha 1 will show you more |
| 11:42 | chouser | but not enough. |
| 11:42 | fliebel | I'm not on the alpha |
| 11:43 | chouser | right, so use (.printStackTrace *e) |
| 11:43 | chouser | so I'll just tell you -- the REPL calls your .seq method during printing. |
| 11:44 | chouser | seq must return an ISeq ... can implement that? |
| 11:44 | fliebel | But seq isn't in ISeq, or is that up in IPersistentCollection? |
| 11:44 | chouser | fliebel: IPersistentCollection |
| 11:45 | fliebel | No, Sequential I guess |
| 11:45 | chouser | but you can put it under ISeq in your reify |
| 11:46 | fliebel | I know, but I need to know it's… how do you call that... |
| 11:47 | chouser | http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Seqable.java#L16 |
| 11:47 | fliebel | right… Now I made it return a list. It prints that and *then* gives the same error. |
| 11:48 | chouser | yeah. so that final error is it calling equiv. not sure why |
| 11:49 | fliebel | hm…. Do we need to fix that? |
| 11:49 | chouser | probably not |
| 11:49 | chouser | so, what do you have so far? |
| 11:49 | fliebel | A ISeq that returns 1s |
| 11:50 | fliebel | (reify clojure.lang.ISeq (first [this] 1) (next [this] this) (seq [this] (list 1 2 3))) |
| 11:50 | fliebel | Maybe I could make seq return a cons of first and rest, but then I'd need to define that as well |
| 11:50 | chouser | ,(reify clojure.lang.ISeq (first [this] 1) (next [this] this) (seq [this] (list 1 2 3))) |
| 11:50 | clojurebot | (1 2 3) |
| 11:50 | technomancy | there's no zeroconf stack for the JVM, is there? |
| 11:51 | technomancy | that would be great for conj shenanigans... |
| 11:51 | chouser | fliebel: do you have an ISeq handy already for your 'seq' to return? |
| 11:52 | fliebel | this? |
| 11:52 | clojurebot | this is not a bug |
| 11:52 | chouser | fliebel: what happens when you try it? |
| 11:53 | fliebel | I guess it'll get stuck |
| 11:53 | mrBliss | there's (quote ..) for ', what's the function for `? |
| 11:53 | chouser | mrBliss: doesn't exist. ` is implemented differently |
| 11:54 | fliebel | chouser: It does get stuck, but doing take 10 gives java.lang.AbstractMethodError again |
| 11:54 | chouser | ,(read-string "1(foo)") |
| 11:54 | clojurebot | 1 |
| 11:54 | mrBliss | chouser: too bad, now I have to wrap it in (fn [] ..) |
| 11:54 | chouser | ,(read-string "`(foo)") |
| 11:54 | clojurebot | (clojure.core/seq (clojure.core/concat (clojure.core/list (quote sandbox/foo)))) |
| 11:55 | jashmenn | hey, one more question to add to the mix: if i compile and import a gen-class from the repl, is there a way to reload the gen'd class without restarting the jvm? |
| 11:55 | chouser | fliebel: you're in a plain REPL or in slime or what? |
| 11:55 | jashmenn | (my code: http://gist.github.com/595569) |
| 11:55 | fliebel | cake |
| 11:55 | chouser | fliebel: cake and a terminal? |
| 11:56 | fliebel | okay, just the terminal prints a lot of 1 :) |
| 11:56 | chouser | good job! |
| 11:56 | fliebel | but take 10 doesn't work yet |
| 11:56 | chouser | take is calling your (unimplemented) rest method |
| 11:57 | chouser | er, 'more', rather |
| 11:57 | fliebel | I keep forgetting the difference between next and rest... |
| 11:57 | fliebel | and I don't know more at all :P |
| 11:57 | ubii | looking to get back into clojure after a 9 month hiatus and have the following questions |
| 11:58 | fliebel | chouser: There arn't any docstrings on ISeq :( |
| 11:58 | ubii | 1) I am still very much a newbie and am wondering if I should stick with 1.2 or go ahead and check out 1.3 |
| 11:58 | chouser | the difference between more (called by clojure.core/rest) and next only matters when being very careful about nearly vs. complete laziness. |
| 11:58 | ohpauleez | fliebel: new rest is almost always what you want, except when you don't |
| 11:59 | chouser | that is, we don't really care much. So what happens if youre 'more' is the same as your 'next'? |
| 11:59 | esj | ubii: i'd stick with 1.2, its still pretty new :) |
| 11:59 | andyfingerhut | ubil: You'll likely have less confusion with 1.2. More tested with other add-ons |
| 11:59 | fliebel | chouser: Works :) |
| 11:59 | ubii | 2) should I install clojure via the zip files, source(github), or use Leiningen? |
| 12:00 | chouser | fliebel: congrats! |
| 12:00 | mrBliss | ubii: leiningen or cake |
| 12:00 | ohpauleez | ubii: I agree with 1.2, but if you want to play with some of the new stuff, and can deal with some exceptions now and then, 1.3 has been fine for me |
| 12:00 | mrBliss | ubii: or cljr for a standalone repl to play with |
| 12:00 | fliebel | chouser: I know how to reverse it :D |
| 12:00 | ohpauleez | ubii: what mrBliss said |
| 12:00 | chouser | fliebel: :-{ |
| 12:00 | chouser | fliebel: :-P |
| 12:01 | chouser | fliebel: ok, but you want to apply a function instead of just repeating, right? how would you do that? |
| 12:02 | fliebel | chouser: Hey, my ISeq doesn't implement clojure.lang.Reversible |
| 12:02 | chouser | fliebel: hm, what are going to do about that? |
| 12:02 | ubii | 3) which editor (emacs, vi) or IDE do most of you use and what would you recommend? |
| 12:03 | Raynes | Emacs is the most used, followed by vi and the IDE plugins. |
| 12:03 | Raynes | I did a poll a while back, which was further confirmed by cemerick's poll not too long ago. |
| 12:03 | fliebel | chouser: I don't think reify allows me to define multiple ancestors :( |
| 12:03 | chouser | there are about as many emacs users as non-emacs users |
| 12:03 | chouser | fliebel: I would not have led you astray |
| 12:04 | fliebel | chouser: Can I nest reifies? :P |
| 12:04 | Raynes | Wasn't it like 62% of Clojurians using Emacs? |
| 12:04 | chouser | fliebel: yes, but that's not what you want here. |
| 12:04 | fliebel | Nope :( |
| 12:05 | chouser | fliebel: according to the deftype docs, "Each spec consists of..."? |
| 12:05 | andyfingerhut | Emacs is free as in beer, free as in libre, but if you are new to it, it costs some time :-) It was new for me a long time ago... |
| 12:05 | fliebel | ah... |
| 12:06 | chouser | Raynes: oh, you're right. 70% |
| 12:08 | andyfingerhut | chouser: So did you understand Haskell somewhat well before reading the published paper on finger trees? |
| 12:08 | fliebel | chouser: I added clojure.lang.Reversible (rev [this] this) but it still says Can't define method not in interfaces: rev |
| 12:09 | fliebel | huh…. I need to define rseq, but rseq calls rev |
| 12:09 | fliebel | ,(source rseq) |
| 12:09 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 12:10 | fliebel | no. wait... |
| 12:10 | chouser | fliebel: yeah, I did that first too. |
| 12:11 | fliebel | chouser: (. rev (rseq)) what is this? |
| 12:11 | fliebel | Why the parens abround rseq? |
| 12:12 | chouser | fliebel: ancient syntax. the same as (.rseq rev) |
| 12:12 | fliebel | lol |
| 12:12 | fliebel | Okay, so now for the real thing :) |
| 12:15 | fliebel | chouser: Can we go somewhat more down the inheritacne tree to find something that covers the basics? Or do we need everything customized anyway? |
| 12:19 | chouser | fliebel: reify doesn't let you inherit from anything but pure methods. |
| 12:22 | anonymouse89 | ,(quote (first '(0 1 2))) |
| 12:22 | clojurebot | (first (quote (0 1 2))) |
| 12:22 | fliebel | you mean interfaces? |
| 12:23 | anonymouse89 | why does this happen? |
| 12:24 | fliebel | chouser: So what is next? |
| 12:24 | andyfingerhut | anonymous89: If you mean "why does the ' change to (quote ...)?" it is because that is what ' is defined to mean. |
| 12:25 | anonymouse89 | andyfingerhut: oh, duh the repl is just taking the outside quote off |
| 12:29 | mrBliss | I've written a lazy-let macro which doesn't evaluate any of its bindings until they are needed, handy when you're dealing with many conditional bindings. http://gist.github.com/595634 |
| 12:30 | mrBliss | s/written/hacked together ;-) |
| 12:30 | chouser | fliebel: sorry, distracted. |
| 12:30 | fliebel | nvm |
| 12:31 | ohpauleez | mrBliss: I like that substitute |
| 12:32 | fliebel | chouser: Did you mean present or past? |
| 12:33 | chouser | fliebel: I'm on the phone at work. |
| 12:33 | fliebel | work? oh right… timezones, I'm sorry |
| 12:34 | stuartsierra | 1.3.0-alpha1 artifacts deployed... let the carping commence! |
| 12:35 | ohpauleez | stuartsierra: haha |
| 12:35 | ohpauleez | stuartsierra: btw, really loving lazytest stuff |
| 12:35 | stuartsierra | awesome |
| 12:35 | stuartsierra | Speaking of Lazytest |
| 12:35 | stuartsierra | I'm thinking of releasing 1.0.0 final today. |
| 12:35 | ohpauleez | yes! |
| 12:35 | ohpauleez | please do |
| 12:36 | stuartsierra | Anybody have any bug reports before that goes out? |
| 12:36 | andyfingerhut | carping: Why wasn't this ready when Rich asked us to try out 1.3? Why is it alpha1? Why am I losing my hair? |
| 12:36 | stuartsierra | andyfingerhut: What? |
| 12:37 | technomancy | consult your healthcare provider if you experience hair loss in conjunction with upgrading to Clojure 1.3 |
| 12:37 | andyfingerhut | Sorry, just wanted to commence the carping in a silly fashion. Should have added :-) |
| 12:37 | stuartsierra | As I understand from Stu Halloway & Rich, the plan is to release more frequent alphas to get more people to test out new features without having to depend on SNAPSHOT versions. |
| 12:37 | esj | stuartsierra: quick question - is there any intent to add a test coverage tool ? |
| 12:37 | stuartsierra | esj: Sure, want to write one? :) |
| 12:38 | technomancy | esj: do you know about radagast? |
| 12:38 | ubii | thx for the answers |
| 12:38 | esj | stuartsierra: would love to - unsure you would though. Care to supervise ? |
| 12:38 | esj | technomancy: googling. |
| 12:38 | ubii | sorry, got tied up with dealing with a client request |
| 12:39 | esj | technomancy: now I do ! I'll go play with it, thanks. |
| 12:39 | stuartsierra | esj: It doesn't interest me a great deal. I think doing it "properly" would require instrumenting the JVM. |
| 12:40 | ubii | regarding Emacs, which is the preferred method for installing/configuring clojure-mode, slime, and swank-clojure? |
| 12:40 | technomancy | stuartsierra: radagast offers coarse-grained test coverage, but for branch-level you'd have to hack the compiler |
| 12:40 | andyfingerhut | If you haven't done it before, ELPA |
| 12:40 | stuartsierra | ubii: Sacrifices of fattened animals generally help. |
| 12:40 | esj | ubii: ELPA, as per technomancy's guide. |
| 12:40 | stuartsierra | technomancy: Yeah, that's what I meant. |
| 12:41 | esj | technomancy: 35 lines... |
| 12:41 | stuartsierra | It would be an interesting dive into the Clojure compiler, but I think the effort would far outweigh the reward. |
| 12:41 | technomancy | stuartsierra: especially when coarse-grained coverage is trivial to implement |
| 12:41 | stuartsierra | yeah |
| 12:42 | stuartsierra | So if anybody wants to play with integrating radagast with Lazytest, I'll try to help out. |
| 12:42 | ohpauleez | stuartsierra: I might be into that |
| 12:42 | stuartsierra | cool |
| 12:42 | ohpauleez | If I get anywhere, I'll ping you |
| 12:43 | stuartsierra | ok |
| 12:43 | fliebel | chouser: I need to prepare dinner. I'll talk to you about reify later. Thanks for helping me. I'm now struggling with where to keep state and how to modify things withouy an endless recursion. |
| 12:43 | chouser | fliebel: yep. hint: fn args are state |
| 12:44 | ubii | http://technomancy.us/126 - is this the correct url to the guide? |
| 12:44 | technomancy | ubii: try "getting started with Emacs" on the official Assembla wiki |
| 12:45 | ubii | cool, thx all |
| 12:49 | andyfingerhut | Are there "inner deftypes" that are analogous to Java inner classes? |
| 12:49 | stuartsierra | Ack! |
| 12:50 | chouser | andyfingerhut: there's reify |
| 12:51 | andyfingerhut | chouser: I ask because I was thinking of how one could modify your finger trees without having a meter-obj in every deftype'd object in a whole tree. |
| 12:51 | chouser | andyfingerhut: yeah, I mentioned an alternative in a recent email |
| 12:52 | chouser | ...passing in the meter as an arg to methods that use it, and relying on some outter context to provide the correct one every time. |
| 12:52 | chouser | I didn't have outer contexts before, but my most recent commit adds a couple examples |
| 12:54 | andyfingerhut | ok. It is just that so many of the methods need it. I'm not advocating for inner deftypes, but they look like they would kinda-sorta help in this kind of case. I'm sure there are other ways. |
| 12:55 | chouser | it would still have to be stored somewhere that all the node methods could find it, wouldn't it? |
| 12:55 | andyfingerhut | Yes. So you make all the node deftypes inside the main one. |
| 12:56 | andyfingerhut | Maybe a crazy idea, and maybe problems with it I haven't thought of. But if the feature were there, I would have been crazy enough to try it out :-) |
| 12:57 | chouser | :-) |
| 12:57 | chouser | gotta go. bbl. |
| 12:57 | stuartsierra | Even nested classes aren't really contained in Java. |
| 12:57 | stuartsierra | It's just a namespacing convenience. |
| 12:57 | stuartsierra | With some funny rules about public/private visibility. |
| 12:58 | andyfingerhut | Inner classes do not get access to per-instance fields of the class in which they are nested? |
| 12:58 | stuartsierra | I can never remember the rules. |
| 12:58 | andyfingerhut | That's OK. Some rules, only the writer of the rules can keep in their head at one time. |
| 13:02 | amalloy | inner classes have access to instance fields of the outer class. the one that always gets me is method-local classes |
| 13:12 | proyal | howdy! question: i have two seq's, one of fn's, the other of values. in order, i want to map each item of my value seq with the corresponding (nth-wise) fn from my seq of fn's. is there a handy way to do that? |
| 13:12 | stuartsierra | (map (fn [f v] (f v)) fns values) |
| 13:13 | chouser | or #(%1 %2) |
| 13:13 | proyal | stuartsierra: ah, awesome. docs weren't clear that's how it worked |
| 13:13 | stuartsierra | what chouser said |
| 13:13 | proyal | i tried 'for', but that gave me a cartesian product |
| 13:13 | ohpauleez | proyal: I'd do what chouser said, typically |
| 13:14 | proyal | yah, anon-fn's preferred indeed. worked like a charm, thanks gents! |
| 13:16 | amalloy | chouser: wow, i didn't know that worked. i sorta assumed #() needed something it could resolve at the call site |
| 13:17 | ohpauleez | amalloy: the beauty of first-class of functions |
| 13:17 | amalloy | yeah. when i look at the expansion of #() into (fn []) it's clear that there's no reason the latter should work but not the former; but the first one just looks mind-boggling |
| 13:18 | dnolen | somebody who is able want to open up a ticket for even? in 1.3.0-alpha1 (I really need to send in my CA :P) http://groups.google.com/group/clojure/browse_thread/thread/f46fc7389ecdf1f8# |
| 13:21 | birdspider | hi, anyone familiar with penumbra(clj wrapper for lwjgl)? can't get the examples to work |
| 13:24 | dnolen | birdspider: what's the problem? |
| 13:27 | birdspider | dnolen, well first I'd like to know if the examples are bundled in the penubra.jar ? or if I have to pull them seperatly |
| 13:28 | dnolen | birdspider: the jar? did you d/l the git repo? |
| 13:29 | birdspider | dnolen, nope I just downloaded the clojar via lein deps |
| 13:29 | dnolen | birdspider: that won't work I think as you need something to set the classpath to the native libs. |
| 13:30 | dnolen | birdspider: it's simpler to just checkout the repo, and run 'lein repl' and run the examples from the REPL |
| 13:30 | birdspider | dnolen, well yes, my current status is that I downloaded a single example and tried to (require) it |
| 13:30 | birdspider | dnolen, native libs via native-deps in place afaik |
| 13:31 | birdspider | dnolen, which I link via -Djava.library.path=pathToSo |
| 13:31 | dnolen | birdspider: do you have a paste somewhere of the error? |
| 13:31 | birdspider | but it gives me java.lang.ClassNotFoundException: org.lwjgl.opengl.GL11 (core.clj:9) |
| 13:31 | birdspider | dnolen, do I have to link each *.so specifically |
| 13:32 | birdspider | dnolen, or just the path |
| 13:32 | dnolen | birdspider: no, what do you set the library path to? |
| 13:32 | birdspider | dnolen, -Djava.library.path=native/linux/x86/ |
| 13:32 | birdspider | dnolen, which contains: libjinput-linux.so liblwjgl.so libopenal.so |
| 13:34 | cemerick | I'd like to invoke a fn a no-arg function within the context of comp or ->, but for the life of me, I don't see a clean way to do so. |
| 13:34 | cemerick | ,(-> str .invoke count) |
| 13:34 | clojurebot | 0 |
| 13:34 | cemerick | is the best I've come up with, which sucks. |
| 13:34 | cemerick | Someone tell me I'm nuts. |
| 13:35 | dnolen | birdspider: hmm that should work yes... and yr classpath is set as well I assume? You do need to include each jar individually. |
| 13:36 | birdspider | dnolen, well there is a bunch of stuff in lib, but i tried: java -cp lib/clojure-contrib-1.2.0-20100813.160219-142.jar:lib/clojure-1.2.0-master-20100813.160144-94.jar:lib/penumbra-0.6.0-20100502.112537-3.jar:src/ -Djava.library.path=native/linux/x86/liblwjgl.so clojure.main |
| 13:36 | birdspider | dnolen, clojure, clojure-contrib, and penumbra |
| 13:36 | birdspider | dnolen, ah |
| 13:36 | birdspider | dnolen, there are the lwjgl jars |
| 13:36 | birdspider | dnolen, :) |
| 13:36 | stuartsierra | cemerick: You're nuts (-> (str) count) |
| 13:36 | dnolen | birdspider: yup |
| 13:37 | dnolen | birdspider: those get unpacked by native-deps so it's a bit weird |
| 13:37 | cemerick | stuartsierra: right, but assume the fn I want to invoke is the result of a prior invocation in -> or comp |
| 13:37 | birdspider | dnolen, thats what I got wrong, I looked there after calling deps |
| 13:37 | birdspider | dnolen, ok thx for now |
| 13:37 | dnolen | birdspider: np |
| 13:38 | stuartsierra | cemerick: with comp, easy, just wrap in #() |
| 13:38 | stuartsierra | With ->, you're still nuts :) |
| 13:38 | hiredman | ,(str (apply nil) count) |
| 13:38 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (1) passed to: core$apply |
| 13:38 | stuartsierra | well, not #() but (fn [_] foo...) |
| 13:38 | hiredman | ,(-> str (apply nil) count) |
| 13:38 | clojurebot | 0 |
| 13:39 | cemerick | My real trouble is that I"m actually using comp and partial with equal frequency as -> and #() these days. |
| 13:39 | momos | Hello :-) |
| 13:45 | andyfingerhut | With 1.3.0, is someone already planning a web page or something similar that people can go to in order to assist in upgrading their code base from 1.2.0? As a minor example, I had some calls to re-gsub that worked on 1.2.0, but the name changed so it took some time to find in 1.3 |
| 13:45 | stuartsierra | re-gsub was already deprecated in 1.3 |
| 13:45 | stuartsierra | I mean 1.2 |
| 13:53 | andyfingerhut | Is there a way to enable warnings of using deprecated things in 1.2? |
| 14:09 | duncanm | anyone working on incanter here? |
| 14:09 | duncanm | is there a reason why the API page is broken? it only shows the package names, but none of the functions |
| 14:09 | fliebel | chouser: I have a full stomach now. Do you have time to explain me a few key things about reify? I'm thinking in circles now. :( |
| 14:10 | duncanm | hmm, liebke is not around |
| 14:13 | ohpauleez | ~seen liebke |
| 14:13 | clojurebot | liebke was last seen quiting IRC, 2561 minutes ago |
| 14:17 | fliebel | ~seen chouser |
| 14:17 | clojurebot | chouser was last seen in #clojure, 64 minutes ago saying: or #(%1 %2) |
| 14:47 | chouser | fliebel: back in a sec |
| 14:48 | fliebel | sure :) I nearly got it working :) |
| 14:50 | chouser | ok, back. That's great. what have you got? |
| 14:50 | fliebel | http://gist.github.com/595835 |
| 14:51 | chouser | nice! |
| 14:52 | fliebel | thanks :) You're a good teacher :) |
| 14:52 | chouser | I think that's the same as what I have. but you said "nearly"? |
| 14:52 | fliebel | The problem I had was that first was defined as the first of this, but I couldn't do (first this) of course. |
| 14:53 | fliebel | The same goes for next, that should return this with first replaced, but I can't just do (assoc this) |
| 14:53 | fliebel | So then I figured I needed the fn. |
| 14:54 | chouser | if you want to "check" your answer: http://gist.github.com/595663 |
| 14:54 | fliebel | this is your version? |
| 14:54 | chouser | yep |
| 14:56 | fliebel | very close :) Only you have equiv defined and next uses more. Does it matter if you use .more(method call) or rest? |
| 14:57 | chouser | not really. yours is probably faster |
| 14:57 | chouser | but duplicates half a line of code. :-) |
| 14:57 | fliebel | yea… :( |
| 14:57 | chouser | so take your pick. what you've got is good. |
| 14:58 | chouser | better arg names than mine |
| 14:58 | fliebel | One problem I have is that drop 5 returns a lazy seq which I can't reverse. |
| 14:58 | chouser | yeah, you see how I work around that in my example? |
| 14:59 | fliebel | rest, I used seq to do the job |
| 14:59 | chouser | oh! smart! |
| 14:59 | chouser | interesting -- I hadn't considered that, and wouldn't have been sure it would work. nicely done. |
| 14:59 | fliebel | One thing I haven't figured out yet is how to make a seq that goes 1 2 3 4 5 4 3 2 1, so changes direction in the middle. |
| 15:00 | fliebel | chouser: I wasn;t sure it would work, but seq is magic you know.. |
| 15:02 | chouser | (let [[prefix the-rest] (split-at 5 (iter-bi 0 inc dec))] (concat prefix (rseq (seq the-rest)))) |
| 15:04 | fliebel | yea, so much trickery… :( |
| 15:05 | chouser | hm |
| 15:05 | fliebel | It'd be awesome if there was a clean way to do that as an infinit seq. |
| 15:06 | fliebel | I've been thinking about reduce and recur, but immutable stuff makes it hard t say "hay, rseq the rest" in the middle of a loop. |
| 15:07 | chouser | fliebel: right, the problem is applying a different function partway through a seq. split-at is one way to do that. reduce and loop/recur would be others, but aren't lazy. |
| 15:09 | fogus_ | I am perplexed by the contrib modules. |
| 15:12 | chouser | fliebel: ((fn f [s] (lazy-seq (cons (first s) (f (rest (if (zero? (rem (first s) 5)) (rseq (seq s)) s)))))) (iter-bi 1 inc dec)) |
| 15:14 | fliebel | chouser: I'm going to try and understand :) |
| 15:15 | fliebel | it works, but I'm not yet sure how :P |
| 15:17 | chouser | BTW, I wanted to call attention to my comment on rseq. I think we're abusing it here and probably ought to define a new protocol instead. (defprotocol Spinnable (spin [_])) or something. |
| 15:19 | fliebel | Okay… you use defprotocol for that? |
| 15:19 | chouser | yep |
| 15:20 | chouser | hmm... |
| 15:22 | fliebel | So now in reify I replace reversible with spinnable? |
| 15:24 | chouser | oh, wait -- does reify not work on protocols? |
| 15:24 | chouser | nm, dumb mistake |
| 15:25 | chouser | there, now you don't have to call seq manually on lazy-seqs: http://gist.github.com/595663 |
| 15:26 | briancarper | Is anyone here actually able to pull 1.3.0-alpha1 contrib via Maven or Lein? |
| 15:27 | raek | anyone know why the clojure.github.org/clojure docs for 1.2 seems to have been reverted to 1.1-ish? |
| 15:27 | fliebel | chouser: What? You can just add behavior to existing types? Am I in #ruby? |
| 15:27 | raek | all the clojure.java.* and clojure.test namespaces are gone |
| 15:28 | chouser | fliebel: nope. in clojure we do it without monkey patching or adapter classes. :-) |
| 15:28 | AWizzArd | why was it named clojure.java? |
| 15:28 | chouser | fliebel: I mean "nope" you're not in #ruby. Of course you can write new functions that take existing classes as args that then do their own thing with them. |
| 15:28 | AWizzArd | It could have been more platform neutral, instead of clojure.dotnet/java |
| 15:29 | raek | probably because those are very host-specific |
| 15:29 | AWizzArd | you find? |
| 15:30 | raek | feels like those are mostly wrapper libs for certain java feauters |
| 15:30 | AWizzArd | those libs are also present in .net |
| 15:30 | fliebel | chouser: But you just added extra behavior to LazySeq, right? |
| 15:30 | raek | ok, maybe they are more similar than I thought |
| 15:30 | AWizzArd | it means that if I want to use typical IO stuff, we will have funny java names in my .net code |
| 15:31 | raek | does .net have input/ouput streams and readers/writers in the same way java does |
| 15:31 | dnolen | fliebel: it's a properly namespaced extension tho. It's not visible to other namespaces. |
| 15:31 | chouser | fliebel: it certainly looks like I did. In this case we could have written spin like: (defn spin [x] (if (instance? LazySeq x) ...))) right? |
| 15:32 | fliebel | I think so... |
| 15:32 | chouser | it's our function, we just defined it with defprotocol which allows us to add new cases on the fly |
| 15:32 | fliebel | yay |
| 15:32 | replaca | Has anyone else seen a stack overflow out of clojure.lang.Keyword? |
| 15:32 | replaca | in the intern method |
| 15:32 | chouser | essentially. Except then rhickey sprinkled it with magic dust to make it very fast. |
| 15:33 | fliebel | :) |
| 15:33 | chouser | fliebel: it's good to know not everyone knows about this yet -- it's my topic at Strange Loop |
| 15:33 | bhenry | from the moustache docs: |
| 15:33 | bhenry | (app ["foo" name] my-handler) |
| 15:33 | bhenry | ; will route requests to "/foo/", "/foo/bar" to my-handler and bind @name@ (a local) to the matched segment (eg "" or "bar") |
| 15:33 | bhenry | how do i access the name where (= name "bar") |
| 15:33 | fliebel | oh, I feel special now :) |
| 15:34 | chouser | fliebel: good I'm glad! But... why? |
| 15:34 | dnolen | bhenryy: you need to create a handler fn, 'name' will be visible to it - (fn [req] (my-handler name)), moustache also has a delegate fn to make this less tedious |
| 15:35 | fliebel | Because I know something not everyone knows ;) |
| 15:35 | chouser | ah, good! |
| 15:36 | bhenry | dnolen: i had that and it didsn't work |
| 15:36 | fliebel | Except that I'm not o sure yet what exactly you just said. Only that it's magic and fast. Two things I like especially. |
| 15:36 | bhenry | *gisting* |
| 15:39 | chouser | fliebel: not coming to Strang Loop I suppose? Or Clojure-Conj? |
| 15:40 | fliebel | I'm located in the Netherlands, so I'm afraid not :( :( |
| 15:41 | fliebel | I'd love to though |
| 15:42 | chouser | fliebel: Here are the basics: http://clojure.org/datatypes |
| 15:42 | chouser | or perhaps "raw details" is a better description. |
| 15:42 | fliebel | chouser: I tried to read that this morning, but maybe with my new knowledge I can understand it. |
| 15:43 | chouser | "Joy of Clojure" and "Practical Clojure" I believe both cover protocols and reify. |
| 15:43 | fliebel | I never read programming books, except when I did Java. |
| 15:44 | chouser | I do sparingly. Learned Pascal and Lisp from books, but not perl or ruby |
| 15:46 | chouser | in both cases the paradigm shift from what I knew to what I was trying to learn warranted the kind of wholistic coverage a book does better than random web postings. |
| 15:46 | chouser | and official docs |
| 15:47 | fliebel | That would have been true when I started with Clojure, but now I'd get bored by the stuff I already know, and lose myself in side projects based on hte book. |
| 15:48 | ohpauleez | Joy of Clojure has an awesome section on proxy, reify, defprotocol, and defrecord |
| 15:48 | ohpauleez | I reference it often to judge if I'm abusing something |
| 15:48 | fliebel | Man, I turned 100-bootles-of-beer-song-generators from a book into webapps and such, to find out they'd do that a couple of chapters later. |
| 15:49 | fliebel | Yea, maybe I should get a book anyway… |
| 15:49 | ohpauleez | fliebel: At the point you're at in Clojure (based on what I follow in here), you'd get a lot of mileage out of it |
| 15:50 | chouser | ohpauleez: thanks. didn't want to say it myself. :-) |
| 15:50 | ohpauleez | very well organized and telling you when and why, instead of how and a little why |
| 15:50 | ohpauleez | chouser: :) it's all good |
| 15:51 | ohpauleez | chouser: real talk, it's one of the best books I've read. Works great as a story, examples are intelligent and easy to follow, but advanced enough to be adapted, Easy to use a reference. |
| 15:52 | fliebel | ohpauleez: I think I agree with you. |
| 15:52 | ohpauleez | and the biggest problem I had in clojure was deciding, "when" |
| 15:52 | fliebel | ohpauleez: ? |
| 15:52 | ohpauleez | it helped me a lot with that |
| 15:52 | fliebel | when? |
| 15:52 | ohpauleez | fliebel: In clojure, you have this whole array of functionality. Take concurrency |
| 15:52 | ohpauleez | we all have that little chart burned in our brains by now |
| 15:53 | ohpauleez | we know vars and atoms and agents |
| 15:53 | ohpauleez | but when should I be using promises over futures, or when am I abusing a future and should really be using an agent |
| 15:53 | ohpauleez | when should I use protocols and not some other small hack |
| 15:53 | fliebel | right… I have that problem a lot indeed |
| 15:54 | chouser | ohpauleez: that's very encourging, thanks. |
| 15:54 | ohpauleez | Joy of Clojure is structured by answering when, and for me, that pulled it all together |
| 15:55 | ohpauleez | chouser: np, thank you! |
| 15:55 | fliebel | muhahaha, under 10 there is a whole set of "when to use … " |
| 15:56 | bhenry | dnolen: can you give an example of delegate? |
| 15:57 | ohpauleez | chouser: Out of curiosity, how did you and fogus assemble the book |
| 15:57 | dnolen | bhenry: lemme look |
| 15:57 | ohpauleez | LaTeX? |
| 15:57 | fliebel | ohpauleez: How comes you have already read it when it's not out yet? You do the MeAP ebook thing? |
| 15:57 | chouser | ohpauleez: heh. you don't want to know. |
| 15:57 | chouser | ohpauleez: sausage-making and all that. |
| 15:57 | ohpauleez | chouser: haha, fair enough |
| 15:58 | chouser | ohpauleez: nah, I kid. We wrote it in markdown, augmented with our own various extensions. |
| 15:58 | ohpauleez | fliebel: Yeah, I got the MEAP when the first chapter was finished, and read the chapters as they were released |
| 15:58 | chouser | ohpauleez: then wrote tools to generate Manning's docbook-like XML from that, which they use to generate PDFs, etc. |
| 15:59 | ohpauleez | ahh, cool |
| 15:59 | fliebel | nice |
| 15:59 | dnolen | bhenry: http://github.com/cgrand/moustache/blob/master/src/net/cgrand/moustache.clj#L159 |
| 16:00 | dnolen | bhenry: (delegate foo name) -> (fn [req] (foo req name)) |
| 16:00 | fliebel | chouser: Is there a release date, or is it a "don't ask, it's read when it's ready" thing? |
| 16:01 | chouser | fliebel: fogus_ and I are essentially done, as far as I understand. It's going through final editing revisions now and should be on dead trees by Nov or Dec. |
| 16:02 | fliebel | Cool :) I prefer a real book over an electronic one, except for searching :) |
| 16:02 | bhenry | dnolen, i had just read that and gotten it to work when you posted. thanks for the help. |
| 16:02 | ohpauleez | fliebel: I don't know if you can still do it, but you can get a package deal |
| 16:03 | ohpauleez | ebook and physical one, for a great price |
| 16:03 | fliebel | "MEAP + Print book (includes Ebook) when available" |
| 16:03 | ohpauleez | right, you get the ebook now |
| 16:03 | ohpauleez | and the print book is shipped |
| 16:03 | fliebel | nice :) |
| 16:04 | dnolen | anybody know who the intro is written by yet? |
| 16:04 | ohpauleez | dnolen: The Stu's |
| 16:04 | chouser | fliebel: there are often coupon codes listed at joyofclojure.com |
| 16:04 | ohpauleez | dnolen: nah, I'm just making it up |
| 16:05 | chouser | dnolen: not yet announced, afaik. :-) |
| 16:05 | dnolen | arg |
| 16:06 | fliebel | chouser: ? |
| 16:06 | fliebel | Where do I look for? |
| 16:06 | chouser | fliebel: we're very excited about who we've got to write the foreward for us, but for some reason are keeping it a secret for now. |
| 16:06 | chouser | oh, what are you asking? |
| 16:07 | fogus_ | chouser: BTW, got an email. Things are back on track WRT to the foreword. :-) |
| 16:07 | chouser | fogus_: ah, great news. I wasn't really worried. |
| 16:07 | fliebel | chouser: I was asking about the coupon codes. What do you mean by listed? |
| 16:07 | fogus_ | yeah really. |
| 16:07 | chouser | fogus_: not as if this person has shown difficulty producing large amounts of text in the past. |
| 16:08 | chouser | fliebel: oh, sorry. It would be right by the "Buy it" link if there were one running right now. |
| 16:08 | fliebel | chouser: Ah, okay, I'll keep any eye on it, or probably not actually, but anyway. |
| 16:08 | lpetit | hello all |
| 16:09 | chouser | fliebel: if you use twitter you can follow fogus or me -- we generally tweet when we hear about coupon codes. |
| 16:09 | chouser | lpetit: hi! |
| 16:10 | fliebel | chouser: I was about to do that anyway :) My Twitter is becomming full of awesome Clojure people :) |
| 16:10 | lpetit | chouser: you lose. I need somebody's help, you answered to me, you're the one ! :) |
| 16:11 | lpetit | chouser: more seriously, is it a time where I can talk about a problem, do you have enough bandwidth currently ? |
| 16:12 | alpheus | How do you specify that a Var is bound in a function's :pre condition? |
| 16:13 | fogus_ | The Clojure Maven repos are busted. Should be fixed... eventually. |
| 16:13 | wwmorgan1 | alpheus: can you call the java method isBound on it? |
| 16:13 | chouser | lpetit: hm, it's nearly time for TF2, so perhaps not. |
| 16:14 | lpetit | I have questions related to clojure and its use of classloaders. We're trying, with cgrand, to see what could be done better in our way to embed in OSGi. |
| 16:14 | alpheus | I think I'm really just asking what is the argument for bound? supposed to be? |
| 16:14 | lpetit | What's TF2 ? |
| 16:14 | ohpauleez | TeamFortress 2, I'm guessing |
| 16:14 | chouser | lpetit: way off topic. ohpauleez is correct. |
| 16:16 | alpheus | I would have thought (bound? 'foo) but clojure.lang.Symbol cannot be cast to clojure.lang.Var |
| 16:16 | lpetit | First question: is there a way for me to initiate the Clojure environment, or very quickly after its initialization, with a parent classloader of my own. So that clojure always tries to find a classpath resource (bytecode on disk, clojure file on disk) via my classloader before "giving up" ? |
| 16:16 | MayDaniel | alpheus: (bound #'foo) |
| 16:16 | MayDaniel | bound?* |
| 16:17 | lpetit | >(doc bound?) |
| 16:17 | lpetit | ,(doc bound?) |
| 16:17 | clojurebot | "([& vars]); Returns true if all of the vars provided as arguments have any bound value, root or thread-local. Implies that deref'ing the provided vars will succeed. Returns true if no vars are provided." |
| 16:17 | ninjudd | lpetit: not sure i am qualified to answer, but i spent many hours a few months back trying to do something similar |
| 16:17 | alpheus | (bound? #'foo) raises Unable to resolve var: foo in this context |
| 16:18 | hiredman | -Djava.system.class.loader |
| 16:18 | lpetit | ninjudd: interesting. If you have a clearer "vision" of how things work |
| 16:18 | hiredman | but if the classloader you specify references clojure clojure will be loaded |
| 16:18 | wwmorgan1 | alpheus: do (declare foo) first. then bound? on #'foo will return false |
| 16:19 | lpetit | hiredman: I can not tweak things at this level. I cannot force every user of ccw to tweak its loading script for eclipse |
| 16:19 | MayDaniel | alpheus: What are you trying to do? Are you sure bound? is what you need? |
| 16:19 | hiredman | so you need to either write the classloader in java or use ASM to generate byte code that doesn't reference clojure |
| 16:19 | hiredman | lpetit: *shrug* |
| 16:19 | ninjudd | lpetit: my solution was to use setContextClassLoader, but i ran into what i think is a bug in how clojure handles *use-context-classloader* |
| 16:20 | ninjudd | lpetit: my travails are detailed in this thread: http://groups.google.com/group/clojure-dev/browse_thread/thread/f61b550abf7f9c52/da25ba7e31b9431c |
| 16:20 | lpetit | ninjudd: you tried your tests for which kind of environment ? OSGi ? WebApp ? |
| 16:20 | stuartsierra | Bwahaha, I broke Contrib. |
| 16:20 | stuartsierra | Trying to fix now. |
| 16:20 | lpetit | ninjudd: thx I'll consult it |
| 16:22 | alpheus | I am not sure bound? is what I need. I am writing a function that relies on something that I expect will be set up by def/defvar or in a binding form and I wanted to assert that in the pre part of a condition-map for the function. Please feel free to tell me I'm going about that all wrong and point me toward the right documentation. |
| 16:22 | lpetit | hiredman: no problem. I can write the classloader in java. But I can not "insert it" in the classloader hierarchy in the classical way. It's "constrained" by OSGi. Rather, I would like to create my own classloader, which will leverage the OSGi classloader as its parent one, and then inject mine (which will have some goodies such as being able to consult all classloaders of all bundles that... |
| 16:22 | lpetit | ...depend on the clojure bundle) as the "reference" classloader for clojure |
| 16:22 | lpetit | hiredman: at this particular moment, I don't even know if what I just described makes sense |
| 16:23 | lpetit | ninjudd: before even reading your post, reacting to your explanation: my fear is that I do not have control over the context class loader in the long run. I'm thinking about entering by the backdoor room :) |
| 16:24 | wwmorgan1 | alpheus: I think that what you want to know is whether the namespace has the symbol you need. In this case you want ns-resolve |
| 16:24 | hiredman | lpetit: that is a complex issue |
| 16:24 | hiredman | and surprisingly oracle or ibm have some patents related to it |
| 16:24 | hiredman | (ugh) |
| 16:24 | lpetit | hiredman: oooh yes ! took us awake veeerry late yesterday ! |
| 16:24 | lpetit | patents ? |
| 16:25 | hiredman | ninjudd: I haven't look at clojure's use of classloaders much, but the use of dynamic classloaders the way they are may be what allows the redefinition of records at a repl |
| 16:25 | hiredman | lpetit: I know right? crazy |
| 16:25 | lpetit | hiredman: probably not an issue, everybody knows those people work for science, not profit ;-) |
| 16:26 | hiredman | filtering classloaders and such |
| 16:26 | hiredman | http://www.faqs.org/patents/app/20080271002 |
| 16:27 | duncanm | la la la |
| 16:27 | lpetit | hiredman: it really is totally crazy to place patterns on such trivial "thoughts" ! |
| 16:28 | lpetit | and even more crazy to accept those as patterns ! |
| 16:29 | lpetit | hiredman: I haven't played with records that much. There's still a restriction on their redefinition ? Due to the fact that a real class is generated, right ? |
| 16:30 | ninjudd | hiredman: my change didn't affect the repl. it still had DynamicClassLoader as the parent of NativeClassLoader. plus i only change the classloader temporarily in my import-native method |
| 16:31 | lpetit | hiredman, ninjudd: reading ninjudd's link and others related to OSGi/context class loader. Will come back to you within 15 minutes |
| 16:32 | ninjudd | hiredman: but i'm past NativeClassloader anyway. cake handles native libs perfectly without having to muck with the classloader |
| 16:32 | ninjudd | my point was just that i think there is still a bug in how clojure handles *use-context-classloader* |
| 16:33 | hiredman | as I said, I have not really looked at it, but classloading is very complicated, and is definitely tricky in the case of redefining classes |
| 16:36 | ninjudd | hiredman: agreed, it is very complicated. which is probably why cemerick was the only person brave enough to respond to my message |
| 16:37 | cemerick | which message was that? |
| 16:37 | ninjudd | that classloader message from way back when |
| 16:42 | ninjudd | hiredman: the complexity is also likely why nobody wanted to touch a patch from some kid they'd never heard of to fix a bug that nobody else had noticed ;-) |
| 16:42 | ninjudd | but that doesn't mean it isn't a bug |
| 16:44 | hiredman | I will with hold judgement on bugness until it's been reviewed elsewhere |
| 16:45 | ninjudd | hiredman: probably won't ever happen. it's over four months old. |
| 16:46 | hiredman | *shrug* |
| 16:46 | ninjudd | unless someone with more clout has the same problem. then i shall be vindicated! |
| 16:47 | cemerick | ninjudd: is there a bug opened on assembla? |
| 16:48 | ninjudd | good question |
| 16:48 | ninjudd | looks like i never opened one. i think this was back before i had access |
| 16:49 | dnolen | ninjudd: do it! |
| 16:50 | lpetit | ninjudd, cemerick, hiredman: just read an article or two on the subject of OSGi and its affinities with context class path. It's just a no man's land in the spec. Every container has its own way to use it. Some expose every exported package by every bundle in this classloader, some do not guarantee that it is set, some by the use of proxies at bundle boundaries try hard to always set it... |
| 16:50 | lpetit | ...correctly (but I guess that you need to always use OSGi services then, not directly call classes exported by another bundle ... |
| 16:51 | ninjudd | you scared him off |
| 16:54 | ninjudd | lpetit: sounds painful |
| 16:55 | lpetit | ninjudd: ooh yes. That's why I somehow give up on trying to cheat with OSGi, and now I'm trying to cheat with clojure :-). I can even consider hacking it a little bit in the corners. But right now I just need to understand how it works. |
| 16:57 | ninjudd | so how do you plan to cheat with clojure? replace DynamicClassloader? |
| 17:00 | lpetit | ninjudd: first step = find a summary of how the parts that use classloaders work, or someone with the ability to do this summary "live" for me. Then I'll see if this "DynamicClassloader" should be extended, composed, replaced, etc. (I don't even know exactly what I'm talking about, concerning Clojure and classloaders. And this kind of subject does not suffer to be imprecise) |
| 17:02 | ninjudd | lpetit: i would start by trying to write your own classloader that users DynamicClassLoader as it's parent, which means that resources that are not found by your classloader will be loaded using dynamic classloader. |
| 17:02 | ninjudd | s/users/uses/ |
| 17:02 | sexpbot | <ninjudd> lpetit: i would start by trying to write your own classloader that uses DynamicClassLoader as it's parent, which means that resources that are not found by your classloader will be loaded using dynamic classloader. |
| 17:03 | ninjudd | lpetit: then you can use setContextClassLoader to change clojure to use your classloader instead of DynamicClassLoader. |
| 17:04 | ninjudd | lpetit: what you are doing sounds very similar to what i was doing. NativeClassLoader and my import-native function are good examples |
| 17:04 | lpetit | ninjudd: it's more that I don't know in which ways I can direct clojure to use my classloader. I remember vaguely having seen various places where a modif can be made (some *use-context-classloader*, some CLASS_LOADER static attributes of RT / Compiler, BASE_CLASSLOADER, etc). I'm lost between those "alternatives" |
| 17:06 | lpetit | ninjudd: but *when* to call setContextClassLoader() ? I cannot do this once and for all, or I'll not play well with OSGi (that's what I understand). By doing so I may expose to few or to many things to all other following users of the thread. And I have no guarantee that it will not be changed by somebody else in the future. |
| 17:06 | lpetit | Instead of telling clojure "use the context classloader", I would rather have a way to tell him: please also try to always use as a last resort this classloader I'm handing you |
| 17:06 | lpetit | once and for all |
| 17:09 | ninjudd | well, clojure does that with the parent of DynamicClassLoader, which should be whichever classloader loaded clojure.lang.Compiler |
| 17:09 | lpetit | Oh and I also just thought about this one: the context classloader, by definition, is for one thread. I'm not sure at all in OSGi that I have any guarantee that it will always be this thread that will be used when accessing e.g. RT ? |
| 17:09 | ninjudd | IIRC |
| 17:09 | ninjudd | lpetit: good point |
| 17:13 | ninjudd | lpetit: this part of clojure seems like a total mess to me. if you can convince someone (i.e. stuarthalloway) to clean it up, that would be a very good thing |
| 17:15 | lpetit | ninjudd: a real world example of the problem. An AOT class is declared in a bundle A, via the plugin.xml. At some point the eclipse frameworks wants to load the class. I don't know when, I have no control, the class will automatically call clojure in another bundle to initialize its implementation namespace. I have no way to take control in this workflow by superimposing my "classloader-which-will |
| 17:15 | lpetit | -call-back-to-the-calling-bundle-loader" so that clojure will even be able to find the implementation namespace's ".clj" resource |
| 17:16 | lpetit | ninjudd: I'll try, as soon as I seem to know what I'm talking about :) |
| 17:16 | ninjudd | http://books.google.com/books?id=CvvdZtzxnAEC&lpg=PP1&ots=3G5cW4y2NJ&dq=stuart%20halloway%20Component%20Development%20java&pg=PA11#v=onepage&q&f=false |
| 17:17 | ninjudd | written by stuarthalloway |
| 17:19 | ninjudd | lpetit: yeah, i think changing the classloader used by clojure can't be done without a patch |
| 17:19 | ninjudd | unless you can control which classloader is used to load clojure.lang.Compile |
| 17:20 | lpetit | ninjudd: I can live with such a (probably) tiny patch for the needs of ccw. |
| 17:20 | ninjudd | lpetit: but then every user of ccw must use a forked version of clojure |
| 17:22 | AWizzArd | ninjudd: were you the guy who implemented a Set that keeps the order of insertion? |
| 17:22 | lpetit | ninjudd: no we thought about 2 scenarios with cgrand: one where we totally bypass OSGi and indeed create and wire "on the fly" clojure environments. In this scenario we control which classloader is used to load clojure.lang.Compile. But this scenario does not play well with OSGi when you add AOT compiled classes to the dance. They just never will be able to get a the proper clojure classes,since t |
| 17:22 | lpetit | hey are isolated from OSGi. |
| 17:22 | ninjudd | AWizzArd: yes |
| 17:22 | lpetit | ninjudd: thanks god no. |
| 17:23 | lpetit | ninjudd: it's been months (if not years) since ccw does not mistake its own clojure environment with each of the user's projects environments :) |
| 17:23 | ninjudd | i see. like lein and cake |
| 17:23 | AWizzArd | ninjudd: please look into your priv messages |
| 17:24 | lpetit | ninjudd: but it's fair to say that users whose job is writing Eclipse plugins could benefit from this new approach (and the patched clojure) if they want the greater repl experience in their own development cycle |
| 17:24 | lpetit | ninjudd: yes, they now do like ccw :-p |
| 17:53 | erikcw1 | 5 |
| 17:54 | amalloy | erikcw1: 11 |
| 17:55 | erikcw1 | I have a string that contains some html. I'm trying to process it with enlive, but I can't figure out how to get started. Any ideas? |
| 17:58 | raek | I suspect that you could pass an instance of java.io.StringReader ot html-resource (note: I have not tested this) |
| 17:58 | erikcw1 | raek: thanks -- I'll try that. I still have a heck of a lot more Python in my head than Java |
| 17:59 | raek | hrm, maybe you need to pass an java.io.StringInputStream instead... |
| 18:01 | raek | here's the multimethod that handles how a resource is made from the argument: http://github.com/cgrand/enlive/blob/master/src/net/cgrand/enlive_html.clj#L49 |
| 18:01 | erikcw1 | I was just looking at that, looks like it takes both a java.io.Read and an InputStream |
| 18:02 | raek | ah, didn't see the Reader part... |
| 18:02 | erikcw1 | what's the difference between a Reader and a Stream? |
| 18:02 | raek | using a Reader would be preferred |
| 18:02 | lpetit | best resource on the subject I've found: http://www.infoq.com/articles/code-generation-with-osgi |
| 18:02 | raek | they do characters and bytes, respectively |
| 18:03 | raek | strings are character-based, so using a reader avoid any redundant encoding to and decoding from bytes |
| 18:03 | erikcw1 | ok, makes sense |
| 18:04 | erikcw1 | you wouldn't happen to know off the top of your head how to render the enlive object back into a string after it has been processed would you? |
| 18:05 | raek | I have barely begun using elive :-) |
| 18:05 | erikcw1 | :) |
| 18:05 | raek | iirc, it makes lazy sequences so that the whole document doesn't need to be in memory at once |
| 18:08 | erikcw1 | raek: (apply str (html/emit* ENLIVE_OBJECT)) does the trick |
| 18:12 | raek | ok, neat |
| 18:13 | raek | I think Ring accepts sequences of strings as reponse bodys |
| 18:14 | raek | (in case you were coding web with some Ring-based framework) |
| 18:20 | erikcw1 | not using Ring yet. thanks for the info though |
| 18:22 | amalloy | raek, erikcw1: Ring does indeed accept seqs of strings. i was reading through the APIs just last night to get my feet wet |
| 18:24 | duncanm | i want (contains? [10 20 30 40 50] 50) to return true, which call should i be using instead? |
| 18:25 | raek | hrm, I think that new fn was added recently |
| 18:25 | raek | it scanned the sequence for the element in linear time |
| 18:26 | raek | anyway, using sets are often a better solution |
| 18:26 | raek | ,(contains? #{10 20 30 40 50} 50) |
| 18:26 | clojurebot | true |
| 18:26 | scottj | it was discussed or possibly temporarily introduced but I don't think it made it |
| 18:27 | iGNOSaurus | Hi! |
| 18:27 | raek | ,(some #{50} [10 20 30 40 50]) |
| 18:27 | clojurebot | 50 |
| 18:27 | iGNOSaurus | How do I turn a seq of characters into a string? Sorry for being a noob! |
| 18:27 | raek | ,(some #(= % 50) [10 20 30 40 50]) ; if you really need a bool |
| 18:27 | clojurebot | true |
| 18:28 | duncanm | iGNOSaurus: (apply str s) |
| 18:28 | raek | iGNOSaurus: not very obvious, but (apply str [\f \o \o]) |
| 18:28 | iGNOSaurus | duncanm: Thanks! |
| 18:29 | iGNOSaurus | It makes a lot of sense if you know how stuff works. :) |
| 18:29 | wwmorgan1 | ,(clojure.contrib.seq-utils/includes? [10 20 30 40 50] 50) |
| 18:29 | clojurebot | true |
| 18:33 | amalloy | duncanm: you probably don't want true anyway, just something non-false; in which case raek's first two examples are perfect depending on whether you can store your stuff as a set or not |
| 18:54 | lpetit | ,(some #{false true} false) |
| 18:54 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Boolean |
| 18:54 | lpetit | ,(some #{false true} [false]) |
| 18:54 | clojurebot | nil |
| 18:55 | lpetit | I love this one :) |
| 18:55 | amalloy | ,(some false? [false]) |
| 18:55 | clojurebot | true |
| 18:56 | lpetit | of course. But for example cannot be used in a generic way (not controlling the set :-)) |
| 19:02 | abedra | does anyone know how to read a raw device from java? |
| 19:02 | abedra | i'm trying to capture input from /dev/input/js0 |
| 19:02 | abedra | which I know is spitting out information |
| 19:02 | abedra | because I can cat /dev/input/js0 |
| 19:04 | alsocasey | I was wondering whether anyone could offer some insight concerning this aquamacs/SLIME/swank-clojure setup issue I'm struggling with over here? |
| 19:05 | alsocasey | specifically, while I can run a standalone REPL just fine, initiating a swank session and connecting to it in Aquamacs leads the REPL to freeze on any but the simplest inputs |
| 19:09 | scottj | does it work in normal emacs? |
| 19:11 | alsocasey | Haven't tried with standard emacs yet - I was hoping someone might have experienced similar and could provide a quick solution |
| 19:12 | amalloy | abedra: it's the same as reading any file, isn't it? |
| 19:12 | iGNOSaurus | Is there a really simple way to add a list of characters to a set? That is, the individual characters. :) Thanks again! |
| 19:13 | amalloy | (,into #{\a \b} [\n \6]) |
| 19:13 | iGNOSaurus | I've been watching 5 hours of video, and it seems so simple when other people are doing it. When I type myself most things fail miserably. |
| 19:13 | amalloy | ,(into #{\a \b} [\n \6]) |
| 19:13 | clojurebot | #{\a \b \n \6} |
| 19:14 | iGNOSaurus | ,(into #{\a \b} '(\n \6)) |
| 19:14 | clojurebot | #{\a \b \n \6} |
| 19:14 | iGNOSaurus | Thanks! OMG. That is simple. :) |
| 19:14 | amalloy | it always is, eventually :) |
| 19:14 | iGNOSaurus | Yeah. :) |
| 19:18 | amalloy | (use 'clojure.java.io) |
| 19:18 | amalloy | (->> (file "/dev/urandom") reader line-seq (take 2)) |
| 19:18 | amalloy | abedra: ^^ |
| 19:21 | technomancy | alsocasey: aquamacs is not very well supported since it's not cross-platform |
| 19:21 | alsocasey | I suppose I'll try again with regular emacs |
| 19:22 | abedra | amalloy: i guess it is |
| 19:23 | technomancy | alsocasey: could also be an issue with clojure 1.3 if you're using that; swank hasn't been updated for it yet |
| 19:23 | ninjudd | alsocasey: i know lancepantz uses aquamacs with swank all the time with no problem. |
| 19:23 | ninjudd | but he talks about switching off aquamacs all the time |
| 19:23 | alsocasey | technomancy: no, this is using clojure 1.2 |
| 19:24 | alsocasey | ninjajudd: yes I figured it was something I was missing since Aquamacs seems to be used by others without problems - also "switching off"? |
| 19:25 | ninjudd | to plain-old-emacs |
| 19:25 | alsocasey | ah - well I'll try that then |
| 19:31 | iGNOSaurus | Like, dudes. I'm amazed, my first program. :) Thanks for the help. |
| 19:35 | amalloy | what's it do, iGNOSaurus? |
| 19:41 | iGNOSaurus | Not much. It reads in a Norwegian dictionary from file, and it picks out the words that uses "allowed" letters. |
| 19:41 | iGNOSaurus | A friend of mine, who's a teacher for young children, wanted it. They only know four letters, and she wants to know which words they can learn to spell. :) |
| 19:44 | alsocasey | technomancy: sure enough it works fine under regular emacs |
| 19:46 | lpetit | if somebody can explain how RT.USE_CONTEXT_CLASSLOADER works, please explain |
| 19:46 | ninjudd | not very well ;-) |
| 19:48 | lpetit | seems convoluted, and I don't fully grasp why so |
| 19:48 | ninjudd | ,(clojure.lang.RT/baseLoader) |
| 19:48 | clojurebot | #<DynamicClassLoader clojure.lang.DynamicClassLoader@1fd523d> |
| 19:48 | ninjudd | ,(.getParent (clojure.lang.RT/baseLoader)) |
| 19:48 | clojurebot | java.security.AccessControlException: access denied (java.lang.RuntimePermission getClassLoader) |
| 19:48 | ninjudd | meh |
| 19:49 | ninjudd | ,(println "#<DynamicClassLoader clojure.lang.DynamicClassLoader@169c6f2>") |
| 19:49 | clojurebot | #<DynamicClassLoader clojure.lang.DynamicClassLoader@169c6f2> |
| 19:49 | ninjudd | that's better ;) |
| 19:49 | ninjudd | try it for yourself. the baseLoader is a dynamic classloader, as is it's parent |
| 19:50 | ninjudd | which is not right |
| 19:51 | lpetit | no, its parent is a FactoryURLClassLoader for me, with cljr and |
| 19:51 | lpetit | ... |
| 19:52 | lpetit | some probably not so old (.getParent (clojure.lang.RT/baseLoader)) |
| 19:52 | iGNOSaurus | What's the best framework for doing web with Clojure? |
| 19:52 | lpetit | 1.2.0-master-SNAPSHOT |
| 19:53 | ninjudd | hmm, running clojure from the jar directly i get: DynamicClassLoader -> DynamicClassLoader -> AppClassLoader |
| 19:53 | ninjudd | iGNOSaurus: i'm fond of compojure |
| 19:53 | iGNOSaurus | Cool, thanks. I'll look at it. |
| 19:54 | ninjudd | not quite a framework though. you'll still need a few more pieces for html, javascript, ORM? |
| 19:54 | lpetit | anyway, I want to interpose something between DynamicClassLoader and AppClassLoader. If I could make it "generic" or "pluggable", it *could* be an acceptable patch |
| 19:55 | ninjudd | lpetit: here is my patch to RT to fix *use-context-classloader*: http://github.com/ninjudd/clojure/commit/4dac03fb2b47a33c77704c00fc9086f4c9b9dc3a |
| 19:55 | ninjudd | that's how i think it should work |
| 19:56 | lpetit | ninjudd: I' look at it. Please not that I absolutely want to avoid using *use-context-classloader*, though :). Is this "var" intended to be used from outside clojure core ? |
| 19:56 | lpetit | (ok I must really read your post) |
| 19:58 | ninjudd | i assume so, but at one point they changed the root binding from false to true to fix a bug. now it is kind of pointless. i believe the right fix would have been changing baseLoader as i have done |
| 20:01 | ninjudd | http://github.com/clojure/clojure/commit/b045a379215d1f48e6a2e6cedcdb41526cd5bb25 |
| 20:01 | ninjudd | i believe that change was prompted by the netbeans problem cemerick mentioned in the thread |
| 20:15 | amalloy | iGNOSaurus: http://gist.github.com/596278 is my go at it. probably not as legible as yours, but you might get some neat ideas from it about how expressive clojure is |
| 20:25 | lpetit | ninjudd: all this *use-context-classloader* remains opaque to me. Looks like a hack, |
| 20:25 | lpetit | s/remains/stuff remains/ |
| 20:25 | sexpbot | <lpetit> ninjudd: all this *use-context-classloader* stuff remains opaque to me. Looks like a hack, |
| 20:26 | lpetit | ninjudd: in your patch, shouldn't you try to position it to true from within the main.clj ? |
| 20:26 | ninjudd | lpetit: agreed seems that it would be better to have a *classloader* var that you can modify the root of |
| 20:28 | ninjudd | lpetit: not sure what you mean about main.clj |
| 20:29 | ninjudd | oh, you mean to wrap the call to setContextClassLoader with a binding of *use-context-classloader*? |
| 20:30 | lpetit | ninjudd: in the changeset of Rich you pointed, there was a conjunction of several changes: on in main.clj to try hard to set the context classloader to a meaningful value, and one to change the value of *u-c-c* so that what has been done in main.clj has a chance to be used |
| 20:30 | lpetit | no |
| 20:30 | lpetit | I mean, in main.clj, set the value of *use-context-classloader* to true, for the REPL thread |
| 20:31 | ninjudd | lpetit: that's what i meant when i said "wrap the call to setContextClassloader" |
| 20:31 | ninjudd | i wasn't all that clear. should have qualified it with: in the repl function |
| 20:32 | lpetit | ninjudd: sorry I dindn't understand that. I thought you hoped that just calling binding for the duration of the setContextClassloader() method call |
| 20:33 | ninjudd | oh, right. you would have to bind it for longer than that. good point |
| 20:34 | ninjudd | lpetit: i don't think the setContextClassLoader is necessary with the the fix to baseLoader. that is what is causing the double-parent problem i pointed out |
| 20:35 | ninjudd | (which may be why you didn't see it in cljr) |
| 20:35 | lpetit | guess we'll have to block rich hickey in some corner at the clojure conj to know the final word about all this :) |
| 20:36 | ninjudd | hehe. and stuarthalloway since he "wrote the chapter" on classloaders ;-) |
| 20:37 | lpetit | huh ? |
| 20:37 | ninjudd | i sent the link before |
| 20:37 | ninjudd | http://books.google.com/books?id=CvvdZtzxnAEC&lpg=PP1&ots=3G5cW4y2NJ&dq=stuart%20halloway%20Component%20Development%20java&pg=PA11#v=onepage&q&f=false |
| 20:39 | lpetit | oh ok ;) |
| 20:40 | ninjudd | lpetit: yep. cljr does its own classloader magic: http://github.com/liebke/cljr/blob/master/src/main/resources/cljr/main.clj#L95 |
| 20:42 | lpetit | ninjudd: why does he store previous-classloader but not use it ? |
| 20:43 | lpetit | Again an example of use of the context class loader as if it were in full control of the whole world :-( |
| 20:44 | lpetit | works for the REPL, from a Request thread in a webapp, but, again, not in an OSGi context :-( :-( |
| 20:44 | lpetit | anyway thanks for the link ! |
| 20:51 | ninjudd | lpetit: no problem |
| 20:52 | ninjudd | lpetit: for your case, would *classloader* be sufficient? assuming you could alter the root to be your modified classloader |
| 20:53 | lpetit | I guess so |
| 20:55 | lpetit | I am in control of the first invocation of a clojure class. e.g. I call Class.forName("clojure.lang.RT"). If just after that I set the root of *classloader* to be my own, then it's ok |
| 20:57 | lpetit | but isn't this a problem that for its core initialization, clojure would have used as its root a "temporary" classloader. I should ensure that the "old" *classloader* of clojure is the root classloader of my own, right ? |
| 21:00 | lpetit | ninjudd: if we don't want to break anything, we must keep it in place, though |
| 21:00 | lpetit | ok, must go to bed (3am here !) |
| 21:00 | lpetit | cu later ! |
| 22:25 | nroot7 | In my program I represent each user as a agent maintaining its own state. This works fine w.r.t. to concurrency but what if I want to persist this state in a non-volatile way. Is this a common pattern in clojure world ? How is it implemented ? |
| 22:30 | technomancy | nroot7: if 100% absolute consistency is not a requirement, you can have a watcher on your agent that serializes to disk |
| 22:31 | nroot7 | technomancy: thanks |
| 23:36 | bhenry | how can i make this happen? |
| 23:36 | bhenry | [:option {:value "123"} "Item" ] => [:option {:value "123" :selected true} "Item" ] |
| 23:38 | wwmorgan1 | ,(assoc-in [:option {:value "123"} "Item" ] [1 :selected] true) ;If you can guarantee that your data structure will be a vector |
| 23:38 | clojurebot | [:option {:selected true, :value "123"} "Item"] |
| 23:40 | bhenry | oh duh. i was looking right at assoc-in and forgot the key didn't already have to exist. |
| 23:41 | wwmorgan1 | ,(assoc-in {} [:a :b] :c) ; :-) You can do multiple levels of nesting too |
| 23:41 | clojurebot | {:a {:b :c}} |
| 23:47 | technomancy | it looks like in some situations clojure.walk treats MapEntries as distinct items, while sometimes it doesn't |
| 23:47 | technomancy | I don't suppose that's intentional? |