#clojure logs

2009-06-05

03:57alinphi
03:57alinpis it possible in clojure to do something like that: (def x (eval "(+ 1 2)"))
03:57alinp?
03:58alinpI'm sure this is not the function that needs to be used
03:58alinpbut is there a function to be used for this purpose ?
03:58opqdonutyou're not fine with (def x (eval '(+ 1 2))) ?
03:58opqdonutyou could always invoke the reader
03:58opqdonuti dunno if it's exposed
03:59opqdonutah, read
04:00slashus2,(eval (read-string "(+ 1 2)"))
04:00clojurebotDENIED
04:00slashus2That is how you would do it alinp
04:00opqdonut,(read-string "(+ 1 2)")
04:00clojurebot(+ 1 2)
04:00opqdonutyeah
04:01alinpread-string, thanks slashus2 & opqdonut
04:37jdzdid anydoby mention that eval is evil?
04:38opqdonutof course it isn't :)
04:39slashus2It would be bad if it was.
04:39jdzhow so?
04:39jdzeval is the most evil function
04:39jdzi'm yet to come across a case when i need it...
04:40opqdonutnot all metaprogramming can be done just with macros
04:42jdzi'd like to see an example
04:44slashus2A really bad example would be if you wanted to use a macro in a function, and you want to expand the & more arguments. (eval `(amacro ~@more)) I don't know..
04:44opqdonutwell i have a macro that interprets a series of sexps into a complex data structure describing a computation
04:45opqdonuta "dsl" if you will
04:45opqdonutbut i still want to invoke lisp deep within this sub-language
04:45opqdonutso the macro evals some parts
04:47slashus2jdz: I think hiredman used it in clojurebot to evaluate form in cond-eval
04:48jdzslashus2: if you want to evaluate Clojure code, eval is what you use...
04:49jdzopqdonut: i'm still not convinced.
04:49slashus2yep
05:55yasonHmmm, what's the idiomatic way to turn a sequence into a new sequence that contain N-sized chunks of the original sequence?
06:00lenst(doc partition)
06:00clojurebot"([n coll] [n step 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."
06:10opqdonutgah, just realised why the eval command is , in clojurebot
06:11yasonah
06:11yasonI've seen it before
06:11yasonthanks
09:06bstephensoncan anyone online answer a weird clojure.contrib.sql problem we are seeing? Otherwise, I will post the question to the newsgroup.
09:15eevar2hard to tell if you don't ask your question..
09:32bstephensonsorry, was hoping the SQL author was online....here is our problem:
09:33bstephensonwe try to use the insert-values function to insert a record into a PostgreSQL database
09:33bstephensonturns out eh record was violating a foreign key constraint by referencing an account that was not in the accounts table
09:33bstephensonwe got this error back from REPL:
09:33bstephenson<CompilerException java.lang.IllegalArgumentException: No matching
09:33bstephensonmethod found: println for class java.io.OutputStreamWriter
09:33bstephenson(NO_SOURCE_FILE:0)>
09:34bstephensoninsterad of a JDBC error indicating that FK was violated (which we usually do)
09:34bstephensonboth ID fields are UUID fields
09:34bstephensononce we put in the account intot he accounts table, the record we were trying to write went into the db without a hitch
09:34bstephensonwondering why we did not see a JDBC error when the problem was an FK violation?
09:39bstephensonahh, sorry channel, we found the problem. Related to our editor, not clojure.contrib.sql
10:23ezyangHey all; what's the difference between using (if (seq l)) and just directly checking if it's null?
10:25Chouserezyang: an empty collection is logical true
10:25Chouser,(let [c []] (if (seq c) "something" "nothing"))
10:25clojurebot"nothing"
10:25Chouser,(let [c []] (if c "something" "nothing"))
10:25clojurebot"something"
10:25ezyangOh. That's different from Scheme
10:25ezyangI thought an empty list was nil
10:25Chouserno
10:26ozzilee,(seq [])
10:26clojurebotnil
10:26Chouser,(let [c (list)] (if (seq c) "something" "nothing"))
10:26jdzezyang: in scheme empty list is logical true, no?
10:26clojurebot"nothing"
10:26Chouser,(let [c (list)] (if c "something" "nothing"))
10:26clojurebot"something"
10:26ezyangjdz: well, you do something like (null? list)
10:27jdzezyang: same here, you do (seq lst)
10:27ezyangOK.
10:28Chouserin fact the idiomatic way to test for a non-empty collection is to use (seq x) in a boolean context.
10:28Chouserinstead of (if (not (empty? coll)) ...), you say (if (seq coll) ...)
10:28ezyangWhy is that the case?
10:29jdzbecause saying "something" sounds better than "not nothing"?
10:30jdzeasier on the brain at least
10:30ezyangjdz: Oh, ok.
10:30ezyangI would normally use null? and then define the base case, and then do the regular stuff in the else
10:32ezyangTotally unrelated question: is there any way to dynamically update the REPL code
10:32ezyangwithout quitting the repl, recompiling, and then running again
10:32ezyangs/update the REPL code/update the code while you're in the repl/
10:32jdzdef?
10:33jdzwell, how did you get the code in the repl in the first place?
10:33ezyangjdz: I changed my namespace
10:33ezyangAnd then the classpath found it
10:33ezyangThe idea is I open the repl to debug some clj files, and then I edit those files
10:34jdzi have not tried, but maybe remove-ns + require will do
10:34ezyangI guess I'm being kind of unreasonable here
10:34ozzileeezyang: (require 'my-ns :reload-all)
10:34jdzwell, most people use some kind of a developement environment, like emacs + slime or netbeans or something
10:35ezyangI spent last afternoon trying to get VimClojure to work
10:35ezyangI think that I'm stuck on some special mvn behavior
10:36jdzserves you well for wanting to use vi[m] for lisp developmement *evil grin*
10:37ezyangI think it's kind of unreasonable to learn a new text editor (emacs) just to develop in it.
10:37ezyangs/in it/in clojure/
10:37jdzwell it's reasonable for a lisp developer to want to redefine stuff on the fly without reloading the world
10:37jdzlike redefining functions, for instance
10:37gnuvinceThere's NetBeans, Eclipse, IntelliJ that are coming up with plugins for Clojure if you prefer.
10:38gnuvinceEmacs is just so tightly knit with Lisp and its community that it's no wonder that the majority of Lispers prefer it.
10:38Chouserezyang: I agree
10:41ezyanggnuvince: I totally understand why emacs is +1 for lisp development
10:42ezyangAnd it's also a text editor that is worth learning
10:42Chouseris it? is it really?
10:42ezyangI think you should be proficient in both vim and emacs :-)
10:43gnuvinceezyang: thankfully, I am :)
10:43gnuvinceI use vim at work for Django work, and Emacs at home for Clojure and Haskell
10:43gnuvinceAnd I'm pretty happy about my situation
10:46piyoezyang: have you tried technomancy's clojure+emacs guide? http://technomancy.us/126
10:46ezyangNot yet
10:46piyoIt cleared up a number of problems for me
11:18cemerickwe use netbeans + enclojure to very good effect, FWIW
11:19cemerickthe debugger isn't there yet, but I'll bet it's not there for slime, either
11:19Chouserthe size of all these tools scares me. :-/
11:20cemerickIf you can understand the whole thing top to bottom, chances are it doesn't do much for you. ;-)
11:20Chouserwow
11:20cemerickyeah, I always get that kind of reaction when talking to other programmers
11:21cemerickabstractions are good, they give you leverage.
11:21ChouserBut I don't need to understand how it all works, I just need to understand how to use it. That's sufficiently scary for emacs, netbeans, eclipse...
11:22cemerickhuh. I've always found NB very friendly. Somewhat more so than eclipse, and quite clearly more approachable than emacs.
11:22aravindChouser: so.. what do you use for development?
11:22ChouserI'm always afraid to say. People (Rich included) mock me.
11:22hiredmannotepad++
11:22Chousertext editor. repl.
11:23Chouserion3.
11:23hiredmanChouser: have you seen slime.vim?
11:23aravindI see, but don't you like the convenience of having a few key strokes compile/eval what you are working on?
11:23hiredmanhttp://technotales.wordpress.com/2007/10/03/like-slime-for-vim/
11:24Chouservim with syntax coloring and indentation support. repl with rlwrap and vi-like bindings for tab completion and history.
11:24hiredmanit lets you send code to a repl running in screen
11:24Chouseraravind: well, I have that. maybe more keystrokes than with slime, but not too bad.
11:25Chousera couple keystrokes to select a portion of the code, an ion3 keystroke to focus on the repl, a keystroke to paste and execute.
11:25ezyangGave up with vimclojure, am setting up emacs
11:25aravindChouser: ion3 is supposed to be an awesome wm.. I used to use stumpwm for a while, but I finally gave up on tiling wms, switched to openbox (but was able to retain most of my keybindings).
11:25Chouserhiredman: I don't think I've tried that particular one. I did use whatever was before gorilla some, but it never really hooked me.
11:26hiredmanChouser: it is different from gorilla
11:26ChouserAnd I don't particularly *like* vim (vimscript in particular), but it's what I know, and the keybindings are undeniably powerful.
11:26piyoezyang: what is your os
11:27aravindChouser: how about auto navigating to your function definitions if you want to look some stuff up? You would have to hack it up with etags or something like that for equivalent functionality.
11:27ChouserI suppose I should try emacs, but the thought of having to learn elisp in order to customize it makes me gag a little.
11:27hiredmanyou start a repl inside a screen session and then you tell slime.vim the name of the screen session and the name of the window the repl is in, and it just sort of pastes the vode into the repl
11:27hiredmanvery loosely coupled
11:27stuartsierraChouser: it's not that bad, 99% of the customization you'll ever want is in the *customize* GUI.
11:28Chouserhiredman: yeah, that sounds like pre-gorilla (sorry, can't remember the name). He had some vim/ruby code that sent forms to a screen session.
11:28ezyangpiyo: Jaunty
11:28Chouser...and I really must have vim bindings. the last couple times I tried switching to emacs I tried to do things the Emacs Way. I'm done with that.
11:29aravindChouser: well.. it takes time.
11:29ChouserI know Chousuke uses vi bindings in emacs, but my recent attempts at that were unsatisfactory.
11:29aravindbut then, if you are productive with your env, thats all that really matters.
11:30Chouseraravind: oh, I know. My last attempt at emacs went far enough that I was pretty comfortable with emacs bindings for navigating a file. Took time, but was somewhat rewarding.
11:31Chouser...but then I needed features that were not built in, and spent some time trying to port a plugin from xemacs to emacs (or the other way around, I forget) ... largely failed, and then discovered the feature I needed was built in to vim.
11:31piyoezyang: sudo aptitude install ant open-jdk-devel ... # etc...
11:31piyoezyang: ?
11:31aravindI was a huge vim proponent, but its a nightmare trying to customize or hack the configs for anything other than the basic tabwidth, or syntax settings in it. So, I have been using emacs for some time now.
11:32Chousernow I'm just whining. I want emacs flexibility + vim keybindings + clojure core (for multithreading, customiaztion, etc.)
11:32Chouserwhen can I have that? :-)
11:33ezyangOh, I already can run Clojure
11:33ezyang(re piyo)
11:33ezyangI was trying to "improve my productivity" with a non-crappy repl environment
11:33aravindChouser: have you give emacs viper mode a chance, it may be just enough vi for you.
11:33ChouserI have. I should try again.
11:34ChouserI'm frequently startled by missing features, but I should try to get over it.
11:35aravindthats how I switched..
11:35Chouseryou don't use it anymore
11:35Chouser?
11:36aravindvim, nope.. not unless I am in a remote system, when I need to use it for quick things. (I am a sysadmin).
11:36ChouserI mean, you don't use viper mode anymore?
11:37aravindoh viper mode.. nope, I used it to get started.. used it for a few months, then I tweaked the viper levels down to make it more and more emacsy, and finally turned it off for good.
11:37ChouserI just can't imagine living without command mode.
11:38aravindI did stick to pure viper (full vi) mode for a few months though.
11:39aravindcommand mode annoys me now, when I go to remote systems and start typing ALT-n and ALT-b in vim :)
11:39ChouserHolding down the ALT key seems like an inconvenient sort of command-mode.
11:39Chouser:-)
11:41aravindhehe, yeah.. like I said, it takes time :)
11:42Chousersee, and that would be fine if I were deeply convinced of the Rightness of emacs. But the language, the lack of concurrency, etc. weaken that conviction.
11:42aravindI still do like vi mode for other things though. my mutt is all vi mode and so is lynx (though I don't use that much these days).
11:43aravindChouser: for me, it was more of a convenience thing and the fact that its immensely customizable should I need to.
11:43ChousukeI finally got visual block mode working properly with emacs/vimpulse.
11:44Chousuketurns out I had to disable CUA mode because it was screwing up the rendering for some reason
11:44ChouserChousuke: really? works great here! in vim. :-) :-)
11:44ChousukeI still think emacs is fundamentally superior to vim
11:44Chousukethe interface is just not as good :)
11:44Chouserheh
11:45Chousukeelisp lacking concurrency support is a big wart though, but at least it's not vimscript :P
11:46ChousukeI wonder how they're going to go about adding threading to emacs.
11:46aravindalthough I will admit, gnus has defeated me, multiple times. I have tried and failed to adopt it as my mail client. Every time I give it a shot, I go running back to mutt :)
11:47ChouserI've never been a heavy email user, but I got gnus working nicely last time I tried.
11:47piyoezyang: it's just that, when the installation asks you to "M-x clojure-install", it git-clones then does the ant build thing
11:48ezyangOh yeah. No, the project I'm working on has its separate build environment, with hand-rolled jars and eveyrthing
11:48aravindChouser: thats odd! you got gnus to play nice, but you have a hard time with emacs..
11:49cemerickdoes anyone have recommendations for swing app frameworks, aside from the NB RCP?
11:50Chouseraravind: I really tried hard last time, getting emacs going. I wasn't even a lisper then...
11:51aravindChouser: it took me a few attempts.
11:53aravindChouser: if you want to switch (I am not saying you should), I'd start small. Don't try to get your entire env converted and working the way you think it should.
11:53aravindChouser: I'd start with full blown viper mode.. etc..
11:55Chouser:-)
11:55Chousukeviper doesn't have visual mode though.
11:56aravindI have used them both enough, that I don't really mind the taunting.
11:56aravindI take the zen approach and go "whatever works for you" :)
11:56piyoaravind: I like editting with root privs from emacs , /sudo::/etc/hosts , etc
11:56ChousukeI still use vim for some stuff
11:57Chousukebut for clojure editing I need emacs.
11:57aravindpiyo: hehe
11:58piyoexcept emacs first needs to be installed into the os, while vi is sitting there
11:58aravindpiyo: oh wait a minute.. you are serious?
11:59piyoaravind: M-x butterfly, baby
11:59Chousukequite often emacs is too; but vi is pretty universal.
11:59aravindphew!
11:59hiredmanpiyo: well, the vi freebsd comes with is really vi, not vim
11:59piyoso I'm like sudo vi /etc/portage/package.mask # add cutting edge emacs
12:00hiredmanwhich, uh, I'd rather not use for coding
12:00piyoaravind: you do use emacs TRAMP
12:00piyoaravind: ?
12:00aravindpiyo: I do, if I have to do extended editing, and I can't replicate the env locally.
12:01piyoI was being serious with /sudo::/etc/hosts
12:01aravindno way!
12:01aravindyou can't be!
12:01piyoI mean, it works
12:02ezyangHuh. Even with emacs+slime, it doesn't dynamically automatically update things. feh
12:02piyoI do set sudo so that I don't enter my password
12:02aravindpiyo: sure does, but its like writing full blown swing application to cat/view a 10 line text file.
12:03piyosometimes you want to M-x rectangle-yank inside a config file
12:03piyo:)
12:03piyooh wait, you said 10 lines
12:04piyoI guess you could bang on "." for a while
12:04aravindpiyo: vim + ex commands usually work fine for that kind of stuff for me.
12:04piyoaravind: as for me
12:05piyohiredman: I only seem to use vi features, not vim
12:06piyo</offtopic> ?
12:06aravindI am out, have to get ready and head in to earn that paycheck.
12:15piyolet's talk about clojure
12:15hiredman~clojure
12:15clojurebotclojure is like life: you make trade-offs
12:16hiredman~clojure
12:16clojurebotclojure > scheme
12:16gnuvince,(compare "clojure" "scheme")
12:16clojurebot-16
12:17gnuvince;-)
12:17Chouser,(expression-info '(Integer. "5"))
12:17clojurebot{:class java.lang.Integer, :primitive? false}
12:17Chouser,(expression-info '(int (Integer. "5")))
12:17clojurebot{:class int, :primitive? true}
12:17gnuvinceThat's pretty neat
12:18ChouserI wish there were a way to use it on expression deep inside a nested context.
12:24piyohey technomancy thanks for that emacs + clojure blog post, it was useful
12:24technomancypiyo: great, glad it was helpful
12:24piyo:)
12:42ezyangHmm, I still can't get repl reloading to work
12:45ezyangWhat was the command to reload the namespace again?
12:45ozzilee(require 'my-ns :reload-all) ?
12:46ezyangYeah, doesn't seem to do anything
12:47ezyanghttp://pastebin.com/mefa4d10
12:47stuartsierraIt won't delete old definitions.
12:47ezyangOh.
12:47ezyangOk, how should I do that?
12:47stuartsierraTry (remove-ns 'my-ns) first.
12:48ezyangNow I get Var plyzrdata.parser/parse-hoststat-line is unbound.
12:50ezyang(an IllegalStateException)
12:50stuartsierraMaybe your definitions are out of order?
12:51ezyangWhat do you mean by that?
12:51ozzileeezyang: You have to define functions before you use them, unfortunately
12:51ezyangOh, I know why
12:52ezyangRemoving the namespace doesn't remove the function
12:52ezyangozzilee: It loads fine the first time
12:52ozzileeezyang: Ah, ok.
12:52ezyangSo how would I remove all of the functions from a namespace...
12:53hiredmanns-unmap
12:54hiredman,(ns-map *ns*)
12:54clojurebot{sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, pprint-map #'clojure.contrib.pprint/pprint-map, keyword? #'clojure.core/keyword?, val #'clojure.core/val, ProcessBuilder java.lang.ProcessBuilder, Enum java.lang.Enum, SuppressWarnings java.lang.SuppressWarnings, *compile-path* #'clojure.core/*compile-path*, max-key #'clojure.core/max-key, list* #'clojure.core/
12:55ezyangHm, so I would need to map ns-unmap on map
12:56ezyang,(map (partial ns-unmap `plyzrdata.parser) (ns-map `plyzrdata.parser))
12:56clojurebotjava.lang.Exception: No namespace: plyzrdata.parser found
12:56ezyangErm, I get the error rclojure.lang.PersistentHashMap$LeafNode cannot be cast to clojure.lang.Symbol
12:56replacahiredman: autodoc json now has :namespace element for each entry in :vars
12:56replacahiredman: that's what you were after, right?
12:56ezyangGiven how difficult this seems to be, I'm probably going about this the wrong way
12:59hiredmanreplaca: yesssir
12:59ezyangCan I make clojure start the repl in a specific namespace?
12:59replacahiredman: cool
12:59replacahiredman: did you modify clojurebot to ignore autodoc updates?
13:00hiredmanreplaca: yes
13:01replacahiredman: good idea, but I was getting used to the echo :-)
13:02hiredmandispleasure was expressed in my direction
13:02replacahiredman: yeah, makes sense. no real information there.
13:03hiredman(doc xml1->)
13:03clojurebot"clojure.contrib.zip-filter.xml/xml1->;[[loc & preds]]; Returns the first item from loc based on the query predicates given. See xml->"
13:04replacanice
13:05hiredmanso couchdb has no security features built in?
13:07mrsoloah missing :gen-class i am such a dimwit
13:17technomancyhiredman: since it's all run over HTTP it's pretty easy to secure at the proxy level
13:17technomancyno need to build it into the DB
13:53mrsoloare there some online resource that help you to learn about writing macros?
13:53dnolencheck the Clojure wiki
13:53dnolenalso Practical Common Lisp and On Lisp are good general resources about macro writing and they are available for free
13:53Chouser_1mrsolo: I learned by reading On Lisp, which is free online
13:54mrsolo ok
13:55mrsologoing through core.clj... ` seems to be in random places and i don't see the significants :-)
13:55ChouserOn Lisp uses mostly Common Lisp and some Scheme, but the bulk of it is meaningful for Clojure, with a few syntactic adjustments
13:55Chouserheh, it's not random, I assure you. :-)
13:55mrsoloof course
14:00ezyangWhat are the performance properties of partial application in clojure?
14:01ezyangDoes Clojure magically evaluate things it can evaluate when I do a partial application?
14:01hiredmanpartial just returns a new function
14:01hiredmanuh
14:01hiredmanit is function application, not magic
14:01hiredman~def partial
14:02ezyangOk :-(
14:02hiredmanno magic whatsoever, not even a macro
14:02hiredmanwhy the :-( ?
14:02ezyang(unrelated) I am currently editing files in Vim, popping over to emacs and using that to run them
14:02ezyangIt's great. :-P
14:03dnolenezyang: the cost is an additional function call, but those are cheap.
14:03dnolener
14:03dnolenno
14:03dnolenrather the speed of apply
14:07ezyangSo, the question here is there's a pre-computation to one of the parameters that should be done, and I was wondering if I could do it inside the function
14:07ezyangbut that's not hte case
14:08hiredman...
14:08Chousukemrsolo: if the appearance of ` seems random to you, remember that it's just one way to write a list data structure that won't get evaluated.
14:08ezyangBtw, (load-file) is the magic I was looking for earlier on the channel
14:08gnuvinceI got a general CS question for you guys: considering that getting the length and splitting a linked list are O(n) operations, is mergesort really a good candidate for sorting them?
14:09Chousukemrsolo: macros must return clojure code, and clojure code is predominantly made of lists. thus, ` is very useful when making macros.
14:09mrsoloah
14:09Chousukemrsolo: you could write every macro without it too, though.
14:09Chousukebut that's a lot more complicated.
14:11Chousukeactually ` is not limited to quoting lists either, but that's where you see it most often.
14:11Chousuke,(let [a 1] `[1 2 a ~a])
14:11clojurebot[1 2 sandbox/a 1]
14:11mrsolochousuke: i got this to work and i want to know why ..it tooks lot of trials and errors http://paste.lisp.org/display/81422 :-)
14:12mrsoloso ya reading some information on why and how of macros will be very helpful
14:12Chousukemrsolo: did you try calling (macroexpand '(rp (+ 1 2))
14:13Chousukeactually, that macro is a bit weird.
14:13mrsolohmm i didn't.. but that gave (rp (+ 1 2)) back
14:13Chousermrsolo: that macro is not what you want.
14:14Chousukeright
14:14Chousukeit doesn't return clojure code.
14:14Chouserthe use of 'eval' is your first hint that something's wrong.
14:14mrsolook
14:14Chousermrsolo: if you want less than a whole book, we can give you a few tips.
14:15mrsoloyet it works somehow
14:15Chousukemrsolo: your macro runs the println and time at *compile time*
14:15Chousukemrsolo: it doesn't actually expand to any code :)
14:15Chousukeunless (eval a) expands to code
14:15mrsolo(rp (map list-single-files '("/tmp", "/tmp")))
14:15mrsologives back desired result.. though
14:15Chouserfor example, first write out an example of calling your macro. Then write out the code you'd like your macro to produce for that example.
14:15ChouserChousuke: yikes. good point.
14:15Chousukemrsolo: but it doesn't happen at runtime
14:16Chousukemrsolo: it happens at compile time.
14:16mrsolook
14:16Chouserso you've got an example of calling your macro there. that's a great start.
14:16Chousukemrsolo: ask yourself: if rp were a function, what does it return?
14:16Chousernow, what code would you like your macro to produce in that case?
14:16mrsolook
14:17ChouserMaybe: (time (println "(map list-...)" (map list-...))) right?
14:18mrsoloright
14:18Chouserso, your macro should be a function that accepts the list '(map list-...) and returns the list '(time (println ...))
14:19Chouseryou can write regular code without ` or ~ do to that.
14:19Chouserif you want
14:19Chousukeactually.
14:19mrsolowell it was a function origional.. but i was tire dof quoting
14:19mrsoloall it does it print the sexp and time to run it
14:20Chousukeit might be good practice to actually write a function that does that.
14:20mrsolooh?
14:20Chouserit would look something like (defmacro rp [a] (list `time (list `println (str a) a)))
14:20mrsolo(rp '(+ 2 3)) gets kinda tedous.. i though macro will let me do (rp (+ 2 3)) instead
14:20Chouserdo you see why?
14:21mrsoloi see
14:21ezyangHey all; what data-structure should I use if I will have a mapping like 0 => :tag1, 1 => :tag2, 2 => :tag3, etc
14:21ezyangThere will a dozen-ish elements
14:21ozzileeezyang: Hashmap?
14:21ezyangThat seems like overkill...
14:21ozzileeEr. array I suppose.
14:21ezyangIs the array functional?
14:21hiredmanozzilee: vector
14:21ozzilee[:tag1 :tag2 :tag3 :tag4]
14:22mrsolochouser: thanks!
14:22ozzileeYeah, vector, sorry :-)
14:22hiredmanozzilee: that is a vector
14:22stuhoodif the indexes will always be incrementing integers, then yea... a vector
14:22ezyangDoes the vector give me O(1) access?
14:22dnolenyup
14:22ezyangYup, always will be incrementing integers
14:22ezyangAwesome
14:22hiredman,(keys [:a :b :c])
14:22clojurebotclojure.lang.Keyword cannot be cast to java.util.Map$Entry
14:22hiredman:(
14:23stuhoodaw... that should work
14:23hiredman,(keys (map vector [:a :b :c] (range 20)))
14:23clojurebotclojure.lang.LazilyPersistentVector cannot be cast to java.util.Map$Entry
14:23hiredmanGrrr
14:23hiredman,(map (comp second vector) [:a :b :c] (range 20))
14:23clojurebot(0 1 2)
14:24ezyangHm. How do I convert a list to a vector...
14:24hiredman,(vec '(1 2 3 4))
14:24clojurebot[1 2 3 4]
14:24ezyangSweet
14:24hiredmanezyang: clojure.org/api
14:25ezyangYeah, sorry about that; should have looked that up first
14:25Chousuke(let [myfn (fn [lst] (concat lst '(2)))] (myfn '(+ 1))); mrsolo
14:25Chousuke,(let [myfn (fn [lst] (concat lst '(2)))] (myfn '(+ 1))); damn
14:25clojurebot(+ 1 2)
14:25ezyangHere's anot so easy to lookup question: when does clojure approve of (comp)?
14:25Chousukemrsolo: see how that function returns clojure code?
14:25hiredmanezyang: "approve" ?
14:26hiredman~def comp
14:26Chousukemrsolo: now, if you wanted to use myfn to write a macro that appends a 2 at the end of a clojure list form, you'd just do: (defmacro foo [form] (myfn form))
14:26ezyangFor example, I could do something like (comp vec map) but that seems a little poor...
14:26hiredman"poor"?
14:27Chousukemrsolo: notice, no quotes; myfn already returns clojure code :)
14:27ezyangas in, poor form
14:27hiredmanwhy would you say that?
14:27Chousukemrsolo: if you can understand why this works, then you already are well on your way to understanding macros.
14:28ezyanghiredman: Sort of gut feeling. No good reason
14:28hiredmanmy feeling is partial and comp don't get used often enough
14:28ezyangNew question: I'm looking at some code that is building maps using a reduce()
14:28ezyangI feel like there is a... better way of doing this
14:28hiredmanpeople just use function literals everywhere
14:29ezyangmaybe involving zipmap
14:29hiredmanezyang: better way of composing functions?
14:29ezyangOh, sorry, I'm on another topic now :-P
14:30mrsolochousuke: nice big difference between reading and writing though.. still lot a long way to go
14:30Chouserezyang: did you look at 'into'?
14:30stuhoodezyang: reduce is a relatively good way, 'into' would be another
14:30hiredman~def vec
14:30Chousukemrsolo: yeah, but it's not that difficult once you really understand what macros do
14:30hiredmanI imagine vec is faster then into
14:30hiredmanthan
14:31digashDoes anybody know Scala here? I need to do a presentation on Clojure to Scala NY group. I've done Clojure to Java programmers before, but what Scala guys would want to here?
14:32ezyangstuhood: Why wouldn't zipmap work?
14:32Chouserdigash: they want to talk about contravarient type signatures
14:32ezyangSay I have a vector [:a, :b, :c] and a list (1, 2, 3) and I want {:a 1, :b 2, :c 3}
14:32hiredmandigash: my guess is smooth interop with java Collections
14:32stuhoodezyang: in that case, zipmap is the perfect fit
14:32ezyang,(zipmap '[a b c] '(1 2 3))
14:32clojurebot{c 3, b 2, a 1}
14:32mattrepldigash: macros over automated closures for designing DSLs
14:32hiredmanscala is having a huge shakeup over their collections stuff right now
14:32ezyangOk.
14:33hiredman~scala
14:33clojurebot"you can usually accomplish a lot by laboriously enumerating type arguments everywhere." -- seen in #scala
14:33Chousukemrsolo: they take clojure code as parameters: if you have a (foo [a]) macro and call it as (foo (+ 1 3)) then (= a '(+ 1 3)) is true. Then you operate on the parameters like any other function, and return new code (my earlier example would concat '(+ 1 3) and '(2), returning '(+ 1 3 2))
14:33Chousukemrsolo: this function is then run at compile time, and the macro invocation is replaced with its return value.
14:34Chouserdigash: though I was never a committed Scalar, what brought me to Clojure was how much you could get done without ever declaring a type, and how easily a DSL can be made without needing scala's too-clever auto-casting (or whatever it's called that I've now forgotten)
14:34ChousukeScalar :P
14:34Chouser:-)
14:35hiredmanyeah, I think clojure's java interop is (surprisingly?) better then scalas except possibly for Annotations stuff
14:35Chousukemrsolo: you can have side-effects like println in macros, but usually it's not what you want, since it's run at compile time.
14:35digashChouser: thanks, I try DSL. Then the next questions what are the best DSL examples in Clojure?
14:36Chousukemrsolo: however, what you DO often want is *return* code from a macro that has side-effects
14:36hiredmandigash: you could ask in #scala to see what they want to hear about
14:36Chouserdigash: enlive
14:36digashhiredman: thanks, i would go there but first wanted to swim in the friendlier waters.
14:36hiredmanheh
14:37hiredmanthose darn scalars!
14:37Chousukemrsolo: if returning code from a function makes sense to you, then you understand what "code as data" really means.
14:37mrsoloya
14:37mrsoloi see why not
14:37mrsoloso
14:38mrsolodefmaco can be used to intentionally run some code during compile time?
14:38mrsolofor whatever the reason
14:38Chouserdigash: http://github.com/Lau-of-DK/clojureql/tree/master
14:38mattrepldigash: someone in the crowd will probably ask about performance, so having some information on type annotations and unchecked arithmetic would be prudent
14:38stuhooddigash: incanter seems pretty cool too http://github.com/liebke/incanter/tree/master
14:39Chousukemrsolo: there are rules.
14:39digashmattrepl: is Scala performance on the par with Java native types?
14:39Chousukemrsolo: it's not really compile time I guess, but "macro expansion time". usually macros are expanded first, and THEN stuff gets compiled.
14:40mrsolowhat are the rules?
14:40mattrepldigash: I believe idiomatic Scala is more on par with Java than idiomatic Clojure
14:40Chousermrsolo: sure, On Lisp shows some interesting performace tweaks by computing stuff at macro-expand time.
14:40mrsoloone can implement something similar to perl BEGIN i guess
14:41Chousukemrsolo: a macro can't depend on runtime data, obviously :)
14:42hiredmanmattrepl: scala still does a lot of intermediate object allocation
14:42Chousukemrsolo: you can use whatever is available at macro expansion time, though. global vars etc.
14:42hiredmanthey also do what they call "de-scalafying" to get closer to java performance
14:43Chousukescaling down? :)
14:43Chousuke(the mountain)
14:44Chousertoward the Java lowlands?
14:44hiredmanyeah
14:44Chousukeclojure people can just take a paren and use it as a sled.
14:45mattrepldigash: destructing bind and keyword and rest params might be good material too
14:45Chousukethough the ride down might be fun but hitting the ground probably isn't.
14:45Chousukehmm
14:46hiredmanhttp://www.codecommit.com/blog/scala/scala-collections-for-the-easily-bored-part-1
14:46Chousukeabout destructuring bind, I was wondering if it is possible to improve the destructuring that it's always equivalent to a sequential let when the source form is known at macro expansion time to match the target. :/
14:47ezyangIs there a list of clojure's string -> FOO conversion functions?
14:47Chouserezyang: clojure doesn't have many of those. Mostly you use Java methods.
14:47ezyangick
14:48Chouserezyang: 'keyword' and 'symbol' take strings...
14:48Chouserezyang: ick?
14:48Chousukeeg. expanding (let [[a b c] [1 2 3]]) to (let [a 1 b 2 c 3]) instead of the weird (let [a (get somegensym 0 nil) ...])
14:48Chouser,(Integer/parseInt "F00" 16)
14:48clojurebot3840
14:48hiredman,(.toUpperCase "foo")
14:48clojurebot"FOO"
14:49ChousukeI have seen complaints about destructuring let being inexplainably slower than non-destructuring let, and I think it could be fixed :/
14:49hiredman,(-> "foo" .toUpperCase .toLowerCase ((partial map int)) ((parital reduce *)))
14:49clojurebotjava.lang.Exception: Unable to resolve symbol: parital in this context
14:50hiredman,(-> "foo" .toUpperCase .toLowerCase ((partial map int)) ((partial reduce *)))
14:50clojurebot1256742
14:50ezyangWhy did... Integer/parseInt take two parameters?
14:50clojurebotwhy not?
14:50Chousukeezyang: it's overloaded.
14:50hiredmanezyang: because you have to give it a base
14:50ezyangOk... I need to curry the second parameter
14:50hiredman,(Interger/parseInt "10" 2)
14:50clojurebotjava.lang.Exception: No such namespace: Interger
14:50ezyangThis is going to be complicated
14:50hiredman,(Integer/parseInt "10" 2)
14:50clojurebot2
14:51hiredman,(Integer/parseInt "10" 8)
14:51clojurebot8
14:51Chousuke,(Integer/parseInt "10"); works too I think
14:51clojurebot10
14:51ezyangOh, ok
14:51cemerickChousuke: I can vouch for that. Got a 10% speedup on a key inner loop by eliminating [[v0 v1]] and using [v] with (v 0) and (v 1)
14:51ezyang,Integer/parseInt
14:51clojurebotjava.lang.Exception: Unable to find static field: parseInt in class java.lang.Integer
14:52ezyangHmm... is it a first class function?
14:52mrsolocemerick: ack!
14:52Chouser,(let [from-hex #(Integer/parseInt % 16)] (from-hex "fa7"))
14:52clojurebot4007
14:52ezyangBut you anonymized it...
14:52cemerickmrsolo: ack?
14:52ezyangI guess that works
14:53mrsolocemerick: huge performance penality for such an innocent construct
14:53Chouserezyang: no, it's a static method, not a Clojure function.
14:53Chousukecemerick: the problem is that I don't think it's possible to help in the case where you do destructuring like [[v0 v1] v]
14:53ezyang:-* Well, I guess that's the price you pay for getting Java
14:53Chousukecemerick: since the form of the source is not known
14:53cemerickmrsolo: yeah...well, it was a *very* hot spot, FWIW
14:53ChouserChousuke: [v0 (v 0) v1 (v 1)] ?
14:53Chouseroh, if you want to allow for lists
14:54cemerickyeah, I don't think it's such a big deal.
14:54cemerickI got that particular hint from a post that gnuvince made recently, and I remember some commenters trashing on clojure due to the current state of affairs, so maybe CL doesn't have that issue. *shrug*
14:55Chousukeso why would (nth v 1) be slower than (v 1)? :/
14:55cemerickone fewer method call?
14:57Chousuke~source nth)
14:57clojurebotNo entiendo
14:57Chousukegah
14:57Chousuke~source nth
14:57ezyangDoes clojure have a built-in no-op?
14:57Chouser,(do)
14:57clojurebotnil
14:57Chousukeidentity?
14:58cemerickezyang: identity
14:58Chousernil
14:58ezyangOk.
14:58Chousukedepends on the context I guess.
14:58dnolen,(do nil (+ 4 5))
14:58clojurebot9
14:58cemerickChousuke: See, there's actually a number of levels indirection with nth
14:58ezyang,(nil 1)
14:58clojurebotjava.lang.IllegalArgumentException: Can't call nil
14:58ezyang,(identity 1)
14:58clojurebot1
14:58gnuvinceThe doc says that nth is O(n) for sequences while Vectors can index in O(log_32 n)
14:59Chousukecemerick: I think it should inline the not-found case too :/
14:59Chousukegnuvince: (v 1) is O(log_32 n) too, that's no different :)
15:00cemerickChousuke: the function-call overhead could have been the difference in my case.
15:00ChousukeI think it's just that in destructuring, nth is used with the default value and it's not inlined.
15:01Chouser(v 1) compiles to (.invoke v 1), which calls v.nth((1).intValue())
15:01Chousukeokay, so it's basically equivalent.
15:02ChousukeI wonder if the slowdown goes away if the 3-parameter case is added to inline arities as well
15:02ChouserI wonder if the Var lookup for 'nth' itself hurts much.
15:04Chousukeor perhaps c.lang.RT/nth does instanceof lookups that slow it down :/
15:07Chousukethere's an enormous difference between doing (nth v 3) and (nth v 3 1) 10 million times.
15:08Chouserwild
15:11Chouser,(let [v [1 2 3]] (time (dotimes [_ 10000] (v 1))))
15:11clojurebot"Elapsed time: 6.454 msecs"
15:11Chouserwhat am I doing wrong here?
15:11Chouser,(let [v [1 2 3]] (time (dotimes [_ 1000000] (v 1))))
15:11clojurebot"Elapsed time: 101.76 msecs"
15:12Chouserhm, that looks vaguely sane. On my machine doing the lookup *100 more times only costs 0.5 more msecs.
15:12Chouser,(let [v [1 2 3]] (time (dotimes [_ 10000000] (v 1))))
15:12clojurebot"Elapsed time: 85.344 msecs"
15:12hiredman"Elapsed time: 390.49132 msecs"
15:12hiredman:(
15:13ChouserChousuke: oh!
15:13Chouserdestructuring uses (nth v x nil)!
15:14ChouserChousuke: the notFound slowdown you spotted may be the main culprit for destructuring
15:14Chousukeinlining the 3-parameter case is still slower, but saves 200ms for 10 million lookups compared to not inlining
15:15Chouserwhat do you mean by inlining there?
15:15Chousukenth has {:inline (fn [c i] `(. clojure.lang.RT (nth ~c ~i))) :inline-arities #{2}}
15:15Chousukejust adding the 3-parameter version there
15:16Chouserah!
15:17ezyangLet's say I have a map of values and a map of functions and I'd like a map of (function value). What do I do?
15:18ezyang(the maps keys perfectly align)
15:19Chousukehm
15:19hiredman(map #(%1 %2) (vals functions) (vals values)) would return a seq of (function value)
15:19Chousukeright... (map apply (vals fmap) (vals values))
15:19hiredmanor that
15:20Chousukehmm
15:20mrsoloclojurebot runs on fast machine!
15:20hiredmanuh
15:21hiredmanNot Really
15:21ChouserI'd be nervous about using val seqs from two different maps
15:21mrsolo "Elapsed time: 222.746 msecs"
15:21mrsoloor mine is a very slow one
15:23hiredman(let [fmap {:a idenity :b identity} vmap {:a 1 :b 1}] (reduce #(assoc %1 %2 ((fmap %2) (vmap %2))) {} (vals fmap))
15:23hiredman,(let [fmap {:a idenity :b identity} vmap {:a 1 :b 1}] (reduce #(assoc %1 %2 ((fmap %2) (vmap %2))) {} (vals fmap))
15:23clojurebotEOF while reading
15:23hiredmanbah!
15:24Chousukehmm
15:24Chouser,(let [funcs {:a inc :b dec} values {:b 5 :a 10}] (into {} (for [[k f] funcs] [k (f (values k))])))
15:24clojurebot{:b 4, :a 11}
15:25tashafaqq
15:25Chousuke,(map (comp apply apply) (vals (merge-with vector {:foo + :bar -} {:foo 5 :bar 1})))
15:25clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: LazilyPersistentVector
15:25tashafahow do you install clojure-mode.el thru ELPA?
15:26Chousuke(vals (merge-with vector {:foo + :bar -} {:foo 5 :bar 1})))
15:26Chousukegah
15:26Chousuke,(vals (merge-with vector {:foo + :bar -} {:foo 5 :bar 1})))
15:26clojurebot([#<core$_PLUS___3949 clojure.core$_PLUS___3949@482bad> 5] [#<core$___3975 clojure.core$___3975@46a55e> 1])
15:26mrsoloM-x package-install clojure-mode
15:26tashafamrsolo thanks!
15:27ChouserChousuke: ooh, I like where you're going.
15:27Chousukesafer than relying on the order anyway
15:27tashafamrsolo: hmm, no match
15:27Chousuke(apply hash-map (merge-with vector {:foo '+ :bar '-} {:foo 5 :bar 1}))))
15:27Chousuke,(apply hash-map (merge-with vector {:foo '+ :bar '-} {:foo 5 :bar 1})))) ;a hsfjslkfjg
15:27clojurebot{[:foo [+ 5]] [:bar [- 1]]}
15:28Chouser, (let [funcs {:a inc :b dec} values {:b 5 :a 10}] (merge-with #(%1 %2) funcs values))
15:28clojurebot{:a 11, :b 4}
15:28Chousukeaha, even better.
15:28mrsolotashafa: package-list-packages will list available packages
15:28mrsolotash: it should be in there
15:29mrsolotash: you can navirage then do package-menu-execute afterward 'I' to mark for install
15:31tashafago it
15:31tashafathanks man
15:31tashafagot it*
15:31mrsolonp
15:32Chousuke(let [fs {:foo + :bar - :zonk reduce} params {:foo [1 2] :bar [10 5] :zonk [conj #{} [1 2 3]]}] (merge-with apply fs params)); fun
15:32Chousuke,(let [fs {:foo + :bar - :zonk reduce} params {:foo [1 2] :bar [10 5] :zonk [conj #{} [1 2 3]]}] (merge-with apply fs params)); ASDFSDJFK
15:32clojurebot{:foo 3, :bar 5, :zonk #{1 2 3}}
15:33Chousukehow is it that I ALWAYS forget the comma
15:33ezyangSo, merge-with is the magic?
15:33Chousukeyeah
15:34ezyangI wonder if it'll 'splode if the keys don't match up
15:34Chousukeit probably will
15:35Chousukeor rather, this happens:
15:35Chousuke,(let [fs {:foo + :bar - :zonk reduce} params {:foo [1 2] :bar [10 5] :zonk [conj #{} [1 2 3]] :nonexistent 5}] (merge-with apply fs params));
15:35clojurebot{:nonexistent 5, :foo 3, :bar 5, :zonk #{1 2 3}}
15:36ezyang,(merge-with apply {:foo +} {})
15:36clojurebot{:foo #<core$_PLUS___3949 clojure.core$_PLUS___3949@482bad>}
15:37ezyangEw
15:37Chousukeyeah, the function printing thing is ugly ;(
15:37Chousukeneed metadata for functions so it can be made prettier!
15:38Chousukeshould say something like #<Fn clojure.core/+>
15:41hiredmanclojure.core/+ is a symbol
15:42Chousukethat's why it says Fn in there
15:42hiredmanwhy would the function care about a symbol it might be bound to?
15:42Chousukeokay, well, it could be just #<Fn +>
15:42hiredman+ is also a symbol
15:42Chousukeyes, but it's the function's name.
15:42Chousukeand if it has no name #<lambda 2398449> or something
15:43Chousukepoint being, something that easily identifies the function's name and possibly origin
15:44hiredmanthe only thing a function really maps to is a java class, which is what the current .toString is
15:44hiredman,(.toString (fn []))
15:44clojurebot"sandbox$eval__1992$fn__1994@1be0369"
15:44Chousukehiredman: that's why functions need metadata.
15:46Chousukethe .toString is useless and icky anyway so if there were metadata it could be used
15:49ChousukeI wonder if there's something that prevent IFn or AFn or something from just extending IMeta :/
15:52ezyangQuestion: I want to dynamically define a function, like (def func (func-gen 0))
15:52ezyangBut it would be a defmethod
15:52ezyangSo I'm a little confused how to do it (defmethod being a macro and such)
15:53ezyangCan I put the defmethod inside of another function?
15:54Chouserezyang: usually best in these cases to do what the macro does, rather than try to call it.
15:54Chouser(.addMethod multifn :value (fn ...))
15:55stuartsierraChouser: where are the dispatch arguments?
15:55stuartsierraOh, :value, I get it.
15:56stuartsierraSpeaking of multimethods, did anyone ever figure out multiple-arg dispatch with inheritance?
15:56stuartsierraThat is, (defmulti m (fn [x y] [(class x) (class y)]))
15:59stuartsierraOh, never mind, isa? works on vectors of derived types.
16:05ezyangrepl is giving me an exception, but not telling me where it came from...
16:05Chouser(.printStackTrace *e)
16:06ezyangThanks!
16:12ezyangHmm... apparently, #(%1 %2) is not equivalent to apply
16:12Chouserindeed not
16:12Chouserapply wants its final arg to be a collection, which it "unrolls" into the final args of the call.
16:13Chouser,(apply + 1 2 [3 4 5])
16:13clojurebot15
16:13ezyangsavvy
16:26ezyangHow do I introspect the contents of a multimethod?
16:26Chouser"contents"?
16:29Chouser,(doc methods) ; perhaps
16:29clojurebot"([multifn]); Given a multimethod, returns a map of dispatch values -> dispatch fns"
16:31cemerickit's unfortunate that the names of the fns installed as multimethods don't consist of, say, a concatenation of the method name and the dispatch value. That'd be handy, though probably dicey to implement safely.
16:33stuartsierraespecially since the dispatch value could be absolutely anything
16:36ezyangHey, does (load) do any dicey caching based on filemtimes?
16:38Chouserit checks file mtimes to determine if it should load .class or .clj
16:38ezyangOuch
16:39mrsolowhat if it is in resource file?
16:39ezyangA behavior of this is that multimethods don't get reinitialized properly
16:40mrsoloi mean if a resource file has both .class or .clj, what gets loaded?
16:40hiredmanmrsolo: if the clj is newer, it gets loaded
16:42Chouserhttp://code.google.com/p/clojure/source/browse/trunk/src/jvm/clojure/lang/RT.java#373
16:43ezyangThis is a likely bug, then
16:48jkantzin a single namespace make file_a, add a multimethod definition and (load "file_b")
16:48jkantzadd a defmethod to file_b
16:48jkantzadd another to file_c
16:49jkantzcompile the namespace
16:49jkantznow change the file_b multi method
16:49jkantzand load-file on file_a
16:49jkantzthe method in file_c will be gone
16:50hiredmana) you must be missing steps
16:50hiredmanb) if by compile you mean AOT compile, you should not compile single segment namespaces
16:51jkantz"single segment namespaces"?
16:51hiredman~namespaces
16:51clojurebotnamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
16:52hiredman~compile
16:52clojurebotthe unit of compilation in clojure is the namespace. namespaces are compiled (not files). to compile a namspace the namespace needs to be on the classpath and so does ./classes/ (and the directory needs to exist) because clojure writes the class files to that directory. http://clojure.org/compilation
16:53ezyangThe real code isn't single segment
16:54jkantzhiredman by b) do you rather mean you should not compile namespaces that have calls to load?
16:55hiredmanno
16:55hiredmancompiling namespaces that call load is fine
16:56hiredmanit will cause the loaded code to be compiled
16:56replacastuartsierra: it looks like the autodoc is right now. Can you confirm? http://code.google.com/p/clojure-contrib/wiki/StrUtils2ApiDoc
16:56hiredmanjkantz: pastebin your test case
16:56jkantzright and then run into issues with defmulti and and defmethods in the loaded files when you try to reload the main file.
16:57stuartsierrareplaca: closer, but not complete
16:57replacawhat's missing?
16:57jkantzk, just a sec
16:57hiredmanjkantz: I imagine you are running (defmulti ...) again which creates a new multimethod
16:57stuartsierraupper-case, lower-case, split, trim, contains?, get, split-lines, ltrim, rtrim...
16:58hiredmanthe new multimethod will not have any methods attached
16:58replacak, I'll take a look
16:58replacathanks
16:58stuartsierrasure, thanks for working on autodoc
16:58ezyangRight, but then when we (load) the sub files, the multimethod should then get repopulated
16:58ezyangWhat's happening is that (load) is not loading the subfiles
16:58jkantzhiredman, right, and due to the other files not being modified they aren't reloaded to re-add themethods
16:59hiredmanso how is that a bug?
16:59jkantznot so much as a bug as a gotcha
16:59ezyangI would argue it's a bug
17:00ezyangThere should be no functional difference between loading the clj and loading the class
17:00hiredmanwell, java cannot reload classes (unless you monkey with the classloader, I believe)
17:00hiredmanso there must be
17:01stuartsierraClojure monkeys with the classloader
17:01jkantzyou'd have to pass on the dependency information to subsequent loads
17:01replacastuartsierra: functions with no doc strings don't get put in the autodoc. Put an empty doc string if you believe they're that obvious
17:02jkantz~load
17:02clojurebotdownload is http://code.google.com/p/clojure/downloads/list
17:02stuartsierraAh, ok
17:02jkantz,(doc load)
17:02clojurebot"([& paths]); Loads Clojure code from resources in classpath. A path is interpreted as classpath-relative if it begins with a slash or relative to the root directory for the current namespace otherwise."
17:02replacastuartsierra: I think that explains all the funcs that were missed
17:04hiredmanjkantz: is there a reason you are using load instead of require, use, etc
17:05technomancyI've played with defining methods in a different file from the defmulti. It's not a lot of fun when dealing w/ reloads.
17:06hiredmannever had an issue with it with clojurebot
17:06jkantzhiredman, many individual methods organized each into their own file, don't want the extra namespaces
17:07hiredmanugh
17:07technomancyI think there's a way to force files to load even if they haven't changed.
17:08technomancybut yeah, if you step outside the one-file-per-namespace path, you're going to hit trouble
17:08technomancyno way around that
17:08hiredmanis this a chrome thing? or is github's source code numbering brolen
17:08hiredmanbroken
17:08jkantzanyway touch * is the work around of the day
17:08jkantzhiredman why ugh? you find it gauche
17:08clojurebotwhy not?
17:09hiredmanjkantz: sorry I was refering to loading up github and noticing the line numbers are off
17:10jkantzah ok, I'm out of here, have a good weekend
17:16replacastuartsierra: ok, I think the autodoc is right now
17:19stuartsierrareplaca: yes, looks good. Thanks!
17:19replacastuartsierra: thank you!
17:25replacabtw, for anyone who was here on Wednesday - turns out we broke the cable to the projector and that's why everything turned pink. A new cable fixed everything.
17:28stuartsierraNow you can copy files and streams in pure Clojure!
17:28technomancyoh, I was going to write that.
17:28technomancynice. =)
17:28technomancyhow about recursive copy now? =)
17:29stuartsierraYou mean recursive copy of directories?
17:29technomancyyeah, so I don't have to shell out to "cp -r"
17:30stuartsierraHmm. Worth having, although I was aiming to handle streams.
17:30technomancystuartsierra: would you take that as a patch?
17:30technomancyyeah, it doesn't seem to belong in duck-streams
17:30technomancythere's probably enough stuff that could go into a file-utils namespace to justify its creation
17:31stuartsierrasurely
17:32technomancyI've also got an extract-jar function that I thought should go in jar.clj
17:33technomancybut jar.clj could be subsumed into file-utils too
17:33stuartsierraGo for it.
17:33technomancysince there's only two functions in it
17:33technomancystuartsierra: want me to make an issue+patch?
17:34stuartsierraDo you have a CA? Or commit access on contrib?
17:35technomancyjust a CA
17:36stuartsierraOk, you can make a patch or just email me the code.
17:37technomancyall righty
17:37technomancyjust for extract-jar right?
17:37technomancyI haven't written recursive copy yet
17:37stuartsierrayeah, sure
17:37stuartsierraWell hop to it, then! :)
17:38technomancyhehe
17:48replacastuartsierra: you're going crazy today!
17:49stuartsierraI'm shirking real work. :)
17:50replacayou and me both, man
18:00replacastuartsierra: can I add fnmap.PersistentFnMap to compiled_classes in build.xml (that's where I'm putting anything that needs to be gen-classed to help support the autodoc)
18:00replacaI think that's fix the fnmap autodoc
18:01stuartsierrasure
18:01replacak, thanks
18:04stuhoodi have 1 hour and 30 minutes to write a mapreduce job in clojure for the first time
18:04stuhoodlet's see how this goes.
18:05technomancystuhood: a hadoop mapreduce or just a pure-clojure one?
18:05stuartsierrastuhood: you've seen mine?
18:05stuhoodtechnomancy: using the hadoop api from clojure... we already have some base classes in java
18:05stuhoodstuartsierra: not yet... is it painful?
18:06stuartsierraThe Clojure part is easy. The Hadoop API is... dense.
18:06technomancystuartsierra: I read through yours. I think it would be super-helpful if you could make a blog post or something about how that works.
18:06stuartsierraI spent about a month learning Hadoop before I made serious use of it.
18:07technomancyreading the altlaw code was helpful, but trying to figure out which parts were specific to the task at hand vs which parts you need to copy was tricky.
18:07stuartsierratechnomancy: yeah, it's on my agenda for... July?
18:07technomancyheh; ok cool.
18:08technomancythe job input and output formats are a lot to wrap your head around too
18:08technomancyI just got my example to the point where it would run; didn't actually get it to produce meaningful output. =)
18:22stuartsierraGood luck. I'm off.
18:22triddelltechnomancy: just created a blog and updated my tutorial: http://riddell.us/blog/2009/06/05/tutorials-available.html
18:23triddellnow mentions you're approach
18:23triddellyour that is
18:24technomancycool
18:24stuhoodif you don't add a ':state true' clause to gen class, do you still get a 'this' parameter added to your method calls?
18:24hiredmanerm, I believe so
18:25technomancytriddell: I'm really _not_ trying to just drive hits to my blog, honest. It just comes off that way. =)
18:25hiredmanwait
18:25hiredmanstuhood: this is only in proxy
18:25triddelltechnomancy: just want the best info out there... that was my intent with the tutorial
18:25hiredmanfor gen-class the this parameter is explicit
18:26triddelltechnomancy: gotta run though... just wanted to give you and other an fyi
18:26technomancycool; have fun w/ your new blog
18:26triddelltechnomancy: thx ;-)
18:26hiredmanlike, a function backing a two arg method needs to have arity 3
18:26stuhoodhiredman: explicit, in that i have to ask for it by saying :state true?
18:26stuhoodgotcha
18:26hiredmanno
18:28rsynnotttechnomancy: so that you can make a VAST FORTUNE on google ads? :)
18:28technomancyrsynnott: you've found me out!
20:13mrsolohmm aquaemacs doesn't have locate-dominating-file ....
20:59dbudworthJust checking to see if my IRC client is functioning, no one is saying anything...right?
20:59ctdeanright
20:59dbudworthahh, good. thought i was crazy (or this mac irc client was)... (usually it's me)
21:00ctdeanJust the time and day I think, not much going on
21:06dbudworthany idea how to get the classpath set when using emacs-starter-kit + slime + swank-clojure? the username.el in .emacs.d is loaded too late it seems to take effect
21:06ctdeannope, sorry. I always set the classpath by hand
21:06dbudworthtrying to go through the "programming clojure" book, but when using slime I can't get the classpath to include the book root dir (which is needed for things like (use 'examples.foo)
21:07dbudworthyou can set it inside clj? is there a way to dynamically add to the cp?
21:07durka42yes and no, there is add-classpath but it's discouraged
21:07ataggarthighly
21:08dbudworthnormally, wouldn't even need it. but for this particular case (book examples) they make a big assumption about your working dir (or at least having the root be in the cp)
21:09ataggartskipping over and just using the book's repl.sh made life easier
21:09ataggartthough I haven't gotten too far into the books code
21:10dbudworthyeah, that was the other choice. just use a regular shell. just thought slime was neat. IntelliJ's clojure plugin actually has a repl (and the standard Idea project classpath setup).. just wanted to use emacs' fanciness
21:11ataggartbeing neither an emacs user nor lisper, having to deal with emacs as well as learn the language was just too much to bear
21:11ataggartnow I just need to figure out how to kill the IntelliJ REPL
21:12dbudworththere's a "delete repl" or something like that, that kills it... checking
21:15dbudworthtools -> add / remove reply (option-command-a/option-command-m on a mac)
21:15dbudworths/reply/repl
21:15ataggartah thx
21:16ataggartrunning doseq on an infinite fibonacci seq tends to bog things down
22:53mattreplanyone been using c.c.error-kit?