#clojure log - Jan 18 2010

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:11 tolstoy: Is there a nice way to prompt for and read in a value from the repl?

0:13 Ah. Hm. Maybe it's just the Netbeans repl that's the prob with (read).

0:15 Or maybe not.

2:36 LauJensen: Morning crew

2:47 wooby: hi all, when destructuring... how might i go about separating head and tail in an fn's arglist?

2:47 i'm aware of :as but that seems to yield the entire arg list

2:47 tolstoy: (let [[a b & rest] (some-list)]....) ?

2:48 wooby: oh duh, thanks tolstoy

2:48 tolstoy: no prob. I just learned you can do whacky map {} things that way, too.

2:50 wooby: i saw that

2:51 pretty soon my fn's won't have any bodies left :)

3:16 yangsx: it seems the problem of using swank-clojure/slime won't be resolved soon (let me know if I'm mistaken), I'm looking for using clojure on netbeans or eclipse. Anyone has any suggestions?

3:16 tolstoy: what's the problem?

3:18 yangsx: Latest versions have a problem that renders interactive using slime on clj source files impossible, but repl is OK.

3:19 tolstoy: You mean you can't eval functions or buffers into the image?

3:21 yangsx: tolstoy: that's right.

3:22 tolstoy: Yikes. I've been using the elpa package for slime / clojure mode, and then making my own standalone swank server (with appropriate classpath). Seems to work.

3:23 yangsx: tolstoy: see http://paste.lisp.org/display/92713

3:29 janmejay: has anyone experienced this problem where slime repl console doesn't

3:29 evaluate forms on pressing return

3:29 ?

3:33 hitting return executes slime-repl-return but doesn't evaluate the expression and doesn't return the prompt either

3:35 inferior-lisp buffer however responds to return key and evaluates the expression

3:38 ordnungswidrig: janmejay: I remember to have encountered this behaviour but this was surely some month ago. I now use clojure-mode from elpa with a swank server started from leiningen and have no problems.

3:41 janmejay: ordnungswidrig: in my case, clojure is running as an inferior process, will try starting swank server and connect to it

3:43 ordnungswidrig: any ideas where the problem is? any other ways to fix it?

3:44 LauJensen: janmejay, if par-edit is active in the REPL nothing will evaluate

3:46 janmejay: LauJensen: it doesn't have paredit mode

3:47 any other gotchas?

3:47 LauJensen: Which modes are active?

3:49 janmejay: LauJensen: REPL, {user clojure} and autodoc

3:50 LauJensen: hmm... You don't need autodoc, but it doesn't appear to be a mode thats causing it. Try disabling it

3:51 janmejay: LauJensen: didn't help

3:51 LauJensen: it responds to return key, does new lines and all that, but doesn't eval the expression and return prompt

3:57 LauJensen: janmejay: then I don't know - You could try following these instructions http://www.bestinclass.dk/index.php/2009/12/clojure-101-getting-clojure-slime-installed/

3:57 Then I'm sure it'll work

3:58 janmejay: LauJensen: sure, will try this one

4:20 vu3rdd: yangsx: are you running Debian?

4:20 I resolved the problem.

4:22 yangsx: Debian's netbase package had an issue which was causing the problem.

4:23 The default port being listened was an ipv6 port. You can fix it by either of the two following ways

4:24 1. open /etc/sysctl.d/bindv6only.conf and make net.ipv6.bindv6only=0

4:24 2. Start Java with -Djava.net.preferIPv4Stack=true

4:25 either of this will work fine

4:39 jevgeni: Hi guys, I wonder, is the Clojure Google Group premoderated for new members just for the first message or is there some other logic behind?

5:10 angerman: If i have(let [t {:a {:b 1} :b {:a 2}}]) how do I get 1 or 2. ((t :a) :b)? or can I do something like (t :a :b)?

5:12 esj: (-> :b t :a)

5:13 or (-> :a t :b)

5:13 angerman: thanks

5:13 esj: np

5:13 angerman: I guess (->> t :a :b)

5:14 is more "readable" :D

5:14 but i totally forgot about threading

5:14 LauJensen: ->> is incredible useful and easily read

5:15 esj: yeah, I always forget that one. Feels like playing Robin Hood :)

5:16 LauJensen: Steel from the rich do you ?

5:16 Steal

5:17 * angerman wonders what the poor guy who's going to judge my project is going to have headaches about clojure.

5:18 LauJensen: Its a healthy headache though

5:18 esj: a neurogenesis headache

5:21 * esj finally got 2-up, doublesided printing on his single-sided printer to work. Awards himself degree in topography. Not sure he saved any paper though.

5:21 angerman: clojure has list comprehention, right_

5:22 esj: for

5:22 angerman: ok

5:25 Chousuke: it produces a lazy seq, though, but close enough, right? :)

5:45 LauJensen: Chousuke: lazy-seq != list comprehension ?

5:49 powr-toc: Does anyone know why add-classpath is deprecated?

5:52 lpetit: pwor-toc: because it was black magic :-)

5:54 powr-toc: lpetit: How is it black magic... other than of course

5:54 being classloader related :-) All it seems to do is add the jar

5:54 classes into the classloader clojures compiler uses

5:59 lpetit: I don't remember the exact details

5:59 unfo-: nice ctcp spam

5:59 could somone set +R

5:59 andreas1: "nice"?

6:00 unfo-: holy fuck.

6:00 aaaah /ignore #clojure CTCP helps a lot :)

6:00 angerman: Again. if I have a structure that looks like {:key1 {:subkey1 value}}. so the values are the leafs, can I apply a function to all leafes an get a new structure back?

6:18 LauJensen: I wonder what kind of money you make off a ctcp spam campaign

6:18 VorTechS: none, it's an attack against freenode

6:19 Chousuke: well, they might also gain some spambots

6:19 LauJensen: Oh, seems a little futile then

6:19 Although its surprising that Freenode didn't have some kind of mechanism in place which stopped it

6:20 Chousuke: Well, that's easy to say, but do you have any idea what that mechanism could be? :P

6:20 LauJensen: Looks like a simple IPTables rule could have stopped it

6:20 Chousuke: sure, but how do you know the network before the attack happens?

6:20 LauJensen: Or just to check if a ctcp message contains a link

6:21 Chousuke: that's too general.

6:21 LauJensen: Not really - Who needs links in CTCPs ? :)

6:21 Chousuke: Well... someone might.

6:21 LauJensen: Chousuke - You're either with us.... or against it

6:21 So whats it gonna be spam-lover?

6:21 Chousuke: :P

6:23 VorTechS: I understand our new daemon will prevent these attacks

6:31 powr-toc: /ignore #clojure CTCP

6:32 unfo-: powr-toc, indeed

6:57 angerman: Hmm bad network.

6:57 Sorry to ask again. if I have a structure that looks like {:key1 {:subkey1 value}}. so the values are the leafs, can I apply a function to all leafes an get a new structure back?

6:59 Chousuke: angerman: there's update-in

7:00 angerman: Chousuke: thanks, will look into

7:00 Chousuke: though if you need to apply a function on the values of the entire submap given a key, it might be better to do it "manually"

7:04 dabd: How do I pass a Map to a Clojure function from Java?

7:05 Chousuke: hmm

7:05 clojurefn.invoke(themap)?

7:07 dabd: Chousuke: thx

7:08 Chousuke: I haven't actually tested it, but it's something like that

7:09 dabd: however I still don't get how to create the keywords in Java so the Clojure function retrieves them as they are expected in the function signature...

7:11 Chousuke: clojure.lang.Keyword.someStaticMethod :P

7:11 take a look at the source

7:11 the java side of Clojure is not very well documented. Though I think I saw Chouser working on that.

7:12 I hope I didn't hallucinate

7:12 andreas1: Hi!

7:12 Did I understand that correctly that there is no such thing as a mutable vector in Clojure?

7:12 Chousuke: Depends on what you mean.

7:13 the native Clojure vectors are persistent, but you can always use java things.

7:13 AWizzArd: OT: how do I say this correctly? "The user may call the web server's /xyz resource." Is it "servers" or "server's" or "servers'" or better "The user may call the /xyz resouce of the web server."?

7:14 LauJensen: andreas1: (transient []) is mutable

7:14 andreas1: Chousuke: Mh, I see.

7:14 Chousuke: LauJensen: no, it's transient!

7:14 andreas1: The difference being?

7:14 LauJensen: Chousuke: Its mutable eve nstill

7:14 andreas1: (using Java is cheating in my book...)

7:14 Chousuke: andreas1: calling it mutable might make you think you can use it like a mutable vector :P

7:15 dabd: Chousuke: it looks like it should be like this: clojure.lang.Keyword.intern(null, "name");

7:15 andreas1: Ah!

7:15 Chousuke: dabd: yeah.

7:15 LauJensen: andreas1: The difference is, that once you've worked on it, persist it with (persistent ..). That way it cant leak into your system. It has its own set of functions like conj! assoc! etc

7:15 Its for local mutations only, not something which is passed all around your project

7:15 * andreas1 tries to figure out how one would implement an efficient heap in Clojure, i.e. for Dijkstra's algorithm.

7:15 Chousuke: andreas1: or I guess the correct phrasing should be "you might be tempted to use it like a non-functional data structure"

7:16 LauJensen: andreas1: http://clojure.org/transients

7:19 andreas1: Hm, transients. I see.

7:19 Chousuke: It's very important to remember that you still need to write functional algorithms if you use transients

7:20 They don't allow you to escape into the imperative world :)

7:20 andreas1: Hm...

7:20 LauJensen: Chousuke: If he read Richs rationale I'm sure he'll be good to go :)

7:21 andreas1: Even though I appreciate persistent data structures and functional programming, I sometimes feel like mutable data structures are a good thing, if used carefully.

7:21 Chousuke: If you need mutable data structures, the JVM's are as good as anything.

7:21 andreas1: And what if I'm using ClojureCLR?

7:22 Chousuke: then I guess you need to use the CLR's data structures :/

7:22 andreas1: That... is not a satisfactory answer. :)

7:22 Chousuke: if portability matters, you'll need to write a wrapper

7:23 Clojure doesn't offer you mutable data structures because you're not supposed to use them :D

7:23 andreas1: That does start to sound like the IO monad.

7:24 btw., how can making a structure transient be O(1) if it copies said structure?

7:25 Chousuke: it doesn't.

7:25 Maybe some time in future Rich or someone else will come up with a way to integrate real mutable data structures into the clojure model of programming, but that hasn't happened yet.

7:27 the thing is, they don't work well with most of the good stuff Clojure has to offer. the STM breaks with mutable data, as do seqs. Probably some core functions presume that the things passed to them are persistent, too.

7:28 dnolen: andreas1: in the docs it says "shares structure", there's no actual copy op.

7:28 andreas1: Hrm. One could use escape analysis to get the performance of mutable data structures out of persistent structures.

7:28 Chousuke: perhaps.

7:29 that's up to the JVM folks for now :)

7:29 There isn't much interest in making the Clojure compiler very smart

7:29 andreas1: That is a huge mistake, if you ask me.

7:29 Chousuke: it just tries to produce code that's easy for the JVM to work with.

7:29 andreas1: Sure, the JVM does a lot of interesting optimizations.

7:30 Chousuke: Well, maybe someone will work on it after it gets reimplemented in Clojure

7:30 but for now, it's not a priority.

7:30 andreas1: But there are some things the JVM just can't do, because it lacks information the Clojure compiler has.

7:31 Chousuke: I mean, certainly no-one would object to a having a smarter compiler, but currently the cost-benefit ratio is not very good.

7:31 andreas1: Does the current compiler do any kind of type inference?

7:31 dnolen: andreas1: not really.

7:32 andreas1: The thing I would be afraid of is that there are things in the language design that make writing a good compiler intractable.

7:33 Chousuke: I don't think that will be a problem.

7:33 dnolen: andreas1: i doubt that.

7:33 andreas1: I don't have an opinion on that yet, as I don't know enough clojure yet.

7:34 But the way multi methods work looks suspicious. One wants to have the capability to resolve dispatch at compile time.

7:35 dnolen: andreas1: look into deftype and defprotocl then.

7:35 Chousuke: but that would break dynamicity

7:35 and the JVM can optimise such things pretty well.

7:36 andreas1: I'm coming from a Dylan background, btw., the last attempt at a better Lisp dialect.

7:36 dnolen: I will.

7:36 Chousuke: but yeah, multimethods are needlessly slow for the common case. that's why everyone's excited about deftype and protocols :)

7:36 dnolen: adnreas1: mikel, a dylan fan, really got into Clojure. So I assume there will be plenty in Clojure to make you happy ;)

7:37 Chousuke: but now I must leave for food. Later.

7:37 andreas1: dnolen: Clojure is certainly the first language in this millenium that I'm getting excited about. :)

7:37 Chousuke: later!

7:59 * andreas1 can't find any reference on deftype and protocols.

8:01 LauJensen: http://www.assembla.com/wiki/show/clojure/Protocols

8:03 andreas1: LauJensen: thanks.

8:04 LauJensen: np

8:05 andreas1: Although given all the research done on multimethods, I fail to see the point of introducing yet another mechanism to do about the same.

8:08 esbena: gen-and-load-class is an unknown symbol for me - what do I need to do to make it available?

8:09 dnolen: andreas: deftype and defprotocol are mostly about performance as well as being the groundwork for implementing Clojure-in-Clojure. If you want something more flexible/general multimethods are certainly the way to go.

8:11 andreas1: dnolen: if performance is the reason, somebody didn't do their homework on how to make multimethods fast.

8:27 ohpauleez: Can anyone point me to a resource that will help me hook up a clojure REPL to a maven project?

8:28 or is the typical way to make a clojure script that does all the imports and starts a repl

8:39 alexyk: ~maven clojure

8:40 clojurebot: google maven clojure

8:40 clojurebot: First, out of 9260 results is:

8:40 talios's clojure-maven-plugin at master - GitHub

8:40 http://github.com/talios/clojure-maven-plugin

8:40 ohpauleez: the maven clojure plugin?

8:40 alexyk: yep

8:40 ohpauleez: cool, thanks

8:41 I was just about to try it, I couldn't tell if it was strictly for handling clojure projects, or if I could also use it for interop

8:41 alexyk: am not sure

8:48 cemerick: ohpauleez: talios' plugin is very good, FWIW

8:48 ohpauleez: cool, thanks cemerick

8:48 cemerick: We don't use clojure projects per se -- just regular java projects + clojure-maven-plugin

8:49 ohpauleez: that's exactly what I'm looking for

8:50 cemerick: I'm not sure what a "clojure project" would be, actually. Enclojure has the concept, but as far as I can tell, that just pulls in some custom packaging mechanism (which has been rapidly subsumed by other efforts, IMO).

8:51 ohpauleez: not sure what environment you use, but enclojure provides a 'start repl here' command for *any* project, which is nice.

8:51 ohpauleez: that's what I'm looking for

8:52 at whatever level I'm at, I want to have a repl

8:52 with all the dependencies I need

8:52 so I don't have to do all the imports

8:53 cemerick: yeah, the nice thing about enclojure is that, even if you have a pure-java project that depends upon clojure (or another project that depends upon clojure), but which has no clojure code itself, the 'start repl' command will work without a hitch.

8:54 ohpauleez: cool, I'll take a look at it

8:55 andreas1: try/catch unwinds the stack before caling your exception handler?

8:58 jcromartie: so is compojure + enlive kind of a "blank slate" in terms of how you set it up?

8:58 like, there's no convention for how to name things or where to put stuff?

9:11 chouser: someone on the internet is wrong!

9:11 _fogus: chouser: Go get em!

9:11 chouser: :-P

9:12 dnolen: andreas1: try/catch is from java so yes. you might want to look at chouser's error-kit in clojure-contrib

9:12 andreas1: dnolen: I see, thanks.

9:13 chouser: ,(fn [] (loop [i (int 0)] (recur nil)))

9:13 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: recur arg for primitive local: i must be matching primitive

9:14 chouser: look at that, a nice tidy compile-time error because i is an unboxed primitive and so nil is not a possible value

9:14 LauJensen: uuuh

9:14 thats new

9:14 chouser: since when?

9:14 I mean, not very new.

9:14 Chousuke: I think that's quite old, actually.

9:14 jcromartie: how do you all structure your compojure projects?

9:14 dnolen: jcromartie: no conventions, definitely blank slate.

9:15 jcromartie: maybe at least have views/ for Enlive templates

9:16 maybe src/ and public/

9:18 _fogus: That quote is from here: http://clojure.org/data_structures

9:18 chouser: gah!

9:18 rhickey: may I please fix that?

9:19 LauJensen: _fogus: when you say 'that quote' what do you mean ?

9:19 _fogus: The other quote is from here: http://clojure.org/runtime_polymorphism

9:20 "Clojure does not support implementation inheritance." and "nil is a possible value of any data type in Clojure (since primitives are always boxed)"

9:20 jcromartie: what's the most up-to-date Clojure tutorial?

9:20 err

9:20 Compojure

9:21 andreas1: fogus: You seem to be reading my tweets. :)

9:21 jcromartie: (sorry parsing only this morning C.*j.*)

9:21 _fogus: andreas1: That would not be false. ;-)

9:22 cemerick: jcromartie: we follow maven conventions. Enlive templates are in src/main/resources.

9:22 jcromartie: ah, so you can then just deploy as a WAR?

9:22 chouser: andreas1: it looks like the official pages are a little out of date or something.

9:23 LauJensen: jcromartie: I think I have a few blogposts on Compojure, www.bestinclass.dk

9:23 cemerick: actually, src/main/webapp so they're in proper position w.r.t. css and js, but we define src/main/webapp as a resource root so that they're copied into the war as classpath-accessible resources

9:23 jcromartie: right

9:24 chouser: perhaps just overly broad.

9:24 rhickey: chouser: fix what?

9:24 chouser: "primitives are always boxed" on http://clojure.org/data_structures

9:24 andreas1: chouser: I see... however, what is the truth in this case?

9:24 "nil is a possible value of all data types except unboxed"?

9:25 AWizzArd: Does the master branch now include most recent updates, such as deftypes, the new agent error handling, etc?

9:25 cemerick: cgrand: is there any potential downside to using xml-resource to consume xhtml in enlive?

9:25 rhickey: chouser: ok - fixed to say what?

9:26 chouser: nil is a possible value of any non-primitive, I guess

9:27 cgrand: cemerick: no, as long as it's xhtml xml-resource is ok

9:27 chouser: or "primitives are boxed except when held in primitive locals or fields"

9:27 cemerick: cgrand: OK, that's what I figured, but your github msg got me slightly worried :-)

9:28 andreas1: Is there documentation on what primitives are?

9:28 I think btw. that nil being a possible value for all non-primitive data types is one of the major misfeatures of Java.

9:28 chouser: LauJensen: that compile-time check of the primitive has been in place at least since Jun 1 2008

9:29 Chousuke: andreas1: well, java only really has two things: primitives and references

9:29 chouser: andreas1: it is true that Clojure is (mostly) dynamically typed, which almost necessarily brings in some of the things I think you're objecting to.

9:30 andreas1: chouser: That's not true. I can easily have a dynamic language with a type that doesn't allow nil.

9:30 _fogus: chouser: Why not just change the part in parens to "(except for primitives)" with a link to http://clojure.org/java_interop#toc37 perhaps

9:30 LauJensen: chouser: I guess I'll just have to give up my old habit of immediately dismissing the backtrace in order to look at the code :)

9:30 Chousuke: andreas1: it might be useful to have references that you can't explicitly nullify, but hm.

9:31 chouser: like "no type inference" -- it's mostly unnecessary because Clojure's dynamically typed, though there is a little bit of type hint deduction going on...

9:31 andreas1: Chousuke: it is extremely useful, because I don't have to deal with nil all over the place.

9:31 _fogus: The problem with nil isn't that it's there... it's that it plays double or triple duty

9:31 Chousuke: andreas1: but nil is also a very useful value sometimes.

9:31 andreas1: as "I have nothing"

9:32 chouser: andreas1: hm, maybe we're not meaning the same thing. there's no such thing as a nil vector, for example, but anything that can hold a vector (a local, a var, a ref, etc.) could also be nil

9:32 andreas1: Chousuke: type unions of your type and the canonical false value serve this purpose pretty well.

9:32 Chousuke: andreas1: what if you want the value to be false?

9:32 andreas1: chouser: and type inference is extremely useful to get performance out of dynamically typed languages.

9:32 chouser: _fogus: yeah, I like your solution.

9:33 andreas1: Chousuke: I just cons up a special magic "no such value" object.

9:33 Chousuke: or you could just use nil :)

9:33 I think Clojure handles nil pretty well.

9:33 andreas1: What if you want nil to be a legal value?

9:33 Chousuke: well, it is.

9:34 andreas1: Type inference in dynamic languages was pioneered by CMU CL, btw., some 20 years ago.

9:34 Chousuke: in most cases it just means "nothing".

9:34 andreas1: Yeah. However, sometimes it doesn't make sense to pass "nothing".

9:34 Chousuke: I mean, it's not perfect, but in a dynamic language there's not much use in having separate "nothing" types.

9:35 andreas1: I think this is the time to ask what exactly your definition of a "dynamic language" is.

9:36 Because yes, it makes perfect sense to allow "nothing" values only in those places in your program where they do make sense.

9:36 chouser: andreas1: "allow" as in to otherwise prevent at compile time?

9:36 Chousuke: yes, but I think it would make no difference if the null is of type "String null" or "Keyword null" because it would behave the same in every case

9:37 andreas1: chouser: at compile time if you can, at run time if you must.

9:37 _fogus: Chousuke: I can imagine a separate nothing type being highly useful in a language with Clojure-like multimethods

9:37 andreas1: It wouldn't be "String null". It would be type union of "String" and "null".

9:38 Chousuke: so Maybe String, then? :P

9:38 chouser: currently, Clojure does to rather less at compile time than it could, but there are interesting possibilities ahead.

9:38 andreas1: (def maybe-string (type-union :String :Null))

9:38 Why not.

9:38 Chousuke: but how is that different from Maybe Keyword, if the type is necessarily determined at runtime anyway.

9:39 I mean, because the language is dynamic, you can pass a Maybe Keyword to something that expects a Maybe String

9:39 and it'll just fail.

9:39 at runtime.

9:39 you might be able to do static compile time checks to prevent such things, but fundamentally you must not make it *impossible*

9:40 because then the language would not be dynamic

9:40 andreas1: I don't think it is a good idea to have everything dynamic anyways.

9:40 I don

9:41 I don't see why it should be a bad idea to write a function and declare "this function takes two strings as its argument".

9:41 Chousuke: it's not a bad idea.

9:41 but you should also be able to redefine that function to take two keywords

9:41 in a static language, that's impossible.

9:42 andreas1: And I don't see why it would be less dynamic just because I get a meaningful type error at compile time or runtime when trying to call the function with something else than a string.

9:42 Plus, I don't mind when redefining the function signature at runtime is an expensive operation.

9:43 Chousuke: you (ideally) do get meaningful type errors at runtime in a dynamic language.

9:43 chouser: Clojure has pre/post conditions to help check things at runtime

9:43 _fogus: andreas1: You can get some of this using :pre and :post

9:43 chouser: :-)

9:43 _fogus: ... or what chouser said

9:43 Chousuke: tht's the point. the types are there; whether the code makes sense is determined when you actually execute it

9:43 you can't add together two strings

9:44 andreas1: I prefer if the type system automatically takes care of that.

9:44 Chousuke: unless you define the + operation for them somehow, which might be possible in a dynamic language.

9:44 chouser: And I am looking forward to the static checking that datalog may be bringing.

9:44 andreas1: chouser: datalog?

9:45 Chousuke: andreas1: it's a difference in approach

9:45 chouser: andreas1: there's a datalog lib in contrib. I don't know how far away it is from providing what I'm hoping to see...

9:46 Chousuke: andreas1: that said, dynamicism doesn't completely preclude static checking

9:46 chouser: the idea is that it could be used to make deductions and assertions about your code at compile time -- just just classic types, but whatever other assertions you which to make based on facts you provide in the code at compile time.

9:47 s/just just/not just/

9:47 andreas1: chouser: that sounds good.

9:47 * andreas1 thinks compilers should come with a full-blown theorem prover.

9:47 chouser: andreas1: I think so too, but like I said I don't know how far away it is.

9:47 _fogus: Speaking of contrib's datalog... is that actively maintained?

9:47 Chousuke: andreas1: however, I consider it important that you can just tell the compiler to shut up and let you write the code :)

9:48 andreas1: Chousuke: I second that.

9:48 spariev: hi, is there any yaml parser in clojure ?

9:48 Chousuke: andreas1: for example, with a dynamic system it's trivial to write "incomplete" systems that you *know* will fail if you execute a certain code path, simply because it's not implemented yet.

9:48 andreas1: it's very nice for incremental development.

9:48 chouser: ~google java yaml

9:48 clojurebot: First, out of 187000 results is:

9:48 JYaml - Yaml library for the Java language

9:48 http://jyaml.sourceforge.net/

9:48 andreas1: I have that pet theory that the difference between static and dynamic languages is that the former throw errors at compile time, and the latter throw warnings and introduce runtime type checks.

9:49 chouser: spariev: there you go!

9:49 andreas1: Chousuke: Yes, but when I'm done hacking, I want to be able to tidy up the code and make it run fast.

9:49 Chousuke: Without having to rewrite it all in a different language.

9:49 Chousuke: andreas1: sure, and a dynamic system can allow that.

9:50 chouser: andreas1: Clojure does some interesting things to get performance out of dynamic code, esp. post-1.1

9:50 andreas1: Chousuke: I'm coming from a Dylan background, which does have such a dynamic system. :)

9:50 spariev: chouser: thanks, I know about jyaml, I just thought there are exist pure clojure lib

9:51 chouser: spariev: oh, I see. I don't know of one, but I would recommend embracing Java libs that get the job done. :-)

9:51 andreas1: chouser: I hope you're not referring to defprotocol here...

9:52 Chousuke: andreas1: I just think that you don't need static checking to get faster code :)

9:52 andreas1: Chousuke: Let me give you an example.

9:53 chouser: andreas1: hm, don't you like defprotocol? :-) I was referring to the keyword call-site caching stuff.

9:53 andreas1: In Dylan, the for loop is a macro.

9:54 Chousuke: in Dylan, the FOR loop is a macro.

9:54 You write 'for (i in collection) do-something(i); end;'

9:55 The macro expands into a call to a multimethod, that returns a number of functions to iterate across the collection.

9:55 A local function with tail recursion is used to implement the loop, and the functions are called to do the iteration.

9:56 Now if the compiler happens to know that 'collection' is, say, a vector, it can resolve the multimethod call.

9:56 It can then inline the call to the specific method for vectors.

9:57 Chousuke: right.

9:57 andreas1: It can then inline all the functions that make up the iteration protocol.

9:57 Tail recursion removal kicks in, too.

9:57 Chousuke: the JVM does stuff like that at runtime :)

9:57 andreas1: In the end, a whopping 4 assembler instructions are emitted.

9:57 An init, an increment, a compare and a branch.

9:58 chouser: Mmmm. That does indeed sound like some good engineering.

9:58 Chousuke: it can notice that 99% of the objects passed to a certain function are of a certain type, and inline code based on that.

9:58 chouser: If you later pass in something that's not a vector, does it drop back to a slow path?

9:59 andreas1: chouser: You make a promise at compile time that this will always be a vector.

9:59 chouser: ah, so not dynamic anymore.

9:59 andreas1: No.

9:59 Chousuke: the JVM? As far as I know, yes.

9:59 chouser: right, so that's one interesting trade-off.

9:59 Chousuke: the fun thing is, the type check should be free

9:59 andreas1: chouser: If you have the compiler at run time, you might be able to do stuff like that dynamically.

10:00 Chousuke: because of weird out-of-order processor black magic

10:00 chouser: Chousuke: right

10:00 free. amazing.

10:00 andreas1: chouser: exactly. I can write dynamic code for my experimental hacking, and then when I'm down with it, I sprinkle a couple of type declarations over my code, and it becomes fast.

10:01 chouser: andreas1: sure, but I meant a trade-off between dynamic-to-the-end (with as much speed as possible) vs. speed via staticness

10:02 Chousuke: chouser: I don't claim to understand the details, but I think it in essence executes both codepaths simultaneously and just throws out the one that fails :P

10:02 chouser: black magic.

10:02 chouser: andreas1: anyway, my main purpose is not to convince you of anything, but I want to make sure you at least have correct facts about Clojure on which to base your conclusions. :-)

10:03 andreas1: chouser: This is well appreciated.

10:03 chouser: Clojure does have some things (sprecifically primitive locals) that cannot hold nil, and the compiler even does some of that checking at compile time.

10:04 Chousuke: you also get compile-time checks for tail-recursion

10:04 which is fun.

10:05 chouser: Clojure can be aware of the (host vm) types of things at compile time, and make very simple deductions (not sure I would call it "inference") based on those.

10:06 Chousuke: Also why I think recur should stay even if the JVM gains a TCO guarantee. And maybe for mutual recursion you could have a (recur-at somefn args)

10:06 chouser: Clojure does allow you to define objects (via proxy and now reify) that inherit implementation from host vm classes.

10:06 andreas1: I keep reading "host vm". :)

10:07 chouser: but having said that Clojure does not encourage implementation in heritence (I think rhickey considers it a misfeature) and instead encourages more of mixin approach

10:07 andreas1: yes you do. :-)

10:07 Chousuke: andreas1: There are two implementations of Clojure on two different hosts. :)

10:08 chouser: Three if you count JavaScript. Which I don't. So 2.

10:08 Chousuke: That said, Clojure on the JVM is the "standard" and ClojureCLR just tries to look like it as much as possible.

10:08 andreas1: I'm just saying that it is cheating to point to the host VM for features that I feel missing in a language.

10:08 chouser: no! not cheating!

10:08 andreas1: Especially if there are multiple.

10:08 Chousuke: Well, Clojure is very tightly bound to the host

10:09 chouser: ...whichever host you happen to choose. :-)

10:09 Chousuke: That might become less true as things advance, but right now ClojureCLR and ClojureJVM are quite separate entities

10:10 andreas1: And if I got my terminology right, "mixins" do have implementation inheritance.

10:10 The thing without implementation inheritance is "interface".

10:10 chouser: it's really a lovely idea. Maybe one day someone will create a vm designed specifically for running Clojure code, but I have a hard time believing it will be able to compete with other broader vms

10:10 andreas1: I just don't see why you wouldn't have all your language features specified independently of the host vm.

10:11 Chousuke: andreas1: well, you could. but some of those features could be a really bad fit for the host

10:11 chouser: andreas1: "mixin" may not be quite the right word. when you extend a protocol, you can reuse existing functions or groups of functions.

10:11 Chousuke: so you'd have to implement all kinds of workarounds and you'd lose the "seamlessness" that clojure provides.

10:12 That's the reason strings don't have metadata, among other things

10:12 andreas1: I *was* wondering about that.

10:13 And I haven't made up my mind about metadata yet.

10:13 Chousuke: The tight interop is sometimes limiting, but it's still a feature. :)

10:15 chouser: I do think the JVM is probably the single biggest drawback to Clojure, as well as one of its most important features.

10:16 andreas1: Hm. You probably have a point there.

10:16 The thing that attracts me ATM is the new approach towards concurrency.

10:17 chouser: but as yet unconvinced about the persistent collections?

10:18 andreas1: Still unconvinced. The transient thing might be the right solution, I need to meditate about that.

10:18 I know why persistent collections are required to make concurrency work.

10:18 Chousuke: transients are just a performance optimisation for a very specific use case, though.

10:18 chouser: what about immutable locals? How does that sit with you?

10:18 andreas1: However, sometimes I don't need concurrency, but fast mutable vectors.

10:19 Again, Dijkstra's algorithm comes to mind.

10:19 chouser: andreas1: Java has a nice suite of mutable collection types that are handy to use.

10:20 andreas1: chouser: from a language designer perspective, that's considered cheating.

10:20 Akin to "if you want performance, use assembler".

10:20 chouser: but from a language user's perspective, it's fantastic.

10:20 nono, they interoperate quite nicely

10:20 datka: dropping to java is much different from dropping to assembler

10:20 chouser: ,(for [x (java.util.ArrayList. [1 2 3])] (+ 10 x))

10:20 clojurebot: (11 12 13)

10:20 andreas1: Immutable locals... I don't see why they are needed yet. SSA transformation does exist.

10:21 So, why isn't there a mutable array in Clojure that's *implemented* using a Java vector?

10:21 chouser: that's clojure's lazy-seq-generating 'for' macro walking through a mutable Java ArrayList

10:21 andreas1: why bother?

10:21 Chousuke: andreas1: what would that win you over just using the java vector? :/

10:21 andreas1: Chousuke: consistency?

10:22 Chousuke: in which way?

10:22 andreas1: No need to touch my code when porting to ClojureCLR?

10:22 chouser: ah, well. That's a whole different feature set that Clojure does not attempt to provide

10:22 Chousuke: the thing is, you couldn't allow the java things to use conj etc. because then they could get mixed with persistent collections

10:23 chouser: Clojure JVM helps you port between Windows/Mac/Linux, but what language lets you port between JVM and CLR? Certainly not Dylan...

10:23 Chousuke: which is not acceptable. :)

10:23 chouser: Common Lisp implementations perhaps.

10:23 chouser: Chousuke: hm, perhaps. Good point.

10:24 andreas1: In theory, I could write Dylan backends for both JVM and CLR. In practice... well... me and which army? :)

10:24 Chousuke: providing you don't use threading or anything nonportable :P

10:24 andreas1: Scheme should run on both VMs.

10:24 chouser: andreas1: right. :-/

10:25 andreas1: Ok, folks, I'm going to get lunch. Has been nice talking to you, thanks for all the information.

10:25 chouser: same applies to Clojure of course. How much effort do we want to put into rewriting mutable vectors in pure Clojure compared to getting more advanced concurrency features. or whatever.

10:25 andreas1: thanks for dropping by :-)

10:26 andreas1: I try to kick my ass intro writing a decent blog entry on all this.

10:26 Chousuke: andreas1: you could try specifying a protocol for mutable things and then implementing it on both ClojureCLR and Clojure :)

10:27 andreas1: Chousuke: Yeah, something like that. Introduce mutability into Clojure!

10:27 Chousuke: and watch as people run away from you

10:27 * andreas1 looks into rhickey's general direction and puts on his asbestos underwear. :)

10:28 andreas1: Well, one day there will be a language that's close to perfect. And Clojure explores an important point in the design space.

10:28 Anyways, cu all!

10:36 AWizzArd: I just read some parts of this discussion static vs. dynamic. One thing that I would like is optional static typing.

10:36 * ordnungswidrig always thought lisp actually was close to perfect.

10:37 AWizzArd: The typing system can spit out all info about the problems it finds. And the developer can decide how many of these warnings he/she wants to remove. This could end up in a completely statically typed program, or there could be no change at all.

10:37 Chousuke: lisp can be anything :/

10:37 it's so malleable

10:37 ordnungswidrig: AWizzArd: hmmm, static typing plus persistence sounds a lot like haskell. You'll be soon in higher-order-type hell :)

10:38 _fogus: AWizzArd: Have you looked at Qi?

10:38 AWizzArd: _fogus: yes

10:39 _fogus: Is that along the lines of what you're talking about?

10:39 AWizzArd: I was thinking about something like that: http://groups.google.com/group/clojure/browse_frm/thread/7a48f48e4b197a15/9538dbdb1549f1c6?tvc=1&q=thieme+#9538dbdb1549f1c6

10:41 One interesting alternative could be to extend an already existing bug detector with the necessary capabilities to do full optional static type checking of Clojure programs. FindBugs (http://findbugs.sourceforge.net/) could be such a plattform.

10:42 This can (over time) become more integrated into the different IDEs, by using the API to analyse Clojure code.

10:55 jcromartie: Is this really necessary when using Enlive, currently? (:refer-clojure :exclude [empty complement])

10:55 it seems like a straightforwardly bad design

10:55 like it would be better for enlive to specify its own empty and complement fns explicitly rather than making me dance around their redefinitions

11:05 Chousuke: jcromartie: don't :use enlive :)

11:05 jcromartie: oh?

11:05 Chousuke: you should use :require instead, so you can specify an alias for enlive

11:05 then you can type (en/empty ...)

11:06 jcromartie: oh sorry I thought you were saying "don't use enlive" (sans ":")

11:06 :)

11:06 yeah that makes sense

11:07 Chousuke: it's a bit more typing, but should be worth it in the long run

11:08 I think it's also possible to import functions and rename them, but I don't remember the syntax for that.

11:08 jcromartie: yeah, I guess I was just considering repl use

11:08 I usually just launch a repl and (use ...)

11:09 then I stick things in source files when they work well enough

11:09 by the way, rlwrap is a real gem of an tool

11:09 Chousuke: heh.

11:09 you could write a custom import macro and put it in user.clj :P

11:10 (import-rename-conflicts ...)

11:20 Hali_303: hi! How to test that a function returns true on all element of a list?

11:20 something like "forall"

11:21 cgrand: jcromartie: enlive doesn't clash with clojure

11:21 jcromartie: yeah, sorry to badmouth your lib :P I am still getting my head around the idiomatic way to import libs in different cases

11:22 I assume that it's fine to (:use net.cgrand.enlive-html) in an ns in a source file

11:22 as long as I don't use empty or complement

11:22 (and then I can just specify which one I want)

11:22 cgrand: what's the problem with empty and complement? Which version are you using?

11:23 :use (without :only) of any library is strongly discouraged except at the REPL

11:24 Chousuke: Hali_303: "every?"

11:25 Hali_303: Chousuke: thanks :)

12:13 osirisx11: hi

12:13 i want to use a clojure program but it is in source form only, clojure looks interesting but i don't have the time to learn it right now

12:14 please, can anyone tell me how i can compile this code? http://github.com/esessoms/gvgw/blob/master/

12:14 http://github.com/esessoms/gvgw

12:15 r2q2: http://github.com/zitterbewegung/blank-appengine-clj <- I made a blank slate for people to start with google app engine

12:17 osirisx11: thank you r2q2

12:17 datka: If you can get a repl with the src/ in your classpath, you could (require 'com.nubgames.gvgw)

12:17 r2q2: no problem

12:17 i think there might be mistakes i will test it

12:18 but basically its just following a blog post I believe it requires gae 1.2.0

12:18 somnium: arent they on 1.3 now?

12:18 r2q2: yea thats the point alot of the blog posts are from 1.2.x not 1.3

12:18 *point/problem

12:19 osirisx11: datka: i appreciate your help, i am a very skilled web dev and i know lots of languages, but clojure is not one of them (yet), can you please provide me specific instructions on how i can compile?

12:19 datka: It's unfortunate that this project doesn't include a build file

12:20 osirisx11: it can't be inferred based on the libs and the clj files?

12:20 r2q2: somnium: I'm not sure if it actually works with 1.3 though

12:21 Hali_303: two questions: 1. how to evaluate if a list contains only unique elements? 2. how to tell if a function returns true on at least one element of a list?

12:22 somnium: r2q2: Ive been using 1.3 with no problems, though I hardly touch the sdk tbh, so no idea :)

12:22 r2q2: somnium: Okay maybe its my incompetence then.

12:23 _fogus: Hali_303: For #2, look at some

12:23 ,(doc some)

12:23 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)"

12:24 somnium: Hali_303: for #1, you could try (= (count coll) (count (distinct coll)))

12:25 _fogus: Hali_303: And for #1, sets always contain unique values.

12:25 datka: osirisx11: If you look at http://clojure.org/getting_started it gives you the line to start a repl, add the dirs for the libs and src to the classpath (after the -cp)

12:25 osirisx11: thanks

12:26 datka: There are many other ways of starting clojure, but that's just one way

12:27 osirisx11: i installed a binary package on my ubuntu 9.10

12:27 datka: you could probably steal one of the build.xml or pom.xml files from another project if you wanted it compiled to a jar

12:27 osirisx11: so i don't know if referencing the jar will work

12:27 ok

12:27 thanks

12:27 i have one handy from enlive

12:28 Hali_303: _fogus: somnium: thank you

12:29 osirisx11: wow that worked great!

12:29 all i did was a replace from enlive to gvgw and ran ant

12:30 umm ant is complaining it can't find clojure.jar yet it also said build successful and output my jar files

12:31 r2q2: i hate ant :-(

12:31 jcromartie: I'm happy to have some shell scripts to handle my builds right now.

12:32 my stuff is simple

12:32 osirisx11: Exception in thread "main" java.lang.NoClassDefFoundError: //gvgw/jar Caused by: java.lang.ClassNotFoundException: ..gvgw.jar

12:32 jcromartie: env vars to handle dependencies

12:32 osirisx11: so i guess it didn't compile?

12:33 jcromartie: let me take a crack at it on my system

12:34 osirisx11: how do you intend to use this without using Clojure itself?

12:34 it doesn't export any classes as far as I can tell

12:35 it looks like it is only intended to be used from a Clojure lib/repl as it is

12:37 osirisx11: jcromartie: i did install the packages for it, which also includes clojure.jar in /usr/share/java

12:37 jcromartie: osirisx11: yeah, but I mean what are you going to do with a clojure lib that has no Java interface?

12:37 or does it run by itself

12:37 osirisx11: thanks jcromartie, i have no clue about repls

12:37 i have no clue about this project either

12:38 jcromartie: k

12:38 well let's ee

12:38 see

12:38 osirisx11: thanks jcromartie

12:38 i'm a great programmer in other langs, but clojure and scheme is totally new to me

12:38 jcromartie: it looks like it has a main so you can in fact run it by itself

12:39 osirisx11: james@james-desktop:~/projects/gvgw$ clojure src/com/nubgames/gvgw/main.clj

12:39 Exception in thread "main" java.lang.Exception: Unable to resolve symbol: defn- in this context (main.clj:7)

12:39 am i doing it right?

12:39 jcromartie: that's not good

12:40 defn- is part of clojure.core

12:40 osirisx11: lol

12:40 jcromartie: what's your script for starting gvgw?

12:40 osirisx11: just what i pasted

12:40 jcromartie: so what's clojure?

12:40 the command?

12:42 osirisx11: jcromartie: http://pastebin.ca/1756301

12:42 i also have the jar in /usr/share/java/clojure.jar

12:44 jcromartie: oh that's new to me I didn't know there was an official clojure command :)

12:44 where is that from?

12:45 r2q2: when i use clojars

12:45 i feel like im in a spongebob squarepants movie

12:45 jcromartie: hah, what?

12:45 r2q2: look at the errors when you do something wrong

12:46 Blistering barnacles! Something's not shipshape:

12:46 Password can't be blank

12:46 jcromartie: osirisx11: I was assuming clojure was a custom shell script or something

12:46 r2q2: Password: Hunter1

12:46 jcromartie: that's hilarious

12:46 osirisx11: jcromartie: it came when i did apt-get install clojure

12:46 jcromartie: ah, fancy dancy apt user

12:47 nice stuff though

12:47 osirisx11: *shrug* everyone's got their flavor

12:47 jcromartie: so clojure.jar should already be somewhere

12:47 osirisx11: yes, as i said, /usr/share/java

12:47 i do appreciate your help

12:48 jcromartie: when you just run clojure, do you get a prompt?

12:48 you should be able to type defn- and hit enter and get some sort of message

12:48 other than a missing symbol error

12:49 "Can't take value of a macro" would be good

12:49 otherwise there's something seriously messed up

12:49 osirisx11: yes i got that can't take a value of a macro at the clojure prompt

12:50 wow i didn't think this would be so hard to compile a clojure app

12:50 r2q2: osirisx11: Its industrial strength

12:50 osirisx11: what happened to good ol' ./configure make make install?

12:50 r2q2: osirisx11: Try out incanter

12:50 osirisx11: I mean lein

12:51 osirisx11: Much easier than ant in my opinion

12:51 datka: osirisx11: in this case, there's no "makefile" that's the only reason it's so hard

12:51 osirisx11: datka: i made one

12:51 still won't compile...hmm

12:51 jcromartie: osirisx11: you generally don't just compile a clojure app

12:52 osirisx11: oh, well i'm okay with just running it

12:52 or however

12:52 jcromartie: yah

12:52 osirisx11: but idk how to do that either

12:52 lol

12:53 jcromartie: OK so the deal with this gvgw is that you need to put all of its dependencies on the classpath

12:53 that's lib/*.jar

12:53 and more, elive too

12:53 enlive

12:54 osirisx11: ya i have a lib folder

12:54 jcromartie: this project is not quite ready for prime time when it comes to being runnable

12:54 osirisx11: i fixed enlive, everything is good on libs

12:54 jcromartie: ok cool

12:54 hiredman: I would ditch whatever script you are using to launch clojure

12:54 osirisx11: is there not a one liner to start this sucker?

12:54 jcromartie: apparently not

12:54 osirisx11: java -cp clojure.jar clojure.main gvgw something?

12:54 hiredman: osirisx11: yes

12:55 osirisx11: what is that?

12:55 hiredman: but you also need any other required jars in the classpath

12:55 -cp clojure.jar:whatever.jar

12:55 osirisx11: it's in the lib folder there

12:55 ok

12:55 i can't just reference the one folder huh

12:55 hiredman: nope

12:56 clojurebot: simple?

12:56 gah

12:56 datka: blame java, not clojure for that one

12:56 hiredman: clojurebot: ping?

12:56 clojurebot: PONG!

12:56 hiredman: clojurebot: dirt simple

12:56 r2q2: yay pushed to clojars

12:56 hiredman: gar

12:57 osirisx11: i'm giving up

12:57 hiredman: clojurebot: how much do you know?

12:57 clojurebot: I know 528 things

12:57 r2q2: clojurebot: I <3 you

12:57 hiredman: http://www.thelastcitadel.com/dirt-simple-clojure

12:58 clojurebot: dirt simple setup is http://www.thelastcitadel.com/dirt-simple-clojure

12:58 clojurebot: Ack. Ack.

12:58 hiredman: clojurebot: dirt simple setup?

12:58 jcromartie: OK I got it running

12:58 clojurebot: dirt simple setup is http://www.thelastcitadel.com/dirt-simple-clojure

12:59 jcromartie: incoming Gist in a few

12:59 http://gist.github.com/280232

13:00 OK that script will put together a classpath with all of the jars in lib/ and then start a repl

13:00 osirisx11: thanks hiredman, why are they skipping step VII?

13:00 jcromartie: at which point you can load gvgw

13:00 osirisx11: thanks guys

13:00 Raynes: Gist incoming!! Take your positions! FIRE!

13:00 hiredman: osirisx11: don't worry about it

13:01 jcromartie: osirisx11: I must admit this is way more work than most languages

13:01 but I've gotten my clj down to irb simplicity

13:01 osirisx11: i blame java for most of it

13:01 jcromartie: indeed

13:01 the classpath

13:02 osirisx11: yeah

13:02 java is so bloated and falling over itself

13:02 jcromartie: but it is supposed to be finer-grained control over what you load

13:02 and java is not supposed to be used for small utilities

13:02 osirisx11: so many ways to do things in java, and most of them are not the Right way

13:02 jcromartie: eh, I don't think that's really the case

13:03 the way to run a Java program is to specify where to find the classes in $CLASSPATH and specify the main class

13:03 ajazz: hello, how can I change *default-encoding* in clojure.contrib.duck-streams (http://bit.ly/7kZ3Fy)?

13:03 jcromartie: that's it really

13:03 osirisx11: rlwrap not found

13:04 jcromartie: oh, I use rlwrap

13:04 you should install it :)

13:04 osirisx11: just installed it

13:04 jcromartie: it makes things without readline much more pleasant to interact with

13:04 osirisx11: now getting Classnotfound on clojure.lang.Repl

13:04 lol

13:04 hiredman: osirisx11: use the dirt simple setup

13:04 osirisx11: i should forget the binary install from ubuntu repos i think

13:04 ok thanks hiredman

13:04 hiredman: it does not advocate using deprecated classes

13:05 jcromartie: oh?

13:05 hiredman: like Repl and SCript

13:05 osirisx11: any idea why they skip VII?

13:05 jcromartie: I didn't know those were deprecated

13:05 hiredman: they are

13:05 jcromartie: osirisx11: VII is for older JVMs

13:05 hiredman: clojure.main is better and has been around forever now

13:05 jcromartie: ah

13:05 man

13:05 the docs are all over the place out tehre

13:05 there

13:05 hiredman: this is why I said ditch the script

13:05 jcromartie: not the official docs

13:06 alexyk: I reduce a lazy seq, dumping intermediate results every N elements. I need to dump the remainder as well. One way to do it is to append a terminating element to the seq. How is it done so laziness is preserved? The seq is coming from a database...

13:07 Chousuke: concat is lazy

13:07 alexyk: Chousuke: how about conj?

13:07 osirisx11: oh man i am running open source java

13:07 i should be using the sun version, shouldn't i?

13:07 hiredman: openjdk is fine

13:07 osirisx11: ok cool

13:07 hiredman: gcj is not

13:07 Chousuke: alexyk: that one's not.

13:07 alexyk: ok

13:07 Chousuke: alexyk: but you can do (concat yourseq [terminator])

13:08 alexyk: good, thx

13:08 osirisx11: well the version num isn't matching for this dirt simple instructions though.. what is java ver 7.4 for openjdk?

13:08 hiredman: osirisx11: what does java -version say?

13:09 osirisx11: doh.. i..had a typo.. i'm at 1.6.. i'll keep following dirt simple

13:10 i've been up all night heh

13:13 bah

13:13 i can't get this

13:13 anyone looking for a small closure side job? :D

13:13 i'll paypal

13:15 jcromartie: you're not far off

13:15 it's just a matter of getting all of the jars on the classpath and then loading the lib and running (main)

13:16 do you have all of the Postgres stuff set up?

13:17 osirisx11: i dont have time to learn and do all this stuff

13:17 i do appreciate all the help, everyone

13:18 jcromartie: sure

13:18 osirisx11: but i am giving up on it for now

13:18 if anyone wants to help me for pay, pm me

13:20 lypanov: starbucks? :D :P

13:22 wilig: technomancy: http://github.com/wilig/swank-clojure

13:23 technomancy: wilig: excellent! I'll try to merge that in later today.

13:24 wilig: let me know how it works for ya. And code pointers would be graciously received. :-)

13:25 technomancy: sure thing

13:32 * technomancy is considering enabling whitespace-mode by default in the next version of clojure-mode just so some people will realize how sloppy the code they're writing is. =P

13:34 lypanov: do it.

13:34 end of line spacing or just general style complaints?

13:34 * lypanov googles

13:35 Raynes: How would I zip two sequences together?

13:35 chouser: technomancy: I sympathize. :-)

13:35 lypanov: technomancy: my coworkers would hate you. i would love ya.

13:35 well, first they will hate me, when i tell them we're switching from ruby to clojure.

13:35 Raynes: Like (zip [1 2 3] [4 5 6]) should yield (1 4 2 5 3 6).

13:35 lypanov: :))

13:35 chouser: ,(interleave [1 2 3] [4 5 6])

13:35 clojurebot: (1 4 2 5 3 6)

13:36 Raynes: That'll do it.

13:36 Thanks.

13:36 * jcromartie is having fun with finding keys present or not present in a map

13:36 chouser: np

13:36 jcromartie: ,(let [required [:foo :bar] x {:foo 1}] (every? x required))

13:36 clojurebot: false

13:37 jcromartie: ,(let [required [:foo :bar] x {:foo 1}] (filter (fn [k] (not (x k))) required))

13:37 clojurebot: (:bar)

13:37 jcromartie: handy for web parameters :)

13:45 lypanov: yo LauJensen

13:45 LauJensen: Hey heey

13:45 lypanov: LauJensen: /me has arch running on his ibook now

13:45 * lypanov blames you completely

13:46 technomancy: lypanov: mostly trailing whitespace and extra-long lines

13:46 also mixing tabs and spaces

13:46 lypanov: all evil. i'd say enable.

13:47 technomancy: lypanov: http://www.emacswiki.org/pics/static/TabsSpacesBoth.png

13:47 LauJensen: lypanov: So are we enemies now, or are you liking it? :)

13:47 the-kenny: I thinkg highlight80+ should be enabled by default

13:48 s/kg/k/

13:49 LauJensen: highlight 80+ is nice, but should it be 100 nowadays? :)

13:49 the-kenny: I use 80

13:50 Maybe 100 is fine too

13:50 LauJensen: I remember trying to enforce the 80c rule on a PHP team once, they objected strongly because of SQL statements... of course ClojureQL fixes that for us

13:51 chouser: 80

13:51 hiredman: typographically speaking the optiminal characters per line is somewhere around 60, so 80 splits the difference with 100

13:51 the-kenny: It's almost impossible to enforce the 80 rule with Java or so. But it's really easy in Lisp, in my opinion

13:52 LauJensen: Also very doable in ASM

13:52 the-kenny: heh

13:54 lypanov: LauJensen: loving it. excellent distro.

13:54 LauJensen: Glad to hear it :)

13:54 lypanov: didn't get any time whatsoever to play with clojure itself though yet.

13:54 ppc archlinux isn't quite as easy as x86

13:55 LauJensen: Takes about 2 minz to install though

13:55 technomancy: with 80 cols you can have two side-by-side windows on a reasonably-sized laptop without squinting

13:55 lypanov: LauJensen: totalled 6 hours yesterday for me.

13:55 LauJensen: oh... I spoke to soon :)

13:55 lypanov: LauJensen: biggest complication, couldn't find a ethernet cable.

13:55 ended up setting up network sharing via firewire.

13:55 chouser: technomancy: exactly

13:55 lypanov: trivial in the end.

13:56 second complication, i installed twice. first time i missed out the "mount your partitions step"... reboot. and blank drives. everything was in the unionfs ;)

13:56 LauJensen: hehe

13:56 * lypanov blames his 9% beer

13:56 Licenser: I don't really see the reason for the 80c rule any more, screens are so big that it often is totally annoying if code only uses 1/3rd of it - at least to me

13:57 chouser: I suppose an editor with sufficiently smart wrap/autoindent functionality could eliminate the need for width restrictions, but I've never seen such a thing.

13:57 hiredman: Licenser: the point is you have multiple columns of code

13:57 technomancy: Licenser: you want to carry a 23-inch monitor with you on the subway? =)

13:58 Licenser: technomancy: I mostly use 25" ones for the subway, the 23" screens are not handy to beat people of the chairs with

13:58 LauJensen: chouser: Wouldn't be too tricky to do in Emacs

13:58 Licenser: they just don't pack the punch

13:58 technomancy: hehe

13:58 Licenser: hiredman: but why 80c then and not 'whatever fits your screen best'

13:59 hiredman: Licenser: because everyones screen is different

13:59 if you know everything is going to be 80 columns you can adjust your setup until you get a nice fit for 80 columns

14:00 two, three, or four side by side

14:00 lypanov: agreed

14:01 i do prefer 100ish though.

14:05 * lypanov wants to start on his clojure -> java ->(gwt)-> js project already

14:06 lypanov: LauJensen: and now, together with using awesome as my wm, i no longer need anything other than a netbook..

14:07 * lypanov wonders if he can realistically run mongodb / emacs / mysql / clojure / 264 decoderon a 3gb machine

14:07 jcromartie: I downloaded clojure-1.1.0 and when I run it I get Clojure 1.0.0-

14:08 hiredman: where did you download it from

14:08 jcromartie: clojure.org

14:09 hmm, apparently it comes with a 1.0.0 jar

14:09 running ant results in a 1.1.0 jar

14:09 lypanov: oops

14:10 hiredman: jcromartie: works for me

14:10 where on clojure.org?

14:10 how did you start clojure?

14:10 jcromartie: or rather http://code.google.com/p/clojure/downloads/list

14:10 hiredman: do you have a different clojure.jar on your classpath?

14:10 jcromartie: started with java -cp and the path to clojure.jar

14:10 perhaps

14:11 hmm, no, no $CLASSPATH

14:11 I'm setting up clojure on a server

14:11 hiredman: I grabbed the zip and the clojure.jar inside is 1.1.0

14:11 jcromartie: hmm weird

14:12 not sure what happened then

14:12 lypanov: evil proxy conspiring against you!

14:13 konr: What was the list-length function called?

14:13 jcromartie: count

14:13 konr: jcromartie: thanks!

14:14 jcromartie: yay I'm good for something!

14:15 konr: haha

14:34 Hali_303: how to launch REPL giving it a directory of Java classes that I can import in REPL?

14:34 the-kenny: Hali_303: Read about the classpath

14:34 (java -cp)

14:35 Hali_303: the-kenny: thanks

14:36 * lypanov suggests using leiningen, much easier

14:36 * the-kenny supports this suggestion

14:36 the-kenny: Leiningen is just awesome

14:39 mitchellh: Hali_303: Here is a simple bash script if you need something quick and fast: http://gist.github.com/280294

14:39 oh wait dead link one sec

14:40 Hali_303: http://gist.github.com/280295

14:42 the-kenny: You can also use M-x swank-clojure-project if you're using emacs

14:43 LauJensen: ~swank-clojure

14:54 wooby: anyone recall off hand that function that returns a swing window showing a value's structure?

14:58 mabes: wooby: you mean clojure.inspector? http://richhickey.github.com/clojure/clojure.inspector-api.html

14:58 wooby: mabes: exactly what i was looking for, thank you

15:00 mabes: np

15:09 Hali_303: I'm using the maven goal clojure:repl, however, if I specify a replScript parameter, maven exists after running the script instead of starting the REPL, any idea on this?

15:12 alexyk: can I "break" out of a reduce on a condition inside fn?

15:13 I mean I can feed it pairs (keepgoing,realval) and eff with the keepgoing global from within fn...

15:14 but then FPistas will ostracize me

15:14 ynniv: the idea of "break" is not functional

15:14 thats why clojure has lazy sequences

15:15 you keep processing them until you've had enough

15:15 thats kind of like "break"

15:15 alexyk: ynniv: use case. reduce wrks with a humongous seq of days. Test runs must be limited to N days. In advance, we don't know how much of a seq to take.

15:15 the-kenny: This reminds me a bit of monads

15:15 ynniv: alexyk: yeah... there's no way to force something like that to break

15:15 alexyk: Or, how do we tell reduce it had enough when the fn sees a terminating case inside an element?

15:16 ynniv: see, FP dogma breaks.

15:16 ynniv: yes, it does... thats why most useful systems aren't only FP :)

15:16 LauJensen: alexyk: if you saw my Reddit Scraper it kinda breaks :)

15:17 alexyk: LauJensen: didn't see it, how do you solve this?

15:17 ynniv: I would write your own reduce that checks the time after each iteration and stops appropriately

15:17 LauJensen: http://www.bestinclass.dk/index.php/2010/01/hadoop-feeding-reddit-to-hadoop/

15:17 alexyk: Have a look, the code is posted there

15:17 ynniv: the other method is to dispatch to a thread and kill it if it times out

15:18 alexyk: LauJensen: ok

15:18 ynniv: killing things is overkill, I'd prefer a zen approach :)

15:19 ynniv: hmm, i kind of think that killing the thread is more zen...

15:19 its certainly more FP-like than a break equiv

15:19 Chousuke: alexyk: you might try a hybrid approach

15:20 alexyk: write a reduce-some function tht reduces a subseq of the sequence, then returns the result and the rest of the sequence

15:20 alexyk: then use that in a procedure that determines whether it should keep going.

15:20 Raynes: I has parseded XML in Clojurez.

15:21 Chousuke: alexyk: the point is not to avoid side-effects, but to keep them clearly separated from functional code :)

15:21 or well, the point IS to avoid side-effects, but you can't always do that :P

15:22 ynniv: Chousuke: yes, knowing exactly where side effects happen is important

15:22 alexyk: Chousuke: promising. So I have a predicate (day twit) which tells me which day is this twit from. Upon the day change, a summary stats must be run; also the thing must be limitable to N days, and the end of sequence must force day change anyways. Indeed it looks like it needs a special-case reduce.

15:23 hiredman: how do I locate source for reduce again?

15:24 i.e. reduce must do take-while on the seq

15:24 Chousuke: if you want to do it the quick and lazy way, then (defn reduce-some [seq n] [(reduce (take n seq)) (drop n seq)])

15:24 alexyk: Chousuke: day is hidden inside elements, so I can't know n in advance

15:25 I can break them as soon as I fetch them

15:25 but I fetch them lazily from mongodb

15:25 Chousuke: does it matter if you reduce a bit too much? :/

15:25 i guess you could just use take-while and drop-while instead

15:25 alexyk: Chousuke: it matters as each day is about 2M twits and I want tests to run fast.

15:26 hiredman: you could, you know, *not* use reduce if what you are doing is not what reduce does

15:26 Chousuke: alexyk: well, if you do the reducing in chunks of 1000, it's not going to be that bad.

15:26 hiredman: I really don't know why you keep insisting on a round peg in a square hole

15:27 Chousuke: hiredman: isn't collecting stats from a sequence fundamentally a reduction? :P

15:27 alexyk: hiredman: I do everything with map and reduce :) But I guess this is the case where a special-case function with recur and accumulator may be just what the Dr. ordered

15:27 hiredman: Chousuke: but if what he wants to do does match what reduce does (early termination) why shoe horn it into reduce?

15:28 Chousuke: well, the early termination is handled with take-while and drop-while I guess.

15:29 alexyk: I'd have to change the condition for -while's, so reduce would be driven by a manager anyways

15:35 jcromartie: should I be able to access a var defined in another namespace?

15:35 ynniv: alexyk: (use 'clojure.contrib.repl-utils) (source reduce)

15:35 jcromartie: like if I have a lib, foo, with foo.clj doing (def *bar* :whatever)

15:35 chouser: jcromartie: only if you're 'use'd or 'require'd that namespace

15:35 jcromartie: hmm

15:35 alexyk: ynniv: thx

15:36 the-kenny: alexyk: Or in Emacs: M-.

15:36 jcromartie: tried that

15:36 the-kenny: It'll take you to the source of the function in Emacs

15:36 jcromartie: I have foo.clj and foo/access.clj

15:36 and access.clj (:require foo)

15:36 but I get "no such var" on foo/*bar*

15:37 alexyk: the-kenny: ok

15:37 Chousuke: jcromartie: are the namespaces really named like that? :p

15:37 jcromartie: no

15:38 Chousuke: if the require succeeds then it should work

15:38 you're not using any shorthand for the namespace in access.clj, are you?

15:39 jcromartie: which namespace?

15:39 in foo.clj I am doing (:use [foo.access :as access])

15:39 Chousuke: eg. if the namespace you've :required is foo.bar then you need to say foo.bar/*var*

15:40 jcromartie: hmm, no access.clj does (:require foo)

15:40 hiredman: that looks like a cyclical dependency

15:40 alexyk: what's the idiom to recur on a parameters elems depending on whether it's x & xs or not?

15:40 elems is the trailing parameter out of many

15:41 Chousuke: (if (seq elems) (recur elems) (something when no elems left))?

15:41 jcromartie: hiredman: yeah it is

15:42 hiredman: jcromartie: don't do that

15:42 jcromartie: yeah

15:42 Chousuke: heh.

15:42 jcromartie: I should let foo/access.clj handle its own refs

15:42 alexyk: Chousuke: I mean the whole idiom from breaking elems to x & xs to recur; so I'd have to do (let [[x & xs] elems ...] <ahead of your stuff)) right?

15:43 Chousuke: alexyk: ah. I guess so.

15:43 usually it's the function parameters that are structured so, though

15:43 alexyk: in ocaml/haskell I could pattern-match on top of the function body, but if I have may parame I guess I can't do that by arity...

15:44 jcromartie: I'm wondering if I shouldn't be passing around an application instance object

15:44 alexyk: Chousuke: so would I have parameters as [a b c x & xs]?

15:44 jcromartie: something like a ref with the various bits of state

15:44 that would be smart

15:44 then I can encapsulate saving and loading it, etc.

15:46 Chousuke: alexyk: hm

15:47 alexyk: Chousuke: a b c etc. are accumulators and static limits; x & xs are elems.

15:48 I.e. if the number of preceding things is fixed, can I do the breaking in the parameter list?

15:48 Chousuke: then it'd go something like (fn [a b c [x & xs]] (if (seq xs) (recur a b x xs) ...))

15:49 a b c* for the recur

15:49 alexyk: right.

15:49 Chousuke: you can also do it with let, but that's your choice

15:50 one common idiom is to have an inner function do the walking for you, so that you don't need to pass the static things to recur

15:50 alexyk: Chousuke: but when you said the fn is usually structured for x & xs, did you mean [x & xs] as above in the params?

15:51 Chousuke: and the inner is defined in a (let walker (fn [a b c [x & xs]] ... (walker a b c elems))?

15:52 Chousuke: eg (fn [a b c elems] (letfn [(dostuff [acc [x & xs]] (recur (+ a b c x acc) xs))] (dostuff 0 elems)))

15:52 alexyk: ah! letfn

15:52 Chousuke: let works too

15:53 the point is the inner function doesn't need to take the statics as parameters because it can just close over them :)

15:53 alexyk: Chousuke: so the inner sees the outer's vals

15:53 Chousuke: yes.

15:53 alexyk: and clojures over them :)

15:53 Chousuke: c:P

15:54 clojuring over a function sounds weird.

15:54 alexyk: that's a good point to ask, " do you remember what the language you're programming in is called"? :)

15:54 Chousuke: We need some new closure-like object in Clojure so that we can say that something forms a clojure.

15:55 alexyk: yeah

15:58 letfn allows, instead of a let's pair: name (fn [params] exprs), write (name [params] exprs), possibly many, and then have a body inside same [], vs let's name val pairs inside [] and then body, right?

15:58 I sense a discrepancy: (let [...] body) vs (letfn [.....])?

15:59 i.e. (letfn [.... body])?

15:59 no that's not right

16:00 Chousuke: (letfn [(fnname [args] body)*] body)

16:00 alexyk: (doc letfn) is confusing: ([fnspecs & body])

16:00 clojurebot: "([fnspecs & body]); Takes a vector of function specs and a body, and generates a set of bindings of functions to their names. All of the names are available in all of the definitions of the functions, as well as the body. fnspec ==> (fname [params*] exprs) or (fname ([params*] exprs)+)"

16:01 alexyk: ha, (doc ...) triggered clojurebot

16:01 (doc google)

16:01 clojurebot: Titim gan éirí ort.

16:01 Chousuke: that's not too weird

16:01 alexyk: ,(doc google)

16:01 clojurebot: Gabh mo leithscéal?

16:01 ynniv: don't forget that you can rebind global vars for the duration of a scope

16:01 Chousuke: fnspecs is the vector containing fns and body is the body

16:02 ynniv: so global variables aren't as "bad" in clojure as in C or java

16:02 somnium: hmm, letfn* is a special form, is there more to it than a shortcut for (let [f (fn f* ...)])?

16:02 alexyk: Chousuke: so *those* []s are the params to the letfn

16:02 scode: Hmmm. WHat would be the idiomatic equivalent of (read-line) that takes a reader rather than using *in*? (I know I can rebind *in*)

16:03 ynniv: scode: heh, i was going to suggest rebinding *in* :)

16:03 polypus: ynniv: in java there are lots of global variables, which aren't frowned upon. they're called classes :)

16:03 scode: ynniv: ;)

16:05 ynniv: polypus: well... sure. they're still messy because a different thread can access them, and if someone overwrites them temporarily they won't necessarily restore the original value at the appropriate time

16:05 but (binding [varname value] ...) does exactly this

16:05 Chousuke: binding is dangerous too, sometimes

16:06 ynniv: hmm. how so?

16:06 Chousuke: especially when laziness is involved

16:06 ,(binding [+ -] (for [x (range 10)] (+ x 5))

16:06 clojurebot: EOF while reading

16:06 Chousuke: ,(binding [+ -] (for [x (range 10)] (+ x 5)))

16:06 clojurebot: (5 6 7 8 9 10 11 12 13 14)

16:06 Chousuke: ,(binding [+ -] (doall (for [x (range 10)] (+ x 5))))

16:06 clojurebot: (5 6 7 8 9 10 11 12 13 14)

16:07 Chousuke: hmm

16:07 ynniv: heh

16:07 Chousuke: gah

16:07 somnium: I think + is inlined on 2 args :P

16:07 Chousuke: bad example again

16:07 yesh

16:07 I always forget that

16:07 ,(binding [+ -] (doall (for [x (range 10)] (+ x 6 5))))

16:07 clojurebot: (-11 -10 -9 -8 -7 -6 -5 -4 -3 -2)

16:07 Chousuke: ,(binding [+ -] (for [x (range 10)] (+ x 6 5)))

16:07 clojurebot: (11 12 13 14 15 16 17 18 19 20)

16:07 Chousuke: there.

16:07 ynniv: i see where you're going tho - if a computation is returned outside your binding, the binding won't apply when its evaluated

16:07 Chousuke: yeah

16:08 and inlining further complicates things, as it makes binding completely ineffective ;/

16:08 alexyk: can lambda fn hace a docstring?

16:09 have

16:09 Chousuke: no.

16:09 _fogus: yes

16:09 alexyk: discord!

16:09 Chousuke: not yet, anyway

16:09 since fns don't support metadata

16:09 alexyk: and those defined by letfn are plain fn's?

16:09 Chousuke: yes.

16:09 jcromartie: ooh, even better...

16:10 Chousuke: wait, wtf.

16:10 jcromartie: ,(filter (complement {:foo :bar}) [:bat :baz])

16:10 clojurebot: (:bat :baz)

16:10 * alexyk notices _fogus left right after the discord ensued

16:11 Chousuke: hm, got confused about nothing for a moment

16:11 (it wasn't about fogus leaving)

16:11 alexyk: was it a _fogus from the future where fn's have docstrings?

16:12 Chousuke: well, you can always do (def #^{:doc "somestuff"} foo (fn ...))

16:12 but that's not the fn that has a docstring :)

16:12 alexyk: nah,  a comment will do

16:13 jcromartie: is 'future' a decent general-purpose way to do something in a separate thread?

16:13 Chousuke: probably.

16:13 * hiredman uses future exclusively for that purpose

16:13 Chousuke: if you don't care about the result, just don't store a reference to the future

16:14 jcromartie: yeah

16:14 I've used things like (doto (Thread. (fn [] ...)) .start) before but it seems easier to just use future

16:14 Chousuke: that's basically what future does anyway

16:15 jcromartie: right

16:15 hiredman: future uses a threadpool

16:15 jcromartie: well then that's one more point for future

16:15 hiredman: indeed

16:18 alexyk: so in an if/when condition (boolean), (seq elems) is exactly the same as (not (empty? elems))?

16:18 * alexyk sees a threadpool in jcromartie's future

16:20 chouser: alexyk: yep

16:21 alexyk: empty? is defined at (not (seq coll)) :-)

16:21 alexyk: :)

16:25 AWizzArd: Do we have experts in Open Source licenses here?

16:25 I would like to know in very short words the differences between 1) Apache Licence 2, 2) Eclipse Public License and 3) Mozilla Public License 1.1

16:28 Chousuke: AWizzArd: wikipedia probably knows :P

16:28 janmejay: Hi, i used swank-clojure elpa install and got it working, but i can't get my old SBCL repl now. here is the error (Couldn't load "/home/janmejay/.emacs.d/elpa/slime-20091016/swank-loader.lisp": file does not exist.)

16:28 any ideas?

16:29 the-kenny: janmejay: You have to install the sbcl-swank-backend

16:29 janmejay: i tried loading autoloads file from clojure and swank-clojure from the elpa directory without package.el, which didn't work either(i was using slime HEAD)

16:29 the-kenny: with asdf

16:29 janmejay: the-kenny: from elpa?

16:29 the-kenny: no

16:29 elpa only contains emacs lisp files

16:30 you need a common lisp file with the necessary code to run swank in sbcl

16:30 AWizzArd: Chousuke: yes right :-)

16:32 janmejay: the-kenny: i have slime HEAD and i tried preloading it, and then loading clojure-mode and swank-clojure by adding directories in load-path and loading the autoload files, but that doesn't work either(all that loads in sbcl repl)

16:32 the-kenny: M-- M-x slime RET clojure RET doesn't work with that setup

16:33 the-kenny: janmejay: You need to understand that the "real" slime distribution ships with a bunch of .lisp files which contain the backend (swank) for many common lisp derivates

16:33 janmejay: The elpa-version only ships emacs-lisp files

16:33 You have to install the backend for sbcl by hand

16:34 janmejay: the-kenny: is the best way to do it is dumping it inside the elpa slime directory?

16:34 the-kenny: maybe.. but I would install it with asdf-install

16:34 asdf-install is the packet manager for common lisp

16:34 janmejay: the-kenny: sure, i let me try it using asdf

16:35 the-kenny: janmejay: http://www.cliki.net/Swank

16:36 janmejay: Everything should be in a checkout from the slime cvs

16:40 * technomancy has never been able to figure out what asdf actually is

16:40 Chousuke: technomancy: proto-skynet

16:40 ohpauleez: hahaha

16:42 alexyk: how can I have two optional parameters, like [a & b c]?

16:42 Chousuke: alexyk: you can use destructuring, but overloading on arity is more common

16:43 technomancy: if you want them to default to nil and don't mind losing arity checks, destructuring is the way to go

16:44 Chousuke: eg. (defn foo ([a] (foo a 0)) ([a b] (foo a 0 1)) ([a b c] (someop a b c)))

16:44 oops

16:45 should be (foo a b 1) in the middle and (foo a 0 1) in the first :P

16:45 alexyk: right, I have a huge body and these things are optional, so destructuring will do

16:45 but I'll remember arity, hard to divine a ( after function name! Java flashback!

16:46 Jeopardy $200 questionL in which Lisp-like language, there's an opening paren after a function name?

16:46 chouser: dylan

16:47 alexyk: chouser: am not familiar with the language dylan... is it a lisp with inverted syntax?

16:47 Chousuke: also common lisp :P

16:47 you didn't specify what it's for.

16:47 qbg: alexyk: Javascript?

16:47 Chousuke: (defun foo (a b c) ...), isn't it.

16:47 chouser: dylan is generally considered lisp like, but with more C-ish syntax. I don't know much else about it.

16:47 Chousuke: I think dylan actually has macros

16:48 alexyk: qbg: well... :)

16:48 Chousuke: but I have no idea how they're implemented.

16:49 danm_: learn to let go of syntax and be happy

16:50 somnium: javascript should stand as a warning to all who would try to 'fix' lisp's syntax

16:51 * chouser added macros to javascript.

16:52 alexyk: so if I want 3 totally optional params, I declare (defn foo [& [a b c]] ...)?

16:52 chouser: alexyk: that's one way.

16:52 arj: is there a shorter way to write (not (= X Y))?

16:52 qbg: (not= x y)

16:52 chouser: alexyk: another is (defn foo ([] (foo nil nil nil)) ([a] (foo a nil nil)) ([a b] (foo a b nil)) ...)

16:52 arj: qbg: thanks :)

16:53 alexyk: chouser: I'll stick to the first :)

16:53 chouser: alexyk: :-)

16:54 alexyk: the second may be better when you have: non-nil defaults, defaults in a different order, or need maximum speed.

16:54 alexyk: chouser: ok

16:55 chouser: alexyk: but if you just need default-to-nil in the normal order, yes destructuring is much tidier.

16:56 alexyk: I actually may need to flip order, so may come in handy

16:56 chouser: also note I said "may" -- it may also be easier to just destructure and fiddle with order or non-nil defaults. just depends

17:01 Raynes: How would I map a function to all of the values in a map?

17:02 chouser: (zipmap (keys m) (map f (vals m)))

17:02 kotarak: (zipmap (keys the-map) (map f (vals the-map)

17:02 * chouser high-fives kotarak

17:02 Raynes: Thanks. :D

17:02 kotarak: hehe :)

17:02 chouser: m was shorter. I wasted time on the-map. ;)

17:02 chouser: heh. yep.

17:05 hiredman: are keys and vals guaranteed to always return keys and values in the same order?

17:05 chouser: for the very same map, sure.

17:06 once you insert something, you have a new map with a new order

17:06 arj: has anyone seen this kind of error before? my repl gets completely filled with endless of these messages and then stops. I can't seem to see where it all starts: http://pastebin.com/m73da1552

17:06 Raynes: http://gist.github.com/280420 yayme!

17:06 chouser: since the map is immutable it would have to work pretty hard get different orderings out of it.

17:07 arj: hm, infinite recursion

17:07 hiredman: chouser: yes, but that is a by product of the implementation of map, not part of the contract of keys and vals

17:07 arj: chouser: ok, I don't really do any recursion in my code as far as I know. Maybe in some code I'm calling

17:08 any idea how I can figure out where it starts?

17:08 chouser: hiredman: I believe rhickey has said it's guaranteed

17:08 Hali_303: how to make functions cascadable? by that I mean if I have functions (test1 pred coll1) and (test2 pred coll2), how to have a "master function" that takes a predicate which is like fn [x y] (test-based-on-x-and-y) I hope you get what I mean :)

17:08 hiredman: ok

17:08 Hali_303: where x is bound to something in coll1 and y is bound to an element in coll2

17:09 rhickey: hiredman: yes, will always be same order. Not much utility otherwise

17:09 Hali_303: I mean something like a nested for loop with an if inside (in an imperative language)

17:10 rhickey: but might not be adequately documented

17:10 kotarak: Hali_303: (filter #(apply test-based-on-x-and-y %) (map vector coll1 coll2))?

17:11 chouser: Hali_303: 'for' can take multiple bindings and treat them like nested loops

17:11 ,(for [a [1 2 3], b [10 11 12]] (+ a b))

17:11 clojurebot: (11 12 13 12 13 14 13 14 15)

17:11 Chousuke: hmm

17:12 Hali_303: ah I see, thank you

17:12 kotarak: ,(filter #(apply = %) (map vector [3 2 1 0] [1 2 3 0]))

17:12 clojurebot: ([2 2] [0 0])

17:13 chouser: Hali_303: kotarak's showing you how to walk two seqs "in step" if that's what you wanted instead.

17:14 Hali_303: thank you guys, I'll try to decode that :)

17:17 Raynes: How can I get all but the last element in a sequence?

17:18 lpetit: ,(doc butlast)

17:18 clojurebot: "([coll]); Return a seq of all but the last item in coll, in linear time"

17:18 Raynes: Thanks.

17:20 kotarak: Wow. It's surprising how far you can get with excluded =, and, or, not, ...

17:22 * jcromartie learned that #compojure exists today

17:22 jcromartie: just for anybody else who might be using it

17:23 chouser: kotarak: excluded = ?

17:24 arj: are you using 'filter' in your code anywhere?

17:25 kotarak: chouser: (ns foo (refer-clojure :exclude (= not= < <= > >= not and or nil?))) And didn't have to change a line in ca. 80 lines of code.

17:25 chouser: oh! huh.

17:25 why? :-)

17:26 kotarak: Because non of these functions were used. :)

17:26 chouser: I mean, why would you want to exclude them? Why does it matter if they were used?

17:27 kotarak: chouser: I have to provide = and friends for a DSL. http://gitorious.org/clojureql/pages/FrontendReworked

17:27 chouser: ahh

17:27 kotarak: So I have to exclude the core ones.

17:28 I don't want the query-= hack.

17:28 I prefer query/=.

17:28 janmejay: the-kenny: thanks for the help

17:28 chouser: any users of the lib will have to exclude those as well, then, right?

17:28 the-kenny: You're welcome

17:29 kotarak: chouser: no. (ns user.namespace (:require [clojureql.query :as q])) (q/only (q/= :table/x 5) (q/from :table)).

17:29 chouser: ah! very good.

17:29 kotarak: Only if you :use clojureql, you have to exclude them probably.

17:29 chouser: yes

17:30 kotarak: I'm a bit undecided about verboseness, though....

17:33 Chousuke: hmm

17:33 if you're inside a namespace, can you do (def namespace/= ..)?

17:33 that would get around having to exclude core = etc.

17:34 kotarak: Chousuke: don't think so.

17:34 chouser: def doesn't let you give some other namespace

17:34 Chousuke: what if it's the namespace you're in?

17:35 chouser: It would be so easy to do that I assume the inability is intentional

17:35 Chousuke: hm

17:35 kotarak: In general I design my namespace for require with :as and not for :use. But I in this case... hmm...

17:35 Chousuke: it actually works.

17:35 I can do (def user/z 5) in the repl

17:36 chouser: yeah.

17:36 interesting.

17:36 Chousuke: useful, too

17:36 chouser: really?

17:36 kotarak: ,(name (ns-name *ns*))

17:36 Chousuke: well, say you need to define your own seq in terms of clojure.core/seq :)

17:36 clojurebot: "sandbox"

17:36 kotarak: ,(def sanbox/= 5)

17:36 clojurebot: DENIED

17:37 chouser: Chousuke: you still need to exclude core/seq from your own ns

17:37 Chousuke: at which point you can just (def seq ...)

17:37 Chousuke: are you sure, though?

17:37 couldn't you just do (defn myns/seq [...] (seq (weirdstuff))

17:37 chouser: (def user/map 1)

17:38 java.lang.IllegalStateException: map already refers to: #'clojure.core/map in namespace: user

17:38 Chousuke: hm, apparently not :( damn.

17:43 Hali_303: how to or a sequence of booleans? I've tried (reduce or coll) but that does not work

17:43 the-kenny: (apply or coll)?

17:43 chouser: nope

17:43 or is a macro

17:43 the-kenny: :(

17:43 oh, of course it is..

17:43 chouser: ,(some identity [nil false 1 2])

17:44 clojurebot: 1

17:44 * the-kenny is dumb

17:44 chouser: nah, it's a natural mistake

17:44 once upon a time (apply or coll) would return code you could 'eval' to get your answer.

17:45 ,(apply #'or [1 2 3])

17:45 clojurebot: (clojure.core/let [or__4472__auto__ 1] (if or__4472__auto__ or__4472__auto__ (clojure.core/or 2 3)))

17:45 chouser: heh. don't do that.

17:48 the-kenny: isn't there apply-macro, whoch no one should ever use? :D

17:49 Chousuke: clojurebot has some feature creep

17:49 Hali_303: thanks, I've used (some true? coll) this work

17:50 Chousuke: ,(true? 3)

17:50 clojurebot: false

17:50 chouser: Hali_303: sounds good, but not that doesn't behave the same as 'or'

17:50 note

17:50 kotarak: ,(if 3 true false)

17:50 clojurebot: true

17:50 kotarak: ,(or 3 false)

17:50 clojurebot: 3

17:50 Hali_303: chouser: you mean in the sens of lazyness?

17:50 chouser: no, as kotarak is showing

17:51 Chousuke: Hali_303: true? only returns true if it's argument is the literal 'true'

17:51 Hali_303: ok, that's true, but I don't need that

17:51 kotarak: ,(some true? [3 false])

17:51 clojurebot: nil

17:51 chouser: ok, good enough then.

17:51 Hali_303: I have a collection of trues and falses

17:54 hiredman: Chousuke: some?

17:54 Chousuke: hiredman: :P

17:58 seths: question on deftype... is it strange to use Object as the supertype when I only want to override methods from Object?

17:58 e.g. (deftype Foo [bar] Object (toString [] (str (gndn bar))))

17:59 somnium: deftypes have supertypes?

17:59 seths: I'm probably mixing the terms up

18:00 in Java-ese, extending Object

18:01 Chousuke: in deftype's case, Object is treated more as an interface rather than a class

18:02 kotarak: chouser: (ns user.space (:use [clojureql.query :as q :exclude (= not= < <= > >= not and or nil?)])) (only (q/= :table/x 5) (from :table)) Seems to a be a compromise.

18:02 seths: q2: I'm tempted to override the factory methods, but what type of thing should I return?

18:02 (defn Foo [bar]

18:02 (throw (Exception. "hola!")))

18:02 that works as a proof of concept, but doesn't clue me in at all

18:03 Chousuke: I don't think you should do that :P

18:03 hmm

18:03 seths: chousuke: which? both?

18:03 Chousuke: maybe (def old-Foo Foo) (defn Foo [] (old-Foo .....))

18:04 ohpauleez: just a sort of poll, Am I the only one who likes error-kit more than the current try/except?

18:11 * lpetit things he really needs to use error-kit more

18:14 the-kenny: ohpauleez: I like it, however I haven't done very much with it yet - Just saw some code in clojure-couchdb

18:14 ohpauleez: ahh cool

18:17 also, congrats chouser and fogus, ch 1 was great!

18:23 chouser: ohpauleez: great, thanks! fogus is in the process of revamping it right now, along with the rest that was released in the MEAP

18:24 ohpauleez: cool, once I get this bonus for my current contract, I plan on buying a copy

18:25 chouser: we're working on a "bundle" deal: the book + 1 year clojure funding. We'll see if that actually happens...

18:25 ohpauleez: that would be awesome, my bonus is basically going to bounties, clojure, and similar efforts

18:26 chouser: cool, that's a good idea

18:27 ohpauleez: I know how it goes, PyPy was always in that situation, so now that I have more contracts, it feels only natural to give it all

18:28 seths: chouser: I would definitely do the package deal

18:28 and have already funded

18:30 * the-kenny would have bought the book, but he doesn't own a credit card and he won't own one in the next months/years :(

18:36 seths: chousuke: no dice with old-Foo. I want to sometimes remap the input value of a factory argument before it winds up as the value of a field

18:37 after old-Foo my Foo is immutable

18:37 er foo

19:02 konr```: What should I use to turn HTML into XML? TagSoup?

19:02 ohpauleez: konr```: enlive

19:02 it's based on TagSoup

19:03 http://wiki.github.com/cgrand/enlive/

19:03 it allows you to apply a template to html or xml to do transformations, exactly what you need

19:04 alexyk: is (or ...) always short-circuiting?

19:04 ohpauleez: alexyk: I would assume so

19:04 konr```: ohpauleez: looks great! thanks!

19:05 ohpauleez: konr```: totally welcome

19:09 tcrayford: is there any point to unit testing macros?

19:10 seths: chousuke: I r moron. sry.

19:17 alexyk: how do you load a .clj file into repl?

19:19 * alexyk a lull before a storm

19:19 seths: ants.clj uses load-file

19:19 ,(doc load-file)

19:19 clojurebot: "([name]); Sequentially read and evaluate the set of forms contained in the file."

19:20 alexyk: thx!

19:20 seths: de nada

19:28 derrida: Hey guys, i've been trying to have a little fun with clojure but am having some trouble shifting emacs/slime to work alongside clojure. typing clj from teh commandline works fine, i set all my env. vars in that script and the repl inside SLIME does actually work and say it is clojure but there are problems and slime never connects: http://pastie.org/784097

19:29 if anyone had any ideas I would really appreciate it :) sorry this isn't exactly clojure specific

19:39 AWizzArd: Can there be conflicts when trying to use/require a NS? A conflict such as that there is more than one NS with the given name on the classpath?

19:39 replaca: alexyk: yes, or is always short-circuiting

19:40 alexyk: ok

19:43 jcromartie: AWizzArd: there won't be any conflicts when using require

19:43 use, however, imports all of the defs in the use'ed namespace

19:43 alexyk: technomancy: where did $RLWRAP go from lein??

19:44 AWizzArd: jcromartie: let's say I have the dirs X and Y in my CP. Both include a file z.clj which begins with (ns z ...). How will Clojure decide which lib it will load?

19:44 jcromartie: oh

19:44 that's not good

19:44 that's why you should make detailed namespaces

19:45 Raynes: How would I remove a key from a map?

19:45 hiredman: AWizzArd: just like java, what comes first on the classpath

19:45 AWizzArd: also, don't use single segment names

19:46 jcromartie: AWizzArd: are these third-party namespaces? if so, you should point them out

19:46 AWizzArd: hiredman: and there is no way to enforce loading a specific lib in such a case?

19:46 jcromartie: maybe the authors could fix it

19:46 there's no way to load the "second" one, no

19:46 hiredman: AWizzArd: not that I am aware of

19:46 Raynes: Ah, dissoc.

19:46 AWizzArd: jcromartie: I don't have the problem, but was thinking about using a single word as my namespace

19:47 hiredman: AWizzArd: don't

19:47 jcromartie: a single *unique* word, like the name of your very uniquely named project, for instance, is probably OK

19:47 hiredman: jcromartie: no

19:47 jcromartie: but if your project is "utils" or "game" or "app" then no

19:47 hiredman: want to tell it to rhickey ?

19:47 :)

19:47 hiredman: you should not use a single segment namespace

19:47 jcromartie: compojure

19:48 hiredman: jcromartie: compojure is broken

19:48 AWizzArd: even if i use more complex names, it will then only make it more unlikely that there will be a collision, but it can never be guaranteed

19:48 hiredman: rhickey is the one that moved clojure to clojure.core

19:48 jcromartie: is it broken in any discernible way?

19:48 or is it broken because it breaks the rules?

19:48 hiredman: I thought clojure.main was a class

19:48 in clojure

19:48 a single-segment namespace

19:49 hiredman: jcromartie: you don't know what you talking about

19:49 jcromartie: but that's just an assumption

19:49 hiredman: classes are java constructs

19:49 namespaces are clojure

19:49 classes don't live in namespaces

19:49 jcromartie: right but packages/namespaces use roughly the same concepts in terms of paths

19:49 hiredman: and besides, the namespace is clojure.main, not a single segment namespace

19:50 jcromartie: OK

19:50 I'm just going off of the various projects I've seen

19:51 hiredman: jcromartie: I was sitting here in this irc channel when rhickey announced the switch in AOT compilation schemes that made single segment namespace inadvisable

19:51 jcromartie: I believe you

19:51 hiredman: when he renamed the clojure namespace to clojure.core

19:51 none of those projects asked me

19:51 or I would tell them the samething

19:51 ~namespaces

19:51 AWizzArd: hiredman: is there a strategy for handling conflicts with multi-segment namespaces?

19:51 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

19:51 alexyk: how do you specify the dependency on clojure and c.c. in a lein project?

19:51 hiredman: AWizzArd: the first on the classpath wins

19:52 AWizzArd: no java tricks to rename those beasts when starting up the jvm?

19:52 hiredman: nope

19:52 jcromartie: someone should document this on clojure.org

19:53 at least in a more conspicuous place

19:53 like here http://clojure.org/namespaces

19:53 but as far as I can tell it's not mentioned

19:53 and the practices demonstrated by community projects don't help

19:54 maybe a warning is in order

19:54 hiredman: very true

19:55 jcromartie: this seems to be the best explanation of it http://groups.google.com/group/clojure/browse_thread/thread/8618a1d93cbbf8b7

19:56 hiredman: clojurebot: logs?

19:56 clojurebot: logs is http://clojure-log.n01se.net/

19:56 AWizzArd: Basically someone could invest a lot of his freetime to develop an incredibly useful library and then name the namespaces like org.apache and such ;-)

19:59 Well, sounds like Sun is in the position to fix this, though it seems to be very unlikely to encounter such a problem.

19:59 alexyk: why did pom.xml for clojure-contrib stayed at 1.1.0-master-SNAPSHOT when clojure proper inc'ed?

20:05 jcromartie: AWizzArd: well, I think Java has a simple system for loading resources, and the people in here are advocating simple guidelines to avoid problems with that system.

20:05 now someone tell me why I can (use 'my.lib) but not (compile 'my.lib) :)

20:05 I have a classes directory

20:05 java.lang.RuntimeException: java.lang.ClassNotFoundException

20:06 alexyk: somnium: if I want to work with clojure 1.2.0-master-SNAPSHOT, should I build congomongo with it, i.e. have to edit project.clj?

20:06 somnium: alexyk: hmm, yes but cant guarantee ClojureDBObject wont break

20:08 alexyk: well, it shouldnt break, but will need to recompile the .clj files I think

20:08 alexyk: somnium: is db-object now a separate projetc?

20:08 congomongo project.clj lists it as a dependency

20:09 lypanov: whats the best way to work on a linux gui in java nowadays?

20:09 somnium: alexyk: no I just suck at ant and maven so it was easier to compile the .java separately

20:09 alexyk: :)

20:10 jcromartie: speaking of compiling

20:11 trying to compile from the REPL is giving me problems, namely: java.lang.RuntimeException: java.lang.ClassNotFoundException: my.company.ns$loading__6327__auto____24 (NO_SOURCE_FILE:0)

20:12 if I say (use 'foo) it works, (compile 'foo) does not

20:12 hiredman: ~compile

20:12 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

20:12 jcromartie: and?

20:12 AWizzArd: jcromartie: you don't have the classes dir in your namespace

20:12 jcromartie: ./classes/ exists

20:13 AWizzArd: it needs to be on your classpath

20:13 jcromartie: ah... I see

20:13 hiredman: jcromartie: so follow the instructions on the website

20:13 jcromartie: I must yield to the almighty classpath

20:13 hiredman: also, unless you need to

20:13 I would recommend against aot compilation

20:14 Guest24347: is there a way to create a seq from an Iterator (without the Iterable)?

20:14 AWizzArd: just decide for any directory on your classpath and then (binding [*compile-path* "/home/jaycro/hg/com/example/any/dir/on/cp/"] (compile 'my.ns))

20:14 hiredman: you trade off the dynamic for almost no gain

20:14 ,(doc iterator-seq)

20:14 clojurebot: "([iter]); Returns a seq on a java.util.Iterator. Note that most collections providing iterators implement Iterable and thus support seq directly."

20:15 Guest29961: thx hiredman

20:16 jcromartie: hiredman: how about for deploying a web app?

20:16 source would work there, I suppose

20:16 hiredman: jcromartie: for compojure you do need to compile a Servlet class

20:16 jcromartie: ah

20:17 hiredman: so you will need to compile

20:17 jcromartie: right now I'm running my web app from a REPL

20:17 even on the server

20:18 but it's very much under active development :P

20:18 chouser: even if you AOT compile with gen-class, you can still load new method implementations on the fly

20:19 hiredman: I am not that familiar with compojure's internals so I am not sure wha the minimum you need to compile is

20:40 Raynes: I wish I had known 45 minutes ago that Twitter blocks duplicate tweets. Would have saved me 45 minutes of trying to find a non-existent bug in my code.

20:56 janjan: i'm getting a bit confused with the import/use/refer functions

20:56 is there one that allows me to

20:56 use a java static method as a function in my namespace?

20:57 hiredman: no

20:57 methods, static or otherwise, are not fns

20:57 janjan: bummer

20:58 qbg: What do you need it for?

20:58 hiredman: but, I imagine you are just confusing your terms

20:58 albino: can't he call it whether it's a clojure function or not?

20:58 hiredman: if you want to, for example call the static method shuffle from java.util.Collections

20:59 janjan: I wanted to import org.apache.commons.lang.StringUtils.Join as Join

20:59 hiredman: ,(import 'java.util.Collections)

20:59 clojurebot: java.util.Collections

20:59 hiredman: ,(import 'java.util.ArrayList)

20:59 clojurebot: java.util.ArrayList

20:59 janjan: yea, importing the class works

21:00 but I don't need all of it, and I thought it would save me some typing

21:00 qbg: If you wanted to do that for enough static methods, you could write a macro

21:00 hiredman: ,(let [a (doto (ArrayList.) (.add :a) (.add :b))] (Collections/shuffle a) a)

21:00 clojurebot: #<ArrayList [:b, :a]>

21:00 janjan: need to use the :as thing I guess

21:00 hiredman: no

21:00 use and requre are not for java classes

21:00 require

21:00 janjan: ow

21:01 hiredman: import is for java classes

21:01 janjan: guess I missed that part

21:01 thx

21:01 I thought they were more or less interchangeable

21:01 hiredman: nope

21:02 ,(macroexpand-1 '(Collections/shuffle a))

21:02 clojurebot: (. Collections shuffle a)

21:02 hiredman: ,(macroexpand-1 '(.foo a))

21:02 clojurebot: (. a foo)

21:03 hiredman: ,(macroexpand-1 '(foo. a))

21:03 clojurebot: (new foo a)

21:34 defn: hello all

21:35 ,(macroexpand-1 (

21:35 clojurebot: EOF while reading

22:00 wilig: hmm, now I've got no excuse not to start my project. swank-clojure was a nice distraction.

22:07 alexyk: technomancy: ping

22:22 how do I print classpath in repl?

22:23 hiredman: classpath?

22:23 clojurebot: classpath is (System/getProperty "java.class.path")

22:24 chouser: that's one of them, anyway.

22:47 alexyk: how do I tell lein to ise a specific version of clojure? it seems not respecting it

22:48 chouser: alexyk: do you mean when you launch a repl using it?

22:48 alexyk: yep

22:49 chouser: I haven't tried lien yet, but I think I've heard that for the repl it uses the clojure that came with it.

22:49 Or something. Does that make any sense?

22:49 defn: alexyk: you can specify a different version of clojure by changing the dependencies entry for it

22:49 and then running lein deps

22:50 alexyk: defn: is not respected

22:50 defn: so you've changed it with no results?

22:50 alexyk: yep

22:50 defn: from what to what

22:50 alexyk: I see CLOJURE_JAR hardcoded in lein

22:51 which it's using for itself

22:51 defn: i remember tricking it awhile back into using 1.1.0 by just overwriting .clojure/... with the newest version, same name as the old

22:51 you could change that env var in the script i suppose as well

22:52 but lately i seem to remember just setting the dep to a more recent version and then running lein deps

22:52 derrida: i'm struggling witht his too

22:52 defn: that gave me the most recent version in a swank session

22:52 derrida: that's because you are named derrida

22:52 derrida: ;>

22:52 defn: everything will be inherently more complex for you as a result

22:52 derrida: it's the story of my life :)

22:53 defn: I suggest changing your name to Foucault

22:53 you might have a better experience ;)

22:53 derrida: his friend is my altnick ;>

22:53 defn: <chomsky> will probably have the best chance at solving problems in clojure

22:53 derrida: hahaha

22:54 defn: although it will likely involve a lot of mentions of hegemony, anarcho-syndicalism, etc.

22:54 (defn anarcho-syndicalism)

22:54 * defn thinks up a good joke for that...

22:57 derrida: when i start slime, it continuously polls ... swank? but never connects

22:57 defn: derrida: add :dev-dependencies [[swank-clojure "1.1.0"]] to your project.clj

22:57 then run lein deps

22:59 derrida: defn: ahh project.clj, i kept seeing that as package.el for some reason :)

22:59 defn: :) did it work okay for you?

23:00 hmmm, i need to implement an anarcho-syndicalism function with agents

23:00 derrida: hm

23:00 seems to have the same result

23:01 is there a systemwide project.clj?

23:01 defn: derrida: no

23:01 derrida: pastie your project.clj somewhere and let me take a look

23:02 i might step away for an hour, but ill take a look when i get back

23:02 derrida: my problems actually occur without a project.clj at all, when i start slime this is the output: http://pastie.org/784269

23:03 no problem i'll be here :)

23:03 i'll take the opportunity to grab food

23:03 defn: derrida: how are you starting slime

23:03 derrida: M-x slime

23:03 defn: ah okay, i thought you were running swank-clojure-project

23:03 and then selecting the project root dir

23:04 M-x swank-clojure-project

23:04 derrida: oh? :)

23:04 defn: are you using elpa?

23:04 derrida: yes

23:04 defn: do you have slime, slime-repl, swank-clojure, and clojure-mode installed?

23:04 derrida: yep

23:05 i removed everything emacs on my whole system in fact hehe

23:05 defn: hmmm, do you have a ~/.clojure/ dir?

23:05 derrida: yes, which is one confusing part of the whole thing for me

23:05 defn: brb derrida -- keep up the deconstruction until i get back

23:05 derrida: emacs wanted to install to ~/src

23:05 defn: ;)

23:06 I did M-x clojure-install ~/.clojure

23:06 which seemed to work :)

23:07 except that things arent really working hehe :)

23:13 joegg: I'm just getting started with clojure (and lisp) but not java or programming. Can anyone offer some suggestions on http://paste.lisp.org/display/93599?

23:13 I don't know agents and such yet, and will expand into that soon.

23:14 For now, I'm looking for even more basic things, like I just discovered if (instead of cond) a few minutes ago; and I'm not really thrilled with all the dotos.

23:15 The code above "(def spiro ..." is more library-ish, and the rest is using the very simple library.

23:21 technomancy: alexyk: that method of getting the classpath only gets you the classpath Java was launched with, not the classpath of the nested classloader

23:21 alexyk: I need to document that better for the next release and include a function to get the nested classpath

23:22 but you *should* be using the correct (project-level) version of clojure

23:22 alexyk: technomancy: forget classpath! how do I make lein respect clojure version from project.clj?! :)

23:23 I get the prompt for Clojure 1.1.0 even when desirous of 1.2.0-master-SNAPSHOT

23:23 technomancy: derrida: M-x clojure-install is deprecated; see the swank-clojure readme

23:23 alexyk: the latter is dutifully moved into libs/ by lein deps

23:23 yet the prompt is 1.1.0

23:23 technomancy: alexyk: oh... one further bug is that the lein repl task is the only one not to use the subclassloader

23:24 tests, compilation, and launching the swank server should all work correctly

23:24 derrida: technomancy: i saw that but the readme's advice seemed a bit ..

23:24 technomancy: but there are issues with clojure.main not setting *in* correctly

23:24 alexyk: technomancy: are you saying I'm out of luck with repl?

23:24 what if I hack git checkout to use 1.2.0...?

23:25 derrida: i'm using 1.2.0 now

23:25 alexyk: derrida: apaprently not in repl?

23:25 derrida: repl shows 1.2

23:25 alexyk: repl from lein repl?

23:25 derrida: only if i install manually htough

23:25 oh

23:25 sorry :)

23:26 technomancy: alexyk: it's easiest to use lein-swank or lein-ng

23:26 derrida: o O

23:26 this is really getting crazy

23:26 alexyk: an hour ago I could do work. Now I decided to upgrade clojure, contrib, and some deps, and it's a horrible mess since clojure people don't version by clojure version!

23:27 technomancy: you can't use clojure 1.2.0 with contrib right now

23:27 since contrib is still compiled using 1.1.0 =\

23:28 alexyk: ah ok. So I'll rollback. Still, clojure people, do version by clojure version, please! :)

23:28 technomancy: yes

23:28 =(

23:28 contrib is a bit of a mess right now

23:28 * technomancy secretly advocates breaking up contrib into independently-usable libraries that can be versioned at their own pace

23:29 hiredman: secretly?

23:29 derrida: i agree, there needs to be more seperation if it causing this.

23:29 technomancy: hiredman: don't tell anyone

23:29 alexyk: technomancy: lein hardcoded LEIN_JAR to $HOME/.m2/... and CLOJURE_JAR to same repo, not to the checkout!

23:29 that's the bin/lein from git.

23:29 technomancy: alexyk: yes, that's the version of clojure that lein uses, not the version that your project is loaded with

23:30 alexyk: shouldn't LEIN_JAR point to the checkout?

23:30 technomancy: (except for the bug in the repl task as noted in the readme)

23:30 oh, the checkout of leiningen?

23:30 * derrida head is spinning

23:30 alexyk: yeah

23:30 euwyn: working my way through the pragmatic bookshelf book. any suggestions on a good first clojure project. have some experience with functional languages (ml) from college, but rusty.

23:31 technomancy: alexyk: well the checkout of leiningen has its src/ on the classpath in front of LEIN_JAR, so it will take priority

23:31 derrida: what precedent does leiningen follow?

23:31 alexyk: technomancy: one massive problem remains: no respect for settings.xml

23:31 my ~/.m2/settings.xml specify the repository in /opt/m2/repository

23:31 technomancy: alexyk: it's on the roadmap

23:32 alexyk: ok

23:32 derrida: it's hard to know what to equate it to, is it inteded to function like cabal?

23:32 alexyk: derrida: it's simply lipstick on a pig of maven

23:32 clojure lipstick on a maven pig

23:33 derrida: i'm getting discouraged too :(

23:33 alexyk: it installs into maven repo and drags jars to a local libs/ to fool old-time tools

23:33 I'm in fact encouraged and applaud technimancy

23:33 derrida: have you used cabal?

23:33 technomancy: derrida: it's a lot easier to write a package manager in a language that allows you to alter the load path at runtime

23:34 alexyk: derrida: not much better than CPAN for that matter

23:34 derrida: technomancy: i bet

23:34 alexyk: nothing wrong with maven, really :) and lein avoids XML, so it's just fine

23:34 derrida: cpan is pretty excellent

23:34 maven is just driving me mad

23:34 alexyk: it's the clojure people who should straighten up and version properly

23:35 technomancy: yes

23:35 stuart is doing the right thing with the release of contrib 1.1.0, it's just taking a while

23:35 since it's a 1-man volunteer show

23:35 derrida: well, the key to getting more volunteers is getting more users

23:35 alexyk: well, around the new year, I'm not surprised

23:36 derrida: if we can't use it we're not going to be able to contribute

23:36 alexyk: technomancy: so, to sum up, there's no quick and dirty way to force lein repl to behave?

23:36 technomancy: derrida: contrib has had a bit of an aristocratic vibe to it for a while

23:36 alexyk: yeah, it's really hard to get a subclassloader working without screwing up *in*

23:36 alexyk: I'm on a paper deadline and to revive my Emacs with elscreen and sidebar would be too obssessive

23:36 technomancy: alexyk: have you tried nailgun?

23:37 I think that should be more straightforward than swank

23:37 derrida: what is nailgun?

23:37 alexyk: technomancy: once or twice. Can I drive it from any editor?

23:37 derrida: similar to MrED?

23:37 alexyk: clojurebot: google java nailgun

23:37 clojurebot: First, out of 1820 results is:

23:37 Nailgun: Insanely Fast Java

23:37 http://martiansoftware.com/nailgun/index.html

23:38 derrida: that sounds interesting

23:38 technomancy: alexyk: vimclojure uses it, you can also use it with clojure-mode (without slime) by setting inferior-lisp-program

23:38 derrida: does vim-clojure work better than swank?

23:38 technomancy: never tried it

23:38 derrida: i'm more than happy to use vim for a while

23:38 damn

23:38 :)

23:39 hiredman: vimclojure has its own set of issues

23:39 derrida: i'm one of those sickos that likes both

23:40 so .. how are people writing clojure code? :)

23:40 technomancy: tbh swank-clojure is not great

23:40 derrida: not slime quality?

23:40 technomancy: I haven't been able to give it the attention it deserves

23:40 alexyk: derrida: I do it all in repl and paste back into textmate, then eval in repl what I need.

23:41 derrida: alexyk: you've gotta be kidding me?!

23:41 alexyk: my textmate has a snippet to send it to iterm.

23:41 * hiredman uses emacs and vim

23:41 alexyk: it's so damn compact, you can write 5 lines an hour and get it done by the EOD

23:42 hiredman: how's vimclojure then? what are the issues?

23:42 hiredman: the dynamic features of vimclojure require it to eval every buffer you open

23:42 derrida: on open?

23:42 hiredman: which is annoying if you have something like (iterate inc 0)

23:42 yes

23:43 derrida: bleh

23:43 hiredman: so i have that part turned off

23:43 derrida: it turns off you had to excise?

23:43 alexyk: hiredman: how do you turn them off?

23:43 hiredman: the highlighting and indentation is pretty good

23:43 * hiredman checks his vimrc

23:44 derrida: my vimrc is like 500 lines :s

23:44 hiredman: ""let g:clj_want_gorilla=1

23:44 so without that line

23:44 derrida: omg 560 lines ...

23:44 hiredman: I haven't really kept my vimclojure install up to date

23:44 mine is only 220

23:45 my .emacs.el is only 127

23:45 derrida: 560 is insane, i'm embarassed, i knew it had gotten long but ..

23:45 hiredman: that is a lot of vimscript :(

23:45 alexyk: "my chomsky is bigger than yours" :)

23:46 * hyp3rvigi1ant uses leiningen to create a project, download dependencies, run swank, and then connects to swank using emacs/slime-connect...but i'm a clojure/emacs/swank/slime/leiningen noob

23:46 derrida: 560 is more like being obese than having a big .. :>

23:47 hiredman: I used notepad++ to do a few euler problems with clojure

23:47 derrida: :(

23:47 alexyk: I can never remember how to save things into buffers and then recall them properly in vim. Emac sis easy

23:47 derrida: :h @

23:47 it's really easy in vim

23:47 hiredman: :wq

23:47 :tabn

23:47 derrida: i dont think thats what he means

23:48 but maybe it is!

23:48 hiredman: tabs are sweet

23:48 derrida: i just use buffers, never tried tabs

23:48 hyp3rvigi1ant: when i started to learn vim years ago, i found reaching for Esc and then doing a Shift+colon all the time to be extremely annoying...never used vim much...more recently have started using emacs a lot, and like it much better

23:49 derrida: hyp3rvigi1ant: everything new takes getting used to

23:49 hyp3rvigi1ant: true

23:49 alexyk: I mean cut and paste

23:49 hiredman: I have < and > mapped to tabp and tabn

23:50 derrida: < > indent though :(

23:50 hiredman: get errors in emacs because M-: is eval elisp and w isn't bound

23:50 derrida: hiredman: i do that constantly haha

23:50 or ZZ in the middle of documents lol

23:51 hiredman: gg=G reformats the entire docuement btw

23:52 alexyk: anything you delete goes into the buffer

23:52 alexyk: so, dd - deletes a line

23:52 alexyk: p - will paste that line

23:52 alexyk: you can deliberately copy with 'y' for yank

23:52 alexyk: derrida: that I know. I use it for years for sysadmin tasks, and can never remember reching back into the sequence of yanks

23:53 in emacs it was easy

23:53 derrida: alexyk: yeah, thats not easy in vim

23:53 alexyk: scroll through yanks to pick one

23:53 derrida: alexyk: hehe sorry for the lesson :)

23:53 alexyk: np, thats a few basics which is enough

23:54 I cound lines etc. I used ed even on the iphone

23:54 derrida: hehe

23:54 that's hardcore ;)

23:54 alexyk: vi on the iphone was really cool, in a tiny term

23:55 derrida: technomancy|away: one thing that would be really helpful is a screenshot of a succesful swank-clojure launch so we know what we're shooting for

23:56 my reply *does* work for simple evals

23:56 defn: derrida: get it figured out yet?

23:56 derrida: defn: :)

23:56 defn not quite hehe :)

23:57 defn: derrida: where you at now?

23:58 alexyk: clojars search is so broken, oh man

23:58 derrida: i ran lein deps after adding that line to the project.clj of one of my projects

23:58 defn: alexyk: yeah :(

23:58 alexyk: it's best to just use the repo view

23:59 http://clojars.org/repo/

23:59 derrida: defn: it downloaded several jars but i still get that same http://pastie.org/784317

23:59 alexyk: is _ato around generally?

23:59 defn: derrida: did you paste your project.clj file?

23:59 alexyk: how do you ask irc when a person was seen last again?

Logging service provided by n01se.net