#clojure logs

2009-10-22

00:58technomancyjlilly: I've never noticed any difference between openjdk and sun's.
00:58technomancyI think the only difference is in some desktop-app font rendering
00:59technomancyjlilly: $CLASSPATH and -cp are mutually exclusive IIRC
00:59technomancygenerally the env var is discouraged
01:01mikehincheyI found one problem with openjdk, something about clojure.contrib.jmx, I posted to clojure-dev. But I've used openjdk a lot with clojure.
01:23jlillytechnomancy: I got it all sorted out.
01:24jlillythx though.
02:00hiredmanhah!
02:01hiredmanI can run ant, and the first time clojure will build using LispReader, then run ant again and clojure will build using my reader written in clojure
02:02hiredmannow I just need to get rid of all the calls to LispReader/* in my reader written in clojure
02:05hiredmanhttp://github.com/hiredman/clojure/tree/readerII
02:35mikehincheyhiredman: that's a good way way of putting it :)
03:32angermanhow would I turn (a b c d) -> (d a b c) ?
03:36hiredman,((fn [x] (conj (butlast x) (last x))) '(a b c d))
03:36clojurebot(d a b c)
03:38angermanahh, butlast
05:26G0SUBI was just wondering, what is the problem in introducing optional (and/or) keyword arguments to Clojure?
05:29G0SUBThey are quite useful sometimes.
05:31cgrandGOSUB: perfs and interop
05:31cgrandG0SUB i mean
05:32G0SUBcgrand: interop with what?
05:32cgrandjava
05:32G0SUBcgrand: and is perf a real issue?
05:33cgrandon each call? I think but I haven't thought too far about how it could be implented.
05:34G0SUBhmm
05:34cgrandG0SUB: but you could mimick them with maps and/or macros
05:36cgrand(fn [{:keys [opt1 opt2 opt3] :or {:opt3 42}}] ...)
05:36arbschtG0SUB: you have optional arguments with arity overloading, and something like keywords with hash destructuring (or c.c.def/defnk). that covers a lot of cases
05:37G0SUBcgrand: as far as mimicking keyword args, I don't like that fact that I have to call a fn like (myfn {:a 1 :b 2}) and not (myfn :a 1 :b 2)
05:37G0SUBarbscht: hmm, let me look again.
05:38AWizzArdStrange... I am using htmlunit and do (.asText #^HtmlPage (.getPage webclient url)) and this results in a reflection warning "reference to field asText can't be resolved". But when I do (let [p (.getPage webclient url)] (.asText #^HtmlPage p)) then I get no reflection warning.
05:38AWizzArdcgrand: maybe you have an idea why it is that way?
05:43cgrandG0SUB: (fn [& args] (let [{:keys [opt1 opt2 opt3] :or {:opt3 42}} (apply hash-map args)] ...)) ; and I think that's more or less what defnk macroexpands to
05:44G0SUBcgrand: OK. thanks. I will take a look at defnk.
05:47cgrandAWizzArd: yes I see what's the problem is. macro and inline expansion make type hints disappear
05:49cgrand(meta '#^HtmlPage (.getPage webclient url))
05:49cgrand,(meta '#^HtmlPage (.getPage webclient url))
05:49clojurebot{:tag HtmlPage}
05:49cgrand,(meta (macroexpand-1 '#^HtmlPage (.getPage webclient url)))
05:49clojurebotnil
05:49cgrand,(macroexpand-1 '#^HtmlPage (.getPage webclient url))
05:49clojurebot(. webclient getPage url)
05:50cgrandAWizzArd: can't you just hint webclient?
05:51AWizzArdI will try that
05:51cgrandI guess if webclient (and maybe url) are propely hinted the return type of .getPage will be inferred to HtmlPage
05:51AWizzArdAlthough funnily getpage doesn't produce a complaint
05:52AWizzArdI have a (let [webclient (WebClient.)] ...) so I thought webclient is implicitly hinted.
05:52cgrandcan you paste with more context?
05:53AWizzArdDo you have htmlunit installed and setup in your classpath?
05:54AWizzArdIf yes I could hack up a minimal example for pasting into a .clj file which will demonstrate it.
05:55AWizzArdBut what I basically have is: (let [webclient (WebClient.), url (java.net.URL. "http://clojure.org/")] ... (.asText (.getPage webclient url)))
06:18cgrandAWizzArd: ok, looked at the javadocs .getPage returns a Page object so you must "downhint" it to HtmlPage
06:19cgrandright now your let is the best workaround I can think of
06:22AWizzArdYes, .getPage returns a Page. So in those cases, where a method returns an "instance of an Interface" (such as Page) the type hint info can get lost?
06:26cgrandrhickey: would you accept a patch to preserve (merge) metadata on macro (and inline) expansion? It would make some hinting headaches go away.
06:27rhickeycgrand: preserve which metadata?
06:28rhickeyon the form as a whole?
06:30cgrandyes actually type hints are lost when put on something that is expanded (macro, inline, .method), so I was thinking about merging metadata of the original form into the expanded form's metadata
06:32AWizzArdCurrently it seems a work around is needed, such as (let [p (.getPage webclient url)] (.asText #^HtmlPage p)) ==> no reflection warning, vs (.asText #^HtmlPage (.getPage webclient url)) ==> can't resolve the call to .asText
06:34rhickeycgrand: you can't do that, but it would be nice to have a way to communicate it to the macro itself, so it could if it wanted. Right now there is no &whole-like thing
06:35AWizzArdcgrand: btw, if metadata would be preserved, would that also mean that there won't be reflection warnings anymore for things as (.replaceAll (with-out-str ...) ...)? Currently i need to (let [xyz (with-out-str ..)] (.replaceAll #^String xyz ...)) to prevent reflection.
06:39esjHi everybody, please excuse a very naive question, but can anybody provide an explanation, or link to such, of the -> macro ? I'm struggling to find anything beyond (doc ->), which has, sadly, not enlightened me.
06:40G0SUBesj: (-> {} (assoc :a 1) (assoc :b 2))
06:40G0SUBesj: that expands to (assoc (assoc {} :a 1) :b 2)
06:40esjaha !
06:41esjI get it, much obliged indeed.
06:41AWizzArd,(macroexpand-1 '(-> 5 (+ 3)))
06:41clojurebot(+ 5 3)
06:41G0SUBesj: :)
06:42arsatikiesj: I think it's a sort of a enhanced reverse function composition
06:43arbscht-> it is not function composition
06:43arbschtit simply rearranges code
06:43arsatikiyeah, that's why it's "sort of"
06:44rhickey(-> x a b c) => (c (b (a x)))
06:44rhickey(-> x (a 1) (b 2) (c 3)) => (c (b (a x 1) 2) 3)
06:44rhickeyit just reduces nesting and lets you write things in the order in which they will occur, when that's convenient
06:45G0SUBwoohoo! rhickey
06:48rhickey-> threads the expr as first arg, ->> threads the expr as last arg: (->> x (a 1) (b 2) (c 3)) => (c 3 (b 2 (a 1 x)))
06:48AWizzArdrhickey: it would be so nice to have a function "pipe" that is like comp, but follows the sequence like -> does.
06:51esjThanks very much everybody.
06:52AWizzArdUsing comp often means to write "(comp fn1" then using the arrow keys to go left, editing it to become "(comp #(fn2 1 % 3) fn1", then again the arrow keys, etc.
06:55rhickeyAWizzArd: since it's not a nesting issue, only arg order, not very compelling
06:57AWizzArdI see
06:58AWizzArdJust found myself often using comp, which is not soo nice for editing and reading.
06:58arsatikioh
06:58arsatikiI had the impression that comp use was pretty rare
07:03AWizzArdMaybe not soo often, but for example if your webserver was writing log files readably, containing json strings you maybe want to analyze them (map (comp read-json :text first read-string #(slurp % "UTF-8")) log-files)
07:04liwpit's very nice for things like that. it get's a bit messy if you have to use partial when your functions take more than one argument
07:04AWizzArdliwp: or using %1 %2 %3 or %*
07:04AWizzArdTypically I don't use partial and instead the nice reader macro #(...)
07:05liwpAWizzArd: yep. I tend to prefer #() rather than partial
07:21arsatikire: comp, partial -- I'm often impressed by the ease Haskell handles them (http://www.haskell.org/haskellwiki/Pointfree)
07:21arsatikibut honestly, sometimes pointfree is really pointless :)
07:23G0SUBWhat's the best way to unzip a file in Clojure?
07:33AWizzArdG0SUB: http://java.sun.com/javase/6/docs/api/java/util/zip/ZipFile.html
07:33G0SUBAWizzArd: yeah, looking at that itself :)
07:35AWizzArdyou can do: (enumeration-seq (.entries (java.util.zip.ZipFile. (java.io.File. "c:/clojure/clojure.zip"))))
07:38cgrandrhickey: sorry, I have been called away. Why can't I do that?
07:46G0SUBAWizzArd: how do I handle directories and all?
07:46G0SUBAWizzArd: I want to use as much code from c.c as possible.
07:50kunleyHi.
07:51kunleyDo we have Long literals in Clojure?
07:54AWizzArdkunley: (long 123456789)
07:54rhickeycgrand: because you don't know what the macro wants/needs - it may be creating something non-meta-supporting, or setting meta explicitly, expecting that to be the only meta on the expansion
07:55kunleydoh.. likely need more coffee ;] thx!
07:56AWizzArdG0SUB: What do you mean, how do you handle directories?
07:57AWizzArdThe ZipEntries that .entries returns will list all files in all directories
07:57G0SUBAWizzArd: well, if the zip file has directories, how will the unzipping maintain the same dir structure?
07:58AWizzArdThe java.io.File class has a (.mkdirs ...) method.
08:00AWizzArdG0SUB: and you have a (.isDirectory some-entry)
08:01G0SUBhmm
08:01AWizzArdSo if that returns true, then call (.mkdirs (File. (str some-entry))) and you will have the directory
08:02AWizzArdI'm not sure if .entries *must* return the enumeration of ZipEntry's in such a way that a directory entry D will always come before entries that live in D.
08:03G0SUBAWizzArd: OK, got it. by the way, how do I figure out in which dir a file exists? Does File have a method for that?
08:03AWizzArdI would suggest you to filter all entries that are true for .isDirectory, then mkdirs those, and only then begin storing files in there.
08:03G0SUBAWizzArd: thanks for the tip.
08:04AWizzArdG0SUB: the (str your-entry) will return a string of the directory
08:04AWizzArdplus file name
08:04AWizzArdjust play with it in the repl
08:04cgrandrhickey: don't you find surprising for the user to see his type hints ignored/discarded?
08:04cgrandConcerning your two points: if the macro returns something non-meta supporting, a warning can inform the user his metadata is discarded. And for a macro setting meta explicitely (and expecting it to be the only meta) there would be a problem only when the user adds his own metadata.
08:05AWizzArdG0SUB: in Contrib there is a filter function "separate" which you could use to separate the directory ZipEntry's from the non-directory ones.
08:05G0SUBAWizzArd: will look. thanks.
08:05cgrandI think the new problem would be less frequent than the current one
08:06AWizzArdcgrand: I was surprised today when working with htmlunit, and I also thought that .replaceAll would know that a (with-out-str ...) will return a String.
08:06rhickeycgrand: discarded how? no macro can promise to use any metadata placed on it's invocation. You are presuming some semantics for metadata (that it is destined for the expansion) that's simply not there
08:06G0SUBAWizzArd: where in c.c is separate?
08:07AWizzArdclojure.contrib.seq-utils/separate
08:07G0SUBok
08:09cgrandrhickey: I think I failed to explain what I want
08:09rhickey#^meta (a-macro-call) ==> #^meta (its-expansion), right?
08:10cgrandright :-(
08:11rhickeyso the question is, who should 'own' the metadata on the macro call, the enclosing scope or the macro itself
08:12rhickeyif a macro were to be passed &whole (http://www.lispworks.com/documentation/HyperSpec/Body/03_dd.htm) one would presume it could act on the metadata
08:12cgrandcurrently the macro can't see it (no &whole)
08:13rhickeybut there's nothing in the definition of macros that says they can't become richer than they are (macros are just functions is an implementation detail of the current mechanism)
08:13rhickey&whole and environments would be logical extensions
08:14rhickeyat which point this ownership issue would arise
08:15cgrandok, so I may try to restrict what I'd like: can we have #^meta (.method obj) ==> #^meta (. obj method) and #^meta (inlined-fn obj) ==> #^meta (inline-expansion)
08:16rhickeyin the - a macro call provides its replacement - world, I would give ownership to the macro
08:17rhickeycgrand: I'm wondering in those cases that the meta isn't better place on obj, then return type should flow through
08:18cgrandrhickey: I agree except when the .method says to return an interface and you want to "downhint" to something more specific
08:18rhickeybut yes, those expansions are compiler controlled so could do
08:19rhickeyI would accept a patch limited to that
08:19AWizzArdwould be helpful
08:20cgrandrhickey: ok thanks!
08:20rhickeycgrand: thank you!
08:27AWizzArdrhickey: would a datatype made via deftype be GCable?
08:27rhickeyAWizzArd: the class itself or instances?
08:27AWizzArdthe class itself I mean
08:27rhickeysubject to same issues as all classes
08:28AWizzArdok
08:29rhickeyI'm working on making protocols hold classes weakly, not there yet
08:29rhickeyand not sure it would matter, since their caches must hold strongly
08:29AWizzArdsounds very promising
08:30rhickeyonce implementing a protocol and called, class would be embedded in cache until un-implemented
08:30rhickeyso not so promising
08:42G0SUBAWizzArd: This is what I wrote just now. Works well. http://paste.lisp.org/display/89087
08:43G0SUBAWizzArd: many thanks for the tips. I am a Java n00b :)
08:43AWizzArdAnyway, it would still be enormously helpful to have deftype. We have a lot of structs that contain a :type slot, but this is convention. Having a default way for marking a type (deftype ...) would make things easier. But mostly the speedup will be very nice.
08:44AWizzArdG0SUB: grats! You have a nice zip app now :)
08:44AWizzArdG0SUB: you can download the SDK from http://www.7-zip.org/sdk.html and extend your program to handle .7z files as well.
08:46G0SUBAWizzArd: well, right now, I just need to handle the Zip algo. May be some other time :)
10:11samli installed clojure box. i can type stuff in REPL. where do I learn to actually use it to program? like editing files, loading some defn from files.. debugging, printing doc of a symbol, jumping to definition of the symbol...etc?
10:17RomanRoeIs it possible to get namespace/function code completion in Emacs/Slime? (Just like in Enclojure and CCW)
10:18liwpRomanRoe: you should get it out of the box on the repl, just hit tab
10:18liwpI'm not sure what the keybinding would be for a clojure-mode buffer, try M-tab
10:19RomanRoeliwp: thx. will try that
10:20liwpRomanRoe: looks like M-tab is bound to slime-complete-symbol if your clojure buffer has the slime-minor-mode enabled (as it should)
10:22RomanRoeliwp: unfort. I cant check it right now (different machine right now). But I doubt that M-tab work since it cycles the windows
10:22liwpsaml: try googling for some clojure / slime blog posts. But the basic steps are something like this: open a new buffer (e.g. test.clj), write some code in it, and hit C-c C-k to compile and load the file to the repl
10:22RomanRoeliwp: I will try M-x slime-complete-symbol and remap if it works
10:22liwpRomanRoe: you can hit M-tab by hitting Esc and Tab
10:23RomanRoeliwp: ah thx! I am a emacs newbie... ;-)
10:23liwpannoying, I know, but you can rebind it
10:23liwpI only found out about M-tab maybe a week ago ;-)
10:50KjellskiHi there =)
10:53KjellskiCan someone tell me how I can call a constructor of a native java class with more than one argument? I saw that in the book but can´t find it again...
10:54rhickeyKjellski: (TheClass. a b c)
10:55Kjellski*homerlike* doh... thanks!
10:55rhickeynp
11:08Soulsterhello everyone, whats up with "gen-and-load-class" when i am using it i get "Unable to resolve symbol: gen-and-load-class in this context"
11:08Soulsterwith a java.lang.Exception
11:12ChousukeSoulster: gen-and-load-class went away ages ago :)
11:12Soulsteroutch..^^
11:14chouserSoulster: you may use gen-class, but that requires you use 'compile' to actually generate the class.
12:01ambienti can't quite get this to work: (defmacro foo [num] `(do ~(for [i# (range 5)] `(+ 1 1))))
12:01ambientit's supposed to expand into (do (+ 1 1) (+ 1 1)) etc..
12:01chousertry ~@ instead of ~
12:02ambientcool! thanks
12:05cgrandambient: and no need for the # in i#: you aren't in the syntax quote
12:06ambienti just started doing macros 30 minutes ago :p
12:06ambientso what you mean by syntax quote, i dont know
12:07chouser` is read "syntax quote"
12:07ambientok
12:07ambientwell, i will be so it might as well be i#
12:08ambient(defmacro foo [num] `(do ~@(for [i# (range num)] `(+ ~i# ~i#))))
12:09chouserstill no need for the #
12:09ambientok
12:09chouserdon't worry -- if you forget the # somewhere that you should have it, Clojure will yell at you.
12:10cgrandas soon as you cross a ~ (unquote) you escape from the syntax-quote
12:10ChousukeI think I managed to compile a clojure with my reader
12:10Chousukethe repl still uses lispreader though.
12:11Chousukepresumably because of read... hm
12:14ambientmy first working macro, that's actually useful: (defmacro mdaset [a vals] `(do ~@(for [i (range (count vals))] `(aset #^doubles ~a ~i ~(vals i))))) :)
12:15ambientsets values to an array
12:20Chousuke\o/ it works
12:20Chousukewell, as far as I can tell, anyway
12:20Chousukeexcept for a small bug
12:21Chousukefor some reason, if my input ends with a symbol I need to press enter twice.
12:22cgrandambient: you can't hint an unquote, you should change the do in a let [#^doubles a# ~a]
12:23cgrandand replace all other ~a by a#
12:23Chousukeor ~(with-meta a {:tag 'doubles})
12:38ambienttype hints dont seem to macro-expand :/
12:38ambientcgrand answered my question :P
12:39Chousuketype hints are read-time. you're actually attaching the hints to the macro code :P
12:41ambientmy problem is that if the macro breaks, the execution time of the program goes from 0.2 sec to 16
12:45ambient(defmacro daset [a vals] `(let [#^doubles b# ~a] ~@(for [[idx val] (partition 2 vals)] `(aset b# ~idx ~val)))) ==> "unable to resolve symbol: b__16325__auto__ in this context"
12:47cgrandambient: sorry didn't notice that you were going in an uout of syntax-quote so the two b# are different. Try Chousuke's solution or
12:49ambientthanks, it works now :)
12:49ambient*fist pump*
12:49cgrand(defmacro daset [a vals] (let [b (with-meta (gensym "b") {:tag 'doubles})] `(let [~b ~a] ~@(for [[idx val] (partition 2 vals)] `(aset ~b ~idx ~val)))) ; not worth it here
12:52ambientpretty cool, now i can just write (daset oscm2 [0 (+ car-f os1-o), 2 car-v]) instead of painfully doing it piece by piece
12:52ambientand the performance doesn't suffer at all
12:52cgrandno i'm wrong: this last one is worth the pain because it doesn't cause multiple evaluations of a (which is important when a is not a symbol but a function call)
12:52ambienthere's mine: (defmacro daset [a vals] `(do ~@(for [[idx val] (partition 2 vals)] `(aset ~(with-meta a {:tag 'doubles}) ~idx ~val))))
12:54cgrandtry (macroexpand-1 '(daset (foo bar) [0 1 2 3]))
12:54ambientit's not supposed to be used like that
12:55cgrandok, I just wanted to make you aware of potential shortcomings
12:55ambient(foo bar) would be evaluated at each iteration?
12:57cgrandyes because your macro would expand to (do (aset (foo bar) 0 1) (aset (foo bar) 2 3))
12:58cgrandmy last (untested) one should expand to (let [b457 (foo bar)] (aset b457 0 1) (aset b457 2 3))
13:01ambientif i would be making more general purpose array handling operations, that might be a problem. for my case every array's lifetime is programs lifetime and there are no intermediate arrays
13:38cemericksince it's macro workshop day: how do people deal with using private fns in public macros? I've always just used the corresponding var, but that feels wrong.
13:42Chousukejust make them public and document that the only supported way of using them is via the macro
13:43Chousukehmm, pretty good.
13:44hiredmanChousuke: hows the reader coming?
13:44Chousukerunning the clojure tests with my reader, I got one test failure and two errors
13:44hiredman:/
13:45Chousukethe failure tests compiler metadata which I omit on purpose :P
13:45Chousukethe errors are... something. need to investigate
13:45hiredmancan you build clojure with it?
13:45Chousukehm
13:45Chousukedidn't try.
13:46hiredmanreally?
13:46cgrandcemerick: by "used the corresponding var" you mean @#'ns/private-fn? I agree with Chousuke, make them public but documented as unsupported
13:48cemerickcgrand: yes. Just making the fns public seems worse, though. Reminds me of abstract method overrides on Java APIs that aren't meant to be called that have javadoc that reads "Public as an implementation detail, do not use." Uk.
13:50hiredmanhow do you know if rhickey got your ca?
13:50hiredmanask him?
13:50cgrandhiredman: check the cotributors page
13:50cgrandcontributors even
13:50hiredmanw00t
13:51Chousukehm, I get a nullpointer exception :-(
13:51hiredmanI can build clojure, but the reader is not complete yet, the missing parts are stubbed out to LispReader
13:51cgrandcemerick: can't you make your macro shallow? and backed by a public (supported) function
13:53djorkThis might be more of a Java issue than a Clojure one, but if build a MUD-style game using a thread per-player, will I have problems with high player counts?
13:53djorkthis is just based on some (probably bad) advice from a friend who said that threaded servers don't scale
13:53djorki.e. in terms of memory usage etc.
13:54cemerickcgrand: yeah, I could support it, but the macro helps to ensure proper usage. I suppose I should put the unsupported stuff in a secondary ns.
13:54Knekkmaybe thread-per-connection servers don't scale.... threaded servers scale
13:54hiredmanI doubt you will have any trouble with a mud
13:54cemerickdjork: use an *agent* per player, and you can have thousands, millions perhaps.
13:54djorkhmm
13:55hiredmancemerick: ahem
13:55djorkI'm still not quite clear on agents. Is there a good example on their usage? The docs don't quite "click" yet.
13:55cemerickhiredman: hrm?
13:56Chousukehmm, interesting
13:56hiredmanagents sit on top of threads, so picking agents because you don't want threads doesn't seem like a good idea
13:57djorkyeah
13:57djorkthat's what I thought
13:57ChousukeI suspect there's something wrong with my syntax-quote :/
13:57technomancyagents use a thread pool
13:57hiredmandjork: with the amount of users you will get for a mud, a thread per user should not be a problem
13:57djorkheh :)
13:57hiredmantechnomancy: yes
13:57cemerickhiredman: my point is that agents are lightweight; you could service a very, very large number of agents with a very small number of threads.
13:57djorkthe idea is to scale up to a graphical client on iPhone eventually
13:57hiredmanbut the send-off threadpool is unbounded
13:58djorkwhich could see a lot more users
13:58hiredmancemerick: ah
13:58djorkhmm, so agents join threads in the pool as needed? or something like that?
13:58cemerickI see no reason why you couldn't use send for a MUD (and maybe snapshot state every now and then or something).
13:58hiredmanright, for re-use of threads that happen to be laying around :P
13:59cemerickdjork: agents use threads as needed, when they have an action to service.
13:59djorkOK that makes sense. Now if only I understood their general use :P
13:59hiredmanChousuke: it's statements like that that make me want a line by line port of the java reader :P
14:00djorkBy the way, is there any work towards tracebacks for Clojure code?
14:00Knekkyou'll still run into problems when your number of agents and actions saturate and exceed the threadpool
14:00Knekkmaybe think about queueing actions, decouple your user connections
14:02cemerickThe real criteria is whether one's actions will saturate the send threadpool to such an extent that responsiveness is impacted. For a MUD, probably never.
14:02Knekkcemerick: you are assuming that a MUD won't have thousands of users.
14:02Knekkcemerick: there's no reason why it shouldn't
14:03Knekkcemerick: specially as he wants to port to the iPhone
14:03cemerickKnekk: well, it's a little bit moot one way or the other -- you can do as much decoupling as you want, but you can't do more work than what the send threadpool can schedule (e.g. you've got the cores you've got, and that's a pretty hard limit regardless of the arch.)
14:05KnekkI'd personally queue actions so that the impact of saturation is seen as latency across the system for all users rather than arbitrary delays/timeouts for some connections.
14:05Knekkcemerick: right, but one can control where the pain is felt.
14:07cemerickGood point. I guess it's a product mgmt question, then: IMHO, better to get the thing working, and if he's so lucky to have a load problem, his massive bankroll can be put into an alternative scheduling strategy for agents. :-)
14:08KnekkIt'd be a good problem to have, for sure
14:08cemerickActually, it might be as easy as building a send* variant that uses a given threadpool that throttles as desired.
14:08jasapproughly, how many users is this MUD to support?
14:08cemerick(this is already the most heavily-engineered MUD in history ;-) )
14:08jasappheh
14:09serp_cemerick: how would one do that?
14:11cemerickserp_: in broad strokes, change Agent.dispatch and Agent$Action to take an ExecutorService, rather than a boolean controlling which of two standard threadpools are to be used. I'm sure there'd be a lot of consequences to such a change, but that's the first step.
14:19Chousukeaha, I think I found the bug.
14:20ChousukeI was expanding (Foo. ...) to (fully.qualified.Foo ...) :P
14:21Chousukeor wait
14:22Chousukeyeah
14:25djorkcemerick: yes, I'd love to have too many users :)
14:26ambientFFFUUUUU... macros are killing my brain
14:27djorkambient: just be glad macros are so easy in Clojure... just try digesting the docs for building them in any other lisp
14:27ambientis there somewhere a whole reference for every type of macro possible in clojure?
14:27Chousuketype?
14:28Chousukethere's only one type of macro: one that takes in a form and produces another :P
14:28ambientmeaning comprehensive
14:29Chousukehm, cool
14:29Chousukeonly one test failure for my reader now
14:30Chousukefor line metadata :P
14:31djorkambient: just check out the source
14:31djorkgrep for defmacro
14:37ambienthere's what's giving me trouble: http://paste.pocoo.org/show/146449/
14:38ambientgrep, one of those tools that unices use
14:39mwoelker_quick question: is it possible to create cyclic immutable collections in clojure? e.g. two vectors that contain each other?
14:40cgrandmwoelker_: quick answer: no (apart from cyclic lazy-seq)
14:42cgrandimagine you have a cyclic vector of one item (itself), what does (conj v 42) must return?
14:44cgrand[new-self 42] or [old-self 42]? it seems easy but once you are deely nested, not so: you have to "update" all collections that are on the path to the recursive reference(s)
14:45mwoelker_cgrand: hmm, is it possible to put refs into collections?
14:45cgrandyes of course and it's one way to deal with cyclic stuff
14:46cgrandone other being the relational way
14:46chouserambient: http://paste.pocoo.org/show/146451/
14:46mwoelker_e.g. a list of edges (relations) for a graph?
14:47mwoelker_or a map?
14:47chousermwoelker_: right. like a bag of RDF triples or something.
14:48arsatikichouser: it seems that body is missing in that response
14:48chouserarsatiki: oh! indeed.
14:48mwoelker_wouldn't that kill performance for larger graphs?
14:48ambientchouser perfect, thank you. although just a hint into the right direction would be enough :)
14:49chouserwell then a hint for the body: ~@body
14:52Licenser_a very off topic question, how is the clojurebot secured against tempering? I mean how do you ensure that code that is run on it does not affect the host system it runs on?
14:53lpetit,(System/exit)
14:53clojurebotjava.lang.NoSuchFieldException: exit
14:53djorknice
14:53lpetit,(System/exit 0)
14:53clojurebotjava.security.AccessControlException: access denied (java.lang.RuntimePermission exitVM.0)
14:54chouserLicenser_: it's got a range of things -- uses the Java sandbox to prevent access to filesystem and such, uses a blacklist of words to prevent certain kinds of meddling within the sandbox, runs stuff in a separate thread so it can be timed out to prevent consuming host resources, etc.
14:54Licenser_hmm nice
14:55chouser,(defmacro if [x y z] `(clojure.core/if x z y))
14:55clojurebotDENIED
14:55Licenser_And the JVM provides protection against flooded memory by itself due to it's memory restrictions
14:56chouser,(while true)
14:56serp_how does clojure handle recursion between two functions?
14:56clojurebotExecution Timed Out
14:56serp_a calls b and b calls a
14:56Licenser_recursively
14:56djorkis the clojurebot source available?
14:56Licenser_that'd be incredible nice
14:56serp_I understand if it's just one function you can use the recur thing
14:57djork,"Hello"
14:57clojurebot"Hello"
14:57hiredmanserp_: trampoline
14:57chouserserp_: that consumes JVM stack, just as it would in Java. In some cases you can use 'trampoline' to avoid consuming stack.
14:57djork,*ns*
14:57clojurebot#<Namespace sandbox>
14:57Licenser_serp_: yes then it's optimized as tail recursion (in a kind of iterative way)
14:57chouserclojurebot: where are you?
14:57clojurebothttp://github.com/hiredman/clojurebot/tree/master
14:58Licenser_clojurebot: what did you had for lunch?
14:58clojurebotfor is not a loop
14:58Licenser_interesting diet
14:58djorkhah hah
14:58serp_hiredman, chouser: thanks
14:58Licenser_,(doc trampoline)
14:58clojurebot"([f] [f & args]); trampoline can be used to convert algorithms requiring mutual recursion without stack consumption. Calls f with supplied args, if any. If f returns a fn, calls that fn with no arguments, and continues to repeat, until the return value is not a fn, then returns that non-fn value. Note that if you want to return a fn as a final value, you must wrap it in some data structure and unpack it after trampoline
14:59lpetitserp_: and you (declare) the first function if you want the stuff to compile
15:00chouseror use letfn
15:00serp_I see
15:01djorkclojurebot: 2d6
15:01clojurebotI don't understand.
15:01djorkclojurebot: 2 d6
15:01clojurebotPardon?
15:01hiredmanhmmm
15:01djorkmust not be turned on :)
15:01chouser,2d6
15:01clojurebotInvalid number: 2d6
15:02hiredman2d6
15:02clojurebot4
15:02hiredman5d4+5
15:02clojurebot18
15:02danlarkinIn the case of nested dosyncs, are internal ones no-ops (essentially)?
15:02chouserdanlarkin: I think that's right.
15:03djorkhuh, so no "clojurebot:" first
15:03hiredmanyeah
15:04hiredmanChousuke added a pluginish architecture so I wrote the dice plugin to kind of figure out the ropes
15:04danlarkinchouser: great, so I don't have to worry about the internal one closing the transaction before the outside one gets to finish the rest of its work
15:04djorkI just wrote dice rolling yesterday :)
15:05chouserdanlarkin: you certainly don't need to worry about that. Looking at the code, it's not quite a no-op -- it's still creates and calls a closure.
15:05Licenser_wooh let's play some Shadowrun
15:05Licenser_100d6
15:05clojurebot354
15:07danlarkinchouser: great, that's what I got from the code too, thank you
15:08djorkhah hah
15:12mwoelker_2d6
15:12clojurebot2
15:12mwoelker_2d6
15:12clojurebot11
15:12mwoelker_2d6
15:12clojurebot10
15:12mwoelker_0d6
15:12clojurebot0
15:13mwoelker_-1d6
15:13mwoelker_id6
15:13mwoelker_1d1e3
15:13clojurebot1
15:15Licenser_1d100000
15:15clojurebot6196
15:17ambienti have no clue why this error pops up: "More than one matching method found: aset"
15:17ambientwhile trying to run a macro that uses aset outside any function
15:18chouser10d1
15:18clojurebot10
15:18ambient6d0
15:18Chousukehmmh
15:19ChousukeI don't think I'm going to solve this problem today... :P
15:19Licenser_Chousuke: what is your problem?
15:19Chousuke"clojure.lang.ArraySeq cannot be cast to clojure.lang.IFn" hooray for informative error messages
15:19Licenser_roll a dice to help you decide!
15:20Licenser_I think I had that yesterday - same message
15:20Licenser_problem for me was that I had a () too much around my code
15:20Licenser_I used next instead of second :P
15:20Chousukethe problem is, that comes from core.clj :P
15:20Licenser_wooh!
15:20Licenser_you broke it!
15:21Licenser_I have the feeling that is bad
15:21Chousukebecause I'm compiling it with the version of clojure that resulted from compiling my clojure-reader-clojure with the java-reader-clojure
15:22Chousukeso it's most likely that my reader is producing something that confuses the compiler
15:22chouserambient: what are your args to aset?
15:22Licenser_ah
15:22hiredmanChousuke: I have my reader plugged into build.xml, the first ant run it builds clojure.jar and reader.jar and subsequent runs it uses the reader from reader.jar instead of LispReader
15:23Licenser_why does everyone want a own reader?
15:24ambientusing ~(with-meta a {:tag 'doubles}) seems to break something essential
15:24ambientinside a macro
15:24Chousukehiredman: that's about what I'm doing, too. I guess :P
15:24chouserLicenser_: so we can use whitespace and indentation instead of parens.
15:24hiredmanthis is my first time metacirculating a language
15:24Chousukeme too. :P
15:24hiredmanso figuring out where to put the indirection and stuff is interesting
15:24ambienti'm actually programming a metacircular language...
15:25Licenser_hiredman, Chousuke: why don't you combine your work?
15:25Chousukebut it'll be even more fun when clojure no longer needs java to actually compile itself
15:25neotykHi *, what is your single favorite feature of clojure?
15:25G0SUBWhere can I find the two Wiki pages on datatypes and protocols that Rich published?
15:25lpetit~datatypes
15:25clojurebothttp://www.assembla.com/wiki/show/clojure/Datatypes
15:25lpetit~protocols
15:25clojurebothttp://www.assembla.com/wiki/show/clojure/Protocols
15:26G0SUBneotyk: sequences.
15:26ChousukeG0SUB: assembla for everything :)
15:26G0SUBChousuke: heh
15:26Licenser_neotyk: paralelity
15:26neotykI'm just learning but so far destructuring rocked me
15:26ambientneotyk parentheses
15:26arsatikiambient :)
15:26hiredmanI am really interested to see Chousuke's reader
15:26chouserambient: this works for me: (let [ary (into-array Double/TYPE [1 2 3 4 5])] (dalet ary [a 0, b 1, c 2, d 3] [a b c d]))
15:27hiredmanand how he is building/using it
15:27Chousukehiredman: I'll push my current work on github and tell you how to build it. :P
15:28hiredmanChousuke: how are you getting the reader to run before clojure is loaded?
15:28djorkneotyk: The way it takes the suck out of Java.
15:28Licenser_I undertand how it would work with identation but doesn't that mean I have to use a newline for everything?
15:29ambientchouser this doesn't for me: http://paste.pocoo.org/show/146471/
15:29chouserLicenser_: I was kidding about the reader, though I think there actually is one for whitespace somewhere.
15:29Licenser_o.o
15:29chouserLicenser_: I think hiredman and Chousuke are just writing readers for fun while secretly hoping rhickey ends up using them in cinc. :-)
15:30G0SUBChousuke: what reader? any links?
15:30Licenser_muhaha
15:30Licenser_Well one thing I didn't yet found isa nice parser generator :/ I got too used to having one
15:31ambientwell i construct domain spesific languages with lisp for solving problems so parser generator is not so critical ;)
15:31Chousukehttp://github.com/Chousuke/clojure/tree/reader-integrated
15:32Chousukeit's... quite a mess, still :P
15:32chouserambient: try (double ~val) instead of just ~val in your macro
15:32G0SUBChousuke: what are the features?
15:32hiredmanmy reader is a fn with all the pieces contained in a letfn, so I keep track of the classname of the enclosing Fn
15:33ChousukeG0SUB: features? :)
15:33ChousukeG0SUB: it's just a clojure reader written in clojure :P
15:33G0SUBah, cool
15:34Chousukea rather simple one, too.
15:34hiredmanhttp://github.com/hiredman/clojure/tree/readerII
15:34Licenser_ambient: but if you want to write a interpreter a DSL isn't the way to go :P
15:34ambientchouser works, ty
15:35hiredmanhttp://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj it's an incomplete port of LispReader
15:36hiredmanChousuke: gen-class never worked for me
15:37ChousukeI don't actually use gen-class with my reader
15:37hiredmanloading the gen-class'ed class always seem to try and load clojure
15:37Chousukethe ClojureReader thing is a left-over from an earlier attempt.
15:38lpetitLicenser_ : there's fn-parse, and also cgrand is writing parsley (both are on github)
15:39Licenser_I looked at fn-parse but since last time I worked with racc (something yacc related) it is really hard to understand
15:39ChousukeI suppose a proper parser combinator would be much better :/
15:39hiredmanChousuke: so you load core, then your reader, then reload core using your reader?
15:39Chousukehiredman: yes.
15:41Licenser_Chousuke: but they are hard to understand :P
15:41hiredmaninteresting
15:44lpetitparsley has the interesting property of being an incremental parser
15:45Licenser_hmm parsley
15:45Licenser_I see it is well documented :P
15:45lpetitbut still in inception, not really for prime use / production purpose. But interesting to keep on the radar (We intend to use it for static analysis / user code writing assistance in counterclockwise)
15:46lpetitwait a min., I've something for ya
15:46Licenser_An experimental undocumented parser lib/DSL. Hah!
15:48chouserLicenser_: pretty sure that's the wrong way 'round.
15:48lpetitclojurebot: parsley is an incremental parser with docs at http://wiki.github.com/cgrand/parsley/design-notes and at http://cloud.github.com/downloads/cgrand/parsley/parsley.pdf
15:48clojurebotRoger.
15:48lpetit~parsley
15:48clojurebotparsley is an incremental parser with docs at http://wiki.github.com/cgrand/parsley/design-notes and at http://cloud.github.com/downloads/cgrand/parsley/parsley.pdf
15:48ambientbut what are sage, rosemary and thyme?
15:48lpetitnote those are design notes : subject to change (if not already) :)
15:48Licenser_chouser: why?
15:49Licenser_I want to see if I can do it :P I wrote one in ruby - not perfect but it does a lot already
15:50serp_ambient: they are spices
15:51chouserLicenser_: because I want to write more clojure (perhaps where only JavaScript is supported), not vice versa.
15:51somniumthe day when the DOM can be scripted in pure-clojure will be a beautiful day indeed
15:51hiredmanChousuke: I am going to ask rhickey about exposing LispReader has Fn bound to something like READER in clojure.core, then removing all direct calls to LispReader/read in favor of going through the Fn
15:52Licenser_but chouser when you implement clojure in javascript and I implement javascript in clojure we can run clojure code in javascript in clojure in javascript in clojure in javascript in safari!
15:53G0SUBodd, use of transients actually made the example code slower on my machine.
15:53Licenser_and then chouser we will rule the world!
15:57cgrandlpetit please use the future tense when talking about parsley :-)
16:02chouserLicenser_: heh
16:02rlbIs re-split probably the most efficient way to split a string at (a single) tab, or is there something simpler that might be faster?
16:02Licenser_Another question, is there a good way to scan a string to tokenize it?
16:02chousersomnium: that day already came and went. :-/
16:02rlbi.e find index and substr or similar...
16:02Licenser_I wrote a own function re-scan but I fear it's horrible ineffective
16:05somniumchouser: I was thinking something between clojurescript and scriptjure, 'browjure'? whatever it is it has to play nice with all the js libraries out there. Are you still working on ClojureScript?
16:05Licenser_http://gist.github.com/216251
16:06chousersomnium: ClojureScript's on hold until cinc
16:06Licenser_if someone want to take a look
16:07Licenser_sadly I don't think this will return a lazy seq :P
16:08somnium,(doc re-seq)
16:08clojurebot"([re s]); Returns a lazy sequence of successive matches of pattern in string, using java.util.regex.Matcher.find(), each such match processed with re-groups."
16:11Licenser_somnium: I know but that only works if you have one regexp not if you've multiple
16:12chouserLicenser_: you've considered combining your regexs using | ?
16:12Licenser_yes that a) gets ugly and b) I don't know which regexp matched in the end - which isn't too good
16:13somniumLicenser_: if you don't like ugly best to stay away from regex altogether :-p
16:13Licenser_heh
16:13chouserwell, you could combine them programmatically so you don't have to look at them all together. ...knowning which matched might to tough -- no named groupings in Java
16:14Licenser_I think java allowed named groupings
16:16lpetitcgrand: Oh it's was just an easy way to place some more pressure on parsley's planning :)
16:16Licenser_well no it does not seem to have
16:20somniumLicenser_: have you looked at partition and grep in contrib.str-utils2 ?
16:20Licenser_nope never heared of them
16:20Licenser_,(doc grep)
16:20clojurebot"clojure.contrib.str-utils2/grep;[[re coll]]; Filters elements of coll by a regular expression. The String representation (with str) of each element is tested with re-find."
16:21Licenser_,(doc partition)
16:21clojurebot"([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items."
16:22somniumpartition is in core, not sure how to get the doc from str-utils2 out of him
16:22Licenser_,(doc clojure.contrib.str-utils2/partition)
16:22clojurebotI don't understand.
16:23somnium,(doc split)
16:23clojurebot"clojure.contrib.str-utils2/split;[[s re] [s re limit]]; Splits string on a regular expression. Optional argument limit is the maximum number of splits."
16:25Licenser_I will try to just run the regexp over the stuff twice, once to tokenize it and once ti determine the kind of tiken
16:26somniumclojure.walk is useful if you're building ASTs
16:27somniumso one day you can do away with rhino and script java through clojure back to java ;)
16:36djorkraise your hand if you're using clojure-mode and slime
16:40The-Kenny*raises hand*
16:41Dawgmatix*raises hand*
16:45jasappI am
16:46eyerisIs there any CSV stuff in contrib?
16:49djorkhow do you set up your working environment so that you can load files properly
16:49djorkI'm not sure if that question even makes sense
16:49jasappwhat do you mean load files?
16:49djorkbut I have classpath problems using slime and working on projects
16:50djorkor just what are project layout and file loading/inclusion practices in general?
16:50Licenser_,(doc walk)
16:50clojurebotHuh?
16:50Licenser_,(doc clojure.walk)
16:50clojurebotjava.lang.ClassNotFoundException: clojure.walk
17:06KjellskiCan someone tell me how the regular expression escape for an uppercase character is? \u doesn´t work...
17:09stuartsierra[A-Z]
17:09Licenser_Kjellski: one so- what stuartsierra saied
17:11Kjellskiokay... thanks... was just looking for the java doc... are there any differences?
17:11stuartsierrasome; look up java.util.regex.Pattern
17:11KjellskiThanks!
17:11stuartsierrawelcome
17:11rlbIn my case, I just wanted the fastest way to grab everything up to the first tab from a bunch of strings -- wonder if (subs s (.indexOf s tab)) is preferable -- have to test.
17:11technomancydjork: are you using M-x swank-clojure-project?
17:11technomancyC-c C-k should just work
17:12djorknope, no swank-clojure-project
17:12djorkdoes that come with the whole kit?
17:12djork(not working on clojure right this second...)
17:13technomancydjork: you'll have it if you did M-x clojure-install
17:13djorkoh ok, cool
17:14rlbHmm, so (.indexOf s "\t") works, but (.indexOf s (int \t)) doesn't, though java has a str.indexOf(int character).
17:15KjellskiThis is going to be an stream closed error, does anyone know why?
17:15Kjellski(with-open [rdr (reader *text-file-path*)]
17:15Kjellski(filter #(re-find #"[A-Z]" %) (line-seq rdr)))
17:16technomancyKjellski: filter is lazy; so the reader is closed by the time it gets consumed
17:17technomancyeither consume it inside the with-open block or wrap filter in a doall
17:17Kjellski*doh* ... thanks
17:18rlb(Oh, right *\tab*, not \t...)
17:24radsI'm trying out redis-clojure, and for now I've had to wrap (redis/with-server) around the forms in every function that accesses redis. is there an idiomatic way of abstracting that?
17:37Licenser_hmmm one problem I run into is that when using combined regexp it does not match in the right order o.O
18:01KjellskiI´ve got a pretty stupid question for you advanced, but I can´t get how to accumulate values in a function...
18:01Licenser_define accumulate :P
18:01Licenser_while I
18:01Licenser_'m not advanced I am always curiose!
18:01Licenser_and I really have trouble with the ' on the english keybard ...
18:01Kjellski1 sec... I´ll post an example of my function ok?
18:01Licenser_YaY!
18:02Kjellski,(defn read-with-filter [file regx]
18:02Kjellski(with-open [rdr (reader file)]
18:02Kjellski(let [result []]
18:02Kjellski(doseq [line (line-seq rdr)]
18:02Kjellski(doseq [line-char line]
18:02Kjellski(if (Character/isUpperCase line-char)
18:02clojurebotEOF while reading
18:02Kjellski(conj result line-char))))
18:02Kjellskiresult)))
18:03jasappTry putting it here: http://pastebin.com/
18:04Kjellski*ugly*http://paste.lisp.org/display/89128
18:05KjellskiI´m trying to find the uppercase characters in a file ang conj them into a result...
18:06KjellskiThat this doesn´t work is what I would aspect from immutable result, but how can I accumulate the values I need? I´ve tryed loop, but how to tailcall in nested doseqs?
18:07chouserKjellski: doseq and for both do nesting for you, so you could say (for [line (line-seq rdr), line-char line] ...)
18:08Kjellskiups, the second argument of the function is not used anymoro...
18:08chouserKjellski: both doseq and for also support :when which you could use instead of 'if'
18:08Kjellskiokay? so the complete nesting could be removed with one for?
18:08djorkKjellski: (loop [coll []] (recur (conj stuff coll)))
18:09djorkthat's what I've found to work for building collections
18:09djorkerr, (conj coll stuff)
18:09chouserKjellski: then instead of calling conj manually, the body of the 'for' could just return line-char
18:09Kjellskiinside the if statement?
18:10chouserKjellski: that'll give you a lazy seq of the uppercase chars, but since you're in a with-open you'd want to wrap your 'for' with 'vec' or 'doall'
18:11KjellskiSure, but would there be a way to, just for educational purposes, "save" the state of reading in order to make it "lazy-with-open"?
18:14chouserKjellski: when would you close the file?
18:15wwoodI'm trying to setup liverepl on mac os x
18:15wwoodhttp://github.com/djpowell/liverepl
18:15Kjellski^^ ... I know you would ask, for easyness, after the last value is taken from the lazy-seq?
18:15wwoodliverepl.sh is looking for tools.jar in jdk home
18:15wwoodbut /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home doesn't have tools.jar
18:16wwoodanyone more clueful than I about that?
18:17wwoodthink I found the answer
18:17wwoodtools.jar does not exist. Classes usually located here are instead included in classes.jar. Scripts that rely on the existence of tools.jar need to be rewritten accordingly.
18:17wwoodfrom http://developer.apple.com/mac/library/documentation/Java/Conceptual/Java14Development/02-JavaDevTools/JavaDevTools.html
18:21chouserKjellski: yes it's possible (contrib duck-streams has such a thing) but it's a bit dangerous since normally failing to consume a whole seq is fine, but one of these seqs will leak filehandles if you don't consume it.
18:22wwoodfound it
18:23wwoodunder Versions/1.6.0/classes/classes.jar
18:23KjellskiOkay, but that behaviour is necessary right? If the duckstream keeps opened, the file handles state remains open and the lazy-seq will too... hope you understand what I mean... but a more important question, how have you found that out? What have you typed in google or where have you searched? maybe clojure.org -> api -> duck-streams?
18:24KjellskiI think it´s pretty hard to find informations with examples for learning clojure on the net....
18:25somniumKjellski: browsing the source code in contrib is a good way to get familiar with the libraries (there are a lot, I know)
18:27Kjellskisomnium thanks, that is something i´ve never tryed before ^^...
18:27Kjellski-y +ie
18:27chouser(doc read-lines)
18:27clojurebot"clojure.contrib.duck-streams/read-lines;[[f]]; Like clojure.core/line-seq but opens f with reader. Automatically closes the reader AFTER YOU CONSUME THE ENTIRE SEQUENCE."
18:28lisppaste8foomanchoo pasted "Abtract Class" at http://paste.lisp.org/display/89129
18:28foomanchooHi All
18:28KjellskiHi foomanchoo =)
18:28foomanchoolearning (or trying to learn clojure) and hit a snag trying to gen class an abtract class
18:28foomanchooit is in the above paste
18:29chouserfoomanchoo: no need for genclass there -- just proxy
18:29foomanchooproxy... ok, I will try that. thank you
18:30Kjellskithanks chouser, thats what i wanted to know... ^^
18:35wwoodthat worked!
18:35wwoodliverepl cool!
18:36KjellskiCongratulations!
18:36Kjellski=)
18:38radswhat's the simplest way to convert :foo to "foo"?
18:38rads(str :foo) returns ":foo"
18:39danlarkin,(name :foo)
18:39clojurebot"foo"
18:39radsthanks
18:40hiredmanI have come to a conclusion
18:40hiredmanant is horrible
18:40mtmall build systems are horrible
18:41hiredmanmake is great
18:41mtmdoes it still require hard tabs?
18:41hiredmanwho cares
18:41mtmit offends my delicate sensibilities :)
18:42authenticclj noob question: has something like GWT been made for clojure?
18:42hiredmanI am just sick in tired of ant rerunning everything when nothing has changed
18:42hiredmanor not running anything
18:42authenticmtm: i'd say all imperative build systems are terrible, ant is full of do-this and do-that rather than make-me-an-X
18:43mtmtrue, true
18:48KjellskiWhy is this(http://paste.lisp.org/display/89130) function giving me a seq over one element vectors?
18:50hiredmanbecuase you are using conj to create a new vector that contains one more element than an empty vector
18:51Chousukefor is not a loop
18:51Chousuke~for
18:51clojurebotfor is not used often enough.
18:51djorkhah
18:51hiredmanand conj does not mutate vectors
18:51Chousukeclojurebot: you were supposed to agree with me
18:51clojurebotIt's greek to me.
18:52hiredmanclojurebot: laugh
18:52clojurebotha ha
18:52authenticclojurebot: cry
18:52clojurebotGabh mo leithscéal?
18:53ChousukeKjellski: You seem to have this silly notion that clojure allows you to *mutate* things. It does, but not until you've passed intermediate level. I suggest you prepare to rewire your brain entirely :)
18:54djorkI was wrestling with this same thing yesterday.
18:54cemerickinteresting, looks like transients aren't metadata-friendly
18:55funkenblattauthentic: there's clojurescript
18:55funkenblattwrt a GWT-like thing
18:56funkenblattdunno how complete it is though
18:56KjellskiDon´t tell me to rewrite my brain an forget to tell how ...^^
18:56ChousukeKjellski: for generates a sequence, so you can just change the body of your for to "line-char" and you get a sequence of characters, appropriately filtered.
18:57ChousukeKjellski: then you can use either (into [] (for ...)) or (vec (for ...)) or (reduce conj [] (for ...)) to create a vector of those characters
18:57Kjellskioutch... THAT hurts... btw, today is CAPSLOCK day, isn´t it? ^^
18:57AWizzArdrhickey: please delete ticket 197 on assembla (count in hashmaps is already fixed)
18:57authenticfunkenblatt: thanks, i'll have a look
18:58hiredmanclojurebot: ticket #197
18:58clojurebot{:url http://tinyurl.com/yh7w68h, :summary "Field 'count' not updated correctly for 'PersistentHashMap's when three hashes collide", :status :new, :priority :normal, :created-on "2009-10-15T19:41:24+00:00"}
18:59ChousukeAWizzArd: would just closing it do? :/
18:59Chousukein fact, that's probably better than deleting it. just close as invalid or fixed
19:00Kjellskiclojurebot: ticket #197
19:00clojurebot{:url http://tinyurl.com/yh7w68h, :summary "Field 'count' not updated correctly for 'PersistentHashMap's when three hashes collide", :status :new, :priority :normal, :created-on "2009-10-15T19:41:24+00:00"}
19:00Kjellski...sorry...
19:00lpetitouch what a spam on my emailbox !
19:00AWizzArdChousuke: yes
19:00Chousukelpetit: from assembla? :/
19:01lpetityeah
19:01AWizzArdlpetit: what do you mean? those 70 mails within 3 minutes? ;)
19:01lpetitsure :)
19:01ChousukeAWizzArd: Are you not a clojure contributor? If you are, you could just close it yourself.
19:02lpetitWhen Rich commits, he doesn't do half the job ! :)
19:02Chousukelpetit: you can reduce the spamming to bearable levels from the preferences somewhere.
19:02AWizzArdChousuke: nope, not snail mailed the form yet
19:02Chousukeheh. should remember those "fixes #123" in the commit message
19:02lpetitChousuke: oh yes, I'll have to dig in the options of assembla maybe ?
19:03ChousukeAWizzArd: which commit was it fixed by?
19:03Chousukehmm, b4095306ddc59c1a992c39369f06f1315b97d377 probably
19:04hiredmanI heard contributors get a secret decoder ring
19:04Chousukewell, I marked it as fixed now.
19:04Chousukeenjoy your spam
19:04KjellskiChousuke: Thanks a lot... actually I´ve saved the that above to my notes ...
19:05ChousukeKjellski: the key to functional programming is recursion
19:06Chousukeinstead of looping and mutating the value, you create a new value within the function, and then call the function again on the new value (and possibly other modified parameters) to generate the next value, until you hit the base case
19:07Chousukethe "loop" form, while not a function, is recursive like this too; you always need to "restart" the loop by calling recur with the new values.
19:10AWizzArdhiredman: when one wears the ring... is one visible?
19:14hiredmanit is a metacircular ring
19:15RaynesThe key to functional programming is a functional key. It fits in the lock upside down and right side up. I hear you can even insert it sideways.
19:23djorkI read the Little Schemer last Summer, but I have a hard time applying it to Clojure for some reason.
19:23ChousukeRaynes: but curiously enough, once you turn the key, you will suddenly have two locks.
19:23djorkI wonder why?
19:23djorks/read/did/
19:24djorkPhilosophical question: is the cosmos functional or object-oriented?
19:24djorkFunctional would mean a multiverse.
19:24KjellskiChousuke : thanks for this decription... it brings me steps forward... as i keep reading the same sentences again and again... ^^
19:25djorkKjellski: http://www.google.com/search?client=safari&amp;rls=en&amp;q=define:recursion&amp;ie=UTF-8&amp;oe=UTF-8 (notice the "did you mean")
19:25jasappdjork: http://xkcd.com/224/
19:25hiredmandjork: have you see the slides from rhickey's jvmlang summit presentation?
19:25djorkI think I had them on my desktop for a long time
19:25djorkglanced at them
19:25djorkjasapp: yes, hilarious :)
19:26Chousukeinfinite recursion is not very useful though :/
19:26The-KennyThere is another very good one about lisp, but I don't remember the name.
19:26hiredmanawn quotes like "the future is a function of the present" or some such
19:26Chousukeof the past
19:27Chousukeand present is (deref universe) :P
19:29KjellskiSomeone knows who intentionally said the notepad irc thing?
19:30Kjellski"IRC is just multiplayer notepad..."
19:31hiredmanclojurebot: #clojure
19:31clojurebotclojure is far closer to perfection then python
19:31hiredmanbah
19:31djork~clojurebot
19:31clojurebotclojurebot is like life: you make trade-offs
19:33djorkclojurebot: python
19:33clojurebotpython is ugly
19:33djorkouch
19:33djorkclojurebot: ruby
19:33clojurebotChunky bacon!
19:33djorkHear hear!
19:33djorkclojurebot: Java
19:33clojurebot
19:33djorkthis is fun
19:34djorkclojurebot: c#
19:34clojurebotI don't understand.
19:34djorkneither do I
19:35jasappclojurebot: lisp
19:35clojurebot"if you never learnt Lisp, then you never learned to program" -- some rant on some blog somewhere
19:35Kjellski^^
19:36The-Kennyclojurebot: brainfuck
19:36clojurebotexcusez-moi
19:38ambientso, are there any clojure versions for the shootout? http://shootout.alioth.debian.org/
19:38hiredmanclojurebot: #clojure
19:38clojurebotthis is not IRC, this is #clojure. We aspire to better than that.
19:38djorkclojurebot: IRC
19:38clojurebotPardon?
19:39djorkambient: I have never seen any, but it would be interesting to see how high you can go.
19:39ambientwell, you could write non-idiomatic clojure and make it quite fast
19:39djorkI mean the Java steady-state stuff is pretty much a total hack... and so Clojure would never get that fast.
19:39djorkit would be interesting to see how idiomatic clojure fares though
19:40ambienti did my modular synth functionally, took about 5 seconds to render. imperically the same thing took 100 milliseconds
19:40djorkimperically?
19:40ambienti dont know the word
19:40djorkor imperatively
19:40ambientsomething like that
19:41ambientbut the slowness might've been because of lazy sequences
19:41djorkin Java?
19:41ambientin clojure
19:41djorkoh, nice
19:41djorkhow much audio were you producing?
19:41djork(hopefully more than 100 ms)
19:41ambient2 seconds
19:41ambient88k samples
19:42djorkk
19:42ambientbut the whole thing's not done yet, so it's just a semi-micro benchmark
19:43djorkso is it better to set up clojure to run with java -sever
19:43djorkserver
19:46ambienti'll tell you when i get to the point where it's actually relevant :)
19:46ambientperformance-wise
19:52Kjellskiis there a lazy "pi-digits" function in a lib someone knows?
19:57mattreplrandom question, wasn't there a video posted of Rich Hickey's talk on time/concurrency at the JVML summit?
19:57mattreplgoogle isn't helping
19:57Qvintvsdoes anyone know of a gedit plugin for clojure editing?
19:57Kjellski... enough hacker-quests for today, good night!
19:58foomanchooah... to-array and into-array.. a bit confusing but finally got it
19:58hiredmanmattrepl: not yet
19:59mattreplcould've sworn I watched it.. weird =) thanks
20:02scottjCan you define a stored procedure in MySQL over the jdbc connecting with clojure.contrib.sql?
20:07somnium(use 'mongo.config)
20:12tomojwow, apparently you could somewhat easily write your couchdb views in clojure
20:13The-Kennytomoj: Yeah, it should be pretty easy to write a view-server in clojure.
20:13The-Kenny(I remember seeing one somewhere on github)
20:15tomojcool
20:15tomojfirst I must grok couchdb
20:16The-Kennytomoj: http://github.com/tashafa/clutch/blob/master/src/com/ashafa/clutch/view_server.clj
20:16The-Kenny(I don't know how advanced this server is, I just found it :))
20:18somniumhttp://paste.lisp.org/display/89135 <- any suggestions?
20:48rhickeyhrm, the first graphic here puzzles me: http://fupeg.blogspot.com/2009/10/concurrency-patterns-java-scala-and.html
20:49ambientheh, nice graphics.
20:50ambient-s
20:53rlbI didn't realize that the jvm doesn't support tagged pointers (though it seems there's been some consideration of it).
20:57Licenser_I wonder how you can devide Code Correctly by Comprehend
21:00Licenser_How does scalar resolves the concurrency part task?
21:02ambienti parsed from the text that he meant coding correctly and comprehending are almost the same thing
21:03ambientso the "/" is not a division, but interchangeability
21:03Licenser_:P ambient I know no reason not to make fun out of it
21:08Licenser_rhickey: don't let the post draw you down, I is anything but scientific just an personal oppinion from what I can tell after reading
21:16somniumI saw on a mailing list that the Lift guy gave a presentation at E-Bay recently, maybe they drank the scala kool-aid while he was there
21:16Licenser_heh
21:20rhickey_Licenser_: it doesn't bother me at all, just puzzling - I think refs are a much easier thing to understand (managed variables) than switching to message passing, if you haven't been doing the latter
21:20Licenser_glad to hear that :)
21:29Licenser_so what surprised me most is that scalar is suppost to be faster then java?
21:31somniumcan scala's actors be coordinated like clojure's refs? (for a consistent snapshot of the world)
21:32chousernot likely. actors tend to be more like Clojure agents
21:33chouserthough with actors it usually requires a round-trip message to get their current state
21:33chouserI think this is true of both erlang and scala actors
21:33Licenser_on another note, comojure is darn fast o.O
21:33somniumin that case, it seems like the guy who wrote this blog is barely familiar with clojure at all, since he's comparing scala's actors with clojure's refs
21:33rhickey_no, he recognizes the coordination difference and notes it at the end
21:33Licenser_just for fun I ran apache benchmark against a simple website, it gets 180 reqs/s on my machine
21:37scottjLicenser_: a simple compojure website right? Have you done any similar benchmarks against simple php/apache or other apps?
21:37Licenser_scottj: with ruby I don't tuch PHP
21:38Licenser_not the exact same thing but a simple RoR is a good bit slower I think it was < 100
21:39Licenser_but again RoR does a lot of things like caching & stuff the compojure app is really stupid about it right now - no caching no nothing
21:43Licenser_wow after warming up its get to 250 reqs/s
21:45devlinsfHey, does anyone know why there are 100 patches being applied right now?
21:45rhickey_devlinsf: just merging master into a branch
21:45devlinsfOh, okay
21:45devlinsfThanks :)
21:51Licenser_by the way, why did you people choose git over svn?
21:52Licenser_disclaimer: No I don't want to start a flame war about git vs svn I just am curiose since I often think about using git instead of svn
21:53RaynesLicenser_: Because Git is better than SVN. ;)
21:53Licenser_I heard that I just wonder what features are important for the decision ^^
21:53The-Kenn1Raynes: Simple answers are the best answers :)
21:53rlbDon't hear about too many people switching back...
21:54The-Kenn1Licenser_: Because it's decentral, you have the whole history of the project on your harddrive. Really cheap and easy branching is also cool.
21:54Licenser_that makes sense actually, I hate branching in SVN, or actually not branching but merging
21:55The-Kenn1Licenser_: You should try git. Then try forking a project in Github and you will never switch back to svn :)
21:56Licenser_heh I downloaded a few things from github via git, was nice and easy I've to admit
21:57Licenser_but I'm not sure if the 'fork everything' thing is in the end good, I mean do we really need *checks* 42 forks of clojure
21:57Licenser_while I agree that 42 is a very good number of forks
21:57The-Kenn1Licenser_: It's easy to merge back changes.
21:57chouserclojure was on google code svn for a quite a while
21:57Licenser_hmm so forks are like branches?
21:58The-Kenn1Licenser_: Yes. But a bit more than that.
21:58Licenser_ahhh okay, I always had the impression that forks are really forks of the project
21:58Licenser_I mean always
21:58Licenser_Usually when you read about a fork it means a copy of the project because someone thinks they can do it better :P
21:59Licenser_at least that is how I used it
21:59The-Kenn1They are, but git and especially github makes it very easy to merge back changes from other users.
21:59The-Kenn1Licenser_: Maybe they can. If the owner thinks that someone improved his project, he merges the changes back into the original :)
22:00Licenser_I noticed that rhickey himself had like 4 or 5 fokrs that makes 42 forks look a lot scarry
22:01The-Kenn1Licenser_: These are branches..
22:01The-Kenn1Forks are under the "networks" tab: http://github.com/richhickey/clojure/network
22:01The-Kenn1(They are 41+1 forks :))
22:02Licenser_I see 4 forks from rhickey in ther
22:02Licenser_o.O I just checked rails has over 700 good greif
22:02chousergithub forks are just a way to manage your own set of patches against a project
22:02The-Kenn1rails is a popular project :p Ruby is big on Github.
22:03rlbLicenser_: one key is that git makes all kinds of things *possible* that just aren't possible with say svn -- then you get to decide what you actually want to do.
22:03Licenser_I'll think I'll try git out for my next project just to get a feel for it
22:03mudphonegit == ozmm
22:03Licenser_the console output of git looks a lot nicer then the one of svn :P
22:04rlbgit provides quite a bit of mechanism, and you get quite a bit of freedom wrt policy.
22:04Licenser_^^
22:04mudphoneyou can get colorization of the output too
22:05mudphoneand tab-completion of commands... and set up aliases... :)
22:05Licenser_yea tab completion is eays I fiddled that together for svn too, it was even completeing file names depending on the action you choose ^^
22:06Licenser_then again svn up, and svn commit is what I use 95% of the time
22:06The-Kenn1Licenser_: git will give you completion for commands, files, branches, tags and everything :)
22:06mudphoneI suppose the killer feature for me is branching, painlessly
22:07jasappsomnium: have you gotten very far with mongodb and clojure?
22:07somniumjasapp: yeah, already used it on two projects, right now I'
22:07somniumjasapp: extracting a library so I don't have to copy paste anymore
22:07jasapphow are you going storing objects in mongo?
22:08somniumjasapp: one of the maintainers fixed a bug so clojure hashmaps go right in
22:08jasappa bug in mongo, or clojure?
22:09somniumstrings and numbers, vectors and hashes go in, object-ids are a special object, but they're not hard to coerce to and from strings
22:09somniumin mongo, the json reader wasn't storing nested maps, but he fixed in about 5 minutes when I asked
22:09somniumpretty good service :)
22:09jasappnice, how recently was this?
22:10djorkis a seq generated by iterate memoized or anything?
22:10somniumyou can also teach the java api to serialize arbitrary objects, but thankfully in clojure we don't need this too much
22:10somniumjasapp: a couple days ago? the latest on github has the patch, I don't think he bumped the version number
22:10jasappawesome
22:10somniumI'll probably put my wrapper on github once its a little polished
22:10Licenser_hmm that sounds damn handy
22:10somniumbut the java api is pretty easy as it is
22:11jasappyeah, that's what I've been using
22:11jasappalthough, I've been using their json utils
22:12jasappas well as contrib.json
22:12jasappit's pretty ugly
22:13Licenser_one of the good things to hang out in the channel is that one can read up about new tech when others are talking abou it :P
22:15jasappcool, thanks for the info
22:15jasappI'll keep an eye out for your wrapper
22:16somniumjasapp: you don't have to use json, if you coerce everything to a string or number, you just do (doto (BasicDBObject.) (.putAll {"some" "random" "clojure" ["data" "structure"]}))
22:17somniummy library is just some config helpers and some coercion utils, maybe in a day or two? (want to finish it tonight, but I should turn off irc to do that)
22:17jasappthat'll certainly clean things up
22:17jasappmy code was ugly, but the queries were even worse.
22:18somniumI made some wrappers for those too!
22:18somniumright now just (fetch :mycollection :where {:foo "is bar"})
22:18jasappwow
22:19jasappwell, if you need any help, I'd be happy to
22:19jasappbut it sounds like you've got it taken care of
22:20somniummy acct is somnium, 0.00001 up in a day or two? I'll be happy for contributions, I think it does really well with clojure
22:20jasappok
22:26djorkso apparently (take 10000 (fib-seq)) runs out of memory
22:27Licenser_djork: give it more memory :P
22:27djorkI actually meant to use nth not take ;)
22:27Licenser_teehee
22:27djorkstill trying to grok this lazy-seq generation business
22:28Licenser_I find it funny, I made a primes lazy seq ^^
22:28Licenser_not that I need it or it would make sense, but it was fun :P
22:28somniumdjork: it sounds like its 'holding-the-head'
22:29foomanchooa proxied class, with an overwritten method, can or can not access a protected field? (it seems it can not)
22:29djorkthis particular implementation just doesn't click with me, maybe someone could help explain it
22:29djorkhttp://www.pastie.org/666176
22:30djorkhmm, I think I prefer it like this now (edited)
22:33djorkOK so lazy-seq just takes one expr and doesn't evaluate it until a seq operation is called on it?
22:37somnium,(macroexpand-1 '(lazy-seq (iterate inc 1)))
22:37clojurebot(new clojure.lang.LazySeq (fn* [] (iterate inc 1)))
22:37djorkhah, nice
22:38djorkthat helps
22:38somniumer, bad example, iterate is already lazy
22:38djork:)
22:39djork,(macroexpand-1 '(lazy-seq (cons 1 (inc 1))))
22:39clojurebot(new clojure.lang.LazySeq (fn* [] (cons 1 (inc 1))))
22:40djork,(macroexpand-1 '((fn rfib [a b] (cons a (lazy-seq (rfib b (+ a b))))) 0 1))
22:40clojurebot((fn rfib [a b] (cons a (lazy-seq (rfib b (+ a b))))) 0 1)
22:40djorkhmm that was not what I was looking for
22:41djorkoh well I think I get it now
22:41chouserfoomanchoo: proxy cannot access protected fields
22:41somnium,(source iterate)
22:41clojurebotjava.lang.Exception: Unable to resolve symbol: source in this context
22:42foomanchoochouser: thanks. any ways to work around this?
22:42chouserfoomanchoo: unfortunately. For now you'll have to use gen-class after all.
22:42foomanchoook... i can't seem to grok gen-class. any good examples?
22:43chouserfoomanchoo: uber-proxy is coming (related to new new a.k.a. reify)
22:43foomanchoocool, i might just create a plain old java class for now and move on
22:44Licenser_what the hell is reify doing? it sounds look food
22:45hiredman~google reify
22:45clojurebotFirst, out of 23600 results is:
22:45clojurebotReification - Wikipedia, the free encyclopedia
22:45clojurebothttp://en.wikipedia.org/wiki/Reification
22:45chouserthat's not unreasonable. gen-class can do it in a couple lines to, but if you're comfortable with a little java class you won't be bad off.
22:45hiredmanI think reify still doesn't let you create pedal to the medal named classes, which is kind of a pain
22:46hiredmanyou can instantiate and invoke Fns
22:46Licenser_" the consideration of an abstraction or an object as if it had living existence and abilities; at the same time it implies the thingification of social relations"
22:46hiredmanwhich is how I bootstrap my reader
22:47Licenser_~help
22:47clojurebothttp://www.khanacademy.org/
22:47Licenser_hrm that was not what I was looking for o.O
22:49somniumI didn't know thingification was a word
22:52Licenser_well now it is!
22:52Licenser_wokipedia saied that (amongst other things) about rify
22:52Licenser_b
22:52Licenser_u
22:53Licenser_but it is right we should treat clojurebot better, he has dignity too!
22:53Licenser_or is clojurebot female?
22:54hiredmanhmmm
22:54hiredmanI guess I should add tests to clojure.test-clojure.reader as I find things I left out of my reader that the tests don't catch
22:54Licenser_I think we should rename ',' to 'Good day Mr. Clojurebot, could you please be so kind and evaluate <code> for me'?
22:54somniumI saw something about it being a bad idea to have functions in data, but what's the problem with having a map like {:fun-a (fn [x] x) :fun-b ...} ?
22:56Licenser_why is it bad to have functions in data? Isn't that one of the good things that of first class functions that you can put them in data?
23:24technomancysomnium: nothing wrong with that
23:25Licenser_ hmm reading p about the mongodb thing makes me really curiose to try that out
23:25somniumtechnomancy: ok, in my current case I was having trouble envisioning an alternative.
23:26technomancysomnium: of course the person who warned you may have more context... you shouldn't put fns in a map if another alternative like multimethods would be more appropriate.
23:29somniumtechnomancy: I saw it in an old message on a mailing list. (couldn't find it just now). In this case its a hook for users to add predicates to a library.
23:33chousermultimethods allow for dynamic redefinition where fns in data objects do not
23:33chouseron the other hand, clojure.zip is implemented with functions stored in metadata, so it can't be all bad. :-)
23:34technomancychouser: not to mention clojure.test... (though the reasoning behind that one escapes me utterly)
23:35Licenser_fuctions stored in metadata?
23:36somniumdo multi-methods transcend namespaces?
23:37chousersomnium: no, multi-methods are rooted in namespaces
23:37hiredmanmultimethods are not names
23:37chouserI guess defmethods transcend namespaces, but defmultis create namespaced vars
23:38somniumdefmethods do?
23:38somniumthen that's a more elegant alternative
23:39RaynesDynamic failcat fails at runtime.
23:42jasappsomnium: have you had trouble with mongo serializing keywords correctly?
23:43jasapp(doto (BasicDBObject.) (.putAll {:foo :bar}))
23:43somniumjasapp: it doesn't do keywords
23:43somniumjasapp I use clojure.walk to coerce members
23:43jasappAhh, I didn't realize
23:43somniumif performance is really a concern better to use strings or implement DBObject, but I like the pleasantness of using keywords
23:44somniumat least for the scale of what I've been doing so far
23:44jasappHmm, I'm not sure if it'll be a concern
23:44jasappHow large are your data sets typically?
23:45somniumin current case 100,000 records, but small number of users
23:46somniumpremature optimization is the root of all evil :)
23:46jasappThat's what I keep telling myself
23:46jasappI'll see how clojure.walk works for me