#clojure log - Jul 28 2009

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

0:18 durka42: has anyone tried to play with clojuratica?

2:35 hiredman: ,(eval #=(java.util.ArrayList. (+ 1 2)))

2:35 clojurebot: DENIED

2:35 hiredman: oh

2:35 Right

2:37 I think I would like clojure to treat any java.util.List as a function call

2:49 ,'#=(java.util.ArrayList. (+ 1 2))

2:49 clojurebot: #<ArrayList [+, 1, 2]>

3:01 * hiredman tries to figure out where clojure decides which types to treat as function application

3:04 hiredman: ah

3:06 ugh

3:36 kylesmith: Anyone else have the joy of working with clojure then having to switch to fortran? It SUCKS

3:39 rys: clojure to almost anything else has the same property

3:43 AWizzArd: kylesmith: while you are at it, prove that the saying "Lisp will make you a better programmer" is true :-)

3:47 kylesmith: Oh, it's pretty bad. There's copy & paste all over the place. There are ~5 versions of the code (copies in people's home directories) with varying features and input/output formats.

3:48 AWizzArd: Yes, in my opinion, "good programmers use lisp, and lisp makes good programmers better."

3:53 For example, there are ~50 places where there are nested loops with the same basic body, but minor differences. Those differences could easily be passed in as a function.

4:15 angerman: if I proxy a class, can I access it's private members? if so, how?

4:34 tomoj: trying to do a bit of lazy recursion, seems to be an infinite loop, I can't figure out why. https://gist.github.com/4317ccd3662750ec3876

4:35 it's supposed to be a lazy seq for the bits you get by starting with "10", then each iteration you concat the string with itself and chop off the last bit (so, "101", "10110", "101101011"...)

4:38 I thought wrapping the body in lazy-seq would prevent the endless recursion. hmm

4:43 Chousuke: tomoj: I think you need (lazy-seq (cons prev-bits (bits ...)))

4:48 tomoj: Chousuke: I wasn't clear, the sequence of bits is generated many bits at a time (each iteration the sequence almost doubles in length), but I'm trying to build a lazy seq that just gives you one bit at a time

4:49 Chousuke: hmm

4:51 ,(take 10 (apply concat (iterate (fn [x] (concat x (butlast x))) [1 0]))))

4:51 clojurebot: (1 0 1 0 1 1 0 1 1 0)

4:52 tomoj: strange, that code looks right, but the answer is wrong

4:53 Chousuke: well, it starts with 10

4:53 then 101

4:53 tomoj: oh, I see, the iterations are all stuck together

4:54 Chousuke: ,(take 3 (iterate (fn [x] (concat x (butlast x))) [1 0])))

4:54 clojurebot: ([1 0] (1 0 1) (1 0 1 1 0))

4:57 tomoj: trying to get (take 10 ...) to return (1 0 1 1 0 1 0 1 1 1)

5:04 Chousuke: ,(take 10 (apply concat (iterate (fn [x] (concat x (butlast x))) [1 0 1]))))

5:04 clojurebot: (1 0 1 1 0 1 1 0 1 0)

5:05 Chousuke: hmm

5:08 ,(take 10 (apply concat (iterate (fn [x] (concat x (butlast (concat x (butlast x)))) [1 0 1]))))

5:08 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$iterate

5:11 Chousuke: ,(take 10 (apply concat (iterate (fn [x] (concat x (butlast (concat x (butlast x))))) [1 0])))

5:11 clojurebot: (1 0 1 0 1 0 1 0 1 0)

5:12 Chousuke: hmmh

5:37 angerman: how do I access a member of a class?

5:37 (. myinst field) seems not to work :(

5:38 Chousuke: it should

5:38 but you should use (.field obj) instead

5:39 if it's a static field, Classname/field will work

5:53 tomoj: Chousuke: https://gist.github.com/4317ccd3662750ec3876

5:53 that works

5:53 angerman: Chousuke: it's a private field

5:53 tomoj: but I'm sure there is a prettier way to do it

5:55 angerman: Chousuke: so what I do is: create a swing class with NetBeans

5:55 create a clj file with (ns com.test.myclass :gen-class :extends Frame :post-init setup)

5:56 and then I define (defn -setup [inst] (prn (.textbox inst)))

5:58 And then I get No matching field found: textbox for com.test.myclass

6:01 ok, I'm astonishingly stupid

6:02 private fields are not accessable from within the class not from subclasses as I understand

6:12 AWizzArd: When I have a public field in an instance of a Java class, how can I then access it from within Clojure?

6:12 A public non-static field. So, not like Character/MATH_SYMBOL or something like that.

6:13 ,Character/CURRENCY_SYMBOL

6:13 clojurebot: 26

6:13 AWizzArd: if there is not a getter for that non-static public field...

6:18 rottcodd: AWizzArd: (.instanceMember instance args*)

6:28 AWizzArd: thx

7:07 lpetit: Hi all

7:07 Uh oh, still sleeping or just awakening in the U.S. :-)

7:46 Fossi: hi

8:47 cemerick: rhickey: you'll likely find this interesting, assuming you haven't already seen it: STM.NET: http://blogs.msdn.com/somasegar/archive/2009/07/27/stm-net-in-devlabs.aspx

8:48 Chouser: I assume that's the kind of STM where they let you go on your merry with with mutable object fields and such?

8:49 cemerick: yeah. Ostensibly compatible with manual locking as well.

8:50 rhickey: cemerick: thanks, another entry in the slap transactions on mutable OO game

8:51 cemerick: which, hell, might work with some trickery under the covers. What I do know is that I've enjoyed not having to worry about locks and race conditions over the past year, so I'd rather not have any developer-controlled locks anywhere near my code.

8:52 (maybe "userland-locks" is a better term)

8:52 Chouser: I think the biggest danger there is the common name with Clojure's feature. ...if such schemes succeed then why use Clojure? ...if they fail, why is Clojure using a debunked technology?

8:52 cemerick: Chouser: you mean "STM"?

8:52 Chouser: cemerick: right

8:52 rhickey: Chouser: I just had the same thought, maybe it's a misnomer in Clojure since it doesn't ever pretend its reference types are fields

8:53 cemerick: well, the first time I ever heard about STM was in connection with haskell, which certainly doesn't look like anything the .NET guys are doing *shrug*

8:53 rhickey: OTOH, Cliff Click, Brian Goetx et al are quick to pick up the difference in Clojure that mutable things are called out as such

8:53 Goetz

8:53 Chouser: Transactional Reference Types

8:54 rhickey: because in many STM designs there are holes re: what happens if you touch the field transactionally and non

8:55 cemerick: I remember listening to a podcast introducing the STM concept, and the interviewee said STM:locking::GC:malloc -- with that perspective, it's easy to see that there can be widely disparate approaches to STM, so if one works (or not), it doesn't indicate anything about others.

8:55 rhickey: cemerick: true, but that point needs to be made a lot right now, people are making broad statements about STM that simply don't apply to every approach

8:55 Chouser: anyway, my central reasons for choosing and loving Clojure continue to have little to do with concurrency. I hope people realize that if STM in general or even Clojure's current approach breaks down in some scenario, that's no reason to abandon Clojure's other unique features.

8:57 cemerick: rhickey: I'm sure there will be a period where some widely-available STM will just fall down, leading many to say that it doesn't work (the way that early Java GC made people say GC was a broken concept, despite the scads of other VMs that had GC working well years before)

8:57 Chouser: and of course Clojure's STM isn't terribly deeply embedded in the language implementation. A new set of reference types with some new organizing feature could live alongside and/or replace the current STM.

8:57 cemerick: Chouser: I think as soon as an alternative STM impl is written for clojure (which seems semi-inevitable), that will clarify things.

8:58 rhickey: Chouser: I'm looking forward over the next year to demonstrating more of the value of the persistent data structures outside of concurrency, but that is the easiest case to make for FP - with concurrency mutability is a catastrophe

8:58 cemerick: hah!

8:58 Chouser: cemerick: :-)

8:59 rhickey: It's much harder to tell people their programs are too hard to understand

8:59 Chouser: heh

9:00 Chousuke: well, it helps even with single-threaded code; you don't have to worry about some class somehow obtaining a reference to data you're using and modifying it as part of its private implementation when you call its API.

9:01 but I guess that

9:01 that's just functional programming in general*

9:01 rhickey: Chousuke: right

9:02 Chouser: until someone has experienced it, how can I describe the sinking feeling I get when I realize a function is written imperatively, and I'm going to have to pay a lot of attention to the order of operations, which ones mutate what, etc.

9:03 rhickey: the sinking feeling when facing a method that returns void, or that takes or returns a mutable collection...

9:03 Chouser: the panic climbing my spine as I realize how many different classes and methods I'm going to have to keep in my head to understand the 5 lines in front of me

9:04 tomoj: is there already a convenient way to map with (comp fn fn ... fn) where you want n compositions?

9:04 clojurebot: map is *LAZY*

9:04 Chouser: tomoj: you have those fns in a list?

9:04 tomoj: Chouser: no, they're all the same

9:05 rhickey: the pain of learning a different api for every type of information, with no ability to combine it with any other information

9:05 Chouser: tomoj: oh! maybe 'iterate'

9:05 tomoj: that is, I want to map a single function multiple times, really

9:05 Chouser: ah, yeah, I could iterate and take the nth of that lazy seq, good idea, thanks

9:05 cemerick: rhickey: returning to the stable-static-names topic: I had a (likely) stupid idea last night, which you've likely thought of before...

9:06 Couldn't newnew produce the name of the class it generates by hashing the number and names of the fields it closes over? That's roughly what serialVersionId does automatically, and for stable data structures (like the core collections, app-level structs), that should be perfectly compatible with most if not all "ephemeral" serialization use cases.

9:06 lbj: haha, why are you guys whining ?

9:07 rhickey: cemerick: I was thinking about automatic stable name generation yesterday, it's tricky to guarantee uniqueness

9:07 you definitely need to capture context

9:07 as fn names do already by using nesting $ conventions

9:08 cemerick: well, I'm glad I'm only 24 hours behind you ;-)

9:08 rhickey: but that means renaming a creating context breaks things

9:09 but a pure content-based hash would not prevent duplicates created in different contexts

9:10 cemerick: I'm not really following the "context" term -- do you mean conflict between two usages of newnew in the same ns with the same fields?

9:10 rhickey: there were some interesting threads about serialization of anonymous inner classes

9:10 cemerick: sure, why not

9:10 or same fields in different ns

9:10 or different fns in same ns

9:10 do you include the creating fn in the name?

9:11 cemerick: well, same fields in different ns are already different classnames: foo.bar.newnew1234 vs com.foo.newnew1234?

9:12 rhickey: generically, whatever you include in the context part of the name can't change without breaking serialization. The ns might be presumed stable, but I imagine the constructing fn not so much

9:13 cemerick: really? That seems like a *very* reasonable restriction to me.

9:13 rhickey: so, you leave out the fn, leaving ns+hash, even if you hash the supers and fields there can be dupes

9:13 cemerick: we're just talking about constructing fn's name, right?

9:13 rhickey: cemerick: if you buy the fn-name restriction the context is much smaller

9:14 usually 1:1

9:14 so are done

9:14 cemerick: off the top of my head, I'm not sure why that wouldn't be a reasonable constraint

9:15 Similar in concept to "change the Java classname, you can't deserialize previously-persisted graphs"

9:15 Chouser: but this is much more subtle, surely, than a name change.

9:15 rhickey: cemerick: it just seems completely unrelated to the name of the type, might be something like make-foobar

9:16 com.my.ns.make_foobar$obj123456

9:16 also, right now fn names include gensym incrementing id components...

9:16 Chouser: (defn [] (newnew)) vs. (defn [] (let [f (fn [] ... (newnew))] (f))

9:17 cemerick: well, the definition of that fn is intrinsically bound up with the newnew instance it produces -- tying the classname to it in some way makes good sense, at least on the surface.

9:17 rhickey: if they didn't you couldn't redefine the fn

9:18 cemerick: but the fn could do many things, and have subfns each of which creates instances

9:19 cemerick: rhickey: track the fn names through each level of context...? com.foo.make_bar$make_special_bar$obj1234

9:19 rhickey: cemerick: in any case, I'm not sure what problem auto-generated stable names solves, they'll have the same restrictions as provided names

9:19 cemerick: it's hard for me to conceptualize implementation fully, as I'm sure there's stuff going on that I'm entirely unaware of

9:20 Chouser: huh. I just stumbled on another context where I want to turn a series of callbacks calls into a lazy seq, just like lazy-xml does.

9:20 cemerick: rhickey: the point being, they'll be *stable* across builds, assuming fields/context don't change

9:20 rhickey: ,(class ((fn [] (fn[]))))

9:20 clojurebot: sandbox$eval__5324$fn__5326$fn__5328

9:20 rhickey: ,(class ((fn [] (fn[]))))

9:20 clojurebot: sandbox$eval__5333$fn__5335$fn__5337

9:21 rhickey: not changing fn names

9:21 note

9:21 cemerick: rhickey: OK -- don't do that!

9:21 * cemerick waves magic wand :-D

9:22 rhickey: the reason auto-generation of names comes up in the serialization of anonymous inner classes discussions is there is no space on the syntax for a name, but there could be here

9:22 cemerick: seriously, that's a completely different usage than named fns

9:22 rhickey: ,(class (fn foo []))

9:22 clojurebot: sandbox$eval__5342$foo__5344

9:23 Chouser: well, the discussed solution for that was generating a stably-named interface, then a uniquely-named concrete implementation for each re-definition.

9:23 rhickey: rhickey: ,(class (fn foo [])

9:23 ,(class (fn foo [])

9:23 ,(class (fn foo [])

9:23 clojurebot: EOF while reading

9:23 rhickey: ,(class (fn foo []))

9:23 clojurebot: sandbox$eval__5347$foo__5349

9:23 Chouser: but that doesn't help when a serializer wants a stable name for the concrete thing, I guess.

9:23 rhickey: named fns same problem

9:24 cemerick: rhickey: oh, I'm not saying stable names for named fns are produces now, but it seems like that's what could happen in the future.

9:24 rhickey: the conclusion I came to was that autogenerated stable names don't lift any restrictions other than the one that you provide a name

9:25 redefinition without restart would still be precluded

9:25 classloader problems are the same

9:26 cemerick: I think that's pretty reasonable.

9:26 rhickey: I guess they do prevent people from trying to use the name explicitly

9:26 clojurebot: They found no relationship between a programmer’s amount of experience and code quality or productivity.

9:26 cemerick: Well, explicit usage *is* convenient (e.g. passing clojure data structures into clojure APIs from java, etc)

9:28 rhickey: I guess I'm most comfortable with, if you need a name, name it, and it's AOT-only

9:28 cemerick: rhickey: is it possible that redefinition would be allowable given a certain (perhaps init-time) configuration (with big honking warnings for osgi users, etc)? e.g. if I've got a clojure-only production environment and I know what I'm doing, redefing named classes is a helluva feature.

9:28 rhickey: redefinition requires restart would bleed into named fns if you wanted those to be stable as well, soon we're back to java-like dynamism, i.e. not much

9:30 cemerick: well, the use-cases for redefinition of the things you'd want to be named (datastructures, app-level structs) are few and far between (except maybe for you, ironically enough?)

9:30 rhickey: cemerick: no one is really supporting redefintion without reload, they are just auto-reloading

9:30 are you proposing some 3rd party trickery?

9:31 cemerick: you mean stuff like JavaRebel, etc?

9:31 gah, hopefully not

9:32 rhickey: ok, but without something like that I don't have a way to change the definition of a named class

9:32 already loaded

9:32 in classloaders I'm not able to toss

9:34 you are asking me to implement Java Rebel

9:34 cemerick: rhickey: right, I'm throwing a hail mary towards, in a well-defined configuration, clojure doing its own classloader trickery. Clearly 180º away from your stated mission with newnew, but I'm 1 for 1 raising stupid ideas already this morning :-)

9:35 JavaRebel is *extremely* crude.

9:35 A clojure-only scheme would likely be far, far simpler, and in a clojure-only production environment, make life *really* pleasant.

9:35 Just an idea :-D

9:35 rhickey: cemerick: I've never tried it, but it is certainly fighting a boatload of presumptions in the JVM core

9:36 cemerick: that's why I said "in a well-defined configuration" *shrug*

9:36 rhickey: cemerick: even a Clojure-only scheme didn't work out - I can't force everything to use my classloader

9:37 cemerick: absolutely we can, given a clojure-driven app entry point

9:37 rhickey: or are you suggesting I replace the root classloader? is that even possible portably?

9:37 cemerick: no, no need to do that.

9:39 rhickey: so how is some 3rd party library code doing serialization, calling Class.forName, going to use my loader?

9:39 cemerick: e.g. java clojure.lang.DynReloadMain -mainclass com.foo.MyClass, where MyClass would otherwise be my main entry point, but DynReloadMain (or whatever) sets up the classloader regime. I've done the similar things long, long ago to support live application updates.

9:41 rhickey: it works just like any other classloader -- the classpath just gets provided as an application-level argument (rather than via -cp)

9:43 rhickey: cemerick: I could see doing something like that for an app, but for a language? It will enable all kinds of things that can't be supported except when running like tht

9:43 that

9:45 cemerick: *if* the compiler were aware of that potential config, then it would be possible to reload classes via a REPL, rather than hard-swapping new jars, etc (which, you're right, is easily done app- or framework-level)

9:47 rhickey: cemerick: I'm confused, are you pitching for a dev-time or production-time feature? If the latter I don't see how it works at framework level, all the environments have their own classloading scheme in place

9:48 my current focus is on making Clojure a better citizen there, not a trickier one

9:48 cemerick: rhickey: Production-level, and I'm presuming an all-clojure (or, alternatively, no-framework) environment.

9:48 rhickey: anyway, just an idea, and a speculative one at that

9:52 rhickey: cemerick: I guess the fundamental problem is basing language-level capabilities around such contexts

9:59 hrm: http://www.computerworld.com/s/article/9135958/Sun_s_JRuby_team_jumps_ship_to_Engine_Yard?taxonomyId=57&pageNumber=1

10:01 that's kind of a shame

10:01 Chouser: sounds like they'll keep working on JRuby though.

10:02 * rhickey awaits Clojure corporate sponsor...

10:05 rhickey: yes, good they'll be working on JRuby, but sad in that they were an alternative lang inside Sun, with access to people like John rose eager and able to enhance the JVM

10:06 Chouser: yeah

10:06 hope they misjudged the environment, but I guess that strikes me as unlikely

10:15 AWizzArd: rhickey: would it in principle be possible to add a "defclass" to Clojure which would be similar to defstruct from user POV, but internally more like closures, but even more efficient?

10:15 Chouser: more efficient thans closures??

10:15 rhickey: AWizzArd: you should just wait for newnew and try it out

10:16 AWizzArd: Chouser: yes. I did some realistic tests, just because I need it. I prepared a posting for the Group. I already supposed that newnew can be helpful.

10:17 Chouser: anyway, what I found out is that instantiating a StructMap is slower than returning a closure, which is again slower than making an instance of a Java class.

10:18 (defclass Foo #^String x #^clojure.lang.Keyword y) ==> public class Foo { private final String x; private final Keyword y; } plus two getters.

10:19 In Clojure one could then say (def bar (make-instance Foo "Hello" :clojure)) and access the elements via (:y bar) or (:x bar).

10:19 rhickey: AWizzArd: this is not going to happen

10:20 AWizzArd: and (assoc bar :x "Yes") would create a new instance, so (make-instance Foo "Yes" (:y bar)).

10:20 rhickey: would that have negative impact on other things?

10:20 cemerick: AWizzArd: you're describing what I did with gen-bean

10:21 rhickey: AWizzArd: there is already gen-class, could be enhanced for inline defs

10:21 AWizzArd: And? What are your experiences with it?

10:21 cemerick: though the code that's posted publicly is pretty old, and it's improved much since then

10:21 clojurebot: What is meta

10:22 AWizzArd: In my code I also checked how fast read accesses are. I had 340k objects, stored in three different ways: StructMap, closure, Java class. Each object contained 4 fields/slots. Reading all 4x340k fields took 200 msecs for StructMaps and closures. It took 150 msecs for the Java class.

10:22 rhickey: well, I am not particular in favour for a defclass operator, but a mechanism which is achieving that.

10:23 Something that is as simple as a defstruct and which also has the same interface would make those interchangeable.

10:23 * rhickey is focusing on newnew

10:24 AWizzArd: However it is called, it is nice as long it would reduce the pressure to write Java code :-)

10:24 Such a mechanism would widen some bottlenecks. That could be nice.

10:25 But rhickey, I also keep in mind what you said in one of your videos. You said you made the experience in CL that you wrote a nice algorithm with lists and later switched to some other data structure and had to rewrite bigger portions of his code.

10:26 Just an example: if people begin with structmaps and later find out they are too slow they want to rewrite their algorithm with closures maybe. But that would not be so trivial always, because the callers are affected.

10:26 Maybe the newnew is exactly that thing which will give very good performance for immutable throw-away objects.

10:26 rhickey: AWizzArd: I recently added batch mutability and parallel ops to vectors, and am now working on newnew, so, what are you attempting to convey to me?

10:27 no offense, but this is just distracting now, I've heard your request

10:27 AWizzArd: Nothing, I just would like to know if such an operator would be doable. Maybe some mechanisms in the JVM don't allow that.

10:29 Tha parallel stuff sounds exciting, and I am looking forward to see what newnew will bring.

10:34 angerman_: rhickey: as I understand gen-class does nothing when I don't compile the clj?

10:35 rhickey: angerman_: right

10:37 angerman: rhickey: how would I go about extending a given class and overwriting some methods? just proxy it?

10:37 Chouser: angerman: use proxy when you can

10:38 angerman: there are some things it can't do, but it's much more convenient than gen-class

10:38 * angerman is still trying to figure out how to do gui programming with clojure.

10:39 angerman: I quite like netbeans gui builder. so I end up coding some outlets into the gui builders source and overwrite them with clojure

10:39 seems to be the best solution I came up with ...

10:39 Chouser: proxy usually works great for building callbacks or listeners

10:40 angerman: Chouser: ha, :) too stupid is netbeans on this end though :)

10:41 it's guibuilder creates lots of private stuff (esp. callbacks) ... so one can't subclass it's forms straight.

10:42 Chouser: hm.

10:42 AWizzArd: angerman: you can write a public exporter method.

10:43 That gives you access to all gui elements from Clojure.

10:43 Chouser: I'm successfully using proxy to specialize a C++ class (via swig)

10:45 rhickey: angerman: you can set the default access for the things it generates to public

10:45 cemerick: Chouser: That's pretty hardcore :-)

10:46 I need to figure out how to embed assembly into clojure forms. Gotta keep raising the bar.

10:46 Chouser: heh. swig has actually made this pretty easy.

10:47 rhickey: angerman: preferences/options/guibuilder/variablesmodifier

10:47 options/miscellaneous/guibuilder

10:47 Chouser: that is, it's take a few days to figure out the right incantations, but in the end they are short and unrepetetive.

10:48 y-combinator: hello. i have a problem using clj-record. ive cloned from git and successfully compiled using 'ant jar', aded .jar to classpath(both to $CLASSPATH and to extended SLIME classpath. however i always get 'Could not initialize class clj_record.validation__init

10:48 [Thrown class java.lang.NoClassDefFoundError]' and similar errors for another clj-record members.

10:49 angerman: rhickey: I'll look for that in a second

10:50 how do I have to understand this "Each method fn takes an additional implicit first arg, which is bound to 'this."

10:50 I though if my prototype was foo(String a, String b) i'd define (foo [this a b] ...)

10:50 Chouser: angerman: yes

10:50 angerman: in the proxy though it seems I get called like (foo [a b])

10:50 y-combinator: or maybe someone knows another clojure persistence lib? it seems that clj-record is the only one native clojure solution.

10:51 Chouser: angerman: oh, in proxy?

10:51 angerman: yes

10:51 rhickey: angerman: right, 'this' is implicit in roxy, explicit in gen-class

10:51 angerman: so this is just there ok

10:51 cemerick: angerman: this might be instructive w.r.t. 'this':

10:52 Fossi: y-combinator: sounds like a classpath problem. perhaps check the jar if everything is where you expect it to be

10:52 cemerick: ,(str (proxy [Object] [] (toString [] (str "hello from" (class this)))))

10:52 clojurebot: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessDeclaredMembers)

10:52 cemerick: ah, bummer

10:52 Chouser: y-combinator: I believe the -cp command-line option and the CLASSPATH env var don't work well together

10:52 cemerick: angerman: anyway, see above ^^

10:52 Fossi: y-combinator: and did you add the jar, or just the directory where the jar is?

10:53 angerman: cemerick: well I think i was missguided by the line in the proxy doc

10:53 rzoon: lisppaste8: url

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

10:54 cemerick: I think the docs are correct. The 'this' argument is implicitly bound.

10:54 maybe "first" should be omitted, as that's an implementation detail

10:56 Fossi: i found the docs aren't so easy to understand in that case as well

10:56 cemerick: Fossi: "first" being the rough edge?

10:56 or the implicit arg?

10:56 Fossi: it makes sense once you know what happens, but it's easy to be confused by it

10:56 the implicit part i think

10:57 especially since for gen-class'ed methods you have to write it explicitly

10:57 cemerick: yeah, that's a worthwhile point.

10:58 proxy is going a bunch of majick behind the scenes, which might be the motivation there

10:58 or, perhaps just the desire to eliminate repetition of 'this' everywhere.

10:59 ...which definitely can't be easily done in conjunction with gen-class, short of sustaining a perf penalty.

11:01 rzoon: i implemented ssl-server in contrib and would like some feedback if people have a minute

11:01 Fossi: yeah

11:01 or having to "defmethod" or "defmember" instead of defn

11:01 angerman: rhickey: ahh well, yes setting the variables protected/public that did work, but if I create outlets for ActionListener they will always be private :/

11:04 cemerick: interesting that Nutter et al. bailed from Sun.

11:06 AWizzArd: angerman: you can write one simple getter in NetBeans which will return an array (or hashtable or whatever) with all the fields which you want to access.

11:20 y-combinator: strange thing with my clj-record problem is that if i try to include unexisting class i get FileNotFoundException, but when i try to include some class from clj-record i get NoClassDefFoundError

11:21 user=> (require 'clj-record.valudation)

11:21 java.io.FileNotFoundException: Could not locate clj_record/valudation__init.class or clj_record/valudation.clj on classpath: (NO_SOURCE_FILE:0)

11:21 user=> (require 'clj-record.validation)

11:21 java.lang.NoClassDefFoundError: Could not initialize class clj_record.validation__init (NO_SOURCE_FILE:0)

11:21 user=>

11:21 notice error in first require statement

11:25 and if i unpack clj-record.jar there is clj_record/validation__init.class inside

11:26 maybe there is broken meta info in this jar or something...

11:28 rzoom_: here is the diff of the change for the ssl-server in contrib, pastebinned.

11:28 lisppaste8: rzoom pasted "contrib ssl-server" at http://paste.lisp.org/display/84314

11:29 rzoom_: not sure what to do about the ciphers

11:30 Chousuke: why the weird apply args thing?

11:31 rzoom_: could have explicitly laid out 1,2, and 3 arg versions

11:31 Chousuke: it'll only work with a single arg anyway :/

11:31 since the anonymous function takes only one

11:33 also, if you're going to send patches to contrib, you should use git format-patch instead of git diff. That way it'll include the commit info.

11:34 y-combinator: Could someone please send me working copy of clj-record.jar?

11:37 Chousuke: rzoom_: if you want the ciphers to be configurable maybe you could export a *ssl-ciphers* var and use that in ssl-server-socket?

11:39 rzoom_: (binding [*ssl-ciphers* ["some_weird_string_here" "some_more"]] ...); not very clojurey I guess, but perhaps passable.

11:40 rzoom_: yeah, suggestions on that welcome. :0

11:40 erm, :)

11:40 Chousuke: and, function parameters are usually called just "f" :)

11:42 I usually avoid single-character names but in this case it's a convention and I can't think of a better name :P

11:45 rzoom_: sounds good. changing fun -> f and the apply issue

11:49 rhickey: headius: best of luck at EY

11:50 headius: rhickey: thanks much...it feels like the right move to really keep jruby moving forward

11:50 I'll still be at JVMLS, hope to see you there

11:50 rhickey: headius: yup, I'll be there

11:51 headius: I've been contemplating a thin rubygem that bundles either clojure or clojure's collections/etc for rubyists to use

11:51 there's a need for a good immutable collections library in ruby, at the very least

11:51 rhickey: interesting

11:52 headius: and if it was just a "clojure gem" people could use either/or at will

11:53 rhickey: it would be really interesting to see an interface to clojure where you could send across code-as-data rather than strings

11:54 you can obviously from Java, but it's a bit gross, from something like Ruby would be easier

11:54 JRuby that is

11:55 headius: yeah, it would not be at all difficult to build a dsl in Ruby that produces "code as data" in a nice, compact way

11:55 * angerman thinks lazyness just bit him

11:55 headius: a clojure-builder

11:57 Chouser: that sounds neat.

11:59 cemerick: I think something like that in javascript (a simple remoting interface to a clojure backend) would be my ideal web-dev environment.

11:59 headius: it could either be inside-out sexps a la foo {bar {baz 1}} or literal arrays translated behind the scenes a la [foo [bar [baz 1]]]

11:59 either way the structure would be pretty simple to generate

12:00 we have a few folks using jruby+clojure already, so I know there's interest

12:01 Chouser: javascript literal object syntax wouldn't be sufficient for clojure literal maps. JS array -> CLJ vector should be ok. how to do literal lists though? and keywords?

12:01 or am I misunderstanding the context?

12:02 rhickey: Chouser: no, that's the general idea

12:02 Chouser: I'd think ruby would have the same challenge, though it has keywords and perhaps maps covered.

12:02 headius: I suppose that could be [:foo [:bar [:baz 1]]] and basically just *be* a sexp

12:02 Chouser: still need to distinguish between a clojure vector and list

12:03 angerman: :( meh ... clojure.http is giving me Connection Reset errors

12:03 rhickey: yeah, you'd ideally need list/vector/map/symbol/keyword/number/string

12:04 all are components of Clojure's 'sexprs'

12:04 headius: symbol/keyword and list/vector would require differentiation, but that's not a huge issue

12:04 rhickey: I guess many langs have either list or vector, but not both

12:05 as literals

12:05 headius: yes

12:06 wouldn't be difficult as simply keyword-like methods

12:06 rhickey: do JRuby collections implement the corresponding Java collection interfaces? j.u.Map etc

12:07 headius: [foo list(a, b, c, d)]

12:07 rhickey: yes

12:07 there's a bit of mapping/coercion logic across the boundary, but they do impl

12:08 * rhickey wonders how much of the Clojure compiler *needs* the syntax to be persistent data structures...

12:09 rhickey: right now most of the compiler presumes them, because it was written before the Clojure data structures implemented j.u. interfaces

12:09 headius: if we could just produce ruby structures and dump it directly into clojure's compiler, that would obviously be simplest

12:09 rhickey: right

12:09 another consideration for cinc

12:10 headius: we'd need a better way to map symbols, since our symbol type doesn't impl anything you'd find useful

12:10 clojurebot: map is *LAZY*

12:10 cemerick: ...and then another thread twiddles a mutable map passed into the compiler while the latter is doing its thing? *shudder*

12:10 headius: seems like it's doable though

12:10 rhickey: cemerick: exactly, it's so safe and thought-free now

12:11 I really don't know that it is possible, since for Clojure code-as-data also means code as values

12:11 cemerick: too bad there's no j.u.ImmutableList interface, etc.

12:12 rhickey: cemerick: there's a protocol for read-only but that's hardly the same

12:12 and immutable still less than persistent, I'm sure there are places where I just take some data structure handed to me and conj onto it, producing a new value with no hassles

12:13 persistent data structures spoil you forever

12:14 cemerick: indeed. I get very frustrated anytime I need to dig back into our java (1.4-era!) legacy bits.

12:18 Chouser: also no metadata syntax in ruby/javascript

12:19 maybe only needed for type hints (otherwise with-meta might be sufficient), but it'd be a shame to have to change an entire fn def over to a string just because you want to avoid reflection inside somewhere.

12:21 Raynes: I have a Pepperoni Pizza Calzone, and low end tornado probabilities.

13:00 angerman: how would I map over a hash-map?

13:02 stuartsierra: Same as you map over anything else. The argument to your map fn will be Map Entries.

13:05 angerman: wow ... apache http components is verbose

13:13 benno: is there some clojure macro/function that works like ruby's flatten? that is, flattening a multi-dimensional array into a one-dimensional array?

13:13 angerman: yes! it works!

13:14 benno: hmm like [[1 2 3] [4 5 6]] -> [1 2 3 4 5 6] ?

13:14 benno: yes

13:14 stuartsierra: benno: yes, in clojure.contrib.seq-utils

13:15 Fossi: how do you proxy gen-classes

13:17 benno: thanks

13:19 angerman: what's a good response code for "failed login" on the http protocol?

13:19 stuartsierra: angerman: Unauthorized?

13:19 Forbidden?

13:20 angerman: I guess Forbidden is better though still not perfect :

13:20 Unauthorized needs to have the challage option in the response which is not good.

13:33 lisppaste8: Fossi pasted "untitled" at http://paste.lisp.org/display/84326

13:34 Fossi: any clue as to what the dalvik vm is telling me?

13:34 i guess it happened as i put in the clojure-contrib jar into my deps

13:35 i'm verifying that, i guess then it's off to devide and conquer the contrib.jar :\

13:38 fyuryu: not really a Clojure question, but anyone used the asm library that comes with Clojure?

13:39 stuartsierra: fyuryu: I played with it a bit

13:39 fyuryu: I'm trying to generate simple classes (with only fields)

13:40 stuartsierra: do you know how to set a final static field (not primitive type) when generating a class?

13:41 stuartsierra: 'fraid not

13:41 fyuryu: the visitField method only accepts string, integer etc.

13:42 stuartsierra: I'll keep on trying

13:42 stuartsierra: isn't there a different visit method for static fields?

13:43 fyuryu: fyuryu: I also tried with putStatic in a static ctor that also failed

13:43 err, that was to stuartsierra

13:44 * mrsolo reads up on performance discussion in goggle group..

13:46 stuartsierra: side note from yesterday: (let [x 1, y 2] (fn ...)) generates a class with instance fields x and y

13:48 fyuryu: stuartsierra: hm, that part of Clojure is implemented in java. I'll have a look

13:48 dysinger: wtf is headius doing in here ;)

13:48 headius: shhhh

13:48 dysinger: :) j/k

13:49 Fossi: great. no wonder this code was acting all strange. i didn't have my changes deployed for the last couple of hours

13:49 and i really wondered, why it all wouldn't work

13:50 headius: dysinger: how you been? doing all clojure now?

13:53 lbj: Does anyone have that Java cup logo wear the vapor was a lambda ?

13:54 Chouser: lbj: I've got one where the vapor is a devilish face

13:54 lbj: Ok

13:55 dysinger: headius no we are converting to jruby from mri and using clojure w/ hadoop on the backend for it's functional immutable goodness :)

13:55 (jruby on the front end)

13:55 headius congrats on the team move :) that's really cool

13:56 Chouser: lbj: http://www.zazzle.com/java_2_evil_edition_2_logos_mug-168138170629314846

13:56 fyuryu: stuartsierra: but those fields are probably of Object type, and I can generate those

13:56 with no problem

13:56 dysinger: headius: hope it works out - I was really taken aback by the oracle tak over

13:56 s/tak/take

13:56 lbj: Chouser: Thanks but no thanks, I need it to put on my website, and naturally I dont want to associate with anything evil/devilish

13:57 Chouser: lbj: ah, I see.

13:57 stuartsierra: fyuryu: no, they can be type-hinted

13:57 fyuryu: stuartsierra: oh, right!

13:58 headius: dysinger: you should find some time to wire up a clojure gem that exposes its collections and maybe provides a nice API/DSL for dumping code into clojure from Ruby

13:58 for the collections alone there'd probably be a bunch of folks interested

14:05 stuartsierra: it's actually pretty straightforward without any conversion, since they implement the java.util interfaces

14:08 headius: stuartsierra: yeah, probably true, I would only expect that a wrapper would define any additional complement of Ruby methods users would expect

14:09 we do decorate List and Map and Enumerable and so on already

14:09 so there might not be much to do

14:09 but having it in a gem would mean you could "gem install clojure" and have it just be there

14:46 rzoom_: ok, updated ssl-server, comments please.

14:46 Raynes: (comment Hi there.)

14:46 :p

14:46 lisppaste8: rzoom pasted "ssl-server" at http://paste.lisp.org/display/84337

14:47 rzoom_: ; nice

14:48 ugh, 'fun' in the description, should be 'f'

14:48 Chousuke: rzoom_: I just now noticed, but what is the doto for?

14:48 rzoom_: to set the ciphers

14:48 Chousuke: rzoom_: you're only doing one operation :/

14:49 (.setEnabledCipherSuites ss ciphers) would be enough :)

14:49 rzoom_: would that return the ss object?

14:49 or the result of the member function call?

14:49 Chousuke: ah. probably not.

14:50 but you could explicitly return ss after it I guess.

14:50 rzoom_: yeah, matter of style I guess

14:51 Chousuke: That repetition annoys me though. I wonder if there's a way to get rid of it :/

14:51 rzoom_: yeah, that was my original though with using the apply before somehow

14:51 all 3 versions are essentially identical

14:52 rhickey: poll - what's the greatest number of args you have in a finite arity fn?

14:52 drewr: rhickey: I use defnk after about two

14:52 rhickey: really?

14:52 Fossi: what's defnk?

14:53 ataggart: 5

14:53 Fossi: ,(doc defnk)

14:53 clojurebot: "clojure.contrib.def/defnk;[[fn-name & fn-tail]]; Define a function accepting keyword arguments. Symbols up to the first keyword in the parameter list are taken as positional arguments. Then an alternating sequence of keywords and defaults values is expected. The values of the keyword arguments are available in the function body by virtue of the symbol corresponding to the keyword (cf. :keys destructuring). defnk accepts

14:53 rzoom_: have one with 6

14:53 Chousuke: rzoom_: I suppose it won't work to pass nils to the three-argument version?

14:53 Fossi: neat

14:53 drewr: rhickey: seems to be my pattern lately; definitely by 5 or 6 though

14:54 rzoom_: Chousuke: null pointer exceptions :(

14:54 drewr: if I'm passing in that much maybe the fn is trying to do too much

14:54 stuartsierra: poll answer: 6

14:54 hiredman: 6 sounds like a lot

14:54 :P

14:55 drewr: unless it's a configuration-type fn, like setting up a db conn, where it makes sense to use keywords

14:55 stuartsierra: that's the max, typical is 1-2

14:55 rzoom_: doing simulations, seem to carry around quite a bit of state

14:55 rhickey: counter-poll: who would be troubled if I reduced the fixed-arity max in IFn (currently 20) to say, 10?

14:56 stuartsierra: wouldn't hurt me

14:56 Chousuke: I would be troubled if I saw a function taking 10 arguments :P

14:56 Chouser: I don't think I have more than 6. 10 is a sane limit

14:56 Chousuke: trying to cut back on the amount of copy-paste code you need? :)

14:58 ataggart: 10 sounds sensible to me

14:58 Fossi: i just saw the 20 limit and wondered: that seems a whole lot

14:58 stuartsierra: Maybe you need to implement Macros for Java (TM).

14:58 Fossi: so 10 is more reasonable

14:58 rhickey: poll3: If I could give you the ability to declare long and double primitive args (any combination, with Object too), how many args would you really really need for fns taking primitives? (hint: 3 or 4 are good answers)

14:59 hiredman: 4 sounds good

14:59 Chousuke: people needing more should be able to emulate it with (defn foo [a whole lot of args and & [then some more]]), right?

14:59 stuartsierra: can't think I'd use that much, personally, but I don't do much math

15:00 Raynes: I think 11 sounds reasonable. Even numbers aren't my thing.

15:00 hiredman: 4 would be nice because you could at least pass in two 2d coords

15:02 Raynes: I say 3 because 4 is an even number. >:|

15:02 hiredman: hmmm, seafunc moved meeting locations to place that I actually sort of know where it is

15:04 Drakeson: can I require A.X, A.Y, A.Z all as A?

15:05 ataggart: Drakeson: huh?

15:05 you want to require everything in the A ns?

15:06 Drakeson: ataggart: yeah, almost. everything in one of A.X, A.Y, A.Z

15:06 hiredman: I think he wants to agragate functions in subname spaces and make them available from a single root namespace

15:06 Chouser: ,(let [f (fn [a b c d e f g h i j k l m n o p q r s t & [u v w x y z]] [a z])] (f 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1))

15:06 clojurebot: nil

15:06 Raynes: You want qualified imports?

15:07 ataggart: ah, so using :as with multiple ns

15:07 not sure if that's possible

15:07 Drakeson: *sad*

15:07 hiredman: Drakeson: you can remove and namespace declarations from A.* and jsut have A load the files so everything shows up in the A namespace

15:07 ataggart: note it's very possible I'm wrong

15:08 alternately, you can use 'use and avoid the ns altogether

15:08 Drakeson: hiredman: I didn't get it.

15:09 ataggart: aliasing java packages would be teh awesome

15:09 Drakeson: hiredman: assume A=clojure.contrib Now, what I can do?

15:09 hiredman: Drakeson: suck it up :P

15:09 ataggart: use 'use

15:09 hiredman: no

15:09 use require

15:10 ataggart: bah

15:10 use and :only is fine

15:10 hiredman: REQUIRE!

15:10 ataggart: lol

15:10 Drakeson: ataggart: I cannot use USE. please.

15:10 ataggart: then I echo hiredman's sentiments, re. sucking it up.

15:10 Drakeson: hiredman: so, is it possible with REQUIRE?

15:11 hiredman: nope

15:11 and don't do wnat you want to do

15:11 hoeck: rhickey: regarding poll3, processing (processing.org) and the clojure wrapper rosado.processing has a quad method which takes 8 primitives

15:12 * Drakeson head-desk suck-it-up!

15:12 hiredman: Drakeson: what you seem to want to do is similar to java's import * which just makes code hard to read

15:13 Drakeson: hiredman: it is not *, I want to hand pick only a few of them.

15:14 hiredman: well, write a macro to set it up for you

15:14 http://clojure.org/namespaces has the functions you will need

15:16 Drakeson: I'd rather poke people until (:require [A X Y Z] :as B) starts working :p

15:17 stuartsierra: not going to happen

15:17 hiredman: clojurebot: people?

15:17 clojurebot: max people is 164

15:17 hiredman: that's what you always say!

15:18 ~max people is 5

15:18 clojurebot: You don't have to tell me twice.

15:18 stuartsierra: but somewhere in contrib there's a fn to import vars from another namespace as public symbols, so you can merge namespaces

15:19 Drakeson: I guess the better approach would be to not to make conflicting sub-namespaces in the first palce, and don't create too many subs.

15:20 hiredman: wait

15:20 what?

15:20 conflicting sub-namespaces? what does that mean?

15:20 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

15:21 Drakeson: hiredman: i.e. if I (use '[A X Y Z]) it does not break.

15:21 hiredman: clojurebot: thanks dork-ticon

15:21 clojurebot: No entiendo

15:21 hiredman: use require

15:22 ataggart: Drakeson: what is the actual problem you're having?

15:23 Fossi: coming from erlang you are kinda tempted to write multimethods everywhere

15:24 rhickey: hoeck: it wouldn't impact your ability to call such methods, this is about your own fns. I guess if you were trying to wrap it...

15:24 Drakeson: ataggart: the problem is that I don't like sub-namespaces with so few symbols. They should merge them already.

15:24 ataggart: Drakeson: perhaps pasting the code will help, because it's not clear to me what the *actual* problem is

15:25 hiredman: Drakeson: *shrug*

15:26 I don't see why namespaces that only export a few symbols are a problem

15:28 Drakeson: hiredman: ok, how would you call those symbols? (mylongname.mylongsubname1.foo) ?

15:29 hiredman: (:require (mylongname [mylongsubname1 :as subname]))

15:29 (subname/foo)

15:30 Drakeson: hiredman: now, imagine a package where you need a few of those mylongsubname1's each contributing only a few symbols, and you have to come up with artifical names (such as `subname') that again, do not help with reading the code later.

15:31 hiredman: sure they do

15:32 you have an explicit maping between the real namespace and the alias at the top of the file

15:33 so you can figure out where all these symbols come from

15:33 you don't have to use :as

15:33 you could just use the long name, I mean you do have an editor with completion right?

15:33 Drakeson: hiredman: that makes it *possible* to understand what subname/foo means. but that does not make it *easy*. you have to remember the top of the file ...

15:33 lbj1: rhickey: Do you have an online list of all this interesting research papers you've based Clojure on ?

15:33 s/this/these

15:34 ataggart: http://www.amazon.com/gp/richpub/listmania/fullview/R3LG3ZBZS4GCTH/ref=cm_pdp_lm_title_1

15:34 lbj1: I believe that was rich's list

15:35 lbj1: Wow - Rich reads alot :) Thanks

15:35 hiredman: Drakeson: I, uh, if you can't even remember how to scroll up until the top of the file, I don't know that you can be helped

15:35 lbj1: I hate to see though, that Clojure is in part based on "Javascript - The definitive guide"

15:37 Drakeson: hiredman: please! What is so good about namespaces exporting very few names?

15:37 ataggart: Drakeson: why does the quantity of functions matter?

15:37 either you want them namespaced or you don't

15:39 hiredman: exactly

15:39 it's about a cenceptual grouping of code

15:39 Drakeson: ataggart: I just don't want to go too deep (foo.bar.baz/x). If the names under foo do not conflict I would rather logically consider all of them as `names coming from package foo', learn package foo, and then use them as foo/x.

15:40 ataggart: using your example, there is no package "foo"

15:40 hiredman: it's not about "every 24 functions needs to be split out to their own namespace, a namespace with less then 15 functions exported is under utilized"

15:40 ataggart: or to put this in a real context, "clojure.contrib" is not a useful namespace

15:40 hiredman: are namespaces a scarce resource?

15:40 are we going to run out?

15:41 Drakeson: clojure.contrib is not a single "package"

15:42 it is a bunch of serperate namespaces because it is a bunch of seperate modules

15:44 there is no hierarchy of namespaces

15:44 just like there is no hierarchy of java packages

15:44 import java.awt.* does not import java.awt.event.*

15:45 Drakeson: hiredman: in case of contrib, yes. that is special. but there are other packages where the package is big (using several other jar dependencies, etc.), and I understand why the designer divides them up into logical sub-spaces. But from the library user it might be easier if *unnecessary* divisions are not seen in when you call them.

15:45 hiredman: Drakeson: that is a library designer's choice

15:46 for example, core.clj has a lot of it's printing stuff implemented in core_print.clj put there is no clojure.core-print namespace

15:46 ataggart: same with pprint

15:46 hiredman: if you want to wrap the api the library designer provides, then you can

15:46 ataggart: lots of files, one ns

15:47 hiredman: but the idea that clojure.contrib.* is a super namespace is jsut wrong

15:48 a namespace (or package name in java) is not a path

15:48 it is easy to confuse them as a path because of the maping to the filesystem via the classpath

15:49 but clojure.contrib.foo and clojure.contrib.bar are distinct names

15:49 that just happen, if you call str on them to return strings that contain a similar prefix

15:50 Drakeson: hiredman: I get your point about contrib.

15:51 I still stand corrected (actually annoyed!) that some library designers create too many unnecessary divisions with few symbols in each. I guess I have to suck it up and just type in as long-names as they choose ...

15:52 kotarak: Drakeson: that's what's :as is for...

15:52 hiredman: or write them an email

15:52 Drakeson: hiredman: yes, that sounds like the right thing to do.

15:57 hiredman: I've been thinking about plugin like mechanisms, (require 'foo.some.provider) would load the plugin and then the plugin would define some methods on a multimethod defined in some other namespace

15:57 so the plugin namespace wouldn't even export any thing

15:58 Drakeson: why that should not be `USE' ?

15:58 hiredman: it could be :P

15:58 I jsut like require

15:58 kotarak: hiredman: used that before. Works like a charm. eg. in ClojureQL the different backends just modify multimethods in the main namespace. You just say (require 'dk.bestinclass.clojureql.backends.derby) et voila...

15:59 hiredman: maybe I should use clojureql

16:00 lbj1: Absolutely :)

16:00 kotarak: Well. I think it has some neat uses of multimethods. But it's quite a mess at the moment... :)

16:01 hiredman: well, I was thinking about this plugin stuff in the context of persistent storage, and was going to use derby

16:03 lbj1: ClojureQL and Derby are good friends

16:08 hiredman: ~literal [3] scala

16:08 clojurebot: <reply>{((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

16:09 * stuartsierra published a Clojure/Hadoop library: http://github.com/stuartsierra/clojure-hadoop

16:10 hiredman: ooo

16:10 mebaran151: clojure could really use a nicer pkg management system akin to rubygmes

16:11 Fossi: and also not like asdf or maven ;)

16:11 * kotarak is happy with Ivy.

16:12 stuartsierra: mebaran151: I talked about that at Philly Lambda. The existence of AOT-compiled files and gen-class makes it harder.

16:12 cemerick: mebaran151: or osgi, or felix (?) or ivy or whatever netbeans uses :-)

16:12 Fossi: i guess building on ivy/maven might not actually such a bad idea

16:12 mebaran151: oh come now those aren't real because you can't search them

16:12 the coolest part of rubygems is gem search and the package directory

16:12 cemerick: mebaran151: so you want CPAN for clojure

16:12 mebaran151: yeah, I think that would actually be a pretty simple thing to build, maybe straight on top of github for hosting

16:13 cemerick: (everyone always wants CPAN for X)

16:13 stuartsierra: Rubygems has serious issues with dependency resolution and historical archiving.

16:13 cemerick: stuartsierra: it's funny that this has come up again so soon :-)

16:13 mebaran151: well gems was always better than python eggs (you could uninstall)

16:13 stuartsierra: Building CPAN took years.

16:13 cemerick: mebaran151: it's decidedly not simple, and has only ever worked for perl

16:13 mebaran151: no I understand the complexity

16:14 cemerick: whether that has something to do with perl users' use-cases, preferred environments, or specific implementation choices is up in the air

16:14 mebaran151: it might be good enough even to have a web service that would index clojure porjects and build ivy or maven entries for them

16:14 that you could add to your own build scripts

16:14 stuartsierra: And it's a product of its time. Running a web server was expensive, so people all posted their code on a few public sites. Now, everyone has a web site, there are a dozen project hosts, and code could be stored anywhere.

16:15 Plus the diversity of SVN/Git/Hg/...

16:15 mebaran151: that's why it might be more useful to have a centralized index that could emit the necessary dependency management codes

16:16 most sane clojure products work something like this: clone, run ant, copy jar to libs

16:16 kotarak: mebaran151: I think Kresimir Sojat started providing Ivy versions of a lot of libraries. I wanted to put them on my server (I provide Ivy-enabled clojure and contrib), but didn't have the time, yet.

16:17 mebaran151: ivy already can handle some dependency resolution

16:17 I think it's mroe an issue of building a good index and some good practices to reference external libraries

16:19 cemerick: my broader puzzlement about this is, when would you use something like this in conjunction with a clojure/java project? The development process is just so far away from what's typical in conjunction with python/ruby/perl.

16:19 mebaran151: PLT Scheme (if they didn't insist on breaking it every day) actually has a pretty cool package management system

16:19 cemerick: or, more importantly, the deployment process is so different.

16:20 mebaran151: cemerick, I think you're emphasizing the java-ness of clojure and I'm emphasizing the schemeness

16:21 cemerick: mebaran151: It's hard to get away from the substrate w.r.t. deployment. You're never (or, very, *very* rarely) going to rig up a clojure app via cron, or within a lightweight deployment container like mod_python or whatever.

16:21 mebaran151: even Haskell has the Cabal, which is actually pretty cool

16:21 cemerick: I didn't know that scheme apps were deployed anywhere, so I can't speak to that.

16:21 * cemerick ducks, runs ;-)

16:21 hiredman: cemerick: the guy who wrote that one adware worm did it in scheme

16:22 mebaran151: haha, nah, that's what I told my coworker when he showed me the cool planet system they use in PLT Scheme

16:22 he's big scheme fanatic, and was actually really happy when I showed him clojure (he's enchanted with Incanter)

16:22 stuartsierra: hiredman: I know that guy

16:22 cemerick: hiredman: didn't he use something (chicken?) that compiled straight to C?

16:23 hiredman: http://philosecurity.org/2009/01/12/interview-with-an-adware-author <-- "which probably means that I deployed more Scheme runtime than anybody else on the planet."

16:23 cemerick: dunno

16:23 mebaran151: http://www.haskell.org/cabal/ << maybe Haskell provides a better model for a package system with ahead of time compilation

16:23 cemerick: hrm, C backend for clojure :-P

16:23 mebaran151: it seems a shame to have a new copy of compojure for every web app I write...

16:23 stuartsierra: cemerick: just use gcj!

16:24 cemerick: stuartsierra: haven't looked at it in, jeez, 5 years? Does it work well these days?

16:24 hiredman: mebaran151: but the compojure jar in ~jars and put ~jars in your classpath

16:24 it is pretty simple

16:24 mebaran151: yeah yeah yeah, but there's a reason why people moan about the CLASSPATH

16:24 Fossi: is there a way to return true or nil or such all the time, no matter what the called function returns without do?

16:24 hiredman: mebaran151: because they don't know how to use it

16:25 mebaran151: I would say something like a CLASSPATH shouldn't need to be known how to be used

16:25 it should just work

16:25 kotarak: mebaran151: In which way is CLASSPATH different to - say - PYTHONPATH?

16:25 mebaran151: PYTHONPATH always seemed better managed

16:25 I've never had to fight a PYTHONPATH war

16:25 I've fought the CLASSPATH at least a couple times

16:25 cemerick: mebaran151: I'm gonna have to pull a red card on you for that one. :-)

16:25 kotarak: I've never had to fight a CLASSPATH war. :)

16:26 hiredman: cemerick: I call shenanigans!

16:26 mebaran151: by war I mean: whoops I misconfigured the CLASSPATH, something I better check

16:26 cemerick: heh, haven't heard that one in a while

16:26 stuartsierra: cemerick: no idea; just joking

16:26 cemerick: ah-ha

16:26 in that case, I'll blissfully continue to assume that gcj is unusable :-D

16:28 mebaran151: and more importantly, the deployment option doesn't tackle what I think is the more interesting benefit of packages: knowing what other people have written

16:28 hiredman: mebaran151: a packaging format (jar + some metadata) goes a long way towards solving that

16:29 mebaran151: that's definitely true, but you'd need a CPAN esque repo to actually index it all

16:30 hiredman: mebaran151: that is easy compared to getting everyone to a. cut releases, b. release as jars and not just a source bundle and c. add whatever metadata

16:31 mebaran151: I see that? that's a community ethic thing though

16:31 if the backbone existed, I'd bet that those steps would just naturally arise

16:31 hiredman: the other option is a "package manager" that is just a frontend to everyone's git repo

16:31 which is bleh

16:32 BLEH

16:32 mebaran151: github might form a very good backbone

16:32 they already support most gems via gems.github.com and on some ruby projects

16:32 kotarak: github is not the end of all...

16:32 mebaran151: I've worked on, that was invaluable

16:32 (my team personally uses bitbucket, because of some Windows coders we have)

16:33 hiredman: other the otherhand, I've never really been fond of rubygems

16:34 Chousuke: github is really slow sometimes though :/

16:35 kotarak: And sometimes goes nuts eating CPU...

16:35 hiredman: my OS has a package manager, I don't want anotehr for ruby, python, clojure, haskell, etc

16:36 so everyone just cut a jar file that can be plopped in to the classpath

16:36 mebaran151: hiredman, cabal, which I've used actually generates distro specific packages

16:36 which is pretty sweet

16:37 they support windows deb rpm archlinux and a couple others

16:38 hiredman: that is cute

16:41 cemerick: that's what the jigsaw people are trying to do

16:41 * Drakeson wishes apt, dpkg would *really* let you install local (not system-wide) packages.

16:41 cemerick: which seems pretty sad, IMO

16:42 albino: I've been wishing for dpkg on windows

16:42 well for like years now

16:42 I would be happy even with rpm

16:42 mebaran151: I never liked cabal that much, but it's the only pkg manager I can think of for a truly compiled language, other than the distro repos for C packages

16:42 elwaywitvac: albino: I agree, but I want VFS or dmesg a little more at this point

16:43 mebaran151: albino, you can script add remove programs actually, but I doubt you want to do that...

16:43 albino: mebaran151: Is that with a WMI call?

16:44 mebaran151: think it might be available with just simple shell scripting

16:44 you can automate the installations of MSI's I know that much

16:44 which you can extract from most installers, but it's up to you to put the pieces together in the right order

16:44 albino: oh yeah with msiexec or something, I did do that a while back

16:44 but msi's are awful

16:44 Drakeson: btw, I look at http://nixos.org/ from time to time.

16:45 mebaran151: that looks pretty cool, NixOS

16:46 but it seems like its aiming to solve configuration file issues, which aren't really a problem in library management

16:46 Drakeson: the research papers might be useful.

16:46 drewr: no, nix makes *everything* immutable

16:46 it's awesome, just not quite mature enough

16:47 mebaran151: drewr, but what in a library would ever even be mutated?

16:47 drewr: s/immutable/persistent/

16:47 * stuartsierra added some documentation to his library during this illumination discussion

16:47 drewr: if you install a new bash package on most systems, /usr/bin/bash is going to be a new version

16:48 i.e., it gets overwritten; not in nix

16:49 mebaran151: but usually I want to overrite old bash, because old bash has a shellcode exploit

16:49 and new bash got fixed

16:49 drewr: you can do that, sure

16:49 but if you have something that depends on that version of bash, it won't break

16:50 mebaran151: hmmm, interesting, but I think that's usually handled by major minor and patch revisions in Debian and its ilk

16:50 you'd just make a separate package bash8 or what not

16:50 drewr: no, this is a completely different way of thinking about all that

16:50 you'll have to read the paper

16:50 mebaran151: I'll check it out

16:51 I've just had to do sysadmin, so I'm always skeptical of package management systems that promise to replace me :)

16:51 Drakeson: mebaran151: after you change a library, do you prefer the application to crash, or let it keep running exploitable?

16:52 drewr: mebaran151: don't worry; with nix you would be the only person for miles around that understands it :-)

16:52 mebaran151: Drakeson, I'm not sure

16:52 on a production system, I'm not likely to run an upgrade, and I'm taking snapshots anyway

16:52 but if I do run an upgrade, it would usually be reasoned a little bit

16:53 on my home machine, half the fun of unix is unbreaking what your OS breaks :)

16:53 but actually it woudl alert me I might need to recompile that package

16:53 most packages, if the revision is truly minor, normally wouldn't break anyway

16:55 drewr: nix helps you not have to micromanage that; a file a package expects to be there will be there

16:55 none of this virtual python, python2.4, python2.5 mess, e.g.

16:56 mebaran151: you can do the atomic stuff they describe using a chroot too

16:57 upgrade in the chroot, rsync over, or something like that

16:57 but yeah, there are a couple compelling advantages

17:00 Drakeson: I haven't learned ivy; is there a commandline tool to see what is in the repository?

17:00 Fossi: lisppaste8: url

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

17:00 drewr: Drakeson: with ivy, that can be anywhere; what do you mean?

17:01 lisppaste8: Fossi pasted "Call with optional parameter" at http://paste.lisp.org/display/84349

17:01 Fossi: is there a way to call a method with two params if it accepts them, otherwise just one?

17:01 kotarak: Drakeson: you search for maven artifacts on www.mvnrepository.com. They also work with Ivy.

17:02 Drakeson: assume you know the name of a package, what it takes to get it and have it "installed" in ~/.class/ ?

17:03 hiredman: Drakeson: sounds good to me

17:03 Chousuke: Fossi: try/catch? :P

17:03 Drakeson: hiredman: what sounds good to you?

17:03 kotarak: <dependency org="org.clojure" name="contrib" rev="1.0.0" conf="*->compiled"/>

17:03 Fossi: Chousuke: so that's a "no"? :(

17:03 hiredman: I put everything in ~/.jars/ and have my netbook fire up a nailgun process at boot with ~/.jars/* in the classpath

17:04 Drakeson: I unzip everything in ~/.class/

17:05 Chousuke: Fossi: Well, you might be able to use reflection to figure out the arities

17:05 Drakeson: (well, I put the jars somewhere else, and when they are updated I recreate ~/.class/ ; it is very rudimentary)

17:06 hiredman: Drakeson: that would actually work better with nailgun

17:06 because you cannot update the classpath

17:07 Drakeson: kotarak: is that supposed to be placed in pom.xml ?

17:07 Fossi: Chousuke: well, it would've been nice to make the 'protocol' to take one or two params, but it's not worth any overhead

17:07 kotarak: Drakeson: for Ivy in the ivy.xml

17:08 Drakeson: kotarak: I see. Is it possible to do that from the command-line?

17:08 kotarak: Drakeson: one can invoke ivy from the command line. Never tried it. ant does that for me.

17:08 Fossi: hm... i could make that a map though

17:08 Chousuke: Fossi: well, you could do (defn foo [& [arg arg2]]) and dispatch differently if arg2 is nil

17:09 Drakeson: kotarak: what does ivy do to the dependencies it fetches?

17:10 kotarak: Drakeson: it places them in a directory. But one can also create a local "mirror" with packages, which can then be used by projects.

17:10 Drakeson: I have a project relative classpath. I put everything I need for a project into lib. Works all the time.

17:10 hiredman: CLASSPATH="lib/*"

17:11 kotarak: Bingo

17:11 hiredman: makes sense

17:11 Drakeson: kotarak: if you have 10 projects, you download the poor jar files everytime?

17:11 hiredman: you can ln -s stuff

17:11 kotarak: Drakeson: no. It's cached.

17:12 Then only copied (or linked if possible, IIRC)

17:12 Changing to a different project folder => CLASSPATH is still correct. :)

17:16 Drakeson: I don't like the copying (to ./libs) involved in this. I would really prefer to have one (or very few) local repositories (like ~/.gems/, haven't used ruby much though), where things are installed, and would prefer definite install and remove commands.

17:16 kotarak: Drakeson: at the moment you will run into problems if you need two different versions of a library

17:16 with the lib approach that is a non-issue.

17:17 Java would really need the version handling here for a central directory.

17:18 hiredman: Drakeson: like I said, I just put things in ~/.jars/ set my classpath to CLASSPATH="$HOME/.jars/*" works fine

17:22 Drakeson: hiredman: what part of it ivy does for you?

17:23 (I mean, can you ask it to use ~/.jars/ as the place to download dependencies into?)

17:25 hiredman: Drakeson: none of it

17:25 I don't use ivy

17:25 kotarak: Drakeson: sure, <ivy:retrieve pattern="${user.home}/.jars/[artifact].[ext]"/>

17:25 Not tested, though.

17:26 And not sure, how to do it from command line.

17:26 Drakeson: I don't have ivy on the command-line (debian/sid)

17:27 kotarak: Drakeson: http://ant.apache.org/ivy/history/latest-milestone/standalone.html

17:28 angerman: I cannot call the methods I created with proxy?

17:29 kotarak: angerman: you cannot create methods with proxy. Only implement defined methods from the Superclass/Interfaces

17:29 angerman: (let [o (proxy [Object] [] (tell [] (.toString this)))] (.tell o)) ?

17:29 kotarak: hmm...

17:30 Drakeson: kotarak: thanks

17:30 kotarak: angerman: (gen-class :name my.OwnClass :methods [[tell [] String]]) (defn -tell [this] (.toString this))

17:32 Drakeson: kotarak: I get Failed to load Main-Class manifest attribute from ..., though. I'll see what is wrong with ivy ...

17:32 angerman: kotarak: hmm yep ... but I was advised to try to stay away from gen-class :)

17:32 so I'm trying to find ways without

17:33 kotarak: angerman: gen-class is not evil, and necessary at certain times: you need a class name, you need to define own methods, ....

17:45 angerman: kotarak: :)

17:45 hmm how do I change the 3rd element of a vector?

17:46 (def x (ref [a b c d]))

17:46 kotarak: (assoc the-vector 2 5)

17:46 ,(assoc [:a :b :c :d] 2 5)

17:46 clojurebot: [:a :b 5 :d]

17:47 Anniepoo: anybody else using La Clojure?

17:47 angerman: kotarak: awesome :)

17:48 eyeris: When I clone the clojure-contrib repo, why don't I get all of the branches? I only get master, but I want

17:48 * clojure-1.0-compatible

17:48 Anniepoo: I'm seeing what I strongly suspect is the background syntax checker task peg my cpu

17:48 especially when I leave a file with an error and try to start a repl

17:48 Chousuke: eyeris: it's there, as origin/clojure-1.0-compatible

17:48 angerman: kotarak: so how do I do the assoc in place? e.g. make the ref point to the new changes struct?

17:49 Chousuke: eyeris: git only creates a local tracking branch for master by default.

17:49 Anniepoo: ,(doc assoc)

17:49 clojurebot: "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."

17:49 kotarak: ,(let [x (ref [:a :b :c])] (dosync (alter x assoc 1 5)) @x)

17:49 clojurebot: [:a 5 :c]

17:49 kotarak: )

17:49 angerman: i see

17:50 * angerman stupid

17:50 kotarak: angerman: auch commute, ref-set, etc.

17:50 eyeris: Chousuke So I just 'git checkout origin/clojure-1.0-compatible'?

17:50 kotarak: assoc also appends

17:51 ,(assoc [1 2 3] 3 4)

17:51 clojurebot: [1 2 3 4]

17:51 Chousuke: eyeris: yeah. or checkout -b local-tracking-branch origin/clojure... if you want a tracking branch

17:52 eyeris: Okay, thanks.

17:52 angerman: hmmm :/

17:52 too bad

17:53 ,(let [x (ref [{:a 1 :b 2} {:a 3 c:4}])] (dosync (alter x assoc [1 :a])) @x)

17:53 clojurebot: 3

17:54 angerman: ,(let [x (ref [{:a 1 :b 2} {:a 3 c:4}])] (dosync (alter x assoc [1 :a] 0)) @x)

17:54 clojurebot: 3

17:54 kotarak: ??

17:54 assoc-in?

17:55 ,(let [x (ref [{:a 1 :b 2} {:a 3 c:4}])] (dosync (alter x assoc-in

17:55 clojurebot: EOF while reading

17:55 kotarak: ,(let [x (ref [{:a 1 :b 2} {:a 3 c:4}])] (dosync (alter x assoc-in [1 :a] 0)) @x)

17:55 clojurebot: 3

18:00 angerman: whee ... it did work :)

18:07 Anniepoo: so, no IntelliJ users out there?

18:08 * angerman uses netbeans to for the GUI editor and emacs to for clojure

18:09 Raynes: Anniepoo: I use it occasionally.

18:09 angerman: but didn't I remember hickey saying something on intellij? or was it idea?

18:09 Raynes: I do what angerman does right now.

18:09 rhickey said "I just use IntelliJ"

18:09 According to my googling.

18:10 Anniepoo: Raynes, I'm runnning IntelliJ and La Clojure, the cpu pegs for 45 sec or so frequently

18:10 @angerman - IntelliJ and IDEA are saeme thing

18:10 anybody remember the name of the guy who made La Clojure?

18:10 Raynes: llya Anniepoo

18:11 Anniepoo: thanks

18:11 Raynes: I think it's llya.

18:11 Drakeson: how can I turn the output of clojure.contrib.lazy-xml/parse-trim (or clojure.xml/parse) to the form clojure.contrib.prxml accepts?

18:11 Raynes: I'm just housing all sorts of knowledge. :3

18:11 Drakeson: (do these forms have names?)

18:13 Raynes: rhickey: I thought you used Emacs, the last I heard. You use IntelliJ now?

18:14 Anniepoo: Llya Sergey

18:15 Anniepoo: Raynes, where'd you copy that from?

18:15 Raynes: http://plugins.intellij.net/plugin/?id=4050 Project page.

18:15 Anniepoo: that's the la clojure download page

18:16 Raynes: Mhm.

18:16 Anniepoo: I'm asking where you got the quote from rich hickey

18:16 Raynes: Oh.

18:16 kotarak: Anniepoo: I think he mentioned it here on IRC or on the list.

18:17 Anniepoo: ok

18:17 Raynes: Google. http://clojure-log.n01se.net/date/2008-03-31.html

18:17 Drakeson: clojure.xml/parse "<a>b</a>" -> {:tag :a, :attrs {}, :content ("b")} --???--> [:a "b"] --prxml--> "<a>b</a>".

18:19 Anniepoo: cool

18:21 kotarak: ,(clojure.xml/emit (clojure.xml/parse (java.io.StringReader. "<a>b</a>"))

18:21 clojurebot: EOF while reading

18:21 kotarak: ,(clojure.xml/emit (clojure.xml/parse (java.io.StringReader. "<a>b</a>")))

18:21 clojurebot: java.lang.IllegalArgumentException: No matching method found: parse for class org.apache.xerces.jaxp.SAXParserImpl

18:21 kotarak: pff.. Same error.

18:22 Do I miss something on clojure.xml?

18:24 ataggart: rich uses emacs for clojure, and idea for java, iirc

18:26 kotarak: ,(clojure.xml/emit {:tag :a :attrs {} :content ["b"]}) ; @ Drakeson

18:26 clojurebot: <?xml version='1.0' encoding='UTF-8'?> <a> b </a>

18:27 Drakeson: kotarak: I know about clojure.xml/emit. I don't like that format ({:tag :a :attrs ....}). it is too verbose.

18:27 the vector format [:a "b"] is much easier

18:27 kotarak: oh ok, nevermind

18:28 Drakeson: I just want to know what format is that and how one converts it to the better format

18:29 angerman: one more sutpid question how do i append an item to the end of a vector?

18:29 Drakeson: conj

18:29 ,(conj [1 2 3] 4)

18:29 clojurebot: [1 2 3 4]

18:30 kotarak: Drakeson: (defn c-xml->pxml [tree] (vector (:tag tree) (:attr tree) (vec (map c-xml->pxml (:content tree)))) as a first guess with missing checks for string or so....

18:30 ,(assoc [1 2 3] 3 4)

18:30 clojurebot: [1 2 3 4]

18:31 kotarak: But conj is more comfortable. :)

19:02 hiredman: ,(doc assoc)

19:02 clojurebot: "([map key val] [map key val & kvs]); assoc[iate]. When applied to a map, returns a new map of the same (hashed/sorted) type, that contains the mapping of key(s) to val(s). When applied to a vector, returns a new vector that contains val at index. Note - index must be <= (count vector)."

19:02 hiredman: hmm

19:02 <=

19:03 ataggart: that = is troubling

19:04 ah, nvm, it appends if its one longer than the vector

19:05 hiredman: yeah, which makes sense I guess

19:05 threw me for a bit

19:06 * Raynes throws hiredman.

19:37 mtd: does anyone feel strongly about a clojure tutorial/document/learning aid for a python programmer (lapsed java coder) going offline for a week or so who might have 5 - 10 hours to play with clojure?

19:43 blbrown_win: Anyone familiar with runhprof, know why these classes show up more than once on these lines. OK, here is a better view. http://paste.lisp.org/display/84355

21:14 ataggart: mtd: get the pragprog book

21:15 mtd: ataggart: thanks

23:48 Drakeson: have you seen an example of using JNA in clojure?

23:51 durka42: Drakeson: have you seen Chouser's thing?

23:51 http://github.com/Chouser/clojure-jna/tree/master

23:53 Drakeson: oh. thanks

Logging service provided by n01se.net