#clojure logs

2008-11-30

06:37AWizzArdHi Lau_of_DK
06:38Lau_of_DKGood afternoon Andr� :)
06:38kotarakHi you two.
06:38AWizzArddid you look at the contrib's sql?
06:38AWizzArdMoin Kota
06:38Lau_of_DKHey Kota
06:39Lau_of_DKYes I had a look. Im ashamed to say that my complaints came from a lack of knowledge, of the lib which was wrapped
06:39AWizzArdDo you still miss some important parts?
06:40Lau_of_DKNo, select/insert are covered, and that will be enough for quite some time
06:40AWizzArdyes, and prepared statements and transactios also I think
06:40Lau_of_DKHow difficult is it, so move into stored procedures?
06:41AWizzArdI think this can be done without problems
06:41Lau_of_DKCan you think of a simple example?
06:41AWizzArdalthough you will have to do it with sql, there is no special clojure magic that would help
06:41Lau_of_DKok
06:44Lau_of_DKHave any cool website written in compojure popped up yet?
06:44AWizzArdi think (do-commands "sql stuff here to create a stored procedure"). And then in your "normal queries" you can call them, as in (with-connection *db-conn* (with-results res "select * from tab1 where name=my_procedure(15)" ...)) or something like that
06:44AWizzArdno, although I try to come up with something with Stuart Halloway
06:45Lau_of_DKYea AWizzArd, it'll be something like that
06:45Lau_of_DKStuart... thats the guy who made the Clojure book which is prited on pure gold paper right? :)
06:45Lau_of_DKs/prited/printed
06:45AWizzArdyup :-)
06:45AWizzArdWe would like to make the possibly most powerful webdevelopment framework available for Clojure
06:46Lau_of_DKIn which scope?
06:47AWizzArdWell, we are cheating, because we won't write it ourselves, but instead make Rife available in Clojure, where Rife is a framework for Java. http://rifers.org/
06:47AWizzArdcheck out for example this http://rifers.org/blogs/gbevin/2005/3/18/blabla_tada_in_java
06:47hiredmanclojurebot: clojure is also cheating
06:47clojurebotc'est bon!
06:49AWizzArdhire :-)
06:49Lau_of_DKclojurebot: ?
06:49clojurebotIt's greek to me.
06:49Lau_of_DKclojurebot: *
06:49clojurebot* is just for when you are lazy and sloppy
06:49AWizzArdclojurebot: Why?
06:49clojurebotPardon?
06:49AWizzArdclojurebot: multimethods
06:49clojurebotmultimethods seperate the 20% from the 80%
06:49Lau_of_DKAWizzArd: Rife looks interesting, and like its in its infancy ?
06:50AWizzArdclojurebot: multimethods
06:50clojurebotmultimethods is what separates the boy from the man.
06:50AWizzArd:-)
06:50hiredmanclojurebot: why is <reply> why not?
06:50clojurebotc'est bon!
06:50AWizzArdLau_of_DK: I think development of Rife started around 2001, so it has more years than most other frameworks
06:51Lau_of_DKk
06:53Lau_of_DKI certainly would love to see a webframework, which would wrap html, jQuery and JSon all in one, clojurish elegant looking package
06:54Lau_of_DKoh, and Javascript
06:54AWizzArdThe famous Bruce Tate made comments about it, also the Ruby on Rails inventor: http://rifers.org/testimonials
06:55Lau_of_DKhehe, famous or infamous, we'll leave that in the air
06:55AWizzArdOver some time the framework can be clojurized, so one does not write Java in Clojure. This should give us Rails+ productivity in Clojure
06:55Lau_of_DKI remember in the early days of the Googlegroup, Rich actually presenting quite strong oppinions against continuations
06:57AWizzArdyes, but this has nothing to do with webapplications
06:57AWizzArdit basically means: users can use their back buttons and the website will just work
06:57Lau_of_DKk
06:58AWizzArdall filled out forms stay filled out.. if you accidently move backwards you can go forward again, and so on, or go back a few pages and take a different road through the website from that point on, etc.
06:58Lau_of_DKIts really amazing that those features havent been standarized 5 years ago
06:58AWizzArdClojure itself needs no continuations. It supports threading.
06:59Lau_of_DKYou think threading = continuations?
06:59AWizzArdno
06:59AWizzArdbut all you can do with continuations you can do with threads
07:00AWizzArdhi blackdog
07:00blackdoghi
07:00Lau_of_DKhe's the blackest dog I know
07:01AWizzArdclojurebot: clojure
07:01clojurebotclojure > scheme
07:02AWizzArdclojurebot: clojure is also the bestest programming language available.
07:02clojurebotYou don't have to tell me twice.
07:02Lau_of_DKclojurebot: blackdog is the start of Black Dawg Down
07:02clojurebotOk.
07:02Lau_of_DKclojurebot: blackdog is the star of Black Dawg Down
07:02clojurebotIn Ordnung
07:03Lau_of_DKah, german efficiency, I like
07:06AWizzArdhow can you know that this is german?
07:06Lau_of_DKYou mean besides the fact that he just replied to me in German?
07:06Kerris7 haha
07:07jlesliehey, I'm having trouble with namespaces and :exclude, if I (use 'clojure.zip) I get a java.lang.IllegalStateException: replace already refers to: #=(var clojure/replace)
07:07hiredmanclojurebot: are you german?
07:07clojurebotExcuse me?
07:07jlesliebut I can't figure out how to get :exclude to work.
07:07hiredmanclojurebot: well?
07:07clojurebotI don't understand.
07:07hiredmanclojurebot: useless git
07:07clojurebotIt's greek to me.
07:08jlesliealso, looking in zip.clj seems like there's already something for excluding replace?
07:08hiredmanI am unsure, but I think the one in zip.clj is for inside the zip.clj namespace
07:09jleslieok, that seems reasonable
07:12jleslieI've tried a variety of things like: (refer 'clojure.zip (:exclude (replace))) but haven't had any luck.
07:13Lau_of_DKtried (use 'clojure.zip) ?
07:13jleslieI get a java.lang.IllegalStateException: replace already refers to: #=(var clojure/replace)
07:14jlesliewith use, and refer.
07:14Lau_of_DKMaybe you should restart your REPL
07:15Lau_of_DKDid you try (ns 'j.leslie.ns :import '(clojure.zip)) ?
07:17jlesliesame error.
07:17Lau_of_DKIn a fresh Repl ?
07:17jleslieYeah.
07:18AWizzArdHello rhickey. In http://clojure.org/compilation I think there is a closing paren missing in your -main, at the bottom.
07:19Lau_of_DKjleslie: then maybe its an error in clojure.zip, that it specifically tries to def clojure/replace, and not /replace in its own namespace
07:19rhickeyAWizzArd: fixed - thanks
07:20jleslieI think I just need to figure out the :exclude filter, but I can't quite get it right
07:21AWizzArdrhickey: also I seem to not understand fully how to compile it. I copied the whole example and put it into a file test.clj which is saved in my classpath. I start a fresh clojure and type (load "test"). It begins to load, but then soon it complains.
07:21AWizzArdDo I have to name the file with a specific name or put it into a specific path to make it loadable?
07:22lisppaste8Lau_of_DK pasted "Another Lazy mistake?" at http://paste.lisp.org/display/71257
07:22Lau_of_DKCan somebody help me point of the obvious, what is my mistake here?
07:23AWizzArdjava.lang.ClassNotFoundException: clojure.examples.IBar
07:24AWizzArdMy plan was: (load the-file), (compile the-namespace) and then run it as you showed from the shell
07:26rhickeyAWizzArd: all AOT compilation is based upon classpath and dir pathing, e.g. a ns called x.y.z must be in x/y/z.clj
07:26rhickeyand that path must be under the classpath
07:27Lau_of_DKdisclaimer: My lisp-paste contains only 100% tested code and has been reviewed to eliminated typos, its quite safe
07:27Lau_of_DKoh wait
07:27Lau_of_DKI got it
07:27Lau_of_DKnever mind
07:27Lau_of_DKLike I said, obvious :)
07:27AWizzArdrhickey: okay, I will give that a try
07:40AWizzArdrhickey: my file is now in path/clojure/examples/instance.clj and the path/clojure/examples/ folder is in the classpath var. When I type (load "instance") I still get java.lang.ClassNotFoundException: clojure.examples.IBar
07:40AWizzArdThis is for me an indicator that the file was really found in the classpath, because otherwise I would have gotten a class-not-found exception or something like that.
07:42lisppaste8Lau_of_DK annotated #71257 with "Disregard above paste" at http://paste.lisp.org/display/71257#1
07:43kotarakrhickey: can i import classes from gen-class in the defining namespace? (ns foo.bar) ... (gen-class :name foo.bar.SomeClass) (import '(foo.bar SomeClass)) <- gives exception, that foo.bar cannot be loaded again, while it is loading.
07:44kotarakFor interfaces it works.
07:44rhickeyAWizzArd: things get found in namespace pathed dirs under the classpath. Any component of your ns shouldn't be in the classpath, i.e. classpath = src, files in src/my/namespace/lib.clj
07:47rhickeyAWizzArd: or in your example, only path should be in classpath var
07:51rhickeykotarak: right now, the default is that a gen-class class tries to load its implementing ns. You can control that with :load-impl-ns false
07:52AWizzArdI will try some more combinations. When I put path into the classpath I get java.io.FileNotFoundException: Could not locate instance__init.class or instance.clj on classpath.
07:52kotarakIs this :load-impl-ns a voodoo feature or is it in contained in the new interface?
07:54rhickey(doc gen-class)
07:54clojurebotGenerates compiled bytecode for a class with the given package-qualified cname (which, as all names in these parameters, can be a string or symbol). The gen-class construct contains no implementation, as the implementation will be dynamically sought by the generated class in functions in a corresponding Clojure namespace. Given a generated class org.mydomain.MyClass with a method named mymethod, gen-class will
07:54rhickeykotarak: it's documented
07:54kotarakrhickey: Ok. Thanks. :)
07:56rhickeykotarak: I'm looking into the nesting as well, I think that a nested load might be better as a no-op
08:01rhickeykotarak: If you could, please try 1131 on your original test case, I made nested load of already loading resource a no-op
08:01kotarakOk. Just let me check.
08:03AWizzArdSo now I have path in the classpath evn variable. The example from the website was saved in a file /path/clojure/examples/instance.clj and in a freshly opened clojure I get (load "instance") ==> java.io.FileNotFoundException: Could not locate instance__init.class or instance.clj on classpath
08:04AWizzArd(.getProperty System "java.class.path") ==> "/path/"
08:05AWizzArd(plus other .jar files)
08:05rhickeyAWizzArd: you don't load it, just compile it
08:06kotarakrhickey: 1131 works perfectly. :)
08:06AWizzArdI just compiled 1130 and now there is a 1131 ;-)
08:06AWizzArdRich, you are sometimes a bit too fast *g*
08:06kotarakAWizzArd: Ah, Wizz! You are too slow. ;)
08:07AWizzArdI need a script for automatically checking out clojure, ant'ing it and copy the clojure.jar into the right dir
08:07kotarakBut to honest: I also had to check out a fresh SVN, since I normally use the hg mirror.
08:09AWizzArd(compile 'clojure.examples.instance) ==> java.io.IOException: The system can't find the path
08:11AWizzArdbut maybe this comes from the *compile-path*
08:27AWizzArdcompared with CLs compile-file it is really very complicated. The Java interop is in my opinion the ugliest part of Clojure *sigh*
08:33fran1Hello, I'm new to Clojure. While playing around under WinXP and Linux (Ubuntu 8.04), I encountered the following behaviour: user=> (doto (new String "Test") (length)) works under WinXP (JDK 6u10) but doesn't under Linux (JDK 6u07). Any Ideas?
08:39Lau_of_DKIs there a better way?
08:39Lau_of_DK (alter turtle assoc :x x)
08:39Lau_of_DK (alter turtle assoc :y y)
08:39Lau_of_DK (alter turtle assoc :direction d)
08:39Lau_of_DK
08:41Lau_of_DK(this is where I expect Rich or Chouser to go (alter t^a^xyz #[vals]) or something like that)
08:42blackdogassoc can take multiple key vals
08:42Lau_of_DK(doc assoc)
08:42clojurebotassoc[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).; arglists ([map key val] [map key val & kvs])
08:44Lau_of_DKRight you are blackdog, thanks
08:52Chouserfran1: there was a recent change to doto that would require '.length' instead of 'length' -- perhaps you have slightly different versions of Clojure?
08:56Lau_of_DK1
08:57Lau_of_DKfran1: also notice that 'a recent change' could span about 120 revisions
09:04Chouser20 revisions, in this case, from 11 days ago.
09:12kotarakOff-Topic: How can I check in ant, whether some property is set and how to do something according to the result?
09:19fran1Chouser: Thank you! I've just tried it and it works.
09:19fran1Lau_of_DK: :-)
09:25AWizzArdrhickey: do you have slime installed, and jochu-swank-clojure and emacs?
09:25rhickeyAWizzArd: nope, just Aquamacs + clojure-mode
09:26AWizzArdI experience some strange problems. When I go into the shell and manually run clojure from there I can compile. I can also do it from within slime via (binding [*compile-path* "/path/classes/] (compile 'clojure.something))
09:26rhickeygiven that I'm changing core clj files and Clojure itself, I need to keep it simple
09:27AWizzArdbut .getProperty shows me that "/path/classes/" indeed is on my classpath
09:27kotarakAWizzArd: *compile-path* only default to "classes" in the Repl. So the SLIME stuff probably doesn't change the value. So you have to do it manually.
09:28AWizzArdHmm, possible
09:29AWizzArdin the repl I have *compile-path* ==> "classes"
10:18jtoywhat is the web programming library besides webjure?
10:18jtoy?
10:18jtoyi remember there is another one but cant remember the name
10:18kotarakcompojure
10:19jtoyah yes, which is more mature/robust?
10:20duck1123_I haven't used webjure, but I think compojure
10:20duck1123_that was why I went with that one
10:21jtoyduck1123_: i think so too
10:23duck1123_they both have a way to go
11:12rhickeyChouser: I've been thinking about the dynamic code gen scenarios
11:16rhickeyan additional option for runtime code-gen is to automatically gen into *compile-path* rather than in-memory, the great advantage being classes loaded from there have normal visibility
11:20Chouserhm... because as long as the root of that classpath element exists at startup, other classes can be created and discovered later.
11:21rhickeyChouser: right, that's how compilation works now, classes are gen-ed to disk and immediately available
11:23stuartrhickey: what happens if you gen more than once in a single runtime?
11:23Chouserstuart: screwed. ;-)
11:24Chouseryou could update the .class on disk, but the JVM wouldn't let you reload a new class with the same name.
11:24ChouserIf you need a named class, I'm much more sympathetic with an "only-AOT" solution.
11:25stuartbut worse: Java programmers are used to reloading a new class with the same name by dropping a URLClassLoader and creating another one
11:25rhickeyif you've changed anything, you'll need to reload to see the changes, otherwise it's a no-op
11:25stuartor more accurately having a container do it for them
11:25rhickeystuart: not really, if they are truly relying on the names they need to reload
11:26stuartI think we are saying the same thing
11:26rhickeye.g. container reloads them
11:26rhickeyright, so Clojure can't solve that problem, the thing at hand is the use of custom classloaders and the visibility and deploy constraints therein
11:27ChouserBut there are times when you want to add methods (JNA, Swing, etc.) when the class name isn't important and it'd be nice to get new ones at runtime.
11:28rhickeyChouser: JNA was the first case I've seen of that - Swing is straight interface impls satisfied by proxy
11:28Chousergenerally running those to disk and back wouldn't be hurt enough to matter, esp. if it solves all the visibility problems.
11:28stuartif you drop files into a directory serviced by a URLClassLoader, including the standard "classpath" loader, you create possible oddities
11:29rhickeygen-class and gen-interface are subject to macro fu, so you could call e.g. gensym to fabricate tear-off names
11:29Chouserrhickey: actually it's java.io.Writer proxy that I've got where I'm overriding .close to mean something entirely different. :-P
11:29stuarte.g. if a named class already has been loaded by a child loader, then you create an "impossible" situation, where that class retroactively shouldn't have been able to be loaded by the child
11:30rhickeystuart: that sound like a broken child classloader that's not delegating
11:30stuartit doesn't get a chance to delegate if at time A the file isn't there
11:31stuartand at later time B the AOT compiler puts it there. :-)
11:32rhickeyare you talking about a classloader that either reads from disk or load from memory? I'm not advocating that
11:32stuartno, I am questioning the gen-to-disk approach
11:33stuartif I understand correctly, it doesn't compose with the way other people may be (correctly) using classloaders
11:33stuartbecause it creates a moment in time when a class does not exist, followed by a later moment time when it does
11:33rhickeyputting the file on the disk is not a classloader thing
11:34stuartare you sure of that?
11:34stuartif you are putting the file on disk before any classloader points at that location on disk then I agree
11:34rhickeysure, the compiler just spits out a file and calls it a day, later some classloader loads it
11:35rhickeyit's not a side effect of a load attempt
11:36stuartok as long as people aren't using the compiler at runtime to add classes to a
11:36stuart"live" path
11:36rhickeystuart: well, they might be, e.g. in a repl session
11:37stuartthat's probably OK, if you make a mess in a REPL that's your business
11:37rhickeyI agree the deployment of an app that needs to write to disk is a nightmare
11:37stuartThe notion of tear-off names scares me because when I have seen it used in the past what people often
11:37stuartneeded was tear-off classloaders
11:38rhickeystuart: I agree completely, people should code to interfaces, these are scenarios where some 3rd party cares about the name
11:39stuartcool, I will stop agitating now :-)
11:39stuartwhat's the ETA for sorting this all out to 1.0 readyness?
11:40stuartI am contemplating making the case study chapter a deep dive on integrating with some Java stack, and am holding writing that chapter to see what happens
11:40rhickeystuart: I think gen-clas is in good shape, pending feedback, also gen-interface, AOT proxy probably today
11:40rhickeygen-class
11:40stuartsweet. You are writing this language faster than I can write *about* it. Awesome.
11:41rhickeystuart: have a look at the current version of: http://clojure.org/compilation
11:41rhickeymake sure you refresh, changed a bunch yesterday
11:42Chouserrhickey: AOT proxy will involve some kind of early declaration of the interfaces later runtime proxies will use?
11:42ChouserA simple "no" will suffice, and I can learn about it when it's done. ;-)
11:43rhickeyChouser: no, fixed names will be generated automatically (based on supers), when compiled proxy class is pre-created, should be no change to existing code
11:44rhickeybut compiling will eliminate the need for runtime classloader for proxy, the last scenario requiring it
11:44Chouseroh, because proxy is already a macro it can do some "work" at compile time. of course.
11:44rhickeythen compiled code can target applets, android etc
11:45Chouserbeautiful.
11:45stuartCrikey, this is gonna need a whole chapter.
11:46rhickeyalso moving to named proxy classes (under the hood) will allow proxy constructors to be direct rather than reflective as they are now
11:46Chouseroh! nice!
11:46stuartrhickey: are you interested in bundling an ant-replacement with Clojure, with some support for building hybrid Clojure+Java apps?
11:47stuartI have the lancet sample code, plus fyuryu has built something I haven't had time to look at yet
11:47rhickeystuart: sounds like a good contrib thing to start with - I've added you to clojure-contrib
11:47Chouserand since calls to proxy methods will generally be coming from Java code, those have never needed reflection.
11:48stuartrhickey: Thanks. I will be committing stuff there soon.
11:48rhickeyI intend to start shipping some of contrib, we just need to partition it into experimental, 3rd party dependent, and ready-to-bundle
11:48stuartI wish that people would build stuff anew in Clojure
11:48rhickeyChouser: right, users of proxy interact through the interfaces.
11:49rhickeyproxy construction was its major perf bottleneck
11:49stuartbut I think that for about 90% of adopters, the greased-path story for dropping Clojure into framework X will be key. Whether in Clojure, or Contrib, or just a tutorial doesn't matter
11:49stuartahem, 90% of adopters coming from Java
11:50rhickeystuart: gen-class and AOT should greatly facilitate that
11:51stuartagreed! and the up-in-5-minutes tutorial closes the deal for newbies. I will work on that for at least a few scenarios
11:51Chouserstuart: does an ant replacement really fit into that story? Surely existing projects will have significant investment in ant itself such that replacing it will seem like a non-starter?
11:51ChouserI'm really asking, because I know essentially nothing about Java or Ant. :-)
11:52Chouserman, swing is beating me up.
11:54stuartchouser: build assistance is critical. May have to be *in* ant. Worse, may have to be *in* Maven.
11:55stuartBut I think you could automate a conversion from Ant->Lancet, or something like Lancet. And you would immediately pick up some goodness.
11:55Chouserhm, ok.
11:55stuartI'll give you a better answer in three weeks. :-)
11:56Chouser:-)
12:26fyuryu1stuart: my stuff is in no way a replacement for ant, at least not if you're doing Java+Clojure development
12:29fyuryu1but so far it's been useful to me for Clojure development. automating basic tasks and avoiding editing xml
12:46Lau_of_DKYo yooo :)
13:20rhickeyChouser: what's the drain, just unfamiliarity?
13:20Lau_of_DKhehe, you no like Swing?
13:20blackdogChouser, you seen this one http://pivot-toolkit.org/
13:20Lau_of_DKblackdog: youve always got the greatest links :)
13:20Chouserrhickey: yes, primarily. Trying to get very specific layout behvior, and am awash in options that don't seem to help.
13:22Chouserblackdog: no, I hadn't. I firmly believe (so far with little evidence) that Swing is sufficient. I just need to learn...
13:22blackdogyes it is i'm sure
13:22blackdogbut it may not be easiest
13:23blackdogi haven't really used it in anger, but you also may find the miglayout helps too
13:23ChouserI'd like to use stock Java if it's at all reasonable. Aiming for tiny download...
13:24blackdogChouser, let's talk in another week :P
13:25Chouserblackdog: :-)
13:26rhickeyChouser: are you targeting 1.6?
13:27Chouserdunno, are you? :-)
13:27ChouserI'd like it to work everywhere clojure works.
13:28rhickeyClojure targets 1.5
13:28rhickeyBut 1.6 has GroupLayout, I think you can get it for 1.5 a la carte
13:28ChouserI've got SpringLayout almost behaving.
13:29joewNewbie question: Can you initialize a vector with values from a list?
13:29Chouser(doc vec)
13:29clojurebotCreates a new vector containing the contents of coll.; arglists ([coll])
13:30joewthanks
13:34AWizzArdalso technically possible: (apply vector my-list)
14:43AWizzArdThe google group has now 2^10 members
14:52pjb3For anybody in the DC area, there is a Clojure group forming: http://groups.google.com/group/clojure-study-dc/browse_thread/thread/500d6fb42524b182
15:39lisppaste8ppierre pasted "macro and ns" at http://paste.lisp.org/display/71272
15:40ppierreCan I get some help on macro and ns ?
15:40ppierreI try to get ns of where macro is expended
15:40ppierreBut I can't write it with just one macro
15:43mibuhey, I gotta question about refs. anyone here can help?
15:44Chouserppierre: I don't quite follow. it's namespace-with-default that's not behaving how you want?
15:44Chousermibu: go for it.
15:45ppierreYes but it wouldn't work directly in intl macro
15:45mibuchouser: I can't figure out when I should use alter. How is it fundamentally different from ref-set?
15:46Chousermibu: I think it just saves you some typing in many cases.
15:47mibuchouser: so, it really isn't different from a ref-set, just a fancy apply combined with ref-set?
15:47Chouser(ref-set foo (conj @foo 99)) vs. (alter foo conj 99)
15:47rhickeyChouser: alter is more clearly a function of the current state, ref-set should be reserved for overwrite
15:47Lau_of_DK(doc ref-set)
15:47clojurebotMust be called in a transaction. Sets the value of ref. Returns val.; arglists ([ref val])
15:48Lau_of_DK(doc alter)
15:48clojurebotMust be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref.; arglists ([ref fun & args])
15:48miburhickey: when would you use alter that is inappropriate to use ref-set?
15:48Chouserrhickey: but no less contention or more "complex" return values for alter over ref-set?
15:49rhickeyref-set says 'I don't care what was there before'
15:49Chousermibu: well, probably the example I just gave. Since the new value is based on the old value, I should use alter.
15:49rhickeyno perf or contention differences, alter is read-modify-write
15:50rhickeyalter/commute/send all have the same model, and are preferred
15:50rhickeynew state function of the old state
15:51Lau_of_DKrhickey: have you considered wether or not, using git locally would make you more efficient? It does export to SVN as far as I know
15:51miburhickey: but inside a transaction a ref-set over values that were deref'd (such as in chouser's example) is just as good as alter, isn't it?
15:51ChouserI guess that helps explain why actions are given the current agent state, even though they could get it from @*agent*
15:51lisppaste8ppierre annotated #71272 with "macro and ns (with function)" at http://paste.lisp.org/display/71272#1
15:52rhickeyChouser: exactly, note how they all let you use e.g. assoc directly, rather than making a ref or agent based function
15:52Chousermibu: it works as well, but is less clear for a programmer trying to read your code.
15:53rhickeythe idea is you can test your state transformation functions a la carte
15:53rhickeyadding refs/agents later
15:54mibuchouser: so, they're not fundamentally different. I was busting my head trying to figure out what's so special about alter. I guess having the triplet of ref-set,alter,commute made me think each is special (like vars,refs,agents).
15:58emacsenmattrepl, hey
15:58emacsenwhere in VA are you?
15:58mattreplfairfax
15:59emacsenyou know about the clojure study group next week?
15:59emacsenLOL, or do you care? :)
16:00technomancyhow do you modify the classpath once you're in slime?
16:00mattreplheh, no I didn't
16:00mattreplis that a fringedc related thing?
16:00mibua different question on the same subject, why would one call ensure to protect a ref inside a transaction? the in-transaction-value is already the same as in the entry point. is it more like touch and go, i.e. it would have the same effect as reading and re-setting the in-transaction-value on the commit point of the transaction?
16:01emacsenyup, FringeDC spinoff
16:02technomancyah, the add-classpath function
16:02mattreplemacsen: where's it at?
16:03emacsenmattrepl, hold on I'll get you URL
16:03emacsenhttp://groups.google.com/group/clojure-study-dc
16:04mibuanyone?
16:04emacsenit's at some bar next week
16:04emacsenbut in the future it may be at HacDC
16:05Chousermibu: I don't have a firm grasp on 'ensure' yet, sorry.
16:05stuartmibu: if consistency depends on the relationship between multiple values, then ensure provides a way to state that, without a spurious write
16:06rhickeymibu: you might ensure some data that you will only read, but not write, in a transaction, whose value you make a decision upon and want to pin down
16:07rhickeyIt's there to prevent write-skew, a known liability of MVCC
16:07miburhickey,stuart: so essentially the semantics of ensure, if you didn't have it, is to re-set the in-transaction-value on commit?
16:08mibu(without actually re-setting the ref, I mean semantically)
16:08stuartensure would force a tx retry if a value you ensured was written out from under you
16:08stuartwhich, in general, would be a GOOD thing for concurrency
16:09stuartbut a bad thing for consistency if that value had to stay in some known relationship with another value that you were writing
16:09mibustuart: ok. that's what I meant. so as rhickey said, it's a value-pin-down function.
16:09miburhickey: did I get this right?
16:10rhickeyensure protects the value as if you wrote it
16:10stuartthis guy is pretty authoritative: http://markmail.org/message/4p4gq2xcxbqhqy6a :-)
16:10rhickeysee this for write skew: http://en.wikipedia.org/wiki/Snapshot_isolation
16:12miburhickey: you succinctly said what I was trying to say. thanks everyone for clarifying the subject.
16:14mattreplemacsen: thanks
16:15emacsenno problem! Hope you show up next week!
16:16emacsentell your friends!
16:16emacsentell your enemies!
16:21technomancyso when you send a region to slime (C-c C-r), it looks like that gets eval'd in a different namespace from the slime REPL?
16:27AWizzArdrhickey: do you think some should be renamed to some? to better match every? or not-any? ?
16:27rhickeyAWizzArd: it's not the same, it doesn't return a boolean
16:33dthomastechnomancy: Is there some kind of ns declaration at the top of the file you're calling slime-eval-region in? If so I think it may parse the NS out of that and eval the code in that name space.
16:34AWizzArdrhickey: (some #(= 4 %) (range 20)) ==> true
16:34AWizzArdat least sometimes it returns a boolean
16:35AWizzArdbut yeah (some identity [nil nil 4 nil 10]) ==> 4
16:37technomancydthomas: oh that makes sense. didn't expect it to be that smart
16:38technomancydthomas: yeah, that's it
16:44julian_morrisonHi all, I have a Q about multimethods: what part of the call does the dispatch function get?
16:44julian_morrisonif I call (my-multi 1 2 3 4) then the dispatch function gets what?
16:44kotarak1 2 3 and 4
16:45julian_morrisonas a seq? Or as arguments in their places?
16:47rhickeyjulian_morrison: as individual args, but will match to any sig that can take 4 args
16:48AWizzArdrhickey: why is (-) ==> Exception while (+) ==> 0 ?
16:48rhickeye.g. (fn [x & ignore] ...)
16:48julian_morrisonah, thanks
16:49julian_morrisonso (fn [& p] (map class p)) is a good dispatcher
16:50rhickeyjulian_morrison: could be a traditional type-based multimethod then
16:51julian_morrisonrhickey, BTW, that would be a small useful improvement, make class do the above rather than being forced arity 1
16:51rhickeyyou might want to (vec ..) that, for ease of writing methods
16:52rhickeyjulian_morrison: interesting
16:56julian_morrisonhmm, in the above p is not itself a vec, unexpected
16:57AWizzArdAWizzArd: In CL (-) also throws an error.
16:57rhickeyjulian_morrison: why should it be a vec?
16:57AWizzArdok, thx
16:57AWizzArd:-)
16:58julian_morrisonthe param list is a vec, a slice should be a vec?
16:58julian_morrisonI suppose that's a weak reason
16:59rhickeythe syntax form is a vector, the arguments aren't. & args are seqs
16:59rhickeyyou can apply fns to infinite seqs
16:59julian_morrisonlazy seqs? cute
17:04julian_morrisonare you planning to put splice and concat methods into persistent vectors?
17:05rhickeyjulian_morrison: there is constant-time subvec (with sharing), but concat would not be efficient in this implementation
17:07kotarak(def vec-cat [v1 v2] (reduce conj v1 v2)), maybe this is sufficient?
17:07julian_morrisonrhickey: you could implement as something like a sparse vec of subvec, splice, subvec
17:07rhickeykotarak: (into v1 v2)
17:08kotarakgeez. into...
17:08julian_morrisonconcat reduces to a degenerate splice as does delete
17:09rhickeyjulian_morrison: not and maintain complexity guarantees
17:10julian_morrisonrhickey: that might be a valid trade-off sometimes though. Perhaps a "sparse-vec" datatype?
17:11rhickeyjulian_morrison: there are vector impls with log(n) perf and fast concat, I'd rather just add that than mix metaphors
17:12julian_morrisonwhatever works is good :-)
17:16julian_morrisonthanks, and bye all
17:16timjrhm, if I use recur inside a dosync, I get an error about wrong number of arguments in the recur, e.g. (loop [i 0] (if (> i 2) i (dosync (recur (+ i 1)))))
17:17timjris the dosync a recur target?
17:29rosejnAnyone know how to create a java Enumeration from within Clojure?
17:32rhickeyrosejn: why do you need an Enumeration?
17:33rosejnI'm creating an interface on top of a graph database, Neo4j
17:33rosejnThey require that the edge relations are a typed enumeration
17:33rhickeytimjr: dosync wraps the body in a fn, so yes, but you couldn't loop in and out of a transaction anyway
17:38rosejnSo for example, to create a relation: (.createRelationshipTo n1 n2 FamilyEdgeTypes/SON)
17:38rosejnWhere FamilyEdgeTypes is an enumeration. Not sure if that's how you should reference the SON entry.
17:40rhickeyrosejn: http://clojure-contrib.svn.sourceforge.net/viewvc/clojure-contrib/trunk/src/clojure/contrib/enum.clj?revision=240&amp;view=markup
17:41rhickeynote that that is based on old gen-and-load-class, butyou could do similar with new gen-class
17:43rosejnGreat, thanks. I should have checked contrib before.
17:58rosejnrhickey: It looks like something has changed to break defenum
17:58rosejnThe example in the documentation throws an exception
17:58rosejnuser=> (use 'clojure.contrib.enum)
17:58rosejnnil
17:58rosejnuser=> (defenum my.package.MyEnum FOO BAR)
17:58rosejnjava.lang.ExceptionInInitializerError (NO_SOURCE_FILE:3)
17:58rosejnuser=>
18:00rosejnDoing a stack trace, it looks like it's caused by this:
18:00rosejnCaused by: java.lang.ClassNotFoundException: my.package.MyEnum__init
18:22arohneris there a fast way to turn the keys of a hashmap into a set?
18:23arohneror does (set (keys my-map)) do the right thing?
19:06technomancywhat does this mean? java.lang.reflect.InvocationTargetException / [Thrown class clojure.lang.Compiler$CompilerException]
19:09rhickeytechnomancy: you can get a full stack trace with (.printStackTrace *e)
19:12technomancythat just returns nil. should it work even in slime, or does slime wrap the exceptions differently?
19:12rhickeytechnomancy: I don't know about slime
19:13timjrhm... any idea how I could list the threads that are running and interrupt one of them?
19:13timjrI've got an infinite loop going
19:14technomancyI think I just need to read up on my Java... slime gives me some kind of backtrace, but it doesn't seem to involve any of my code or the libraries I'm using.
19:20erghow does clojure handle the case where a multimethod defines a dispatching function and calls itself recursively in one of the methods?
19:21technomancyI'm trying to translate from JRuby to Clojure...
19:21technomancySyndFeedInput.new.build(XmlReader.new(url.open_stream)) should become (.build parser (XmlReader. (.openStream url))), right?
19:21technomancygiven the proper imports
19:22technomancyoh, and where parser is (SyndFeedInput.)
19:29hiredmanerg: I don't see how that needs special handling
19:31hiredmanare you asking about (recur ...) usage inside multimethods?
19:31erghiredman: if your dispatching function does some preprocessing, you'd only want to do it once and not every time you recurse
19:31hiredmanmultimethods do some catching
19:32hiredmanbut I don't know much about it
19:32hiredmanuh
19:32hiredmanpreprocessing?
19:32hiredmanthat sounds like you are doing it wrong
19:33hiredmanouput from the dispatch function does not go to the multimethod that gets called
19:34hiredmanthe output of the dispatch function is only used to pick which multimethod to use
19:34ergok. that makes sense then
19:34hiredmanclojurebot: multimethods?
19:34clojurebotmultimethods is what separates the boys from the men.
19:35ergheh
19:35Chouserrecur in a multimethod doesn't go through the dispatch function again -- it recurs within the specific method where its called.
19:35hiredmanChouser: good to know
19:39timjrhm. it seems there's no way to interrupt a thread that's in an infinite loop in java!
19:41walterstimjr: you can Thread.stop
19:43timjrhm, yeah, that looks like a likely (if deprecated) option. thanks!
19:43waltersthere was a long discussion about this on the jvm languages group
19:44waltersone could imagine a special option for Thread which would cause the VM to drop into a thread kill check periodically
19:45walterswould force code to effectively stay in the interpreter instead of getting compiled
19:50danlei(?? :foo) => "foo"
19:50gnuvince_name
19:51jlesliewhats the 'right' way to join [1 2] and [[3] [4] [5]] into [1 2 3 4 5]?
19:51danlei(name :asdf
19:51danleignuvince_: perfect, thanks
19:52gnuvince_jleslie: probably something with tree-seq
19:52Chouserjleslie: jleslie (apply concat [1 2] [[3] [4] [5]])
19:53technomancyhow do you run a .clj file on the command line without loading the repl?
19:53Chouseruse Script instead of Repl
19:53technomancyChouser: and where do you specify the script file name?
19:53technomancyjust after clojure.lang.Script?
19:54Chousertechnomancy: yes
19:54jleslieChouser: beautiful. thanks muchly!
19:54technomancyChouser: thanks
19:58technomancyweird... this stuff works in Script but not in Slime.
19:58hiredmanclojurebot: emacs?
19:58clojurebotemacs is hard, lets go shopping!
20:00technomancyclojurebot: pretty-print?
20:00clojurebotexcusez-moi
20:21slava< Chouser> recur in a multimethod doesn't go through the dispatch function again -- it recurs within the specific method where its called.
20:21slavathat sounds like a pretty annoying limitation -- i've written tail-recursive methods before which would need to dispatch again
20:31Chouserslava: perhaps you could use the trampoline mechanism in that case.
20:39timjrI've seen code that has a {:tag java.io.StringWriter}, e.g., inside a (defn ...) form. anybody know what that's about?
20:39hiredmantype tag maybe?
20:41timjrah, I see, yeah, in that case it's a return type. it's documented under "special forms".
20:45timjrit's pretty nice having such easy access to java, because it means almost everything you might need is there already
20:46timjrlike, to list threads, I just ended up using the list method from java's ThreadGroup
20:46timjrvery handy
20:47hiredmannifty
21:42rhickeysvn 1132 adds AOT compilation of proxies, no interface change
21:43Chouservery nice.
21:51duck1123_how hard would it be to give clojurebot a feed parser so he can announce new commits to clojure and contrib in the room? Would that be desirable?
21:53duck1123_has anyone done any real feed parsing with clojure yet?
21:54duck1123_Chouser: how'd it go for you?
21:54Chousernot a problem. I like zip-filter for obvious reasons.
21:55technomancyduck1123_: I'm trying to hook it up to Rome, but it's blowing up pretty hard.
21:55duck1123_I haven't gotten the opportunity to make use of zip filter yet
21:55duck1123_I've been tempted to use Abdera
21:55ChouserI ought to write up a tutorial.
21:56duck1123_Ironically, I'm an RDF guy, but I much prefer Atom
21:56lisppaste8technomancy pasted "nomnomnom for feeds" at http://paste.lisp.org/display/71291
21:56technomancyduck1123_: I think it'd be awesome to hook him up to the feeds though.
21:57duck1123_They do that in #laconica, I thought it was very cool
21:58duck1123_they also did new tickets, but clojure doesn't have a very definitive bug tracker. (save for the mailing list)
22:00Chouserwe have a bot hooked up to trac at work -- check-ins, ticket updates, it's really nice.
22:18arohnerrhickey: can we get an abs that works on ratios and bignums?
22:20arohnerjava.lang.Math/abs doesn't cut it
22:20gnuvince_arohner: you can write your own, it's pretty easy
22:21arohneryeah, but that's the same problem as string libraries in C
22:21arohnerit's easy, but everyone will have their own
22:21gnuvince_I meant in the meantime
22:21hiredmandoes contrib have a mathlib yet?
22:21arohnergnuvince_: mine's already written :-)
22:21gnuvince_Not that I know of
22:21gnuvince_arohner: k
22:21arohnerhiredman: I don't think so, sounds like a good idea
22:22gnuvince_I was thinking that copying Factor's sequence library could be a good idea
22:22gnuvince_(at least, what makes sense for Clojure)
22:22rhickeyarohner: patch welcome
22:24arohnerrhickey: k
22:44timjrhm... what would make something get stuck in alter? my program seems to just hang there forever... it must be something that another thread is doing/has done. this is the backtrace of the stuck thread: http://paste.lisp.org/display/71294
22:47Chouseryou can reproduce it every time?
22:47timjryep
22:47timjrI can't get it to stop reproducing it
22:47timjrI'm almost certainly just doing something dumb
22:48Chouserhow much code does it take to reproduce? can you get it down to a few lines and post them?
22:54timjrI'm trying to figure out how to do that :)
22:55timjrhere's one question: if I've got (dosync (alter foo ...)), where foo is a global variable, after the dosync, should every thread see the new value of foo?
22:56timjrI added something to a map in one thread, and later when another thread looked it doesn't seem to be there.
22:56hiredmanerm
22:56hiredmanyou mean a ref right? not a global variabl?
22:56Chousera ref stored in a global var, presumably
22:56timjrit's (def *mailboxes* (ref {}))
22:57Chouserbut yes, unless the viewing thread is still in a transaction, it should see the new value.
22:58timjrand the alter is (dosync (when-not (@*mailboxes* id) (alter *mailboxes* assoc id (java.util.concurrent.LinkedBlockingQueue.))))
22:58Chousertimjr: ah! yeah, don't do that.
22:58timjrI was hoping you'd say something like that :)
22:58timjrwhy not?
22:58hiredman(doc alter)
22:58Chouserhm, well ... hang on, let me think about that a little.
22:58clojurebotMust be called in a transaction. Sets the in-transaction-value of ref to: (apply fun in-transaction-value-of-ref args) and returns the in-transaction-value of ref.; arglists ([ref fun & args])
22:59ChouserI don't have a specific reason yet, but doing anything that might block from inside a transaction is probably a no-no.
22:59Chouserbut creating a LBQ ... not sure...
22:59timjrwell, I don't think the constructor will block
23:00Chousertimjr: for kicks you could try creating it before the dosync, then assoc'ing it from inside.
23:18timjrah, it looks like it wasn't stuck there, it was just executing that code repeatedly
23:19timjrsorry for the wild goose chase...
23:21Chousernot a problem, glad you figured it out.
23:22timjrit was a really mundane bug -- I was using threads as keys in one place and thread IDs in another, so I ended up with two different mailboxes for the same thread
23:22timjrdumb bugs are good :)
23:24Chouser:-)
23:27Kerris7I wonder how hard it'd be to get Clojure to work with Scala
23:27Kerris7from the same project under NetBeans
23:36matzeronoob question (never done func programming) : I am trying to understand how the apply function works in clojure; so here is what I did:
23:36matzero(def x '(1 2 3))
23:37matzero(defn double-it ([x] (* 2 x)))
23:37matzerothen I try to use those two by saying
23:37matzero(apply double-it x)
23:38matzeroI expect to get a list with each element in it doubled
23:38matzerobut instead i get a wrong num of args from double-it
23:38dthomasIs there a nicer way to write "is X in some-seq" than using (some)?
23:39Chousermatzero: no need for apply in that case. just (double-it x)
23:39Chouserdthomas: (some #{item} the-seq) is a common idiom for that.
23:39Chouser(some #{this-item or-that-item} ...)
23:40matzerothat wont work because the double-it does type inference to figure out that it needs an int so when I pass the list it throws up
23:41Chousermatzero: oh, right sorry. apply is useful for calling a fn that takes multiple args, but you have a collection of items each of which should be an arg
23:41Chousermatzero: for example, + takes multiple args, not a collection. so if i have (def x [1 2 3]) and want to add them, (apply + x)
23:41matzerooh i see
23:42matzerook so i need to figure out how to turn that list into a bunch of args...ok let me chew on that then. thanks!
23:42dthomasChouser: OK, I was not expecting a set to be callable like that. Just found the docs. Thanks for that. I figured there had to be an idiomatic way to express that.
23:43dthomasmatzero: You might also find (map double-it x) to yield the result you were originally looking for.
23:45matzerook i'll try that
23:53technomancyok... what's the first thing to check when code behaves differently in SLIME vs the Repl?
23:54notallamaclasspath?
23:54matzeromaybe what jars each is pointing to? i had a similar problem since I pull from svn and build it every once in a while. But I use enclojure not SLIME
23:55technomancypretty sure the classpath is OK here... how would I double-check though?
23:56technomancythe only difference is I'm using absolute paths in the one that breaks and relative paths in the working one
23:56technomancyno, scratch that; absolute paths both places
23:57notallamaall that would be different should be ".", depending on where you're launching the repl from.
23:57notallamawhat's the problem, though?
23:58technomancynotallama: SLIME just gives this, which doesn't strike me as informative: java.lang.reflect.InvocationTargetException (NO_SOURCE_FILE:0) / [Thrown class clojure.lang.Compiler$CompilerException]
23:58technomancyRepl works fine; clojure.lang.Script exits with no output, but no exception either.
23:59lisppaste8technomancy pasted "nomnomnom" at http://paste.lisp.org/display/71299
23:59technomancythere's the code