#clojure logs

2008-08-04

04:15rhickeycemerick: saw your message about inheriting the 'same' method from 2 interfaces. I've always thought Java got that wrong by merging on signature, even if the semantics were different. C# allows one to disambiguate, but Java doesn't... not sure what is right here - I'd want an error
04:17cemerickrhickey: Yes, in an ideal world, java wouldn't suck on this point, but clojure has to fold into java here. Otherwise, genclass starts to fail in various edge cases.
04:18cemerick(or, has failed, in my edge case :-) )
04:18rhickeyDo you have a legitimate case of where the same method satisfies the semantics of both interfaces?
04:18esoehnelrhickey: still need someone to do the multimethodizing of print?
04:19rhickeyesoehnel: yes, if you have sent in a CA, or will do so, sure
04:20cemerickrhickey: yes -- I have a data structure interface that used to have a size method, but the default impl of it will also implement IPersistentCollection, so I'd like to collapse the old size method to align with IPersistentCollection's count
04:20cemerickotherwise, the impl has size and count defined, which is *really* bad IMO
04:21rhickeycemerick: so you have 2 counts?
04:22cemerickrhickey: no, one count, and I want just one method for obtaining that count. IPC has a count method, and the data structure interface should have a matching method.
04:22rhickeycemerick: still confused - what method are you inheriting from 2 different interfaces?
04:23cemerickrhickey: int count (), defined in my interface as well as in IPersistentCollection
04:24rhickeycemerick: your interface wouldn't derive from IPC?
04:24cemerickrhickey: No, it's for public consumption by non-clojure-aware users.
04:27cemerickI don't think this is so strange in general, regardless of my particular requirement of not exposing clojure interfaces. I'm sure someone down the road will be implementing multiple interfaces via genclass that just happen to have the "same" method.
04:27rhickeycemerick: the flip side is when 2 interfaces define a method with the same sig and different semantics, and a single implementation is used for both. Users often don't realize this is happening. Many times the only solution is to restructure the hierarchy. I'd rather know earlier than later that I needed to do that
04:29cemerickI agree entirely, but w.r.t. Java, that ship has sailed. Given genclass' exclusive role as providing a Java face to clojure implementations, I'm not sure how it could reasonably deviate from Java's behaviour (at least w.r.t. static stuff like this).
04:29rhickeyI understand genclass is about Java, and following Java's bad behavior her is easy to justify...
04:29rhickeyhere
04:30cemerickI'd be perfectly happy with a compiler warning being emitted, if that's something that seems worthwhile.
04:30rhickeyyeah, just thinking about not have a good warning system in place...
04:31cemerickIf you're disinclined to change this, that's fine by me at the moment, but I'm sure it'll come back sooner or later.
04:32rhickeyno, I agree there's no alternative to following Java in this case
04:32cemerickwe're in the happy position of hardly ever implementing third-party interfaces, so it's no big trick to make my interface define 'size' here, and just live with the duplicate definition on the internal impl
04:32cemerickStuff like this makes me wonder why you chose java as clojure's platform, rather than .NET (although I'm *very* glad you did!)
04:34esoehnelrhickey: of course I will do so, i'm currently at removing the reflection warnings
04:34rhickey.Net has plenty of problems of its own, starting with class library anemia
04:34cemerickrhickey: BTW, on a related note -- genclass class <clinit> methods currently load /com/foo/MyClass.clj -- shouldn't it be loading /com/foo/foo.clj instead/also?
04:34rhickeyJava collections and concurrency stuff is much better
04:35cemerickI guess the tradeoffs are endless.
04:35rhickeycemerick: no, I haven't decided to do that (yet, if at all) because multiple classes from same package will cause multiple loads
04:37cemerickYeah, that's what I figured you'd say. Hopefully issues like that will go away once lib is part of clojure.
04:38cemerickIn case you're wondering why I mentioned that: I've got about 12 genbean usages, and was hoping to have them all in a /com/foo/foo.clj file, rather than scattered about.
04:39rhickeycemerick: I definitely want to support that
04:40rhickeymaybe a :use option once lib is integrated?
04:41cemerickyou mean as part of the genclass usage?
04:41rhickeyright
04:42cemerickwhy not have the genclass clinit hook into lib directly, and require the necessary namespace -- make it up to the dev to hook their multiple-file namespace together using lib as well (if they want /com/foo/MyClass.clj files in addition to /com/foo/foo.clj)?
04:43cemerickthat seems like ideal default behaviour to me
04:44rhickeycemerick: for a default, sure, but leave you in the same position as today, just one level up, with a granularity dictated by a 1:1 default, now with class, then with immediate parent package
04:45cemerickoh, right, yes...didn't catch what you meant before
04:46cemerickalso BTW, I'm slowing coming to appreciate the new multimethods ("slowly" because I've got types wired into my head). Haven't written any code to utilize them fully yet, but I definitely have a use-case for them coming up.
04:47rhickeycemerick: they should work better now with existing type hierarchies too
04:48cemerickyeah, I followed the isa? discussion from afar :-)
05:05lisppaste8rhickey pasted "dupe interface sig patch" at http://paste.lisp.org/display/64672
05:06rhickeycemerick: untested, if you could test and resubmit as a patch I'll incorporate it, thanks
05:24cemerickrhickey: +1 on that patch -- our test suite now passes with the "int count();" method overlap. You want that posted to the group?
05:25rhickeyif it works as written, no, I'll just paste it in
05:25rhickeyit was off the top of my head, I didn't run it
05:26cemerickwell, good on you, then, it works as-is (I just copy-pasted it).
05:26cemerickOf course, stuff like this scares the hell out of me (no proper regression tests). Patches welcome, I suppose. :-)
05:38rhickeycemerick: yes, I would love to see a test suite come together. OTOH, Clojure is a testament to the lack of necessity of such suites, and examples of the insufficiency of test suites abound :)
05:39rhickeycemerick: patch is up, thanks
05:41cemerickrhickey: well, in some areas (genclass may be one of them), clojure is changing to rapidly to make having tests reasonable to begin with. Regardless of efficacy though, they certainly help give one a warm and fuzzy feeling prior to doing svn commit. :-)
05:41cemerickthanks
05:43rhickeycemerick: agreed, I'd run a test suite if I had one. I just find the current test-obsessed culture amusing, as no one questions the relentlessly mutable spaghetti mess they are testing in the first place
05:47cemerickthe TDD police would definitely sneer at our test approach, which only tests external API points and results. If we did "proper" unit testing, our test suites would outweigh our "real" code 10:1.
05:49rhickeyTDD people working in imperative languages have missed the big picture
05:52rhickeyTDD and unit tests also focus on too fine a granularity. Real systems have problems in the large, not in the small - e.g. correctly defined functions being passed the wrong data, or being called at the wrong time or in the wrong order, or not being called when required etc etc, none caught by unit tests
06:01cemerickRight, which is why we only test those user-visible results. If there's an actual problem, we trace things back. Putting together suitable mocks to do real function-level testing would be essentially impossible.
06:01rhickeythat seems totally reasonable
06:02cemerickrhickey: it would be handy to have a "boolean isStrict ();" method on Delay, so instances can be unpacked safely; does this sound reasonable?
06:03rhickeycemerick: what doe isStrict mean?
06:03rhickeydoes
06:06cemerickrhickey: a delay is "made strict" if it's evaluated -- so its fn is null, and the val != null (perhaps my terminology here is off); this allows the value to be unpacked from the delay, and passed around as a regular value. The upside is being able to minimize the locking on each get() call.
06:09cemerickfwiw, the unpacking likely wouldn't happen in userland code -- I'd like to use an isStrict method in genbean, so provided properties can be values or delayed fn's, and the delayed values can be unpacked when the map is "updated"
06:09rhickeycemerick: there won't be a way to answer isStrict correctly without a memory barrier like synchronized. However, your presumption that that involves a lock is incorrect. Non-contended synchronized blocks are extremely fast, on par with volatile now, and nothing you should worry about.
06:11cemerickInteresting. That is true in JDK 1.5+, I presume...
06:12rhickeyright, and gets better all the time
06:59lisppaste8cemerick pasted "is there something like this in clojure or contrib already?" at http://paste.lisp.org/display/64677
07:01cemerickI didn't see anything like that floating around already -- seems like a useful addition to some namespace in contrib, though I don't know which one.
07:16blackdogis it possible to get a full stack trace from (agent-errors) right now i just see an error message no line #s?
07:36rhickeycemerick: as is, I see problems with that as fns are perfectly fine values
07:37cemerickrhickey: oh, sure. But sometimes you know that a slot in a map (or whatever) can be a non-fn value or a fn that returns such a value, so that's a clean shorthand for that.
07:43rhickeyblackdog: those are exceptions on which you can call printStackTrace etc
07:45rhickeycemerick: I think that might be an ok function on IRefs (I know I recently took out IRef as Delay base, not knowing what yet to do with validators there), but not on fns
07:47cemerickrhickey: I wasn't suggesting it as an addition to a Java interface or class, fwiw
07:47cemerickit seems thoroughly useful just as a clojure fn
07:55rhickeycemerick: I understand, as a Clojure fn, but I disagree about its generality, since it rules out fns as values
07:59cemerickrhickey: yeah, if you wanted to use that function with a collection that contains fns as values, then you'd be disappointed. I'm using it to support providing delays as values to genbean class constructors, where the corresponding accessors simply will never be IFn or any derivative, so it's safe.
07:59cemerickIn that context, if you *did* want to have a property return a fn, you'd have to wrap your fn with another thunk.
08:05rhickeycemerick: begs the question of what function? does
08:06rhickeycemerick: but if Delay was once again IRef, you could test for that, much more generally
08:06cemerickrhickey: Oh, sorry, function? is from contrib/pred
08:07cemerickit's true only for IFn's
08:07rhickeyThat's going to catch a lot of types, including keywords and symbols
08:08jcriteswhat happens when you invoke() keywords and symbols?
08:09cemerick...and non-zero-arg fn's, for that matter.
08:09cemerickjcrites: keywords and symbols are functions of maps -- return the value they're mapped to.
08:09rhickeyjcrites: they presume the next arg is associative and look themselves up in it
08:09blackdogrhickey, ah thanks
08:11cemerickrhickey: I guess I would ask: what should I be doing, given collections of *potentially* lazy values that need to be resolved to strict values at some point?
08:22dkfhello
08:23dkfI need to study up on syntax conventions for clojure/lisp, like indentation and when to use new lines, etc. Anyone have any links?
08:25dkfback
08:26blackdogdfk best study boot.clj, or the contrib library
08:26blackdogdfk http://clojure-contrib.svn.sourceforge.net/viewvc/clojure-contrib/trunk/
08:32rhickeycemerick: the resolving is the tricky part - usually they would either be uniformly wrapped or not. Here you are saying some are wrapped/delayed, and some not. You could test for Delay, I guess.
08:33dkfblackdog: thanks
09:16cemerickrhickey: interesting, I would actually say the opposite -- usually only a couple of values are delayed. I'll have to think about whether or not requiring the thunks to be delays would satisfy all of the use cases we have.
09:50StartsWithKhi
09:50StartsWithKafter another day of trying myself, I faild again at trying to make clojure work with osgi
09:51StartsWithKso is there any example how this should work
09:51StartsWithKor explanation why it can't
09:51rhickeyStartsWithK: why is it different from any other Java library?
09:52StartsWithKi think it has to do with RT class
09:53StartsWithKin knopflerfish implentation there are some errors with class loader
09:53StartsWithKin equinox RT class can't be initialized
09:54StartsWithKat this point i have clojure.jar as bundle registered, clojure.jar included inside my bunde and clojure.jar merged with my bundle
09:54StartsWithKnon of them will give me any way initialize RT class
10:03rhickeyI don't know anything about OSGi, but when I do this search I see it is a common problem, solved in Equinox by something called buddy classsloaders? http://www.google.com/search?hl=en&amp;q=equinox+osgi+static+initializers&amp;btnG=Search
10:17StartsWithKhmm.. i don't think i have knowledge to understand osgi, java or clojure in that deepth.
12:55ericthorsenrich: I'm loading files with fully qualified namespaces in them but I still just see the file name with no path prefix. I was expecting to see the same as what I see for the clojure files. Do I need to compile/load them differently?
12:55ericthorsenrich:clojure/boot.clj
12:57rhickeyeric: are you saying you are loading with (load-file "a/full/path/foo.clj")?
12:57ericthorsenyes
13:01ericthorsenrhickey: is that wrong?
13:01rhickeyno, just looking to see what might be different - where are you saying you are seeing something different?
13:03ericthorsenrhickey: when i load a fully pathed file with a honker namespace org.enclojure.platform.utils.utils.clj I expected to see org/enclojure/platform/utils/utils.clj as the file name. I just see utils.clj
13:03rhickeyas the file name where? there are 2 names in the smap
13:03rhickeyone is always the simple name, the other the path
13:04ericthorsenrhickey: I' calling into the jdi functions so I do not see that. I just noticed the file names on the clojure meta data were different in this way and that the jdi function calls seem to work when I follow the meta data named files
13:05ericthorsenrhickey: so calling for line locations using clojure/boot.clj works, boot.clj does not (matching what the meta data has)
13:06rhickeyok, I see the boot.clj etc incorrectly have clojure/ before the file name in the simple name, should only be in the path part
13:06ericthorsenok
13:07ericthorsenrhickey: ok...just looking for consistency
13:07ericthorsenthanks
13:07rhickeyI'll fix, one minute
13:08ericthorsennp
13:19rhickeyeric: fix is up
13:26cemerickI'd like to run a clj script that resides in a jar -- at the moment, I'm piping forms to Repl to load the file using RT.loadResourceScript -- any other suggestions short of offering up a ClasspathScript class, etc?
13:27ericthorsenrhickey: thanks!
13:31rhickeycemerick: app that needs to do this is started how?
13:31cemerickrhickey: command line or ant
13:32rhickeyOh, this script in the jar is the app you want to run?
13:32cemerickyup
13:34rhickeyI guess to make it transparently like Java to users you could genclass a class with a main
13:35rhickeyIf you want to put a bunch of cljs and pick from command-line arg, then something like ClasspathScript
13:37cemerickthis isn't for external consumption, but the former may very well be easiest; though the latter will be necessary eventually.
13:39rhickeycemerick: you could write the latter with the former
13:39cemerickvery true. This isn't something you'd want alongside clojure.lang.Script?
13:40cemerick(i.e. a java impl, not a gen-class classfile)
13:40rhickeycemerick: It really should be a variant of clojure.lang.Script, or an enhancement to it
18:04slavaerr
18:04slavaclojure's persistent hashes
18:09wybiralslava, clojure is really cool in that sense
18:44slavai find java code hard to understand sometimes
18:51wybiralslava, yes, me too :)
19:19arohnerI really wish there were a good replacement to SQL...
19:19arohnerI'm writing an app in clojure, and I really wish I could write queries in clojure