#clojure logs

2008-07-02

01:27Lau_of_DKHow do I compile my .clj file into a singla .jar file?
01:27Lau_of_DK(replace \a \e)
01:29Lau_of_DKHow do I compile my .clj file into a singlr .jar file?
01:30Lau_of_DK(replace \r \e)
01:44Lau_of_DKk, nobody knows... When we refer to Trees, are we generally talking about hash-maps?
02:44perspectivetquick newbie question
02:45perspectivethow do I replicate c-style "while( x() ) { y(); }?
02:46Lau_of_DKCheck the loop / recur documentation
02:47Lau_of_DK(loop [x y z] ( x() y() (recur (new x) (new y) (new z))
02:49cgrandperspectivet: can you give more details on what you try to achieve? In FP most functions take arguments and those which don't are constant.
02:51perspectivetI'm tranlating the following swt snippet into clojure
02:51perspectivet;; Display display = new Display ();
02:51perspectivet;; Shell shell = new Shell (display);
02:51perspectivet;; Text text = new Text (shell, 0);
02:51perspectivet;; text.setText ("ASDF");
02:51perspectivet;; text.setSize (64, 32);
02:51perspectivet;; text.selectAll ();
02:51perspectivet;; shell.pack ();
02:51perspectivet;; shell.open ();
02:51perspectivet;; while (!shell.isDisposed()) {
02:51perspectivet;; if (!display.readAndDispatch ()) display.sleep ();
02:51perspectivet;; }
02:51perspectivet;; display.dispose ();
02:52cgrandok, I'm reading it (next time use http://paste.lisp.org/new/clojure for pasting code)
02:52perspectivetsorry
02:53perspectivetwill do
02:54lisppaste8perspectivet pasted "swt snippet tranlation" at http://paste.lisp.org/display/63147
02:54perspectivetthat's things so far
02:55cgrandok: java interop so FP rules don't apply there :-) In that case loop/recur is the simplest way to go
02:56perspectivetcgrand: yeah, I figured. I'm coming over from the haskell world as far as recent fp experience goes and I couldn't find an api for any of the approaches I would use there.
02:58lisppaste8cgrand annotated #63147 with "added translation for the while" at http://paste.lisp.org/display/63147#1
03:01cgrandperspectivet: so as you can see my answer to your original question is (loop [] (when (x) (y) (recur)))
03:08jgrantcgrand : do you know of a way to create a jar of a clojure script/s ?
03:14Lau_of_DKQuoting cgrand
03:15Lau_of_DK for the jar file structure: copy clojure.jar and
03:15Lau_of_DK open it, name you main file "user.clj" and put it in the directory where boot.clj is. Edit
03:15Lau_of_DK the manifest file to point to clojure.lang.Script instead of clojure.lang.Repl as the main
03:15Lau_of_DK entry point for the jar.
03:15Lau_of_DKif you havce to load other files from
03:15Lau_of_DK user.clj, use (. clojure.lang.RT loadResourceScript "xxx.clj")
03:16jgrantthx
03:16perspectiveton a related note, is there a way to standard way to ship compiled clojure files?
03:17perspectivetbtw: thx cgrand
03:17jgrantyea where are the compiled class files that clojure generates ?
03:18jgrant(seems like that would be a much 'saner' approach)
03:21Lau_of_DKI dont know - I would like to know,Im missing (save-lisp-and-die)
03:22jgrantnow if only sbcl was as stable as the jvm ;)
03:23perspectivetis there an emacs mode with automatic-paste-lisp-org-paste or somesuch?
03:53cgrandjgrant: compiled class are never written to disk (except for genclass) and even if they were, they wouldn't be usable as-is because there's some close cooperation (can't give more details: I'm not Rich) between the class loader and the class to close over the environment
03:56hoeckmhh, would it be possible to save an image of the jvm?
04:12Lau_of_DKTheoretically at least, it should be possible
04:22cgrandhoeck: volunteering to test how http://cryopid.berlios.de/ interacts with the JVM? ;-)
04:25Lau_of_DKcgrand, that looks sweet, but its not fully ready yet, would you mind finishing it, so we can toy with it tonight?
07:56cemerickAm I right in thinking that it's totally OK to throw an UnsupportedOpEx from ISeq.cons?
08:14rhickeywhat seq doesn't support cons?
08:22rhickeycemerick: deriving from clojure.lang.ASeq will give you cons and much more for free
08:25cemerickrhickey: A half-hour ago, I hadn't noticed ASeq :-)
08:26cemerickbut, FWIW, it doesn't make sense to cons onto this particular seq (a resultset of sorts -- not from a SQL query, but similar in concept)
08:27rhickeyyeah, someday there will be JavaDoc... until then, everyone should be aware there are abstract helper bases for most of the persistent data structures
08:28rhickeycemerick: the sensibility seems, to me, to be in the eyes of the conser, not the consee
08:29cemerickrhickey: True enough. That's sometimes hard to see when one is playing both sides of the fence.
08:29rhickey:)
08:48cemerickThis might be unreasonable given the current impl, but would be nice in some circumstances to have full destructuring available in def.
08:48cemericks/would/it would
08:48rhickeyin order to def more than one thing at a time?
08:57cemerickrhickey: Yeah, I have a couple of situations where I'm doing stuff like (let [{foo :foo bar :bar baz :baz} (getEnvironmentInfo)] (def foo foo) (def bar bar) (def baz baz)). I fooled around with a couple of macros, but anything short of reimplementing destructuring in them would lead to a crippled result (I think :-) ).
08:58cemerickIt's an infrequent pattern, of course, so it may not be worth thinking about too much.
09:01rhickeydestructuring is available a la carte:
09:01rhickeyuser=> (destructure '[[a b] x])
09:01rhickey[vec__2149 x a (clojure/nth vec__2149 0 nil) b (clojure/nth vec__2149 1 nil)]
09:01rhickeyuser=> (destructure '[{:keys [a b]} x])
09:01rhickey[map__2150 x a (clojure/get map__2150 :a) b (clojure/get map__2150 :b)]
09:06cemerickVery nice.
09:06cemerickThat's not in the docs anywhere, though -- I guess only defns that have docstrings make it in.
09:07scgilardiThe ns-utils lib has a "vars" command that displays all the vars defined in a namespace. (vars clojure) is good to peruse from time to time.
09:09rhickeynot doc'ed because I don't want to guarantee its interface yet, but it's stable, and obviously used often by Clojure
09:09cemerickrhickey: Sure, wasn't saying it should be doc'ed. Just happy I didn't pass over it.
09:09rhickeyyou could easily write a destructuring-def with it
09:10rhickeyone trick about it is that it will return its argument if no destructuring was needed
09:11cemerickI might get around to it. The stuff that uses let for destructuring is put to bed at the moment.
09:12cemerickscgilardi: BTW, thanks very much for the lib tweaks (and pred as well...no need to keep carrying around our own similar utils anymore).
09:13scgilardiyou're quite welcome. I'm glad you're finding them useful.
09:13blackdogscgilardi, where is this library?
09:14blackdogi don't see one by you in the Files section
09:14scgilardihttp://clojure-contrib.svn.sourceforge.net/viewvc/clojure-contrib/
09:14blackdogah, didn't know about that
09:14blackdogthx
09:15cemerickYeah, it took me a minute to look in svn, too. :-)
09:15scgilardiclojure contrib has some cool stuff in it from a few folks :)
09:15blackdogneat, i thought everything of use was on the google group
09:16rhickeyI'm hoping to fold some of the great stuff from contribs into Clojure soon after ECOOP next week
09:16scgilardivery cool. have a great trip. are you presenting anything?
09:18rhickeyYes, I'm presenting twice, once to the European Lisp Workshop on the Lisp nature of Clojure, and once at the Dynamic Languages Symposium on Clojure generally
09:19rhickeytowards the end of incorporating contribs, I have been looking at adopting Sun's contributor agreement for Clojure: http://www.sun.com/software/opensource/contributor_agreement.jsp - any thoughts
09:19rhickey?
09:19scgilardinice (re: presentations). I'll check out the website to see if they make videos or transcripts available.
09:24rhickeythe main purpose of the SCA for Clojure would be to prevent it from becoming license-bound, i.e. everyone contributed under license X, preventing the project from moving to license Y, or X + Y. I like it because contributors give up none of their own rights
09:26scgilardiyes, it does seem like a light touch with the main goal of sharing the copyright on contributions. Sounds good to me.
09:54ChouserThe SCA looks pretty good. I can't seem to find much meaningful critisizm of it, which is impressive for the kind of role it plays.
09:56rhickeyIt originally got bashed for not having the "Any contribution we
09:56rhickeymake available under any license will also be made available under a suitable FSF (Free Software Foundation) or OSI (Open Source Initiative) approved license." language
10:01Chouseryep, I saw that, and it's a good clause to include.
11:10cemerickffailla: Any news vis a vis Shoal on ikvm?
11:31Lau_of_DKAnybody up for tag-teaming on a quick 'n' dirty Clojure-IRC client ?
11:34Chouserajax?
11:35Lau_of_DKswing?
11:36Chouserncurses?
11:36Lau_of_DKWhy not swing?
11:36Chouser:-) I guess my answer is "not really".
11:36Lau_of_DKoh
11:37Lau_of_DKWould have been fun to tag-team with the infamous CHOW-zarrrrrrr
11:37Lau_of_DKBut I'll let you go
11:37Chouserheh.
11:37Chouserwhat do you mean by "tag-team" specifically?
11:38Lau_of_DK I'll fill you in a little later, dinners served. But I was thinking that we divide the tasks, quickly get something working, if somethings too difficult or not done well enough, clap each others hands and switchs jobs :)
11:40Chouserhm, interesting.
11:43cemericksounds like the start of a clojurebot :-)
11:45Chouserhm, now that might be interesting.
11:58cemerickAm I right in thinking that currently the most idiomatic way of yielding a seq without an item is to filter?
12:11ChouserI guess it depends on how you know which item you don't want.
12:17Chouser(filter (complement #{:c}) [:a :b :c :d :e]) ==> (:a :b :d :e)
12:17Chouser(filter #(not= % :c) [:a :b :c :d :e])
12:18Chouser(for [i [:a :b :c :d :e] :when (not= i :c)] i)
12:19Chouser(disj (set [:a :b :c :d :e]) :c) ==> #{:b :d :e :a}
13:46rhickey(set/difference #{:a :b :c :d :e} #{:c})
13:50Chouser(reduce #(if (= %2 :c) %1 (conj %1 %2)) [] [:a :b :c :d :e])
13:52Chousercemerick: so, do you have the value of the thing you want to remove, as all these examples assume? Or do you have its index?
13:53cemerickChouser: sorry, disappeared for a bit. Yeah, I always have the thing I want to remove. I guess I'm thinking that a complement to conj would be handy.
13:54rhickeyunj?
13:54Chouserha!
13:54rhickeylists -> pop, set -> disj, map-> dissoc
13:55rhickeybut remove from middle of list is not opposite of conj
13:55Chouseryou might have duplicates in your seq, though, so you might want to be able to take from either end. like unj-early
13:55Chouserand unj-late
13:55cemerickTrue, true. Just talking into the wind, as usual. :-)
13:55Chousercemerick: would your seq be better as a set?
13:56cemerickUnfortunately not.
13:56Lau_of_DKrhickey: Im considering doing a simple IRC client (swing) in Clojure - Have you got any insights to share _before_ I lay the foundation ?
13:57cemerickI already have a remove-one function that uses lazy cat to avoid consing up the rest of a seq after an item's been removed.
13:57Lau_of_DKOh.
13:57Lau_of_DK:)
13:58cemerickI'm just always looking for the cleaner, more applicable solution. :-)
13:58Lau_of_DKCould you then tell me if there's any networking helpers thought into clojure, or if its going to be pure java interop ?
13:58Chousercemerick: the file and for examples above are fully lazy
13:58Chouserer, "filter" and "for"
14:02rhickeyLau_of_DK: I would just grab a Java IRC lib and use it
14:03Lau_of_DKOkay
14:03Lau_of_DKI'll look into those - Have you checked out MigLayout rhickey ?
14:03rhickeyno
14:04Lau_of_DKIts works very well with Clojure for making Swing applications, you can set up "complicated" GUIs with event handlers and everything in very few lines of code
14:04pjb3So as it turns out, there is an even better solution to Concurrency than Immutability, and that is to have no shared state
14:05pjb3This seem to me to be very common in J2EE web applications
14:05Chouserpjb3: with a relation database as the only shared data?
14:05Chouserrelational
14:05pjb3You have Servlets, JSPs, access to a database via JDBC, and frameworks built on top of those
14:05pjb3Chouser: yeah, and the only shared data is in the database
14:06pjb3I bring this up to discuss the whole "State, you're doing it wrong thing"
14:06pjb3and I think a valid response to that is
14:06pjb3"No I'm not, I'm not sharing any data across threads"
14:07pjb3In other words, whether it be a J2EE app, or Ruby on Rails, or whatever, if you are building a web app that talks to a database, concurrency really isn't an issue, is it?
14:07rhickeyNot doing state at all is perfectly fine - the tools are for when you need state
14:08pjb3rhickey: Sure, and the only reason I bring all this up
14:08rhickeypjb3: it is for the guys writing the appserver you're running on, or the database
14:08pjb3is that what I am finding, the more I work with Clojure
14:09pjb3the more I like it
14:09pjb3but it is for all sorts of other, non-concurrency related things
14:09rhickeyI think one of the saddest things I see is when people pull data from a db and stick it in a mutable object
14:09pjb3and all these things should be mind-blowing to J2EE web app developers
14:10pjb3rhickey: so that's pretty common in web apps, what's sad about it
14:11rhickeywhy mutable? blows the functional/relational model
14:11pjb3not sure what you mean by functional/relational model
14:12ChouserI suspect that as web apps take more advantage of ajax and especially comet-like stuff, databases become less sufficient as the only state.
14:12rhickeythe pervasive caching says that's already the case
14:13rhickeypjb3: you just touted the db as the only state, with a mutable object you've now got your state back
14:13Chouserimagine a chat server -- with polling, a db might be okay, but with comet you'd like to send a message across to another session. Suddenly you've got in-memory multithreaded state.
14:13rhickeydb has state != app is single threaded
14:14Chouserrhickey: yes. did I imply otherwise?
14:14rhickeyapps may need to leverage multiple cores to speed up any calculation
14:14rhickeyChouser: sorry, that was for pjb3
14:15Chouserok
14:16pjb3rhickey: The mutable object is essentially a read-only copy, if you want the changes to persist, you call methods on the object to modify the data, and eventually the object generates a SQL update statement to put the new state of object into the db
14:16ChouserI hope to do some tests and performance tuning on the lazy xml stuff tonight. It seems to me that it ought to be nearly as fast worst case as xml.clj, and if you have multicores or can take advantage of laziness, significantly faster.
14:16Chouserrhickey: you can't just start the nick and press <tab>? what client?
14:17rhickeyChouser: thanks!
14:17Chouser:-) np.
14:17pjb3and AFACT, that's really no different that querying for data, storing it in an immutable map, creating a new, slightly different immutable map based on that, and then generating a SQL update to store that
14:17rhickeypjb3: it's way different
14:18Chousersurely if the mutable object is only within a single thread, it's only slightly different?
14:19rhickeyIt's way different because in one case you can add another thread without a rewrite, reuse the same logic in other MT apps, test without mocks and setup etc etc
14:20rhickeyChouser: the lazy xml is really neat, but the *enqueue* and esp. exceptions for flow control really bother me - is there no other way?
14:22ChouserI don't think there's any way around *enqueue* (or some other acts-like-mutable thread-local binding) without bringing in an new xml parser API (such as a pull parser). Even the existing xml.clj has a pile of thread-local bindings.
14:23rhickeyClojure was born in part due to the extreme pain I saw endured over and over when code that would 'only run with one thread' had MT added
14:23ChouserThe exception is a little messy, but it's not really for flow control. It's only used to kill off an abandoned parser thread. Perhaps I could kill the thread some other way? Again, bringing in a pull parser would solve this.
14:23pjb3rhickey: web apps are MT, they just don't share state between threads
14:24rhickeymaybe not today, but that is, IMO, a false presumption moving forward
14:26rhickeypjb3: and the easiest way not to share state is to not have it, e.g. use immutable data structures
14:29rhickeyChouser: I've been thinking a lot about seqs on stateful things, this queue thing is just another variant of the auto-closing stream requests
14:29rhickeysame problem - dangling non-memory resource
14:34drewrChouser: Is that double LET in your CASE macro a common idiom?
14:34drewr(With the GENSYM..)
14:35Chouserrhickey: that's a good point. your weak-ref solution might be the key.
14:35Chouserdrewr: dunno.
14:36rhickeyChouser: I did a lot of testing and was frustrated by the unpredictability of weak-ref reclamation
14:37Chouserdrewr: probably not uncommon though in a macro. the outer let is just for while the macro's expanding. The inner let is in the expanded code.
14:37rhickeysometimes threads came right back, other times they stayed around indefinitely
14:38Chouserrhickey: yeah, I was surprised to see at least one of those threads hang out for a few minutes with everything in the JVM idle.
14:38Chouserbut that's the flip side of the ethereal GC you like so much, isn't it?
14:39rhickeyChouser: not really, we're trying to tie something non-memory to memory
14:40rhickeyChouser: and I think the problem is when it gets moved to another generation - real ephemeral memory doesn't get there
14:40drewrChouser: Just seem strange to do in two LETs what I would think you wouldn't need to do at all. val already has a binding from the enclosing scope.
14:41rhickeyChouser: my latest thinking is possibly to have LazySeq implement Closeable, and lazy-cons take an optional third on-eos expression
14:41Chouserdrewr: the inner let is common. I could have done without the outer let and just used val# if I hadn't done two separate `() exprs
14:44ChouserHm, apparently doto in boot.clj uses the same idiom for essentially the same reason.
14:46rhickeyChouser: sure, nothing wrong with that - ` and blah# are convenience features with limits
14:48Chouserso what would call LazySeq's close method? Does Java do that automatically?
14:49rhickeyChouser: no, you'd use the with-open idiom
14:49rhickeyplus auto-close on eos
14:50rhickeyThere isn't a way to let someone off the hook from knowing they're holding a resource
14:51rhickeycould use dynamic var to free from manual registration: (closing-all ...)
14:52Chouserbut you certainly don't want to have to use with-close on all seqs just in case they might have some special resource that needs closing.
14:52rhickeywhere resources would register with *auto-close*
14:53rhickeyChouser: no, but there's no free lunch either
14:53Chouserbut you're so close with weakrefs! :-)
14:53rhickeyfinalization is a bad hook
14:54Chouserjust as laziness can be passed up through a series of wrapped seqs, so would the need to use with-close.
14:55rhickeyChouser: I understand, but in the end what you are asking for is the messy stateful world to be as elegant as the beautiful lazy functional world, and it simply can't
14:57pjb3Are there docs on how to use clojure from within a java app?
14:57Chouseryeah, I guess the reason it hurts so much in my case is that the XML parser really doesn't need to be stateful, so I was nearly able to abstract away the statefulness. ...but not quite.
14:58Chouseror rather encapsulate it fully. but not quite...
15:00rhickeyChouser: the queue problem has a different formulation, where consuming from the queue fires off a one-shot agent request to put more in, but doesn't help your event-driven parser problem
15:02Chouseryou're saying seque has the thread resource issue regardless of how the queue is filled? of course you're right.
15:04pjb3If I want to use clojure from within a servlet, what do I need to initialize Clojure?
15:04pjb3If I pass a String to clojure.lang.Compiler.eval, it throws a Null Pointer Exception
15:05Chousereval wants a datastructure, not a string.
15:05Chouserbut that's not the right direction anyway
15:05Chouserhang on, looking for a link...
15:05rhickeyChouser: no, the opposite, I think my original seque can be done with no hanging thread by sending after each take, rather than dedicating a filler...
15:05pjb3Chouser: thanks
15:06rhickeyChouser: but an event-driven SAX parser requires a dedicated thread and state
15:06Chouserpjb3: http://clojure-log.n01se.net/date/2008-06-28.html#10:44b
15:08Chouserrhickey: ah! yes of course! seque could send-off to get n ahead, and then send-off again once per consumer request.
15:08rhickeyright
15:08rhickeyeach send would fill as much as possible then quit
15:09Chouseryeah, which would completely solve the resource issues with all seque's except for mine. :-)
15:09rhickeysorry :(
15:09Chouserstupid sax
15:11Chouserwell, parallel.clj requires an external jar. I guess lazy-xml could require http://www.extreme.indiana.edu/xgws/xsoap/xpp/mxp1/index.html
15:11rhickeycan you pause the sax parser in a handler?
15:12Chouseryes. I do that now by calling *enqueque*, which blocks.
15:12rhickeyno, I mean tell the sax thingy to pause, and call resumeParse later
15:14ChouserI don't think so. I think the problem is that the sax parser's own state is just on the stack, and it sits there calling down into the handlers.
15:14Chouserit doesn't have a way to bundle it's state to resume later. Let me check the API again.
15:15rhickeyok. but even a pull parser will put you in the auto-close camp
15:17Chouserwell, I guess I'll have a file or network reader at the bottom that might need to be closed, but I don't think the pull parser would add requirements above that.
15:17rhickeyright
15:19Chouserbut that's fine. the user of my parser api will give me the reader and will be responsible for closing it, just like they are now with xml.clj.
15:20Chousereach call to "rest" on my parser seq translates to a call to .next on the pull parser
15:20rhickeyno doubt, a pull parser is a better fit
15:23ChouserI guess I could provide a clumsy solution with the built-in sax parser, but provide an identical api to allow switching to a pull parser.
15:23Chouserthe former would have to do *enqueue* and all the rest, the latter could use whatever seque you settle on.
16:44cemerickpjb3: you were asking about an error starting the REPL in enclojure earlier...
16:44cemerickpjb3: There's a couple of patches on the enclojure google group that fix that (at least for me)
16:46pjb3cemerick: ok, I'll take a look at that, thanks
17:49abrooksrhickey: Chouser told me I should be participating in the above discussion.
17:50abrooksrhickey: I was going to bring up a related topic the other day when I was mentioning remote concurrency.
17:52abrooksI've been thinking about some sort of proxying object (or perhaps other mechanism -- a proxying object was a convenient way to think about this) which would allow lazy high-latency objects to work ahead a bit in a separate thread.
17:53abrooksThe proxying object would be application and object type specific to suit different performance / overhead tradeoffs.
17:56abrooksThe parser is a good example (I've not read all of the above yet...) but I've been picturing this sort of mechanism applying to any case where a lazy object incurrs high in-line latency penalties such as stream / file or remote object access.
17:57abrooksIt would be nice to be able to take an object and tell it (not sure how -- special method?) to use function X to determine how far ahead to work. The default function would simply never work ahead.
17:59abrooksMy appologies if the above is completely unclear -- my blood sugar crashed about 15 minutes ago and my head is spinning. Now I get to try to drive home through the rain like this... :)
17:59abrooksrhickey: I'll drop in here later to clarify and talk more about this.
18:05pjb3If I type gen-and-save-class at the REPL, I get an exception, unable to resolve symbol
18:10rhickeyabrooks: have a look through yesterday's log - we were talking about seques, also: http://groups.google.com/group/clojure/browse_frm/thread/e7f4de566eddb6ea#
19:01lisppaste8pjb3 pasted "HelloWorldServlet" at http://paste.lisp.org/display/63177
19:02pjb3The above pastie generates the HelloWorldServlet class file, but when I run it in an app server, it doesn't appear that those methods get called
19:02rhickeypjb3: nice aquamacs screencast - thanks!
19:02pjb3oh, thanks, no problem
19:03pjb3init-void, that should override the public void init() method, right?
19:03rhickeyyes
19:04pjb3hmmm...doesn't seem to work
19:04rhickeyno errors loading servlet?
19:04pjb3no errors
19:05pjb3I can see the log message from the app server that it is initializing my HelloWorldServlet
19:05rhickeycom.paulbarry.HelloWorldServlet.clj is in classes/com/paulbarry/ next to the .class file?
19:05pjb3oh, no it isn't
19:07pjb3unable to resolve gen-and-save-class
19:07pjb3that's progress
19:07pjb3I suppose I just need to make sure that gets loaded in HelloWorldServlet.clj
19:07rhickeyyou probably want the gen-and-save-class in a different file or in a comment, you don't want to run that when the servlet runs
19:07pjb3yeah, good point
19:08rhickeythat's a one-time thing
19:09jgrantrhickey: rich, is there anything equivalent to sbcl's save-lisp-and-die function ?
19:09jgrantor some way to package everything up in a jar ?
19:09rhickeynot if that does what I think it does
19:10rhickeyClojure does no ahead-of-time compilation at this point
19:10rhickeyand serializing the state of Java is not going to happen
19:11jgrantyea i can see why
19:11jgrantserializing state is less important to me personally, i'm trying to figure out a way to package a clojure app as a jar
19:12rhickeyother than jar?
19:12jgrantno
19:13rhickeywith the .cljs and clojure.jar - user.clj should autoload, I guess what's missing is main?
19:13jgrantwas just about to say that
19:34jgrantis it possible to read user.clj from another jar (say user.jar) instead of from the file system ?
19:35rhickeyhave you tried putting user.clj next to boot.clj in clojure.jar?
19:36rhickeyuser.clj will be found on the classpath
19:37jgrantthat's what i gathered from read loadResourceScript
19:38jgrantWhy would java -cp user.jar -jar clojure.jar not work ?
19:40rhickeyhttp://forum.java.sun.com/thread.jspa?threadID=657160&amp;messageID=3882114
19:47jgrantthx but using the -jar switch disables -cp (uggh)
19:47jgrantthis works ...
19:47jgrantjava -cp user.jar:clojure.jar clojure.lang.Script
19:49jgrantwhat's the idiomatic equivalent of common lisp's "collect" ?
19:51rhickeycollect is a loop keyword - no loop in Clojure. you can reduce to build up results
20:05jgrantcool - this seems to do the trick ...
20:05jgrant(reduce (fn [x y] (conj x y)) '(0) '(1 2 3 4 5) )
20:06jgrant(i guess that's one possible definition of collect for clojure)
20:26jgrantis there an equivalent of the mod operator in clojure ?
20:26pjb3jgrant: you know you can write that as (reduce #(conj %1 %2) '(0) '(1 2 3 4 5) )
20:27pjb3(rem 5 2 )
20:27jgrantthx
20:27jgrantand yea
20:43jgrantrhickey : only one problem with this --> java -cp ../user.jar:../clojure.jar clojure.lang.Script -- hello
20:43jgrant*command-line-args* is nil
20:53slavarhickey: do you have a way of wrapping an Iterator in a seq?
20:55rhickeyslava: yes, that happens automatically, iterators, enumerations, Iterables, strings, arrays and all Clojure collections support seq
20:57Chouserrhickey: you're not working on seque, right? I thought I might try to implement your ideas from today.
20:58rhickeygo for it
20:58slavarhickey: sorry, i wasn't clear
20:58slavarhickey: i meant where in the source is it implemented (if it is, which it is)
20:59meredyddrhickey: If you wanted to make something that supported the (seq) operation, would the simplest thing just be to derive Iterator?
20:59rhickeyslava: clojure.lang.RT.seq()
20:59slavacool thanks
20:59rhickeymeredydd: the simplest way is to use lazy-cons
21:00rhickeymeredydd: if you need a class, deriving from clojure.lang.ASeq is the best route
21:00meredyddrhickey: Ah, yes...but I'd like it to behave as something else until (seq) gets called on it
21:00slavaa cool project for an aspiring hacker would be a clojure-like language that compiles natively using llvm.
21:01meredyddASeq sounds promising. Thanks!
21:02rhickeyslava: are there many libs for llvm?
21:03slavallvm is a codegen library
21:04rhickeyslava: right, so you'd have next-to-nothing to build on?
21:05slavawell, if all the libraries written in C count as "next-to-nothing", yes :)
21:09rhickeyslava: it seems tediously low-level
21:10slavasome people are interested in compiler implementation
21:12slavahotspot is not the last word in compilers, though
21:13jgrantright but the jvm was really designed/implemented in the beginning by people like Steele, Gabriel, Gosling etc.
21:13rhickeyno, but it begs the question as to whether people should be working on per-language compilers or hotspots
21:14jgrantthe highest volume sites on the web run on vms not in native code
21:14slavajgrant: the jvm compiles to native code so that's a moot point
21:14jgrant18:12 <slava> jgrant: the jvm compiles to native code so that's a moot point
21:14slavaa better argument is that the highest volume sites on on languages with gc, which makes perfect sense to me
21:15slavanobody wants to manage memory mnually when they really want to be working on their web site
21:15jgrantyea yea everything 'compiles' to native code
21:15slavajgrant: not interpreters :)
21:15rhickeymuch more leverage from building a hotspot than an optimizing compiler for language X
21:15jgranttechnically even interpreters do
21:15slavahotspot is an optimizing compiler for jvm bytecode
21:15jgrantjust a matter of word games
21:15slavajgrant: not really
21:16slavathere is a distinction between interpreting a sequence of instructions and generating code which performs the same operations
21:16jgranttranslation/compilation aside interpreters/compilers still need to run some machine code
21:16jgrantyes yes
21:17slavaa compiled program runs machine code generated by the compiler, an interpretd program runs the machine code of the interpreter itself
21:19jgranteither way the result is still machine code
21:19jgrantis it not ?
21:20slavaof course in the end the cpu is running machine code, but the distinction between compilers and interpeters is a useful one anyway
21:20jgranti for one would love it if my cpu understood english
21:20rhickeyjgrant: no, the distinction matters - is the CPU executing the user's code or the interpreter writer's code
21:20jgrantyes it's useful no doubt
21:21jgrantthe interpreters code is still modified by the script being interpreted to a large degree and influences the actual machine code being executed
21:21jgrantanyway
21:22rhickeyjgrant: you're never going to satisfy compiler writers with that interpretation :)
21:23jgrantrhickey: you are right ! and I'm going to give up I swear :)
21:30slavapersonally i'm just interested in implementation and design of compilers
21:30slavaif i wasn't, i'd be using hotspot, llvm, or compiling to c
21:31rhickeyslava: fair enough
21:34jgrantslava : cool, i personally favor vms just because of the space i find myself working in mostly these days, i'm completely biased
22:30ChouserI am not truly interested in the implementation or design of compilers, so I'm happy to have rhickey. I just want to us a good language.
22:31Chousers/to us/to use/
22:46Chouserrhickey: if the LBQ id not limited, the producer would now always do all the work to the end of the seq, even if the consumer loses all reference to it.
22:46Chouservs. your latest seque that might notice vie the weakreference that it can give up before the end even with an unlimited LBQ.
23:04rhickeyChouser: if the LBQ is not limited, it will be because there aren't memory issues with fully loading it
23:04Chousertrue, but if production is CPU intensive it can hog that resource.
23:05Chouserbut I guess if that's a problem, you should limit your queue.
23:05rhickeyjust another reason to limit the LBQ - unlimited is ppretty risky
23:05Chousergood point
23:05rhickeyright you are :)
23:06Chousermaybe unlimited shouldn't be the default
23:07rhickeyI kept taking it out of mine...
23:09rhickeyforget now why I put it back, I think it was just the 'I know this will fit, but not exactly how big it is' scenario
23:09rhickeygotta run
23:09Chouserif your producer is, say, network bound and you intend to end up with it all cached in a seq anyway...
23:09Chouserok, see ya
23:24Chouserdoes anyone know if bopping in and out of try blocks is expensive?
23:27Chouseras in, is it much worse to put the try block inside a loop rather than outside?