#clojure logs

2009-04-08

00:03hiredmanhttp://googleappengine.blogspot.com/2009/04/seriously-this-time-new-language-on-app.html <-- java on app engine
00:05cmvkkaw, Groovy, Scala and JRuby get a mention but not Clojure. is this still a second-class JVM language?
00:08danlarkinhey now
00:08danlarkinthat's a neat thing
00:09durka42maybe it will get mentioned when we implement it :)
00:11durka42great minds think alike
00:11hiredmandid someone just grab the clojure1 app identifier?
00:11durka42clojurebot: great minds think alike is <reply>and fools rarely differ
00:11clojurebotIn Ordnung
00:11durka42~great minds think alike
00:11clojurebotand fools rarely differ
00:12hiredmancause I tried to get clojure1, the check availability button said it was availble, then when I clicked "next" it said it was in use
00:15Drakesonis there something similar to map that applies the function f first to the whole coll, then to (rest coll), then to (rest (rest coll)), etc. (as opposed to applying f to (first coll), then (second coll), etc. ?
00:16cmvkknot built in, to my knowledge
00:16Chouser(map foo (take-while identity (iterate next coll)))
00:17Drakesonwow, (iterate next coll) is a nice idiom. thanks
00:19cmvkkiterate-while might be a worthwhile function to have
00:19Chouser"For instance, an app cannot spawn threads" ...google app engine
00:19Chousercmvkk: it's come up
00:19cmvkkhmm
00:19Chouseroh
00:19Chousertake-while identity has come up, I think
00:20durka42hmm, no threads could be an issue
00:20cmvkkdoes clojure implicitly use threads or something?
00:21cmvkki don't mean with agents, of course
00:21Chouserhttp://groups.google.com/group/clojure/msg/f88b1675635837a2 -- iterate-while
00:22hiredmanNo, an App Engine app may not spawn new threads
00:22hiredmanoh
00:23cmvkkso, when you send to an agent, are you spawning a thread?
00:23cmvkkif not, when do the threads in a thread pool get spawned?
00:23cmvkkor is it more subtle than all that.
00:27hiredmancmvkk: when you send-off, the executor must be creating a thread
00:27cmvkkyes. but with send, maybe it's not as clear
00:28cmvkkhow often are agents used in web application code anyway?
00:28hiredmanwith send the threadpool creates the threads when it is created
00:29cmvkkright, and when is the threadpool created?
00:29hiredmanhow does that matter?
00:29cmvkkif it's created the first time you use send, then you can use any clojure code as long as you don't use agents.
00:30cmvkkif it's created no matter what, or something, then won't it be a problem for any clojure code?
00:31durka42i suppose it would depend on how silently google makes spawning threads fail
00:32durka42i don't know the answer to your question
00:32cmvkkright. if google kills the process if it tries to spawn a thread, it might be a problem.
00:33durka42,(.getPoolSize clojure.lang.Agent/pooledExecutor)
00:33clojurebot1
00:33durka42in my repl (having not used any agents yet) that returns zero
00:34durka42~javadoc clojure.lang.Agent
00:34hiredmanuh
00:34durka42er
00:34durka42i don't expect that to work
00:34hiredman~def c.l.Agent
00:34durka42~javadoc java.util.concurrent.ThreadPoolExecutor
00:35cmvkkbased on that test, it seems like there's not really a problem, though.
00:35durka42,(.getCorePoolSize clojure.lang.Agent/pooledExecutor)
00:35clojurebot3
00:36durka42setCorePoolSize Sets the core number of threads. This overrides any value set in the constructor. If the new value is smaller than the current value, excess existing threads will be terminated when they next become idle. If larger, new threads will, if needed, be started to execute any queued tasks.
00:36durka42that sounds like they still aren't created unless there are tasks on the queue
00:39slashus2The thread pool is created when the agent is created.
00:40slashus2?
00:43durka42no, it is a static member
00:43durka42,(.pooledExecutor (agent nil))
00:43clojurebotjava.lang.IllegalArgumentException: No matching field found: pooledExecutor for class clojure.lang.Agent
00:43slashus2okay
00:43durka42^- wat
00:49slashus2So all send-off's use the same thread pool?
00:49durka42i think the pooledExecutor is for send
00:49durka42send-off's are handled by the soloExecutor
00:49durka42i think
00:50slashus2,(.pooledExecutor clojure.lang.Agent)
00:50clojurebotjava.lang.IllegalArgumentException: No matching field found: pooledExecutor for class java.lang.Class
00:50durka42,(.getPoolSize clojure.lang.Agent/soloExecutor)
00:50clojurebot1
00:50dnolenfirst public GAE app?
00:50dnolenhttp://guestbook-clj.appspot.com/
00:50slashus2,clojure.lang.Agent/pooledExecutor
00:50clojurebot#<ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor@197f158>
00:50slashus2,(clojure.lang.Agent/pooledExecutor)
00:50clojurebot#<ThreadPoolExecutor java.util.concurrent.ThreadPoolExecutor@197f158>
00:50dnolennice write up here
00:50dnolenhttp://elhumidor.blogspot.com/2009/04/clojure-on-google-appengine.html
00:51durka42cool!
00:52durka42this demands playing with this weekend
00:53cmvkkthat was fast
00:53cp2oh nice
00:54slashus2http://guestbook-clj.appspot.com/exercise What do you make of this?
00:55cp2heh
00:55cp2haha
00:55cp2anon anon anon...
00:55cp2kinda like debian random generator
00:55cp29 9 9 9 9 ..
00:56slashus2Why exactly is the atom value jumping around?
00:56dnolenyeah AppEngine is distributed across JVMs so you really can't really on refs/atoms
00:56slashus2ooh
00:57slashus2That is the number of visitors.
00:59hiredmanme too
01:00hiredmandnolen: that doesn't make sense to me
01:00hiredmanwell
01:00hiredmanhmmm
01:01dnolenhiredman: could be wrong, but I think what happens is the first request is handled by one jvm
01:01dnolenthe next request might not be.
01:01slashus2google broke it :-(
01:01durka42so if you don't write something out to disk it's not guaranteed to persist across requests?
01:02hiredmanno write to disk
01:03dnolenwell not to disk, but to whatever store google provides.
01:03durka42well database or whatever
01:11hiredmanhttp://fragmental.tw/2009/04/08/clojure-on-google-app-engine/
01:30durka42hey, it's an email
01:30hiredman!
01:31hiredmanme too
01:31durka42however, bedtime
02:17kadaverok guys time to launch compojure apps on appengine!
02:18hiredmanit's been done, at least twice already
02:22slashus2Does Common Lisp have multi-methods comparable to clojure's?
02:23cmvkkit has the object system
02:23cmvkkwhich allows you to define methods
02:23cmvkkbut it isn't like clojure
02:24slashus2CL's methods can dispatch on value?
02:25cmvkkno, they dispatch on class type.
02:25cmvkkthat's why it isn't like clojure.
02:25slashus2Hmm, I am getting some mixed information.
02:25cmvkkwell, don't take my word for it...
02:25cmvkkif someone is telling you otherwise, they're probably right.
02:26slashus2I don't know about that.
02:26cmvkkmy understanding is that CLOS is just a regular object system. you define classes, then you define methods which dispatch on the class of each argument.
02:28blbrownis everyone on the appengine train
02:29hiredmanyes
02:34lisppaste8jauk pasted "Problem with lazy parsing of xml" at http://paste.lisp.org/display/78235
02:34jaukI can't get the lazy parsing of xml working correctly
02:35jaukIf anyone has time to look at the code above, I would appreciate it
02:35jauki'm still a newbie with lisp (java background)
02:36hiredmanno exceptions?
02:37hiredmanI am unfamiliar with that lib, but the call to first, then the call to zip/node is very odd
02:38jaukwell, with the default ram it gives finally outofmemoryexception
02:38jaukbut with xMx=1000m xMs=1000m it just freezes
02:39hiredmanyou are sure it is not doing any work?
02:39hiredmanhow large is finland.osm?
02:39jaukwell, it is doing work. but the idea would be that because of lazy parsing it shouldn't need to do much any work.
02:40hiredmanthat is a naive idea
02:40jaukfinland.osm is quite large, 513 megs in total
02:40hiredmanhmm
02:40jaukis it?
02:41hiredman~lazy
02:41clojurebotlazy is hard
02:41jaukin the comments of the lazy-xml lib (http://github.com/dysinger/clojure-contrib/blob/36d13c6d40750b80b612921d5b3499d3a6c2fdb5/src/clojure/contrib/lazy_xml.clj):
02:41jauk; When used with zip and zip-filter, you can get do queries like this
02:41jauk; without parsing more than the first few tags:
02:41jauk; (zip/node (first (xml-> (zip/xml-zip tree) :id)))
02:41jaukthis is why i thought it should work
02:43hiredmanmaybe it should
02:52lisppaste8jauk annotated #78235 "Further details" at http://paste.lisp.org/display/78235#1
02:59jaukhiredman: thanks for your input! i guess i'll have to ask the question again later if someone else would have had experience with the lazy-xml library...
03:00hiredmanChouser is the xml filter guy, he is on central time (US) I believe
03:00hiredmanthere is also always the google group
03:02jaukok, i'll have to ask him then, thanks! i didn't want to start by spamming the google-group with a newbie question :) (maybe there should be separately a stupid questions -group?)
03:48dysingerGAE yayz
05:36leafwany help with vimclojure
05:37leafwI forgot how to view the help page ...
05:37leafwkotarak is not here, *sigh*
05:38Neronusleafw: maybe :help vimclojure
05:38Neronusleafw: Or the doc directory whereever you installed the package
05:53leafwNeronus: :help vimclojure I tried, and variations, but didn't wokr
05:53leafwyeah the help is in a file; was just wondering how to access it from within vim
06:17AWizzArd~ seen rhickey
06:17clojurebotno, I have not seen rhickey
06:17AWizzArd~ max people
06:17clojurebotmax people is 164
07:43cemerickis there some usage for condp floating around somewhere? I don't quote grok it.
07:50AWizzArd,(doc condp)
07:50clojurebot"([pred expr & clauses]); Takes a binary predicate, an expression, and a set of clauses. Each clause can take the form of either: test-expr result-expr test-expr :>> result-fn Note :>> is an ordinary keyword. For each clause, (pred test-expr expr) is evaluated. If it returns logical true, the clause is a match. If a binary clause matches, the result-expr is returned, if a ternary clause matches, its result-fn, which must be a unary function, is called
07:51AWizzArd,(condp = (+ 5 4) 10 'it-is-10 9 'no-it-is-9)
07:51clojurebotno-it-is-9
07:51AWizzArd,(condp #(+ 1 %) (+ 5 4) 10 'it-is-10 9 'no-it-is-9)
07:51clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--1583$pred--1585
07:52AWizzArdyeah, nonsense
07:52AWizzArdWell, it takes the expression and does (pred exp clause), until there is a match
07:53cemerickyeah. I guess I just don't have a use-case for it.
07:54AWizzArdIt is just less repetetive than
07:54AWizzArd,(cond (= 10 (+ 5 4)) 'it-is-10 (= 9 (+ 5 4)) 'no-it-is-9)
07:54clojurebotno-it-is-9
07:54AWizzArdwhere I need to repeat = and (+ 5 4) over and over again
07:55cemerickyeah, I got that. I just thought that there might have been more to it.
09:17Lau_of_DKHey guys
12:20danlarkinquietest I've ever seen this channel!
12:20pjstadigshhh
12:20pjstadigclojurbot: whose job is it to keep danlarkin quiet?
12:20pjstadigclojurbot: who's job is it to keep danlarkin quiet?
12:21danlarkinyou're spelling his name wrong
12:21pjstadigclojurebot: who's job is it to keep danlarkin quiet?
12:21clojurebotTitim gan �ir� ort.
12:21pjstadigclojurebot: whose job is it to keep danlarkin quiet?
12:21clojurebotthat is alek_b's job
12:21danlarkinwhose is correct, not who's
12:21pjstadigfourth time is the charm
12:21danlarkinsweet
12:21rsynnottwhy does that thing speak Irish?
12:26pjstadigso
12:26pjstadigone of the major issues left with Clojure + TC is the fact that you cannot assign a non-portable value as the root binding of a var
12:27pjstadigthe most glaring example is *in*, *out*, and *err*
12:27pjstadigwhat we need is a way to specify specific values to share, and specific values to exclude
12:28pjstadigAWizzArd and I have been talking about it and I think he has some good ideas
12:28pjstadigwe could add metadata values to specific vars that we would want to share
12:28pjstadiginstead of automatically sharing everything
12:30pjstadigthen the trick would be to fracture the namespace map so that when a var is resolved it is either fetched from a shared or a non shared mapping
12:30pjstadigis there a better way to do it?
12:32pjstadiganyone? anyone? bueller?
12:32AWizzArdrhickey maybe has an idea? :)
12:33pjstadig~def clojure.lang.Namespace
12:40pjstadigthe only problem i foresee is classes
12:40pjstadigif you add a var to the TC graph whose value is a compiled function
12:41pjstadigfor that function to be used in another VM its class would have to get added to the graph
12:41pjstadigwhich could be done
12:41pjstadigbut if that function depends on other functions those classes would have to be added as well
12:42pjstadigthe only way around it might be to just add all of the classes into the TC graph
13:13rhickeypjstadig: It's too complex to explain here, but I am keeping in mind these TC issues in my work now on namespace modularity
13:14Carkhum i've fallen behind on the mailing list, did you talk about these changes there yet rhickey ?
13:14kotarakhmm... couldn't with-ns go to ns-utils instead of having a dedicated namespace?
13:17rhickeyCark: no changes yet to discuss
13:18Carkok thanks ! i'm only slightly shaking at the thought of breaking changes
13:18rhickeyCark: This is for down-the-line post 1.0
13:18clojurebotfor is not a loop
13:18Carkah nice =)
13:18Cark~chouser?
13:18clojurebotchouser is ruthless about breaking other people's code
13:20Neronusis variable lookup in clojure performant, or is it always a good idea to avoid using vars?
13:20Neronusrhickey: Any plans when 1.0 will be released? And is there a roadmap available, or is it all in your head?
13:21Chouse1rhickey: there's some pre-lazier verbage on clojure.org yet. I deleted a couple lines from "sequences", but there's still stuff in "lisps"
13:21Carkneronus : might be usefull to enclose a tight loop with a (let [myvar *myvar*]
13:24AWizzArd,((fn [& args] (map class args)) 1 2 3)
13:24clojurebot(java.lang.Integer java.lang.Integer java.lang.Integer)
13:24AWizzArd,(defmulti foo (fn [& args] (map class args)))
13:24clojurebotDENIED
13:24AWizzArdokay, if I do this defmulti, and then (defmethod foo '(Integer Integer Integer) [i] (print "Integers: " i))
13:25AWizzArd(foo 1 2 3) ==> IllegalArgumentException: Wrong number of args passed to: user$fn
13:25kotarakAWizzArd: (defmethod .... [i] <- *m��p*
13:26AWizzArdAh I see, it m��ps at that point.
13:26Neronushehe.. moeep
13:27AWizzArdif I replace the [i] with [& i] now it funnily says: IllegalArgumentException: No method for dispatch value: clojure.lang.LazySeq@4319aced
13:28kotarakTry using vectors for the dispatch value.
13:32rhickeyChouser_: ok, thanks, welcome back!
13:33rhickeyNeronus: 20090320 is feeling like a 1.0 release candidate to me, we (the community) have to have a discussion about what 1.0 means, esp. re: patching etc
13:35rhickeyNeronus: the roadmap is in my head and somewhat in issues, and as always driven by what is happening, where people's (including my own) interests lie etc
13:37cemerickare there any expectations around patching at all? Very large frameworks might backport patches, but that's not at all a typical expectation in most environments (short of security-related stuff, if any).
13:42jaukChouser_: i'm trying to do lazy xml parsing but with a huge xml file (500 megs) the application would seem to consume huge amounts of memory. do you have any tips? some code is here: http://paste.lisp.org/display/78235
13:43rhickeycemerick: I imagine 1.0 is all about patching - being able to get fixes without new enhancements or breaking changes
13:44eevar_rhickey: http://clojure.org/lisps -- the paragraph on sequences looks dated
13:44rhickeyeevar_: yes, some of the site needs touchups to correspond to last release
13:47Carkjauk : i don't know the xml stuff, but it seems to me that a zip will retain all of the data, as it's supposed to be able to reconstruct the full thing
13:47cemerickrhickey: breaking changes, no, but without new enhancements? That's an unnecessary burden, I think (again, outside of security fixes).
13:49jaukCark: ok, it could be that it just doesn't make sense to load a 500M xml. I was just hoping that with lazy evaluation it would just under the hood fetch only those items that are needed for computing the expected result (in the case of the example, the first matching node)
13:50rhickeycemerick: well, that's a topic for discussion - many people want 1.0 so they don't have to contend with 'changes' generically, rarely distinguishing breaking from non. Any core name introduction is potentially (trivially) 'breaking' code that used that name for something else
13:50Carkjauk : try doing your processing without the ziper
13:52stuhoodrhickey: another way to distinguish breaking from non-breaking changes is to use major/point releases
13:52jaukCark: hmm, i could try that
13:52stuhoodrhickey: going straight to 1.0 instead of 0.9.* may be rushing things
13:53cemerickrhickey: eh, that's what :except is for in ns.
13:53cemerickI know that if we backported all fixes to each major release of our product, we'd go absolutely batshit insane.
13:54rhickeycemerick: I'm not arguing for or against, as I personally don't need 1.0. Those that do need to articulate what it means to them, and we need to see consensus
13:54cemerickrhickey: yeah, I know I'm arguing with the wind here :-)
13:55rhickeyAFAIC, those that want fixes in the releases branch can backport them
13:55cemerickmore important than what it means is who's going to do that maintenance?
13:55rhickeycemerick: precisely
13:55jaukCark: it was just that the comments in lazy_xml seem to suggest that xml-zip can be used in a lazy fashion: http://paste.lisp.org/display/78235#1
13:55rhickeywho other than me
13:56cemerickright. And if you're not going to do it (thank goodness!), then what's the real point behind a v1.0 release w.r.t. patches (it certainly has good PR benefits).
13:56Carkjauk : right, but what if you access something toward the end ? the zipper will keep it all in order to be able to reconstruct the full xml
13:57rhickeycemerick: there will be a release branch, a policy for patches (fixes only), a version labeling system 1.0.1 etc
13:57jaukCark: true. in the example code, i'm trying to access the first sub-node in the xml file, so - in theory - that should work ok?
13:58rhickeyOther than the PR side, my impression is that people want 1.0 for stability, but wouldn't consider that they are getting that if there were no fixes other than those on trunk
13:58rhickeythey can fix on a release or an SVN version right now
14:00rhickeybut aren't satisfied with that
14:00jaukCark: thanks for your input! it might be that the approach of using xml-zip with a huge xml file is flawed. this whole lazy evaluation is quite difficult for a java coder to handle :)
14:00rhickeybbl
14:00Carkjauk : don't take my word for it
14:00cemerickobviously, it's very hard for me to see the argument
14:20clojurenoobProbably a stupid Q (I'm not too familiar with Java/JVM): are Clojure-compiled programs particularly amenable to decompilation compared to regular Java code?
14:23AWizzArdclojurenoob: yes, in some sense. I tried it, and while JAP can decompile, it produces programs that can't be compiled with javac again
14:23AWizzArdThe code itself is not really human readable
14:24clojurenoobAWizzArd: are the names of functions mostly preserved?
14:24AWizzArdThey still exist.
14:24AWizzArdSo people could read your function names in clear text.
14:24AWizzArdWe have two solutions for that
14:24AWizzArdOne is: use a java obfuscator
14:25jauki guess one could make a java bytecode -> clojure decompiler
14:25AWizzArdjauk: yes
14:25ChousukeYou'd think the dynamicism makes decompilation less likely to produce anything understandable.
14:25AWizzArdright
14:26AWizzArdclojurenoob: while a obfuscator would be a good solution, you can also use a second method, a simple macro trick
14:26AWizzArdYou write a macro which replaces defn
14:26AWizzArdThis macro creates another defmacro
14:26AWizzArdIt adds your function to a global vector
14:27AWizzArdYour macro manages all magic to find the right function out of your vector
14:27AWizzArdSo, (defsecret foo [x] (+ x 20)) allows you to still say (foo 100) ==> 120
14:27clojurenoobThat's all very informative. Thanks!
14:27AWizzArdbut (foo 100) will be ra macro
14:27duncanmcan i put metadata in non-Clojure objects?
14:28AWizzArdand it will produce something like: ((get secret-functions 14) 120)
14:28AWizzArdclojurenoob: then no function name will be readable in clear text
14:28AWizzArdinstead people could only see how you fetch functions out of this vector
14:28duncanmoh
14:28clojurenoobAWizzArd: wouldn't you need some kind of code walker to look for all function applications? (non-trivial presumably)
14:29duncanmsymbols and collections
14:29duncanmsigh
14:29AWizzArdclojurenoob: no, you would use the defsecret macro only for functions that you write yourself.
14:29clojurenoobOK
14:29AWizzArdIf you use existing clojure libs then their function names would stay readable.
14:30kotarakduncanm: you can implement clojure.lang.IMeta/clojure.lang.IObj with your object. Then they support meta/with-meta.
14:31AWizzArd~ seen AWizzArd
14:31clojurebotAWizzArd was last seen in #clojure, 0 minutes ago saying: ~ seen AWizzArd
14:32pjstadigclojurebot: ~seen clojurebot
14:32clojurebotno, I have not seen ~seen clojurebot
14:32hiredmanclojurebot: seen clojurebot?
14:32clojurebotOf course I have seen myself.
14:32pjstadigah
14:33duncanmso the COND in Clojure is not like COND in Scheme in that it has an implicit BEGIN, is that right?
14:33AWizzArdpjstadig: the ~ is instead of "clojurebot:"
14:33pjstadigyeah i know
14:33pjstadigi realized afterward
14:33kotarakduncanm: no. It has no implicit do.
14:33hiredman"the definition of a lagacy application is one that works"
14:34clojurenoobI'm curious, Clojure seems like one of the most popular functional languages these days. How come it's still not in the ShootOut? (GHC, OCaml, SBCL and some virtual unknowns are)
14:34duncanmin Scheme (if test (begin (a) (b)) (begin (c) (d))) can be written (cond ((test (a) (b)) (else (c) (d))))
14:34duncanmkotarak: ah
14:34kotarakduncanm: (cond test (do (a) (b)) :else (do (c) (d)))
14:35duncanmright
14:35duncanmin that case, it's not that much shorter than using IF
14:35AWizzArdclojurenoob: it is too new
14:35AWizzArdClojure started to take off after Summer 2008
14:35kotarakduncanm: it is for more than one test
14:36hiredmanand the shootout is generaly not well enough thought of for anyone to bother with it
14:36AWizzArdclojurenoob: I think sooner or even sooner Clojure code will appear for the shootout. Maybe you will be the first to submit an entry ;)
14:38cconstantine_I have the shootout on my computer, and I plan on doing some of the tasks for clojure (once i know clojure better and can really represent it)
14:38cconstantine_I expect clojure to get performance very simlar to Java 6 Server
14:39AWizzArdI think this is not possible yet for these micro benchmarks.
14:39hiredmancconstantine_: generally the tasks in the shootout aren't long runner tasks
14:40clojurenoobMost shootout submissions start as lame entries by a noob. Then some angry expert rewrites them.
14:40AWizzArdYes
14:40cconstantine_yeah, I understand. If the solution involves compiling the .clj and running the resulting .class it should be near-identical to native java
14:40pjstadigmaybe instead we could just make Chouser angry
14:40pjstadigand he'll write it to start with
14:40cconstantine_hehe
14:41hiredmanI don't think anything jvm based is really going to shine in short run tasks
14:41cconstantine_some of them aren't all that short-running
14:41AWizzArdAlthough Java does pretty well in the shootout.
14:42cconstantine_java does very respectably.
14:43hiredmanI found ibm devzone article that said java object allocations take about 10 machine code instructions, while C++ takes around 100
14:43cconstantine_it does better than my spelling at the very least
14:43clojurenoobI'm also curious to see what a high-performance Clojure code would look like. Haskell code in the shootout is ugly, for example. (knucleotides, spectral norm, n-bodies). Clojure is "pure functional". How would you be mutating arrays (in n-bodies and others)?
14:43hiredmanclojure is not "pure functional"
14:44Chousukeclojure is not purely fun... damn you
14:44clojurebotclojure is like life: you make trade-offs
14:44hiredmanclojurebot: botsnack
14:44clojurebotthanks; that was delicious. (nom nom nom)
14:44Chousukeclojure is perfectly capable of working with mutable java arrays :)
14:44Carkuse java arrays !
14:44cconstantine_You don't mutate arrays in clojure. Every "modification" returns a new array with the modification in place. There are some very fancy things going on behind the scenes for that to be very fast
14:44hiredmancconstantine_: a vector is not an array
14:45cconstantine_ok, array-like thinger
14:45hiredman"Clojure is an effort in pragmatic dynamic language design"
14:45Chousukecconstantine_: Those are vectors. you can mutate Java arrays.
14:45clojurenoobChousuke: I understand that, but doesn't mixing in mutation dangerous if you also want multithreading, etc?
14:45hiredmancconstantine_: you can make a normal java array
14:45Chousukeclojurenoob: sure.
14:45cconstantine_using a normal java array isn't very clojure-ish
14:45hiredmanjava arrays are very mutable
14:45Chousukeclojurenoob: that's why normal clojure code doesn't use java arrays very often :)
14:45Chousukethe immutable data structures are nicer.
14:45AWizzArdSomeone in here posted a link to this video: http://www.infoq.com/presentations/click-fast-bytecodes-funny-languages
14:45hiredmanthe keyword in that quote from http://clojure.org/rationale is pragmatic
14:46AWizzArdThere a byte code expert explained that he found several things that Clojure could improve to run faster
14:47hiredmanAWizzArd: I only heard two things
14:47hiredmantagged numbers and clojure does a lot of ephemeral object creation
14:47hiredmanwhich isn't reall much of a slow down when you have a good gc and fast object allocation
14:48cconstantine_would there be any benefit to having objects with the same value cached, so the next creation of a value-equal object would just return the already allocated object?
14:48AWizzArd,(time (dotimes [i 1000000] (inc i)))
14:48clojurebot"Elapsed time: 54.802 msecs"
14:49hiredmancconstantine_: I doubt it
14:49AWizzArdtry this loop in pure Java
14:49hiredmanobject allocation on the jvm is very cheap
14:49cconstantine_hiredman: I can see (very easily) how the caching mechanism would be more costly than the allocation/gc
14:49clojurenoobChousuke: when you do use mutable Java arrays (for performance) in the context of a bigger application in Clojure (possibly multithreaded), how do you mentally prove that using those mutable Java arrays is safe?
14:49clojurebotfor is not used often enough.
14:49Chousukeclojurenoob: you're just careful
14:50Chousukeclojurenoob: or you copy them every time they exit your function
14:50cconstantine_clojurebot: the reason to use the immutable types is that it saves you from all that stuff; if you don't use them you don't get the benefit.
14:50clojurebotOk.
14:50Chousukemutable arrays are meant to be used "locally" in clojure
14:50hiredmanhttp://www.ibm.com/developerworks/java/library/j-jtp01274.html
14:51Chousukeie. you shouldn't store data that is passed around a lot in java arrays
14:51hiredman"The JIT compiler can perform additional optimizations that can reduce the cost of object allocation to zero."
14:52Chousuke,(time (dotimes [i 1000000] (let [i (int i)] (inc i))))
14:52clojurebot"Elapsed time: 59.995 msecs"
14:52Chousukehmm
14:52Chousukeactually
14:52Chousuke,(time (dotimes [i 1000000] (unchecked-inc i)))
14:52clojurebot"Elapsed time: 55.9 msecs"
14:53AWizzArdTry this in pure Java:
14:53AWizzArd,(time (let [x (make-array Integer/TYPE 1000000)] (dotimes [i (count x)] (aset-int x i i)) x))
14:53clojurebot#<int[] [I@6258e1>
14:53clojurebot"Elapsed time: 653.335 msecs"
14:54Chousukenot too bad :/
14:54AWizzArdit is not bad
14:54hiredman,(time (amap unchecked-inc (.toArray (range 1000000))))
14:54clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$amap
14:55AWizzArdIt just is for some reason (which I don't know) just dramatically much slower than Java.
14:55hiredman,(time (amap unchecked-inc (make-array Integer/TYPE 1000000) (.toArray (range 1000000))))
14:55clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$amap
14:55AWizzArdno, not dramatically, but it *is* slower
14:55hiredman,(doc amap)
14:55clojurebot"([a idx ret expr]); Maps an expression across an array a, using an index named idx, and return value named ret, initialized to a clone of a, then setting each element of ret to the evaluation of expr, returning the new array ret."
14:57hiredman,(amap (.toArray (range 1000000)) 0 (make-array Integer/TYPE 1000000) inc)
14:57clojurebotjava.lang.Exception: Unsupported binding form: (make-array Integer/TYPE 1000000)
14:57hiredmanok
14:57hiredmanhow the hell does amap work?
14:58hiredman,(amap (.toArray (range 1000000)) 0 a inc)
14:58clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.Exception: Unsupported binding form: 0
14:58AWizzArdhiredman: http://groups.google.de/group/comp.lang.lisp/browse_frm/thread/b24b85f18fee26d7/64a1f1e5ec115ac7?tvc=1#doc_20e2e2efb795f3cf
14:59hiredmanAWizzArd: what is this?
14:59AWizzArdThere is an example program in Clojure.
15:00AWizzArdIn that thread I optimized it a bit, so it runs much faster than the initial version.
15:00AWizzArdBut there is still something in which could be faster.
15:00hiredmandoes it show me how to use amap?
15:01AWizzArdno ;)
15:01AWizzArdI didn't try that
15:01hiredman,(.toArray (range 1000000))
15:01clojurebot#<Object[] [Ljava.lang.Object;@1984161>
15:01hiredman,(into-array Integer/TYPE (range 1000000))
15:02clojurebot#<int[] [I@1cc946b>
15:02AWizzArdI used (int-array ..)
15:02AWizzArd,(doc int-array)
15:02clojurebot"([size-or-seq] [size init-val-or-seq]); Creates an array of ints"
15:02hiredman,(int-array (range 1000000))
15:02clojurebot#<int[] [I@a8cd58>
15:02hiredman,(amap (int-array (range 1000000)) idx ret inc)
15:02clojurebotjava.lang.IllegalArgumentException: argument type mismatch
15:03AWizzArd~def amap
15:04pjstadig,(amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (+ 1 (aget-int r x))))))
15:04clojurebotjava.lang.Exception: Unable to resolve symbol: aget-int in this context
15:04pjstadig,(amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (+ 1 (aget r x))))))
15:04clojurebot#<int[] [I@bde56d>
15:04hiredman,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (+ 1 (aget r x)))))))
15:04clojurebot#<int[] [I@607135>
15:05clojurebot"Elapsed time: 179.273 msecs"
15:05hiredman,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (unchecked-add 1 (aget r x)))))))
15:05clojurebot#<int[] [I@1e0312b>
15:05clojurebot"Elapsed time: 9607.864 msecs"
15:05pjstadig,(print (seq (amap (into-array Integer/TYPE (range 10)) x r (do (aset-int r x (+ 1 (aget-int r x))))))))
15:05clojurebotjava.lang.Exception: Unable to resolve symbol: aget-int in this context
15:05hiredmanwoa
15:05pjstadig,(print (seq (amap (into-array Integer/TYPE (range 10)) x r (do (aset-int r x (+ 1 (aget r x))))))))
15:05clojurebot(1 2 3 4 5 6 7 8 9 10)
15:05pjstadigjust checking if it's doing what I think it's doing
15:06clojurenoob,(range 10)
15:06clojurebot(0 1 2 3 4 5 6 7 8 9)
15:07pjstadigwhy is unchecked-add so much slower?
15:09pjstadig,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (unchecked-add 1 (int (aget r x))))))))
15:09clojurebot#<int[] [I@14cbf3f>
15:09clojurebot"Elapsed time: 168.047 msecs"
15:09gnuvinceI'd like to know too; every single time I've tried an unchecked-* operation, it turned out a *lot* slower than the regular operator.
15:09AWizzArdpjstadig: try that now in TC :)
15:10pjstadig,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (unchecked-add 1 (int (aget r x))))))))
15:10clojurebot#<int[] [I@16e1dd8>
15:10clojurebot"Elapsed time: 160.954 msecs"
15:10pjstadig,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (unchecked-add 1 (int (aget r x))))))))
15:10clojurebot#<int[] [I@4b1bcd>
15:10clojurebot"Elapsed time: 171.053 msecs"
15:11pjstadig,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (unchecked-add 1 (aget r x)))))))
15:11clojurebot#<int[] [I@1aea0c1>
15:11clojurebot"Elapsed time: 8850.087 msecs"
15:11pjstadigholy crap
15:11pjstadig,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (unchecked-add 1 (aget r x)))))))
15:11clojurebot#<int[] [I@1e84244>
15:11clojurebot"Elapsed time: 8873.324 msecs"
15:11pjstadigmust be the int cast?
15:12gnuvince,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r x (+ 1 (aget r x))))))
15:12clojurebot#<int[] [I@15a5aff>
15:12clojurebot"Elapsed time: 171.652 msecs"
15:12gnuvince,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset r x (+ 1 (aget r x))))))
15:12clojurebot#<int[] [I@987e1e>
15:12clojurebot"Elapsed time: 149.145 msecs"
15:13pjstadigit looks like + is doing just about as well as unchecked-add
15:14gnuvinceaset and + seem to be a tad faster than aset-int, unchecked-add and int
15:14clojurenoobaddition probably isn't the bottleneck there. array read / write is more likely to be one. no?
15:15Chousuke(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r (int x) (unchecked-add 1 (int (aget r (int x)))))))))
15:15Chousukeoops
15:15Chousuke,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r (int x) (unchecked-add 1 (int (aget r (int x)))))))))
15:15clojurebot#<int[] [I@10f7ec9>
15:15clojurebot"Elapsed time: 189.218 msecs"
15:15Chouser_literal ints are boxed
15:15Chousuke,(time (amap (into-array Integer/TYPE (range 100000)) x r (do (aset-int r (int x) (unchecked-add (int 1) (int (aget r (int x)))))))))
15:15clojurebot#<int[] [I@798797>
15:15clojurebot"Elapsed time: 149.075 msecs"
15:16hiredman,(time (.toArray (map inc (range 100000))))
15:16clojurebot#<Object[] [Ljava.lang.Object;@19cfefb>
15:16clojurebot"Elapsed time: 138.24 msecs"
15:16ChousukeI wish I knew how to write a compiler that could optimise that :(
15:16hiredmanChouser seems to have started on a self hosted compiler
15:17AWizzArdMaybe when Clojure is rewritten completly in Clojure then Rich will add gradual typing to it.
15:17AWizzArdIn that case Clojure could be in nearly each situation as fast as pure Java itself.
15:17Chousukesomething simple like assuming that if one parameter is unboxed, then others are unboxed too
15:17Chousukesince mixing unboxed and boxed numbers is impossible anyway
15:18Chousukehmm...
15:19ChousukeYeah, I'm hoping that after the compiler is rewritten in clojure it'll get more attention :P
15:20clojurenoobGHC is written in Haskell, but real applications are lacking (despite the language being probably 20 years old)
15:22Chousukeeaster pudding is funky stuff. looks like shit but tastes good.
15:22Chousukeboth impressions are amplified with the addition of some cream
15:24SethTisuedoes anyone know what made Rich decide to rewrite Clojure in Clojure?
15:24SethTisueI asked him about this at Boston Lisp Meeting and he seemed kind of dismissive about it, like it wouldn't be worth the effort
15:24SethTisuewondering why he seems to have changed his mind.
15:24pjstadigChouser is the one writing the Clojure compiler in Clojure
15:25pjstadigbut Rich is generally supporting, i think
15:25SethTisueohh, interesting.
15:25SethTisueok, supportive if someone else does it :-)
15:25AWizzArdSethTisue: he explained it some days ago.
15:25kotarakSethTisue: He said something about it being easier to port to different platforms like .NET and such.
15:25AWizzArdgnuvince asked him 2 days ago or so
15:25gnuvinceSaturday around noon iirc
15:25AWizzArdAlso Clojure in Clojure would open the door for a static type system.
15:25pjstadighttp://github.com/Chouser/clojure-compiler/tree/master
15:26pjstadig~logs?
15:26clojurebotlogs is http://clojure-log.n01se.net/
15:26gnuvinceBasically he talked about: improved performance, doing things that cannot be done at the moment (accepting/returning primitive types), tool support, easier to port to other backends, etc.
15:27SethTisuehmm, that log site stops at Sunday
15:27pjstadigthat brings up an interesting point though
15:27SethTisuemaking it more portable certainly makes a lot of sense
15:27hiredmanSethTisue: rich has mentioned self-hosting has a post 1.0 priority
15:27pjstadigthere seems to be some backlash in here about writing clojure libraries instead of using a Java lib
15:27SethTisuethe other issues, I can imagine.
15:28SethTisueimproved performane, though? really?
15:28pjstadigbut if Clojure is hosted on .NET as well, then a pure clojure lib would be more portable
15:29gnuvince11:17 < rhickey> gnuvince_: improved efficiency removes need to drop to Java - a new implements construct replaces proxy with code as fast as implement-the-interface-in-java
15:29gnuvince< rhickey> removal of any impediments keeping you from defining things like the data structures in Clojure itself
15:29gnuvince< rhickey> better modularity, see above
15:29gnuvince< rhickey> much easier porting to other hosts - JS, CLR, AS3, ObjC? etc
15:29gnuvince< rhickey> possible support for primitive args/returns
15:29gnuvince< rhickey> an accessible AST for tools, type systems etc
15:30gnuvinceThat's pretty much what he said.
15:30Chousukepjstadig: I think if more clojure implementations start popping up then yeah, we'll need some kind of a portability library
15:30Chousukebut what to call it!
15:31Chousukeclojure.portability sounds weird :(
15:31SethTisuegnuvince: thx
15:32Chouser_I think there are a set of features that don't seem to hard in theory to add to the Clojure compiler, but when you look at the current Java implementation those additions suddenly look much harder
15:32Chouser_not to mention less fun, as they would require writing Java code.
15:33Chouser_So between that and ideas that Rich has had relatively recently about what features would be required to get clojure collections written in clojure to perform sufficiently, he may have changed his mind.
15:33gnuvinceA large benefit of switching to Clojure-in-Clojure: one less thing Slava can use to criticize Clojure on proggit ;)
15:33SethTisuewhen I asked the q originally, fun was definitely one of the issues I had in mind. fun for other people contributing, too
15:34eevar_losing out on the whole java ecosystem sounds like a loss imo
15:34gnuvinceSethTisue: that should be a large reason in favor of such a decision; if you can't attract people to hack with you, that's bad for the project.
15:34SethTisueeevar_: in what sense?
15:34Chouser_oh, we're not talking about replacing the JVM
15:35eyerisWhen I run this code, "new.xls" is still 0 bytes and java.exe never closes the file. Am I missing some Clojure detail (something about laziness, perhaps) or is this a problem with the library?
15:35eyerishttp://pastebin.ca/1386362
15:35Chouser_just replacing (most of) the .java code used currently to implement Clojure.
15:35eevar_okies, that makes more sense
15:35gnuvinceThe JVM is the whole point (I think) why Clojure took off so spectacularly
15:35gnuvinceA nice clean Lisp with the largest library of any Lisp
15:36eyerisgnuvince: I think it is the vector syntax, etc. There have been Scheme implementations with decent java interop for a while, hasn't there?
15:37eyerisPerhaps that's what you mean by "clean" :)
15:37Chousukescheme doesn't have as nice a macro system though.
15:37SethTisueor the emphasis on immutability and concurrency
15:37SethTisueor the lack of historical baggage
15:38Chousuke(the problem with scheme's macro system is that I can't understand it. Clojure's is much simpler. :P)
15:38SethTisue:-)
15:38hiredmaneyeris: without looking, it sounds like you need to .close the file
15:38Chouser_jauk: it seems to me that your lazyxml example ought to work -- it should parse all of the first <bound>...</bound> element, and not much more than that before returning
15:39Chouser_but I haven't tested the laziness of lazyxml or zipfilter since the lazier changes to clojure ... perhaps something broke.
15:39eyerisOh man, now I feel silly. Thanks hiredman!
15:40hiredman:P
15:50pjstadigChouser_: oh, we're not talking about replacing the JVM
15:50pjstadiggnuvince: < rhickey> much easier porting to other hosts - JS, CLR, AS3, ObjC? etc
15:50pjstadigwhat does it mean to port to other hosts?
15:50clojurenoobI'm very much a noob, but some aspects of Clojure seem clunky: strange OO (do people use it), appending to sequences creates different ordering of elements depending on type, True/T/False/Nil/'()/0/null is confusing (I prefer Haskell's approach there)
15:51pjstadigif you're depending on a java lib and clojure has been ported to CLR, then your program won't run on CLR
15:51Chouser_pjstadig: hm, good point. But the JVM would still be the "primary" host, especially where it's available.
15:51pjstadigyeah which mean's it's not necessarily insane to think about writing a pure clojure lib for processing CSV
15:51Chouser_pjstadig: right, most apps would not be written for "cross-virtual-platform" support
15:51pjstadigor making HTTP requests
15:52pjstadigi'm not saying it's the most sane thing to do either (it depends on the situation)
15:53hiredmanclojurenoob: what OO?
15:53AWizzArdclojurenoob: Clojure generally wants to motivate you to *not* do OO
15:53hiredmandata structures have different characteristics
15:54Chouser_OO is a pretty vague term
15:54hiredmanvectors can grow at the end O(1), lists grow at the front O(1)
15:54SethTisueclojurenoob: I assume by strange OO you mean using maps for the purposes you'd use structs or classes in other languages?
15:54hiredmanconj is just aware of this, and does the right thing for each
15:56AWizzArdAnd hashmaps can grow "anywhere" in near constant time
15:56Chouser_does it seem odd that sortedMap.insert(k, v) might do something different from hashMap.insert(k, v)?
15:56AWizzArd,(conj {:a 10, :b 20} {:c 30})
15:56clojurebot{:c 30, :a 10, :b 20}
15:56clojurenoobI meant generic methods (or whatever they are called. it's been a while since I've watched the tutorials on bliptv)
15:56Chouser_multimethods
15:56AWizzArdWhat is about them?
15:58Carkif you don't like multimethods, don't use these
15:59Chouser_Here is some rationale about why clojure does multimethods and hierarchies the way it does, and what is desired for the future: http://groups.google.com/group/clojure/msg/0b500f0eba88eda1
16:01Carkthe one time i thought i would use multimethods, i found that i was trying to do OO
16:01Carkso i reconsidered and went for standard high order functions
16:01Carkin the end, this code is now easier to read
16:03hiredmanclojurebot: the world <reply>what the world needs is more higher order functions
16:03clojurebotIn Ordnung
16:03hiredmanclojurebot: what does the world need now?
16:03clojurebotHuh?
16:03clojurenoobAWizzArd: I can't answer in detail, because it's been a while since I've seen the tutorials. But when I saw them, I got the distinct feeling that there was something tasteless about multimethods. That's all I can recall. I was wondering if this feeling was shared by others.
16:04hiredmanclojurebot: tell me what the world needs
16:04clojurebotPardon?
16:04hiredmanoh
16:04pjstadigfor got 'is'
16:04hiredmanclojurebot: the world is <reply>what the world needs is more higher order functions
16:04clojurebotYou don't have to tell me twice.
16:04hiredmanclojurebot: what does the world need now?
16:04clojurebotwhat the world needs is more higher order functions
16:05pjstadigclojurebot: what is our mascot?
16:05clojurebotthe official mascot of clojure is a futuristic ninja robot
16:05Chouser_multimethods are used much less often in clojure than methods are in many languages (such as Java, python, ruby, etc.)
16:06Chouser_when you need a multimethod in clojure, they often fit quite nicely. Sometimes they solve a problem that would require extreme contortions in "standard" OO systems.
16:07marklarChouser_: What does GF stand for in that post?
16:07SethTisueGang of Four?
16:08pjstadigthat would be GoF
16:08pjstadigGF = generic function
16:08SethTisueok maybe not :-)
16:08marklarpjstadig: ah thanks
16:09djpowellIs http://code.google.com/p/clojure/downloads/list working?
16:10pjstadigmaybe code.google.com is being DDoS'ed because of all the people trying to get information about GAE/Java
16:11cconstantine_Has anyone gotten into the Java AppEngine trial?
16:11pjstadigi think i did
16:11cconstantine_I have, and wonder if anyone has played around with clojure in it
16:11pjstadigi haven't tried to play with it yet
16:11hiredmanhttp://www.thelastcitadel.com/_media/clojure.png
16:11cconstantine_same here
16:11pjstadigthere are some blogs about using clojure on GAE
16:12hiredmanclojurebot: delicious
16:12clojurebotdelicious is http://delicious.com/clojurebot
16:12pjstadigsweet!
16:12pjstadigfuturistic ninja robots!
16:15pjstadigyeah i can't pull up the clojure google code page
16:15hiredmanI am in the java appengine trial
16:16hiredmanbut, uh, I just did it without remembering I hate webapps
16:16pjstadighehe
16:16hiredmanso now I don't know what to do
16:16djpowellI just got into the trial too
16:17kotarakDoes someone want to play as guinea pig *coughcough* beta tester with an Ivy patch to contrib?
16:21djpowellEclipse with clojure-dev and google's clojure plugin is probably pretty cool
16:26Chouser_google has a clojure plugin?
16:28dysingeryou meant google gae plugin probably djpowell
16:29pjstadighttp://code.google.com/eclipse/
16:35hiredmanhttp://jonasboner.com/talks/state_youre_doing_it_wrong/html/all.html (from reddit) mentions clojure and rhickey
16:35djpowelloh, er, yeah - I mean't google's eclipse plugin
16:54eyerisDoes anyone here know the predicate form to use for "not equal to" in clojureql?
16:54eyeris(not (= x y )) ;fail
16:55eyeris(not= x y) ;fail
16:55eyeris(<> x y) ;success?
16:56cmvkknot= isn't right?
16:56pjstadig,(= 1 2)
16:56clojurebotfalse
16:56cmvkk,(not= 1 2)
16:56clojurebottrue
16:56kotarakeyeris: doesn't <> not work?
16:56pjstadig,(not= 1 2)
16:56clojurebottrue
16:56kotarakeyeris: should translate to SQL <>
16:56eyeriskotarak I think <> works, but I get a null pointer exception. I'm still tracking own if that is in my code or cql
16:57eyeriss/own/down
16:57kotarakdo you have an example?
16:57eyerisNot a simple one :) brb
17:07djpowellanybody tried the google stuff? i was trying it without compojure. i got a classloader error - maybe I should set *use-context-classloader* ?
17:09eyerisIs there a shortcut in VimClojure/Gorilla that will evaluate the outer-most s-exp of the block the cursor is in?
17:10kotarakeyeris: \et
17:10kotarakEvaluateToplevel
17:11eyerisThanks. I don't know how I misinterpreted the documentation to think "top-level" meant the buffer
17:11kotarakeyeris: the whole buffer is \ef (EvaluateFile)
17:13eyerisWhy, when I place the cursor inside a defn and press \et, it returns nul instead of the new symbol?
17:14kotarakIs the cursor in the opening/closing paren?
17:14kotarakI meant on the paren.
17:14eyerisNo.
17:14kotarakHmm... Which version are you using?
17:14eyerisThough I get the same behaviour if it is.
17:15eyerisWhere is the version number? I don't see it in clojure.vim
17:16kotarakeyeris: there probably is none. Did you download it or use the hg repo?
17:16eyerisIt's definitely not 2.0. I didn't realize that was released.
17:16eyerisI will upgrade to 2.0
17:16kotarakUh. Pre 2.0? Still the Ruby version?
17:17kotarakPlease upgrade! Much better. I plan to release a new update around easter.
17:17eyerisWhere do I put ng.exe?
17:17kotaraksomewhere in your path.
17:17kotarakOr set the vimclojure#NailgunClient variable to the place where you put it.
17:18eyerisWhat about ngserver?
17:18kotarakSomewhere in your PATH.
17:18eyerisOk
17:19eyerisYou should really make it more difficult, so I don't look like such a dope asking :)
17:19kotarakhehe. There is a screencast on http://kotka.blip.tv showing the main points.
17:20kotarakUh.
17:20kotarakThe cast refers to the next release. Sorry for the confusion.
17:21eyerisShould I still be using Gorilla?
17:22kotarakNo.
17:22kotarakIt is merged into VimClojure
17:22kotarakYou should remove the old gorilla files from your .vim directory
17:22dakrone_hbI have "(ns app.hello (:gen-class))" and " (defn -main [& args] (println "application works"))" in a clj file and I'm still getting "java.lang.RuntimeException: java.lang.ClassNotFoundException: app.hello$_main__10 (NO_SOURCE_FILE:0)" when I do a (compile 'app.hello), am I doing something wrong?
17:23kotarakdakrone_hb: is the src and the classes directory in the Classpath?
17:25dakrone_hbyea, the source in in "app/hello.clj" and my classpath has "." in it
17:25kotarakdakrone_hb: and the classes directory?
17:26dakrone_hbkotarak, it's not, the classes directory needs to be in the classpath also?
17:26eyerisHrm. I removed Gorilla and now \ef just beeps
17:27dakrone_hbkotarak, that fixed it, thanks!
17:27kotarakdakrone_hb: yes, and it must exist.
17:27dakrone_hbyep, it works now
17:28kotarakeyeris: you have to put "let clj_want_gorilla = 1" into your .vimrc. And don't forget to start the ng-server before opening a clojure file.
17:31eyerisI have to compile NG myself?
17:32eyerisThat's annoying. I have no Java development tools (like Ant) installed on my Windows machine.
17:32kotarakput the line "nailgun-client=ng" into your local.properties. Then it should be automatically compiled. On Windows just use the ng.exe delivered with the distribution.
17:33eyerisng.exe is the client and the server?
17:33kotarakIt's the client.
17:33kotarakThe server must be started manually on Windows. (Some .bat guru around?)
17:33kotarakjava -cp <your-class-path> com.martiansoftware.nailgun.NGServer
17:34eyerisI can use the shell script provided via cygwin.
17:34kotarakjava -cp <your-class-path> com.martiansoftware.nailgun.NGServer 127.0.0.1 is actually better
17:34kotarakeyeris: the script blows up on cygwin.
17:34kotarakAt least I had problems.
17:34eyerisI can write my own bat file then.
17:34eyerisI just don't have Ant, so I can't compile the ngserver class files.
17:34eyerisWithout a tedious manual compile
17:35kotarakPfew. Ant would help... You can look into the build.xml on how to compile the server files.
17:36AWizzArdkotarak: maybe you can include a shell script which will call a little clojure program which does the compile stuff and which builds a j
17:36AWizzArd+ar
17:36AWizzArdThen no dependencies are needed, such as ant, maven or even ivy
17:38kotarakAWizzArd: Wait a second for my post on the google group. Then you can test yourself.
17:44dmiles_afkis there a good reason to use ClojureCLR over Clojure on IKVM?
17:46dmiles_afkwell i havent trie dlately on IKVM .. but it seems like it might work
17:47eyerisDoes nil? match Java Nulls?
17:47djpowellyeah - nil is java null
17:48duncanmcan I do internal DEFINEs in Clojure like I can Scheme?
17:48hiredmanuse let
17:53duncanmanyone using SLIME with Clojure here?
17:54AWizzArdsure
17:54dakrone_hbis there any good way to do profiling on a Clojure program for performance issues?
17:54AWizzArdalso works very well in a remote setup, via slime-connect
17:54duncanmAWizzArd: how do you do the remote setup?
17:54AWizzArddakrone_hb: just use your favourite Java profiler. For example the one in NetBeans.
17:54duncanmAWizzArd: i'm running Clojure-in-a-box right now
17:55AWizzArdduncanm: On the remote machine I have swank in my classpath. Then I log in there via ssh and run Clojure. Then I can (use 'swank.swank) and do something like (start-server "/dev/null" :port 4005)
17:55djpowellif you have a new-ish version of Java 6, there is a profiler built in called jvisualvm
17:55djpowellI've found it to work quite well with clojure
17:56AWizzArdOn my local machine I can oppen a ssh tunnel forwarding port 4005 and then M-x slime-connect <Enter> <Enter>, <Happy hacking>.
17:58AWizzArddjpowell: yes, good idea. This jvisualvm works very well.
17:59djpowellit doesn't seem as heavyweight as most profilers i've used
17:59djpowellusually if i have a performance problem, connecting a profiler slows things down so much i usually give up waiting for it
18:01dakrone_hbheh, takes Clojure 478 to do the same thing perl does in 54 seconds. Something must be terribly wrong with my code.
19:52dnolenI don't suppose there is an index-of anywhere in contrib is there?
20:08cgranddnolen: .indexOf works on lists and vectors
20:09dnolenmy java ignorance strikes again, thx cgrand.
20:13gnuvince_beware of nil though
20:13gnuvince_,(.indexOf nil "foo")
20:13clojurebotjava.lang.NullPointerException
20:14cgrandtrue
20:14Cark,(.indexOf :a ())
20:14clojurebotjava.lang.IllegalArgumentException: No matching method found: indexOf for class clojure.lang.Keyword
20:15Cark,(.indexOf () :a)
20:15clojurebot-1
20:34dmiles_afkhrrm CojureCLR.. was IKVM not possible?
20:34dmiles_afkwell .. IKVM would probably work .. but the ClojureCLR to do a better job leveraging .NET?
20:37Chousukedmiles_afk: I think the best way to determine that is to give it a try.
20:43dmiles_afki am about to.. actually if i have a question it'd be how close http://dotlisp.sourceforge.net/dotlisp.htm this is to clojure
20:43scottj_How do I get just the 10 from (re-find #"<foo>.+</foo>" "<foo>10</foo>")
20:44Chouser,(second (re-find #"<foo>(.+)</foo>" "<foo>10</foo>"))
20:44clojurebot"10"
20:44dmiles_afkinvoking static vs instance methods are under different syntax rules.. but about other things
20:44SethTisue"I'm not a Lisp expert."
20:45SethTisue- Rich Hickey
20:45SethTisue:-)
20:45ChouserSethTisue: that's an old quote, I would imagine.
20:45scottj_Chouser: thanks
20:45SethTisue2003
20:45dmiles_afkinvoking static vs instance methods are under different syntax rules = clojure use to be like this document .. but now differnt?
20:47Chouserdmiles_afk: I've never looked at dotlisp -- interesting similarities
20:47SethTisueit's interesting to learn that something like this was cooking that far back
20:47dmiles_afki assumed it was the prototype
20:48Chouserdmiles_afk: the relevent clojure docs are here: http://clojure.org/java_interop
20:49Chouseralso interesting how long clojure did *not* have (.foo bar) syntax, and that it still doesn't allow x.y for member access
20:50dmiles_afkallot of why we are using DotLisp is even though w have a full Common Lisp on .NET .. we still too in love with the syntax simplicitty
20:51Chouserclearly some ideas came over, but Clojure's equality symantics, immutability, and concurrency support are fundamental and don't appear to have been in dotlisp
20:51dmiles_afkbut since we havent written much lines of code yet.. it's early enough to switch to clojure
20:51dreishDotLisp doesn't have any of the persistent data structures or STM.
20:52dmiles_afki mean wewritten 100s line s of code.. but not .dotlisp code ;P
20:52Chouserdotlisp has an early form of clojure seqs
20:52Chouserhm, lazy seqs even -- maybe not so early
20:53dmiles_afkyeah all the lazy eval.. and them being default .. is what is so neat
20:53dreishDoesn't look like it has the clever ` either.
20:54dmiles_afkis cljure using , instead of ~ ?
20:54dreishNo, still ~
20:54Chouserclojure on the jvm is a good deal more mature now than dotlisp was on clr. Not sure that any clojure on clr is up to snuff yet though.
20:54dreish, is whitespace
20:54clojurebotjava.lang.Exception: Unable to resolve symbol: is in this context
20:54dreishIt's also clojurebot's sigil. ;)
20:54Chouserdreish is talking about the namespace-based hygine, I think.
20:54dreishYes.
20:57dmiles_afki run ABCL on .NET as a IKVM dll.. it makes the java interop become CLR interope very transparently.. maybe clojure might end up the same way oon IKVM
20:57dmiles_afkoon/on
20:57dmiles_afkso int = System.Int32
20:57dmiles_afketc
21:06dmiles_afk ikvmc /development/clojure-read-only/clojure.jar built clojure.exe most excelently and it works!
21:09dmiles_afkuser=> (.. System (getProperties) (get "java.vm.name")) ==> "IKVM.NET"
21:22dmiles_afkis 'set' == 'set!' ?
21:23hiredmanno
21:23hiredman,(set (range 3)
21:23clojurebotEOF while reading
21:23hiredman,(set (range 3))
21:23clojurebot#{0 1 2}
21:24dmiles_afkok set is a creator of a set ;P
21:48chessguyok, any enclojure users in the house? i'm working through http://enclojure.net/GettingStarted.html and got all the way to the end, but i don't have an option for "Clojure REPL Manager" to open the REPL
21:59marklarchessguy: I don't really use it, but I've installed it and it added just a "Clojure REPL" option under Window
22:02Rayneschessguy: Make sure you have the newest version of Enclojure. You can open an REPL by going to Window and clicking Create Standalone REPL and then entering the paths you want on your classpath including the path to clojure.jar and then clicking connect.
22:02RaynesYou can also create a project specific REPL by right clicking on your project and clicking Create Project REPL
22:02RaynesEr, "Start Project REPL" actually. :)
22:07chessguythanks guys, i'll play around with it more tomorrow