#clojure log - Jun 25 2009

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

0:04 holmak: There is that Common Lisp library, too, "Cells"?

0:04 Some kind of framework for dealing with lots of interdependent values, as in a spreadsheet.

0:04 hiredman: I think there are a few Cells like libraries for clojure

0:05 holmak: I wonder if their approaches would be relevant to the GUI problem. I imagine they would.

0:06 hiredman: holmak: I would check out the libraries page on clojure.org

0:06 holmak: Will do

0:41 codyK: coming from a non-java background, how do people deal with / tolerate classpath? Is setting up a directory with symlinks to jar files and then using a wildcard classpath really considered to be a reasonable solution?

0:43 grrrt: codyK: I don't use symlinks. For light-weight projects, I use a simple directory structure and an ant build script that gets all the sources and jars

0:43 for complex projects I tend to use maven

0:43 holmak: The classpath is a nightmare. Wildcards in the classpath don't work as you might expect -- "some/path/*" _supposedly_ includes all the JARs in some/path; you don't want to type *.jar

0:43 Let me find the relevant docs, if you haven't seen them

0:44 http://java.sun.com/javase/6/docs/technotes/tools/windows/classpath.html

0:44 Note, that is for Windows

0:47 codyK: thanks for the link

0:48 holmak: If you are not developing on Windows, there are lots of people here who know how to work that. I'm doing it the hard way by using Windows...

0:49 codyK: i'm a unix guy

0:49 holmak: So you are in good shape, I think the way to go is ant or Maven, like grrrt said.

0:50 codyK: yeah, its a bit of a shift to have to worry about library usage on a per-project basis

0:50 grrrt: welcome to the java world :)

0:50 codyK: hahaha

0:51 holmak: I swear I have spent more time worrying about the classpath than writing JVM code.

0:51 grrrt: well once you've got it set up you can forget about it more or less.

0:51 how many jars are you trying to manage?

0:51 holmak: But again, it helps if you are not on Windows. I barely have a usable _shell_.

0:52 codyK: eh, right now just clojure, contrib, enlive, compojure

0:52 plus dependencies

0:52 grrrt: that's not too bad

0:52 I'd just put those in your WEB-INF/lib

0:53 (since you're doing webapps that is)

0:54 I have used maven-like directory structures,

0:54 src/main/clojure has my clojure sources, src/main/webapp/ is the webapp root which contains WEB-INF/lib

3:29 hiredman: http://jackcoughonsoftware.blogspot.com/2009/06/pimp-vs-just-plain-fix-my-library.html <-- ouch

4:41 combasa: this works nice `alias clj="rlwrap clj-env-dir"`

6:29 frodef: with proxy-super, how do I chose the particular method to invoke, based on argument classes?

6:33 ..the super method has signature (String Object Object), and I have (String String String), but proxy-super yields an "no method found"?

6:35 argh! I had misspelled the method name, even if I thought I'd looked for that.. twice. Sorry about the noise, again.

6:57 cemerick: rhickey: is new-new the new name for 'instance'?

6:58 rhickey: cemerick: working title, yes

7:01 cemerick: rhickey: maybe you're not sure yet, but will it eventually offer a superset of structs, in particular, structs that have slots tied to java-interface getters?

7:02 rhickey: cemerick: I'm not sure if that will be built in or something you can build with it. I'm concerned about it not becoming laden like genclass

7:03 in particular, right now there is no way to specify fields, your fields are what you close over

7:03 cemerick: I've been thinking of reimplementing struct-maps using ASM to generate fields for each slot, which would probably bring things back to java-native perf, but I obviously don't want to make something that's obsolete a month later. :-)

7:04 AWizzArd: rhickey: (bar xyz) returns lazily a sequence of refs. Now I do return in one of my functions (filter #(foo @%) (bar xyz)). But I was thinking about wrapping a dosync around this, to make sure that while filter is running the refs returned by bar won't change. But as filter itself is lazy, do I need to put the filter inside a doall if I want it to run in a transaction?

7:04 clojurebot: he works hard so you don't have to

7:05 rhickey: cemerick: exactly, but a big point of newnew is so I don't have to write Java anymore, so I'd like to think it would give you the tools for structs

7:06 AWizzArd: yes, you don't want your ref interactions to leak out of the transaction if you want them to reflect a snapshot

7:10 cemerick: rhickey: well, I'd be aiming for an all-clojure impl (with ASM for the class-generation stuff). To foolishly speculate: am I right in thinking that 'fields' in new-new means 'java fields', as opposed to simple bindings to refs or something?

7:11 rhickey: cemerick: immutable java fields, yes, even primitive ones - this is a capability of closures right now

7:11 i.e. locals

7:12 when you call fn it creates an instance of a class implementing IFn with a ctor taking all closed-over locals, which become fields of that class. The point of newnew is to get better leverage out of all that capability

7:13 it'll be a lot like Java anonymous inner classes

7:13 with the same final constraint

7:13 cemerick: rhickey: heh, in that case, as long as there was a facility (say, set! for now, though the semantics aren't right), that allowed you to write something like (myMethodImpl [arg] (set! this-foo field-name arg)), which returned a new instance of this-foo with the field-name field's value set to arg, then that'd be pretty sick.

7:13 slick* (although 'sick' works too)

7:14 (hrm, or maybe that's what the factory mention is about...)

7:15 rhickey: cemerick: what ends up happening is that the fn enclosing a newnew call acts as a factory

7:15 your method could call it to construct a new instance

7:16 what you *don't* end up with is public ctors

7:16 cemerick: that's fine

7:17 sounds sufficiently macro-able, anyway. Though round-tripping through a factory to make a copy (modulo one field, say) puts the super-efficient cloning in JDK7 out of reach.

7:17 rhickey: but the whole mechanism enforces best practice - only methods defined by interfaces are accessible, class is anonymous, no public ctors, factory functions

7:17 cemerick: hrm, or maybe not, if one was clever enough with factory fns

7:18 rhickey: clone + final fields is a problem in practice

7:18 you really need to construct

7:18 cemerick: huh, I thought final was just a flag for javac, and that fields were nonetheless always mutable under the covers

7:18 e.g. via reflection

7:19 rhickey: no

7:19 security violation, plus you'll have the optimizer presuming a constant value and never seeing your changes

7:21 the latter is the big problem, I finessed final once and was burned

7:22 * cemerick knows just enough about 100 different topics to cause a massive flaming disaster each day

7:22 cemerick: I guess I'd ask, why make the fields final if the class is anonymous anyway? Inlining?

7:22 rhickey: if final had no semantics for the optimizer Clojure would be much slower, I want even more final semantics, like for arrays

7:23 cemerick: ah, there we go

7:23 rhickey: cemerick: fields not final would be (precisely) like mutable locals

7:28 cemerick: sure, sure. I had just learned about the Object.clone optimizations, which (IIUC) would make consing copies (or near-copies) absurdly fast.

7:28 rhickey: and the real objection to mutable locals would be that that could be closed over, creating mutable objects

7:28 cemerick: link?

7:29 cemerick: rhickey: the original post is here (which I'm sure you've seen): http://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive

7:30 it's relatively old, but it actually looks like the related bug is closed now, and released, even (though I'm not sure what to think of the 'fixed for' tag of hs10(b13)) http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6428387

7:32 rhickey: I'd say that, as long as digging into mutable locals requires knowing what one's doing (similar to set!, etc), it should be allowed (short of making those fields final delivering an irrefutable perf gain due to compiler optimizations).

7:34 Chousuke: cemerick: but then there's the danger that people who don't know what they're doing find out about it and start using it everywhere :P

7:34 rhickey: cemerick: well, it was a serious design point for Clojure to make them final. I'm really not sure you can trust people not to make a complete mess, which I'd have to support

7:34 cemerick: since marking fields as final or not is so straightforward, maybe two new's could be available -- new and new!

7:35 rhickey: once you have non-final, than volatile comes into play immediately

7:35 then

7:36 that said, it's back on the table again as I need volatiles in a couple of the lowest-level Java classes

7:36 cemerick: rhickey: yeah, by no means am I suggesting this as a default...far from it. But for people who want to build things on top of new-new, where they want that control, it'd be pretty big.

7:37 Chousuke: Virtually no one knows what they're doing. Trying to save everyone from themselves, especially if they're plumbing around in stuff that is explicitly marked as dangerous, seems futile (and liable to hurt people who do know what they're doing).

7:37 rhickey: but any such use in a MT environment requires serious Java concurrency skills

7:38 cemerick: rhickey: well, in my current use-case, it doesn't -- I'm still not modifying any object's fields in-place, I'd only be using it to fiddle a field or two on a newly-created instance in a "setter" impl.

7:39 But yeah, if people want to screw with mutable fields, they need to know what they're doing. When things go awry, it's their fault, "just don't use new! unless you know what you're doing", etc.

7:40 rhickey: cemerick: new! wouldn't cut it, people would rightly expect that to be exposed via locals and fn

7:41 (let [!x! 42] ... (set! !x! 13))

7:42 cemerick: well, that was just off the top of my head, with the broader point being, getting mutable locals could just be triggered by an explicit declaration of *some* kind.

7:42 rhickey: what are the semantics of a closed-over mutable?

7:43 (rhetorical, early Clojure had mutable locals)

7:43 cemerick: Presumably the same as an object with a public, mutable field. *shrug*

7:43 rhickey: except those closures have independent lifetimes

7:43 from the enclosing scope and each other

7:44 cemerick: see, you just blew right by me there :-)

7:44 rhickey: you end up either having to put them in boxes (there goes your field), or to build object reference chains (keeping things alive in surprising ways)

7:45 cemerick: This is all definitely complicated given that new-new is replacing fn as well, which I wasn't really thinking about at all.

7:45 rhickey: cemerick: it really is the same set of problems, the point of newnew is that it is the same as fn, fn is just needlessly specific

7:46 cemerick: well, the usage is pretty different -- you have pretty tight control over what goes on in a fn, whereas a proxy-object gets out into the world and has a much broader set of usage

7:47 rhickey: cemerick: I don't see the difference

7:47 cemerick: e.g. consider the implementation of an interface that requires mutability, and perhaps a ref in a state field is simply too slow, etc.

7:48 rhickey: cemerick: the latter is the question, are atoms too slow?

7:48 I think Atomic* are intrinsified in some ways, not sure about the allocation

7:49 cemerick: I'm not familiar with the guts of atoms, but I'll bet they're slower than a raw java field.

7:50 danlucraft: rhickey: hi rich. is your QCon 09 talk available online yet? I keep looking for it...

7:50 rhickey: cemerick: but to tell you the truth I'm not sure about how much to care about interfaces requiring mutability - is it worth turning Clojure into Java with parens? I'm personally happier saying go to Java for that. But I do want to avoid having to go to Java for method-level perf

7:51 danlucraft: interview is, 2 talks are not, yet

7:52 danlucraft: rhickey: ok, thanks.

7:53 cemerick: rhickey: yeah, I can definitely understand that impulse, but allowing, say, mutable locals in new-new as an option (associated with proxy-like usage only, perhaps, as it doesn't make sense in fn usage AFAICT) means that there'd likely never be a reason to drop to Java. I'm not sure that that narrow affordance turns clojure into Java with parens, though.

7:53 my glass-half-full side would just say that it closes the interop gap completely :-)

7:55 rhickey: cemerick: like I said, I'm thinking about it. And volatile/non is a big issue. For me, I don't want to do anything that at least doesn't have some known MT semantics. Making mutable locals always-volatile might be a way, but there are cases where you are using normal synchronization where you wouldn't necessarily want that

7:57 you could also prohibit closing-over mutables

7:57 that plugs a big hole, and can't be an expectation of an interface

7:58 but even then we'll soon have spaghetti loops etc, right away

7:59 cemerick: rhickey: yeah, I'm mostly just thinking out loud here. I'm sure you'll land in a good place, either way. I guess I'd only say that, it's impossible to know what people will want/need to use clojure for, so building in escape hatches is generally a good thing (where the current java interop is the best example so far).

8:00 I don't know -- idioms are a very powerful thing, and if the usage of mutables is non-default and not widely used in general, I'm not sure people would flock to them.

8:01 s/used/seen

8:01 rhickey: cemerick: keep hope alive! :)

8:02 cemerick: current java interop is good example, genclass not so much

8:02 cemerick: rhickey: you say that, but we'd be in quite a pickle if genclass didn't exist and didn't have the flexibility it does.

8:03 actually, I think it was gen-class (v1, probably) that pushed me over into adopting clojure top-to-bottom.

8:03 v1 of gen-class, that is (sometime last summer), not v1 of clojure

8:03 rhickey: cemerick: doesn't make it less complex or ugly - there's just too much Java cruft, and annotations still to go!

8:04 cemerick: We thankfully have zero use for annotations.

8:04 Although they continue in their general ascendency, so yeah, supporting them in some way is pretty important, although I don't know enough about them to know what that implies.

8:05 rhickey: newnew is a classic case of where adding the last 10% of capability will double or triple the complexity

8:05 Chousuke: rhickey: I remember you mentioning "host-in-parens" a while ago. Is new-new part of that idea, or something else?

8:06 rhickey: Chousuke: host-in-parens is a way to get out of having to duplicate all of the host's capabilities - instead just a macro language that generates host code directly. I think now it might be preferable to genclass.

8:07 or preferable as a way to implement genclass

8:07 Chousuke: ah. hmm.

8:09 rhickey: it would reduce the burden on newnew to provide every capability of Java

8:09 * Chousuke wonders what it would look like

8:09 rhickey: Java in parens

8:09 clojurebot: ΜΟΛΩΝ ΛΑΒΕ

8:38 Chousuke: rhickey: By the way, maybe you should add a notification on the Clojure and contrib google code pages that they've moved. Just in case someone ends up there through google.

8:45 rhickey: Chousuke: done

9:54 Lau_of_DK: Hi guys

9:54 Chouser: good morning!

10:28 Lau_of_DK: I assume Rich is the sole editor of the Assembla wiki ?

10:31 Chouser: Lau_of_DK: no, I think any assembla project member can edit the wiki.

10:31 Lau_of_DK: http://www.assembla.com/wiki/show/clojure/Chunked_Seqs

10:31 Chouser: Anyone with a CA in can become a member just by asking.

10:32 Lau_of_DK: http://groups.google.com/group/clojure-dev/browse_thread/thread/99e2728f665c52fa?hl=en

10:32 Lau_of_DK: Reading something like that I feel a little unsatisfied - If I in any way represent the average Joe, then thats to abstract for me. Like "High level sequence model is ideal for code understanding" I cant possible begin to imagine all the implications of that sentence. Could you guys adopt a more reader-friendly style of writing ?

10:32 rhickey: Lau_of_DK: that's not documentation, that's just my idea scratchpad

10:32 It's a dev space, not user space

10:33 Lau_of_DK: So that means, no catering to the less intelligent ?

10:34 rhickey: that means, before something is finished it's not finished

10:34 has nothing to do with intelligence

10:34 I could keep my notes to myself as I always did

10:35 Lau_of_DK: In that specific case it wouldnt make much a difference to me, because its difficult to imagine how your idea will work in practical terms - Personally I would really enjoy following your ideas, but I need to way of relating to what's being put down in writing

10:36 rhickey: Lau_of_DK: then wait for the feature to be released

10:36 Lau_of_DK: Alright

10:38 duck1123: rhickey: I prefer you sharing your notes, even if they are coarse and don't make much sense atm

10:38 Chouser: me too. I won't claim to understand every statement in such notes, but it's nice to have a sense of what may be in the works.

10:43 rhickey: there are some pictures in http://clojure.googlegroups.com/web/chunks.pdf I need to move over into the wiki

10:44 Lau_of_DK: That, I can relate to, thanks

10:45 danlucraft: are there any performance numbers for chunked seqs yet?

10:46 Chouser: danlucraft: yes, but they change every day.

10:47 rhickey: danlucraft: please try the chunks branch on your own code, there should be no negatives, except right now range is not IReduce, so (reduce + (range n)) demo suffers

10:49 danlucraft: ok.

10:56 Chouser: clearly slide 4 should be "Isn't Clojure too fast already?"

11:00 duck1123: too fast only applies when you're playing old dos games

11:00 rhickey: too fast, what's that?

11:03 Chouser: it's just this vague, lurking fear. In almost every other area going too fast is dangerous, so surely the same applies to software.

11:03 And if anything is in danger of going to fast, surely it's Clojure.

11:04 rhickey: too fast performance-wise or development-wise?

11:04 Chouser: heh. well...

11:05 I guess my ananlogy could be applied to either, but I mean to be talking about performance.

11:05 duck1123: Chouser: so are you suggesting that first include a (Thread/sleep 200)

11:05 Chouser: aren't there speed limit laws we need to be careful about?

11:05 duck1123: yes, perhaps that would suffice.

11:06 duck1123: it'll be great, because anyone employed as a clojure optimizer will have something to tweak to show immediate improvement

11:07 dude: the only one I'd worry about is the speed of light (actually, I'm not really that worried about that...)

11:07 Chouser: duck1123: yes, an excellent point.

11:11 Jetien: hi, i'd like to write a shell script which sends forms to an running repl, but i can't find any information which could help me. can somebody point me into the right direction?

11:12 duck1123: Jetien: just a running program, or do you need it to go to the running repl

11:12 Jetien: yes i need it to go to a running repl

11:12 is this possible?

11:16 duck1123: I was going to suggest checking out c.c.server-socket, but I don't think that can be used to affect the other repl session. (just the program that repl interfaces)

11:16 which is probably good enough for you, so check it out anyway

11:16 http://code.google.com/p/clojure-contrib/wiki/ServerSocketApiDoc

11:16 Jetien: thanks!

11:17 duck1123: I've never used it, as I use swank-clojure to acheive something similar.

11:18 Chousuke: hmm

11:18 defn has some weird behaviour.

11:18 danlucraft: so what fun thing should I write to learn clojure this weekend?

11:18 Chouser: it changed recently.

11:19 Chousuke: (defn foo a) works and produces a function definition whose arglists metadata is (a) :P

11:19 Chouser: danlucraft: reimplement this game in clojure, so that it can be ported to clojurescript with canvas and run on the iPhone: http://www.gamesforwork.com/games/play-12292-Colourshift-Flash_Game

11:20 danlucraft: couldn't you fit a prolog interpreter somehwere in that stack?

11:20 Chouser: danlucraft: note that the boards are not hand-made -- they're generated randomly based entirely on the attributes listed on the right (size, sources, link, dummies, wrap).

11:21 danlucraft: :-) :-) ...just write it for regular clojure, drawing into a swing window or whatever. that much will be fun. the rest will be easy.

11:23 dude: clojure for iPhone? I'm intrigued, but my google-fu is weak. Do you have a link to more info?

11:24 Chouser: no, I'm talking about clojure for javascript in a browser (clojurescript), which would be sufficient to get a game like that working in the iPhone's Safari.

11:24 dude: ah, okay

11:25 danlucraft: dude: http://clojure-contrib.svn.sourceforge.net/viewvc/clojure-contrib/trunk/clojurescript/

11:25 Chouser: OK done. It's been years since I wrote a game.

11:25 except not the ClojureSciprt thing :)

11:25 sgtarr: are there any games written in Clojure?

11:25 dude: danlucraft: thanks

11:26 Chouser: danlucraft: yeah, ignore clojurescript for now.

11:26 danlucraft: sgtarr: wait a couple of days :)

11:26 Chouser: danlucraft: that's awesome. I've been wanting to do that game for a week or two now, but I've just not been able to justify the time.

11:26 sgtarr: clojurescript sounds neat though, for simple things javascript can be used for

11:26 using <canvas> perhaps?

11:27 Chouser: danlucraft: I think it'll have some fun logic challenges, lots of good immutable leveragin, and maybe even concurrency stuff if you feel like it (though hardly necessary).

11:27 sgtarr: that was my thought for this game

11:28 danlucraft: Chouser: fiancee on hen weekend == lots of time for clojure fun

11:28 Chouser: unfortunately clojurescript is pretty outdated now -- clojure has gotten ahead of it.

11:28 danlucraft: Chouser: presumably it could work in an applet?

11:28 Chouser: danlucraft: yes

11:28 duck1123: Chouser: do you have any blog posts or anything on using clojurescript?

11:29 Chouser: danlucraft: though that doesn't help me play it on my iPhone. :-)

11:29 danlucraft: ok new plan. ClojureCLR -> Mono -> native iphone. WDYT?

11:29 clojurebot: new Class(x) is (Class. x)

11:30 Chouser: Mono can compile to native iphone!?

11:30 danlucraft: yep. there are a bunch of iphone games that use Unity on Mono.

11:30 Mono can do full AOT so it doesn't break the rules.

11:31 Chouser: interesting. yet another reason to not worry about that stage yet and just get it working on Clojure/JVM

11:31 sgtarr: danlucraft: but how do you run the application?

11:31 duck1123: would clojure for the iphone actually make past the apple cops though?

11:31 sgtarr: danlucraft: without a jailbroken phone

11:32 Chouser: duck1123: no, nothing really written about clojurescript.

11:32 danlucraft: sgtarr: yes

11:32 Chouser: duck1123: I've had a demo working intermittently, but it appears to be broken at the moment.

11:32 sgtarr: danlucraft: ?

11:35 danlucraft: duck1123, sgtarr: oh sorry. Mono compiles your app all the way to native code, so there is no interpretation, so it doesn't break the Apple law.

11:35 sgtarr: danlucraft: Ok so people are already distributing Unity apps through the App Store?

11:36 because that's pretty much the only way to reach the public

11:36 danlucraft: yes they are.

11:36 sgtarr: neat

11:37 seems like the best way so far to develop iPhone apps

11:37 danlucraft: is the Unity dev kit expensive?

11:37 seems I can download a trial but can't find anything about pricing for now

11:38 ok, found it: $399

11:38 + $199

11:42 duck1123: is there an alternative to conj anywhere that accepts [coll & xs] so that when xs is empty, only coll is returned?

11:44 I was doing (apply conj ["a" "b"] ["c" "d"]) but (apply conj ["a" "b"] []) fails

11:45 Chouser: why not 'reduce' instead?

11:46 Chousuke: ,(into [1 2] nil)

11:46 clojurebot: [1 2]

11:46 Chouser: even better

11:48 * rhickey doesn't get the fascination with apply

11:49 duck1123: into is working, thanks

11:55 jackdempsey: rhickey: you find people overuse it?

11:55 (apply that is)

11:56 anyone have a second to talk let vs binding?

11:57 Chouser: jackdempsey: go for it.

11:57 rhickey: jackdempsey: I dunno, I guess I use it often myself, but some usages I wonder about

11:57 jackdempsey: ah gotcha

11:57 its description still didn't quite click for me......i think i'm overthinking it

11:57 so for let vs binding, i was a bit surprised with an example in Programming Clojure

11:57 http://gist.github.com/135941

11:57 Chouser: let and binding are actually very different

11:58 jackdempsey: the reason print-foo prints the top level foo and not the foo in let

11:58 let foo is making a local foo that print-foo doesn't know about?

11:58 Chouser: jackdempsey: exactly

11:59 jackdempsey: so without completely misusing terms, that feels like print-foo closes on the originally defined foo

11:59 is that accurate to say?

11:59 Chouser: let creates locals with lexical scope. Only chunks of code that are visibly, syntactically, within the let can see that local.

11:59 jackdempsey: no, that's inaccurate.

11:59 jackdempsey: ok

11:59 so its more that print-foo just doesn't see the local foo

11:59 but does see the original globally defined foo

12:00 if it wantedt o see the local foo, you'd have to pass it in

12:00 Chouser: print-foo closes over nothing -- it (presumably) refers to a var named user/foo

12:00 jackdempsey: right, yep

12:01 Chouser: if it were closing over something, binding couldn't be used to change it the way you do on line 11

12:01 jackdempsey: ah i see

12:01 so at a high level binding changes where the function will look up variables?

12:02 you said they were very different, so i dont' want to stupidly oversimplify :-)

12:02 Chouser: print-foo is printing the currnt thread-local value of user/foo (or the root value of user/foo if there is not thread-local binding).

12:03 'binding' temporarily changes the thread-local value of user/foo so that when you call print-foo it sees that new value.

12:03 duck1123: the way I see it, binding is like redefing a global var temporarily, and thread locally

12:04 jackdempsey: ok

12:04 cool. thank you!

13:28 stuartsierra: Is it possible to launch a REPL from an Ant task?

13:29 duck1123: can't ant tasks shell out?

13:30 if so, then sure

13:30 stuartsierra: Yes, but calling <java fork="true" spawn="true"> does wacky things to the REPL display.

13:31 duck1123: I wasted a good day trying to get a repl launched from within maven

13:31 stuartsierra: I take it you didn't succeed?

13:31 duck1123: I gave up

13:33 stuartsierra: hm, ok

13:40 duck1123: It seemed like I had to jump through a

13:44 stuartsierra: <java fork="true" spawn="true"> actually doesn't seem to do anything at all.

13:44 <java> without fork/spawn works, but prints " [java] " before every line.

13:45 duck1123: It seemed like I had to jump through a lot of hoops to simply pipe the input and output of a spawned process to stdin/stdout

13:45 stuartsierra: Yeah, that's basically what I want. Not sure if Ant even supports that without writing a custom task.

13:48 duck1123: it also tripped me up that .getInputStream() was the output, and vice versa

14:04 stuartsierra: ok, giving up and going back to shell scripts

14:06 xeno: lol

14:07 slink_: why do you want a repl from an ant task anyway? just curious

14:08 stuartsierra: Single place to configure classpath/environment, platform-neutral for contributors.

14:11 Jetien: is there a way to force the reader to process what has been entered so far? generally it waits for matching parens etc.

14:11 rhickey: stuartsierra: thanks for your quick response and flexibility on template

14:13 stuartsierra: rhickey: no problem. The arg vector was a good idea, resulted in simpler implementation and cleaner usage.

14:13 When I first wrote template, I hoped it might be generally useful for macros, but that proved not to be the case.

14:14 rhickey: I'm trying to integrate gtic now

14:14 stuartsierra: cool

14:15 Chouser: walk and template will be public?

14:40 rhickey: all done

14:40 someone should do contrib

14:41 commit listed here: http://www.assembla.com/wiki/show/b4-TTcvBSr3RAZeJe5aVNr/Getting_Tests_Into_Clojure

14:46 Chousuke: everything seems to work fine

14:48 contrib should probably be branched, though, because these changes will break applications using contrib for tests with 1.0

14:48 weissj: none of the seq functions listed here: http://clojure.org/sequences , seem to add an item onto the end of the sequence. can someone tell me the magic function name

14:48 jackdempsey: doesn't conj?

14:49 oh, i guess thats for vectors

14:49 * jackdempsey shuts up

14:49 weissj: ,(conj '(1 2) 3)

14:49 clojurebot: (3 1 2)

14:49 weissj: that adds the item at the beginning, like cons

14:49 Chouser: weissj: concat

14:49 jackdempsey: ,(conj [1 2 3 4] 5)

14:49 clojurebot: [1 2 3 4 5]

14:50 jackdempsey: concat for when you have a seq though hm?

14:50 Chouser: Chousuke: the branch doesn't necessarily have to happen before gtic

14:50 jackdempsey: not a.....whats the term....seq-able?

14:50 stuartsierra: "lists grow at the beginning, vectors grow at the end"

14:50 Chouser: the branch can be made in the past

14:51 stuartsierra: so to add something to the end of a sequence, yes, you use (concat the-sequence [x])

14:52 weissj: stuartsierra: ah ok, i had tried (concat seq x)

14:52 ,(concat '(1 2) [3])

14:52 clojurebot: (1 2 3)

14:53 Chouser: weissj: note that's lazy, so you get a closure hanging around that knows how to supply the [3] when its asked for.

14:53 weissj: if you are sure you want to add to the end, do consider a vector. Vectors are good at that.

14:54 weissj: Chouser: ok, but i am basically reading s-expressions from a file and writing them back out, i don't know what'll happen when i start using square brackets

14:54 hopefully will 'just work' :)

14:55 Chousuke: Chouser: sure, you can branch from any commit at any time; I'm just saying it should be done at some point )

14:55 :)

14:55 Chouser: yes, I completely agree.

14:58 Chousuke: hm, looks like no-one has bothered any contrib issues to assembla

14:58 and the only open one is not relevant to contrib after GTIC :P

14:58 also, +moving

14:59 stuartsierra: Anyone tried maintaining multiple Slime configurations with different startup scripts?

14:59 i.e. different projects, different classpath,...

15:19 duck1123: there was some elisp code on the list that would reset the classpath for each project. I think it assumed a certain layout though

15:20 drewr: stuartsierra: I do that with jars in a project-specific dir and then set the classpath from elisp.

15:20 It requires java 6 to get /* behavior.

15:21 I need to clean it up and paste it.

15:30 stuartsierra: ok

15:42 cemerick: ech, can someone remind me how to override only the void-returning overload of a method via proxy (or do I need gen-class and its -methodName-void magic)?

15:45 Chouser: a method can't be overloaded on return value only, can it?

15:45 shoover`: stuartsierra: I also like Phil's slime-project function, assuming you don't mind unpacking all your jars into one location: http://groups.google.com/group/clojure/browse_thread/thread/855804aa6fdd74a1?hl=en

15:46 rhickey: Chouser: not in Java, but generics can generate bridge methods with that property

15:46 cemerick: Chouser: no, I was momentarily confused :-/

15:47 Chouser: do the return values have to have anything in common? are you supposed to call the one from the most-derivative class?

15:50 Anniepoo: lisppaste8: url?

15:50 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

15:51 Anniepoo pasted "keeping the current" at http://paste.lisp.org/display/82507

15:53 Anniepoo: ok, I'm still working at my little toy Clojure browser thingy. I'm going to turn it into an editor. So I need to keep some state - to start, i'm just going to have a 'current scope'

15:54 so in defn d I want there to be some entity that knows how to warn the swing panels they have become the

15:54 current scope.

15:55 from a users perspective, up and down arrow keys navigate to enclosing/first enclosed scope, and

15:55 right left navigate to siblings.

15:56 what's the idiomatic way to hang onto this state info?

15:56 make a ref in defn d's let?

15:57 Chouser: if you have things that need to be notified when some state changes, watchers might be a nice way to do that.

15:58 if you have the "current scope" state in a single reference obj, then when it changes all the watchers will be notified and they can check to see if they're current or not.

15:58 Anniepoo: yes, I'm implementing watcher pattern. Though I'm not totally clear how watcher works in a non OO environment

15:59 Chouser: on the other hand, you could have one ref per panel, each ref holding true or false. Then in a single dosync you could turn off one and turn on the other -- only the watchers for those two refs would fire.

16:00 cemerick: whoo, converting gen-class stuff to proxies makes for much simpler code. It's too bad we can't use it everywhere.

16:00 Chouser: Our hope lies in new-new, may he quickly come.

16:01 Anniepoo: true. Since this is essentially a 'focus' it makes sense to have a single one - order current to nonselected, change, order new to selected

16:02 but I guess my core question is answered - yes, this is a reasonable place to have a ref

16:02 rhickey: cemerick: what keeps you from using proxy? (I know there are things, just wondering which ones)

16:03 cemerick: Chouser: indeed. I'm looking forward to it. Chunked seqs are nifty, but I've no obvious use for them -- for new-new on the other hand, I'm waiting with bated breath.

16:03 Anniepoo: thanks for help

16:12 cemerick: rhickey: the a lot of reasons were cut down when you significantly improved proxy some months ago (January-ish?). At this point, the only remaining issues I can think of off the top of my head are (a) proxies don't provide any Java-visible factory or constructor, and (b) proxies (AFAIK) don't have a reliable class, making things dicey w.r.t. print-dup

16:13 kotarak: ... and multimethods in general.

16:14 Chouser: ouch -- new-new doesn't fix either of those.

16:14 cemerick: right...we just happen to take advantage of the ClassName/create idiom to allow for simple deserialization.

16:14 rhickey: cemerick: hmm, the first is likely to be true also of newnew, re: the second, there may be an option to name class, but will be abstract, and changing hierarchy will require restart

16:15 cemerick: that's fine -- I can get around (a) without much trouble, and an abstract classname will do just fine.

16:16 Chouser: will new-new's abstract base class have a more reliable name than proxy's do?

16:16 oh, I see -- maybe a new parameter that proxy doesn't currently take.

16:17 cemerick: I'm guessing there's some additional issues that keep us using gen-class (aside from us already having a pile of gen-class code), but I can't think of them now.

16:17 Chouser: But proxy could be augmented in that way, couldn't it?

16:17 cemerick: Chouser: it just gloms the superclass+interfaces together, I think

16:17 Chouser: cemerick: yes

16:17 reliably.

16:17 :-)

16:17 cemerick: ...not necessarily in a deterministic way, either, IIRC

16:17 right

16:18 rhickey: names are still inherently static, so I'm not sure what you could use a dynamic name for

16:18 Chouser: I don't think the barrier for a named base class is any higher for proxy than it will be for new-new, right?

16:19 rhickey: Let's say you could call your proxy Foo, when could you use that name?

16:19 cemerick: multimethods

16:19 rhickey: only if the same classloader could find it

16:19 Chouser: catch block

16:19 rhickey: ditto

16:19 also load order issues

16:20 cemerick: hrm, I'm not grokking the class loader issue. AFAIC, all our stuff is going to be in the same jar, so classloader issues are irrelevant.

16:20 rhickey: cemerick: that's ok for you, but not generally

16:20 cemerick: those "other people", always causing trouble

16:21 kotarak: :)

16:21 rhickey: well, it comes down to right tool for the job, dynamic things shouldn't be based on classnames

16:22 I've been thinking about a type field akin to meta in the bases, this could be set to a stable thing regardless of true class identity or class accessibility, and would participate in the hierarchy system

16:22 lisppaste8: Anniepoo annotated #82507 "untitled" at http://paste.lisp.org/display/82507#1

16:23 cemerick: At some point, I may just mandate that we never expose concrete classnames to clients, and only dispatch on interfaces and such, assuming only one implementation (made via new-new or proxy, etc)

16:23 Anniepoo: hmm... let is lexically scoped. so I'm doing something fundamentally wrong.

16:23 rhickey: cemerick: that is a great plan

16:23 and the mechanism I want to best support

16:24 cemerick: rhickey: depends on how the business goes. If our services plan pans out, then that'll be fine. If we end up continuing to be dependent upon selling libs to Java and .NET devs, then not so much.

16:24 rhickey: let interfaces be the only static part of your system

16:24 there is still genclass, also appropriately static

16:25 interfaces + newnew + factory fns + maybe something to package up factory fns for Java

16:26 Chouser: I just did this

16:26 it's pretty, both from the java client viewpoint and from the clojure code.

16:27 rhickey: right, I just want to remove any negatives about proxy, perf and super/protected access-wise

16:28 Chouser: having no thread-safe access to a proxy's parent class is a bit unsettling

16:28 so that'll be quite welcome

16:28 cemerick: yeah, proxy-super scares the hell out of me :-)

16:56 Jetien: i don' understand...if the reader receives a EOF it should stop waiting for further input, right?

17:17 lisppaste8: Anniepoo annotated #82507 "untitled" at http://paste.lisp.org/display/82507#2

17:17 Anniepoo: ok, I'm still stuck on this

17:17 here's what I'm trying to do

17:18 have some dynamicly scoped variable

17:18 notionally lots of people could be ordering taco salads

17:19 thought let made local bindings, but it's lexically local

17:20 hiredman: generally you do something like (def *user* nil)

17:21 then (binding [*user* whatever] do stuff here)

17:21 ,(doc binding)

17:21 clojurebot: "([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before."

17:21 Anniepoo: ah, ok. But that pollutes the global namespace

17:22 ah! it doesn't, cause this is per thread, hence we're not gonna get back

17:22 cool

17:22 hiredman: why not just, you know, pass arguments to functions?

17:23 Anniepoo: because in the real example that gets ugly quick

17:23 look at my previous annotation, it's got the real code attempt (broken)

17:24 hiredman: sorry, c formated lisp is not something I force myself to read

17:24 JAS415: might want to hyphenate set-focal-scope as a matter of style

17:25 Anniepoo: kk, I'll reformat it

17:25 hiredman: clojurebot: style?

17:25 clojurebot: excusez-moi

17:26 JAS415: I guess it doesn't matter because you can camel case in clojure, but I like to make it apparent when i'm doing java and when i'm doing clojure

17:26 Anniepoo: ok

17:28 hiredman: clojurebot: style is http://paste.lisp.org/display/81021

17:28 clojurebot: Roger.

17:30 Anniepoo: doesn't help that IntelliJ assumes java rules for double click selection of a name

17:33 JAS415: Annie I read up the chat channel and am thinking there are a couple ways you can do it depending

17:34 on what you really want

17:34 Anniepoo: ok

17:34 listens

17:34 JAS415: ok so

17:35 if you think about it

17:35 you can write functions that define functions

17:35 Anniepoo: yes

17:35 JAS415: so if you are really worried about cluttering the name space

17:35 you wrap all of your functions in a function that takes a user argument

17:36 then when you change users you call that function and it defines all your functions using that user

17:37 might have to declare them first

17:38 hiredman: you would use with-local-vars

17:38 ,(doc with-local-vars)

17:38 clojurebot: "([name-vals-vec & body]); varbinding=> symbol init-expr Executes the exprs in a context in which the symbols are bound to vars with per-thread bindings to the init-exprs. The symbols refer to the var objects themselves, and must be accessed with var-get and var-set"

17:39 Anniepoo: hmm... my ultimate goal is a little debugger. so you can go (d form) and you get a swing window that displays the form in a neatly colored way, lets you navigate around,

17:39 ah, cool

17:41 lisppaste8: Jonathan Smith annotated #82507 "annotation" at http://paste.lisp.org/display/82507#3

17:41 JAS415: well i put what i was thinking about up there

17:42 Anniepoo: thanks

17:42 JAS415: user could even be a hash table that gets destructured containing user information

17:43 Anniepoo: yes, for the moment it's just the ref to the swing panel. I'm (obviously) a total noob and making small things

17:44 JAS415: :-)

17:45 Anniepoo: thanks for the help

17:48 JAS415: i'm a java noob so i'm struggling here too if it makes you feel any better :-)

17:50 Anniepoo: I've written java since the early java days. Last functional language I wrote in was LiSP in college (cards, I have gray hair)

17:51 lisppaste8: Anniepoo annotated #82507 "untitled" at http://paste.lisp.org/display/82507#4

17:52 Anniepoo annotated #82507 "untitled" at http://paste.lisp.org/display/82507#5

17:52 Anniepoo: ok, I seem to have found what I wanted with def/binding but it's flipping when I do the swap!

17:52 Jetien: can somebody tell me how to get a repl which throws an error when an unexpected EOF is detected?

17:53 hiredman: ,(doc swap!)

17:53 clojurebot: "([atom f] [atom f x] [atom f x y] [atom f x y & args]); Atomically swaps the value of atom to be: (apply f current-value-of-atom args). Note that f may be called multiple times, and thus should be free of side effects. Returns the value that was swapped in."

17:53 hiredman: swap! takes a function

17:53 Anniepoo: hmm

17:54 hiredman: I imagine you are doing something like (swap! some-atom some-jpanel)

17:54 Anniepoo: yes

17:54 hiredman: well, swap! takes a function

17:54 ,(doc reset!)

17:54 clojurebot: "([atom newval]); Sets the value of atom to newval without regard for the current value. Returns newval."

17:54 Anniepoo: thanks

17:55 lisppaste8: mblinn pasted "compile" at http://paste.lisp.org/display/82519

17:55 mblinn: so, should that work?

17:55 hiredman: don't put the compile in there

17:55 mblinn: as in, should I be able to compile that code using (compile)

17:55 well

17:55 hiredman: that will cause a loop

17:55 mblinn: I'm running the compile from a repl

17:56 hiredman: what happens?

17:56 mblinn: com.randomfault.cimeleon=> (compile 'com.randomfault.cimeleon)

17:56 #<CompilerException java.lang.ClassNotFoundException: (org.jibble.pircbot.PircBot) (cimeleon.clj:1)>

17:56 and yeah

17:56 Anniepoo: 8cD

17:56 mblinn: it's on the classpath

17:56 hiredman: are you sure?

17:56 mblinn: that is, the library is

17:56 well

17:57 hmm

17:57 hiredman: ok

17:57 :entends does not take a list

17:57 so remove the parens

17:58 http://clojure.org/API#gen-class

17:59 java has single inheritence, you are generating a java class, so why would there be a list of classes extended?

18:00 mblinn: yeah, stupid mistake

18:00 thanks

18:02 hiredman: I've found pircbot to be very usable with proxy, just setNick after you connect

18:02 mblinn: ah

18:03 hiredman: clojurebot uses pircbot

18:03 clojurebot: where are you?

18:03 clojurebot: http://github.com/hiredman/clojurebot/tree/master

18:03 mblinn: hmm

18:03 yeah that makes sense, just seemed like a good opportunity to figure out how gen-class worked

18:03 thanks mate

18:03 hiredman: ~proxy

18:03 clojurebot: proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays.

18:03 mblinn: heh

18:22 JAS415: cool i just did persistent caching via memoization (more or less) :-)

18:41 what does 'no matching ctor found for class clojure.core$complement_3539$fn3541

18:41 '

19:02 cemerick: hiredman: heh, I've been completely ignorant of reset!. I've been doing (swap! atom (constantly foo)) all this time. :-(

19:36 combas: how long has clojure been in development, about when did it start?

19:45 duck1123: combas: AFAIK, about a year and a half

19:45 less than 2 years

19:46 the 1 year birthday was in nov or oct IIRC

19:46 mblinn: I think it's been public for that long, but in development for over 3 years

19:53 rhickey: http://www.apress.com/book/view/9781430272311

19:55 http://code.google.com/p/clojure/source/browse/trunk/src/org/clojure/runtime/Cons.java?r=3

20:09 jackdempsey: how far things have come, eh? :-)

20:09 rhickey: yup

20:13 a mere 1400 checkins

20:31 jackdempsey: anyone know of people using clojure with a lot of text analysis, NLP, etc?

20:31 really considering porting some stuff, curious to learn what others have who've gone before me :-)

20:40 combas: that's quite amazing really

20:41 jackdempsey: yeah, i can't believe its not more checkisn

20:45 combas: man programming book titles always make me laugh when they use words like definitive, might as well just say 'best evar!'

20:45 im sure its a fine book though

20:48 hiredman: I'm going to be gone for a week, so no one break clojurebot

20:50 holmak_: clojurebot: P =? NP

20:50 clojurebot: Excuse me?

20:53 grrrt: what a disappointment clojurebot!

20:55 holmak_: Clearly Clojurebot was not manufactured to the highest of standards.

20:55 I think #haskell has the most epic ircbot

20:55 They may have as many as 3, I don't remember...

20:56 I think #haskell's lambdabot actually knows how to write Haskell, which makes it smarter than me.

20:56 duck1123: ,(= :p :np)

20:56 clojurebot: false

20:57 duck1123: $1,000,000 please

20:58 holmak_: Your proof... I find it somehow suspicious.

21:12 combas: ,(+ 2 4)

21:12 clojurebot: 6

21:12 combas: cool

21:33 weissj: how do i get map to return a vector

21:33 or convert list to vector i guess

21:34 ,(map inc [2 3 4])

21:34 clojurebot: (3 4 5)

21:36 weissj: ,(vec [2 4 5])

21:36 clojurebot: [2 4 5]

21:36 weissj: ,(vec '(2 3 4))

21:36 clojurebot: [2 3 4]

21:36 weissj: ah there we go

22:05 dreish: map doesn't return a list.

22:14 stuarthalloway: I am going to bring contrib up to date with the move of test-is to clojure.test

22:15 Chouser: stuarthalloway: thanks!!

22:15 stuarthalloway: should I add stub packages that throw exceptions?

22:15 and document to the mailing list the breaking change?

22:15 Ina: Hello

22:18 Chouser: Ina: hi.

22:18 Ina: Is there a good introduction to Clojure for someone unfamiliar with the functional paradigm?

22:18 +Somewhere

22:19 Chouser: stuarthalloway: I don't know what you mean. stub packages for what?

22:19 stuarthalloway: clojure.contrib.test-is

22:19 Chouser: ohhh...

22:19 sorry, just got it.

22:19 codyK: ina, stuart halloways book is good

22:19 stuarthalloway: codyK: thanks! :-)

22:19 Ina: Something no-budget?

22:19 * Ina is poor

22:19 codyK: seriously i would have said the same thing were you not on

22:20 i got it for less than $20 USD

22:20 dunno if thats feasible for your financial situation

22:20 but its not an expensive book as computer books go

22:20 stuarthalloway: which raises the question of a (deprecate [namespace options]) function to automate deprecating namespaces and functions

22:21 codyK: http://jnb.ociweb.com/jnb/jnbMar2009.html

22:21 thats also a good tutorial

22:21 Chouser: Ina: I learned by trying to solve projecteuler problems

22:21 Ina: I know computer books are expensive

22:22 * Ina is a compsci major, which comes with the requirement to buy them.

22:22 Chouser: Ina: they start simple, but doing them in clojure will definitely reward solving them functionally.

22:22 Ina: and when you get stuck, the problems are small enough that people here can help.

22:23 stuarthalloway: I dunno -- seems to me that announcing the change on the g.group and just removing the old namespace should be sufficient.

22:24 stuarthalloway: we still need a 1.0 tag + download

22:24 clojurebot: download is http://code.google.com/p/clojure/downloads/list

22:24 stuarthalloway: well, I will start with that

22:24 Chouser: yeah--any particular reason that is held up

22:25 Chouser: stuarthalloway: nope, just no selfless soul has stepped up to do it yet.

22:25 Ina: If I have the eclipse clojure plugin, does that come with the necessary libs?

22:25 stuarthalloway: is it that nobody wants to step forward and say "I am the person in charge"

22:25 Chouser: stuarthalloway: perhaps

22:26 I imagine I'll do it eventually if nobody else does, but I think I'm a poor fit for release engineering in general.

22:34 durka42: ~forget download

22:34 clojurebot: I forgot download

22:34 durka42: ~download is http://github.com/richhickey/clojure/downloads

22:34 clojurebot: 'Sea, mhuise.

22:34 durka42: ~svn

22:34 clojurebot: svn is http://clojure.googlecode.com/svn/trunk/

22:34 durka42: ~svn is passé

22:34 clojurebot: Ok.

22:35 durka42: ~svn is also use git

22:35 clojurebot: Ok.

22:35 durka42: ~git is http://github.com/richhickey/clojure/tree/master

22:35 hmm

22:35 clojurebot: git?

22:35 clojurebot: git is http://www.github.com

22:35 durka42: ~forget git

22:35 clojurebot: I forgot git

22:35 durka42: ~git is http://github.com/richhickey/clojure/tree/master

22:42 jackdempsey: fwiw, just have to say, the Programming Clojure book is excellent

22:43 first computer programming book i've actually bought and gotten mostly through in a few days :)

22:44 hain: it helps that there's aren't ten chapters on syntax alone :)

22:45 codyK: the contrast with the scala book i read near the same time is amazing

22:47 Chouser: stuarthalloway: did you see there's another book in the works?

22:47 stuarthalloway: chouser: no, that's awesome

22:48 codyK: hopefully it's better than practical ocaml

22:48 Chouser: stuarthalloway: http://www.apress.com/book/view/9781430272311

22:49 stuarthalloway: interesting... not on amazon yet

22:50 hopefully the second of many

22:50 practical common lisp was very good, so high hopes

22:59 Drakeson: what it takes to search, obtain, and maintain the latest version of set of libraries (plus their dependencies), from the maven repository?

23:01 drewr: What's Luke's nick?

23:04 Chouser: he doesn't appear to be a registered contributor.

23:06 and grepping for various obvious derivitives of his name isn't turning up anything in the logs.

23:07 drewr: Hm.

23:08 Chouser: he's posted quite a bit on the g.group.

23:08 drewr: Ah.

23:09 I thought his name sounded familiar.

23:10 Chouser: To the DC study group as well.

23:18 jackdempsey: nice, would love to see some DC clojure get togethers

23:21 Chouser: jackdempsey: I believe they meet regularly

23:21 jackdempsey: ah cool

23:21 will have to look it up

23:22 Chouser: http://groups.google.com/group/clojure-study-dc

23:24 jackdempsey: oh nice, thanks!

23:24 now to just find the time :-)

23:45 combas: Ina: still around? I think this is quite a good free book http://en.wikibooks.org/wiki/Clojure_Programming

Logging service provided by n01se.net