#clojure log - Sep 28 2008

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

0:48 scgilardi: regarding jmap, prior discussions have pointed out the issue of handling nested Clojure maps. I think that could be handled by whatever "get value for key" method(s) jmap implements, checking for Clojure maps being returned as values and automatically wrapping each one in a new jmap.

1:34 yangsx: if I use swank-clojure, how should I add clojure-contrib.jar to the path for clojure?

1:37 is adding the jar to ~/.clojure/ the preferred way?

3:05 hoeck: yangsx: you can use (add-classpath "file:// ...")

3:13 yangsx: hoeck: indedd

3:13 indeed

9:08 ozzilee: Has anyone worked on the Clojure java code in NetBeans or Eclipse? There's no way I'm paying $250 for IntelliJ.

9:09 Or emacs, for that matter.

9:13 achim_p: ozzilee: yeah, i'm using netbeans for that. works just fine.

9:14 ozzilee: achim_p: Ok, I'll try it. I couldn't get Eclipse to match the... interesting... indentation style.

9:16 Maybe Eclipse just did interesting things to it, too :-)

9:42 achim_p: hmm, does anybody know how the new print multimethod works? i'm having some problems ...

9:48 lisppaste8: achim_p pasted "print, ISeq & nth" at http://paste.lisp.org/display/67560

9:51 hoeck: achim_p: i contributed the print-mm

9:52 achim_p: looks like the destruction in print-sequential is using nth instead of first

9:59 lisppaste8: url

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

10:01 achim_p annotated #67560 with "print-sequential" at http://paste.lisp.org/display/67560#1

10:02 rhickey: hoeck: what's the issue there?

10:02 achim_p: hoeck: could this be changed? the paste isn't as elegent as yours, but it should work for all ISeqs, not just ASeqs

10:04 rhickey: there's a description of the problem i'm running into in the paste ...

10:04 hoeck: i used destructuring on a seq, which requires the seq to implement nth

10:06 rhickey: what kind of seq?

10:06 nth works on collections that implement sequential

10:06 clojure.lang.Sequential

10:07 achim_p: on an arbitrary class that implements ISeq

10:07 rhickey: what arbitrary class?

10:07 lisppaste8: hoeck pasted "fixed print-sequential" at http://paste.lisp.org/display/67561

10:07 achim_p: i.e. a proxy [ISeq]

10:08 rhickey: proxy [ISeq Sequential]

10:08 achim_p: it's not about proxies, this was just to illustrate the problem

10:09 rhickey: but I want a concrete case

10:10 hoeck: rhickey: achim_p pasted the problem there: http://paste.lisp.org/display/67560

10:12 rhickey: if you want to participate in nth, you have to implement Sequential

10:12 it's just a marker interface

10:12 achim_p: rhickey: give me a second, concrete case coming up ...

10:15 rhickey: here it is: http://www.bitbucket.org/achimpassen/clojure-w-jmap/src/d678f4e0fe4f/src/jvm/clojure/lang/JavaMap.java

10:16 JavaMap$Seq. i need to wrap ISeqs into ISeqs, so i haven't got access to nth (i could cast, though)

10:17 rhickey: you'll get a lot more from implementing ASeq

10:17 extending

10:18 all the Clojure seqs do

10:18 almost all

10:19 hoeck: rhickey: but shouldn't the print method be able to print 'raw' ISeqs?

10:20 rhickey: sure, just wanted to clarify what it takes to get nth support

10:22 Guest93833: CPL is proving to be a problem for me: it appears to have a lot of license compatibility issues. Are there other licensing options?

10:22 rhickey: Guest93833: what are the issues?

10:23 achim_p: rhickey: i'm using JavaMap$Seq to wrap the result of a seq()-call on an APersistentMap, which yields an ISeq. If it's okay to just cast this to an ASeq, i can take advantage of extending ASeq, otherwise it wouldn't help much, would it?

10:23 Guest93833: 1. It's incompatible with GPL.

10:23 2. It takes over when used with AFL (which my system uses).

10:23 3. It's incompatible with LGPL (which lots of java coders, stupidly, use).

10:24 I was really hoping to make a Clojure-based front-end to a large multiagent swarm simulation

10:24 system that I built and maintain, but it may be out. :-( Kawa I guess.

10:24 rhickey: CPL doesn't reach into other parts of a system with which it is interconnected

10:25 GPL does

10:26 Guest93833: The takeover issue is: CPL is vague in its notion of "extends". If you hook two pieces of code together, and one is CPL, the other notionally extends it. If this it the case, CPL requires that the entire package be released in a license which contains at least the terms of CPL: that is, a viral license.

10:26 rhickey: no one interprets CPL that way

10:26 Guest93833: And CPL is specifically incompatable with GPL. Not CPL's fault -- GPL is an awful, dark-ages license, but that's life.

10:27 The state of Virginia does. My system's developed at a state university.

10:27 rhickey: US Copyright law is not state-specific

10:27 Guest93833: You misunderstand.

10:28 I am not *permitted* to release code that has open source compatibilities because of legal concerns. Probably you saw this: http://yro.slashdot.org/article.pl?sid=08/09/27/2113248

10:28 That's my university.

10:29 "open source compatibilities" -> "open source compatibility concerns"

10:30 In large institutions, getting your ducks in line open-source-wise is a very big issue, and they're very conservative about it. And CPL has a *lot* of ducks.

10:30 rhickey: so you can't use GPL, EPL, MPL either?

10:32 achim_p: why doesn't JavaMap.seq() just return cmap.seq()?

10:33 Guest93833: Viral licenses in general are okay. Though in my specific case GPL is out because it's incompatible with AFL, which covers the system I maintain. It depends on how "extends" is interpreted. A word of advice: when trying to gain mindshare, languages benefit form being released under the loosest terms possible. Apache would be a good license choice.

10:34 Kawa's advantage here is that it's under X.

10:34 http://www.gnu.org/software/kawa/Software-License.html

10:36 rhickey: CPL is not viral, the license does include the word extend, the license specifically states that modules that are separate but distributed together are _not_ contributions, nor are non-derivative works, where derivative is defined by US Copyright law

10:37 Guest93833: I won't be able to convince my university's lawyers of that.

10:37 Rosen says it's viral, and that's good enough for them.

10:38 I think you will find this problem in other institutions as well.

10:38 :-(

10:38 achim_p: rhickey: ithought it would make sense that a seq of map-entries of a jmap with nested maps returned these nested maps as jmaps

10:38 note that the code isn't finished, i just uploaded it quickly to show you the problem in context

10:45 rhickey: I'm not, at this time, willing to release Clojure under a license with no reciprocity

10:46 Guest93833: I don't see where Rosen says CPL is viral, he's very complimentary here: http://www.rosenlaw.com/Rosen_Ch08.pdf

10:46 Guest93833: Well, off to consider other language options then. Crap.

10:47 rhickey: I haven't had any license complaints so far

10:52 achim_p: that's a slippery slope - JMap should be ignorant of what's in it

10:53 probably

10:53 I understand the desire to just jmap the root

11:00 achim_p: rhickey: scgiraldi mentioned the need of nesting: http://clojure-log.n01se.net/date/2008-09-28.html. i personally don't need it at the moment

11:00 another option would be to support nesting only for the java.util.Map-inherited methods

11:19 rhickey: achim_p: that makes more sense

11:53 Chouser: achim_p: I was pondering this earlier (instead of, you know, actually *working* on it) and wondered if it would make sense to pass in to jmap an optional function to be applied on demand to all keys.

11:53 sorry, all values

11:54 this function could, for example, test to see if the value is a map, and wrap it in a jmap -- hense nesting. But it could be used to get other custom behavior as well, while the default would be the simple non-nesting behavior.

11:54 ...just a thought. *shrug*

11:55 rhickey: I think he might be on the right track in just doing auto JMap-izing in Java's Map APIs

11:56 but the fn on value access is interesting for maps of delays, which have nothing to do with Java's Map

11:57 or maps with values reference types

11:57 auto-deref

11:58 Chouser: hm, just a general purpose lazy-wrap on maps?

11:59 a bit like the map function for seqs

11:59 map-map

12:00 rhickey: right, and if I re-introduce Delays-are-IRefs then it could handle Refs/Vars/Agents/Delays uniformly

12:01 * rhickey would probably introduce a new interface, IBox, but Chouser would cringe

12:01 Chouser: if you've have a hash-map of something, you probably know what it is, and passing in the appropriate fn (force, deref, whatever) to map-map wouldn't be a problem.

12:01 achim_p: Chouser: a fn as a value transformer is a nice idea, but i think i'll keep this as simple as possible ;)

12:02 Chouser: achim_p: not a problem. simple is good.

12:02 rhickey: for ClojureScript? My ports of interfaces are minimal, so not a problem.

12:03 rhickey: Chouser: good

12:03 Chouser: since it's all runtime stuff, I just port the name and inheritence. The methods aren't specified.

12:05 I don't have a cljs repl, but I have a js "repl" with the cljs runtime loaded.

12:06 js> clojure.prn( clojure.hash_map( 1, 2, 3, 4 ) )

12:06 hm, that doesn't quite work yet -- I'm still absorbing the new print-mm stuff

12:07 achim_p: Chouser: besides: i need to transform the keys, too (maps are valid keys), and if i used a user-specified function for this, i had do somehow make sure for it to be ...erm... bijective, otherwise i had to either compute the key transformation for every call to simple ops like size, which is a waste of time, or i had to retain all the keys in memory, which is a waste of space

12:08 Chouser: achim_p: maps are valid keys in Java maps?

12:10 achim_p: all objects are

12:11 rhickey: but because many of them are mutable the semantics are broken

12:12 Chouser: oh, do Java APIs modify passed-in maps as a way of communicating back out??

12:12 rhickey: no, but if you use a mutable object as a key...

12:15 mutable objects ought to implement equals as identity ==, but often don't in Java. The semantics of that are broken, see :http://home.pipeline.com/~hbaker1/ObjectIdentity.html

12:16 Clojure implements Baker's egal

12:16 Chouser: yeah, mutable object as a key are scary

12:36 scgilardi: achim_p: wrapping Clojure maps that would otherwise be returned from java.util.Map-inherited methods is what I intended to recommend. Thanks for considering it.

12:38 rhickey: I'll be attending your MIT talk. I'm looking forward to it.

12:39 rhickey: scgilardi: great! will be nice to chat in person

13:47 achim_p: scgilardi: you're welcome, thanks for suggesting it! i wouldn't have thought of it

13:47 it introduces a minor equality/identity-crisis though :)

13:47 hmm, i think my approach is flawed ... since i wrap nested maps on access with disposable flyweights, they can never be equal to anything else (in the java identity sense)

13:48 that practically means that "containsKey" and "containsValue" would be pretty useless. values obtained via "values" or "keySet" wouldn't be comparable to values later obtained via the same calls.

13:49 rhickey: achim_p: why? - 2 things can be equal that are not identical

13:50 equals for Maps is defined in terms that will allow 2 maps of different concrete types to be equal

14:01 achim_p: ah, i misread you. i thought for the key domain of a java map, it had to be "equal iff identical", but you didn't say that, really.

14:02 i'm sorry for the confusion.

14:03 rhickey: equal iff identical should be for mutable maps, but A: Clojure's maps are immutable, and B: java.util.Map defines map equality on (map) value anyway

16:07 Chouser: oops. Can't use java.lang.* in cljs-emitted code to represent Java stubs, because they can represent real java classes via liveconnect in the browser.

17:37 achim_p: is .equals(o) not being symmetrical a problem in the java world? the 'two-faced' nature of jmap wrappers turns out to be a bit ugly: if i don't transform the .seq of mapentries, (.equals {:a :b} (jmap {:a :b})) can't be true (it relies on seq).

19:02 Chouser: rhickey: I think I'm going to try to work up a patch for boot.clj and RT.java that removes all references to java.* classes from the former. Would that be acceptible?

19:03 rhickey: Chouser: should be

19:06 Chouser: I don't think I care about clojure.* classes being named.

19:12 hm. or perhaps split boot.clj into genearal and java-specific parts.

19:13 rhickey: the problem will be order dependencies

19:13 Chouser: yeah. meta-tag java-specific defs? *sigh*

19:14 rhickey: are there many? encapsulating them in RT is a good idea anyway

19:18 Chouser: regex, a smattering of io and string stuff, print-methods, array stuff, a couple concurrent classes

19:19 I've been stubbing them out, which would probably be sufficient, except I've now realized that it's actually legal to refer to real Java classes from JavaScript.

19:20 rhickey: I saw that - let's encapsulate them

19:20 If they are static methods they should inline

19:22 Chouser: I'm currently also skipping certain boot.clj defs entirely (not emitting js for them), and instead defining using hand-written JS.

19:27 If I could make my implementation for that less ugly, and make it able to handle defmethods, that might be at least as good.

19:28 although if I take that too far I may still have order dependency problems, I suppose.

19:32 I'll look at encapsulation. Any hints on how to handle print-method for Character, Class, BigNumber, etc?

19:34 other that, it looks like a few new RT methods and a few new classes (clojure.lang.StringBuilder, etc?) may do it.

19:34 rhickey: woah, why new classes?

19:35 Chouser: there are places that make new java.lang.StringBuilder instances -- what should I replace those with?

19:35 rhickey: I guess I need to understand better what you are trying to achieve

19:38 why wouldn't a call to something like RT.makeStringBuilder() work? It would be typed to return a StringBuilder in Java, your RT function could return anything compatible

19:39 Chouser: oh, of course you're right.

19:40 rhickey: method handlers use the unadorned class names - are you saying Class or BigInteger will resolve to something else in JS?

20:02 Chouser: If there's no Java liveconnect available, java.lang.BigDecimal throws a reference error when evaluated. If there is liveconnect is some kind of JS wrapper around the Java class.

20:06 Either result is probably useless at best for print-method

20:30 I guess I can stub them out if they're undefined, then provide my own print-methods for JS classes.

20:41 rhickey: the print-methods could be moved to a separate clj easily, as they are currently last in boot.clj

21:49 Chouser: how do you feel about importing RT in boot.clj so I can say (RT/makeException "foo") instead of (clojure.lang.RT/makeException "foo")?

22:06 rhickey: it can be imported only after import exists

Logging service provided by n01se.net