#clojure logs

2012-04-14

00:58scottjmuhoo: where the highest rated comments are about smalltalk or yc vs kickstarter.
01:05y3dimuhoo: he joined the ranks only few have reached before him
02:30muhooscottj: the kickstart vs yc flamewar was annoying. the smalltalk stuff was at least on-topic.
02:34muhooi have to say, the more i learn about and understand clojure, the more sourcecode i can actually read and understand, the more in awe i am of what frickin geniuses y'all are.
02:35muhoorather than taking the magic out of it, the more i understand of it, the *more* magical it seems.
03:05amalloyjayunit100: you can't splicing-unquote outside of a syntax quote, because that would be a single form "expanding" into multiple forms, which breaks pretty much everything about the reader
03:06amalloyyou can do it just fine inside of a syntax quote, because `(x ~@foo y) is still a single form - the syntax-quote is "taking responsibility" for the forms under it
03:07wkmanireHowdy folks.
03:07wkmanireWorking with clojure from my linux box for a (nice) change.
03:08wkmaniretechnomancy: You have these instructions for instaling swank-clojure. "Add [lein-swank "1.4.4"] to the :plugins section of either project.clj or your user profile."
03:08wkmaniretechnomancy: what do you mean by user profile/
03:08wkmanire?
03:12_atowkmanire: if you're using the Leingingen 2 preview version (which is where the profile stuff comes from) see the plugins section here https://github.com/technomancy/leiningen/wiki/Upgrading
03:13_atoif you're on Lein 1 just do: lein plugin install swank-clojure 1.4.2
03:15wkmanire_ato: All done.
03:15wkmanireI just jacked into my first clojure lein projuct.
03:15wkmanireI know kung-fu.
03:16_atowkmanire: congrats! :)
03:17muhoowkmanire: fantastic!
03:18amalloyhey, you got it to work
03:18muhoowkmanire: are you going to use a linux vm on your windows box for clojure stuff?
03:18wkmanire:)
03:19wkmaniremuhoo: No, I'll just work with inferior lisp.
03:19muhoothat's how i do it
03:19wkmaniremuhoo: My clojure installation on my windows box is for my 10 minutes here and there when I can't make myself stay on task for work.
03:19wkmanire10~cough 30 minutes.
03:19muhooi discovered the clj-stacktrace plugin, which is great in the shell, but looks like ass in comint-mode
03:20muhoothere has to be a way to turn off the damn colors, but i can't find that knob anywhere
03:20wkmanireI've never really used comint.
03:20muhooinferior lisp, i think, uses comint-mode
03:21muhooi have a clojure repl running on a machine out in the network, which i can connect to from connectbot on my phone
03:21muhoossh, really, and port forwarding to the repl
03:24wkmanire:D
03:25wkmaniremuhoo: I'm trying to understand the work flow here.
03:25muhoothere are lots of options
03:25wkmaniremuhoo: After I've spent a while hacking out some stuff in the REPL, is there a way I can export everything to a buffer?
03:25muhoosave it to a file
03:26wkmanireThe whole REPL session?
03:26muhooin your project
03:26muhoono, jsut the code you want to keep
03:26wkmanireSo I have to traverse my repl session and copy over what I want to keep.
03:26muhoohave a look at the structure of the skeleton file that "lein new" creates and you'll see it creates a core.clj file, for example
03:27wkmanireThere it is.
03:27muhoowhen i'm just playing around in the repl, i just save the buffer in emacs as my "notes"
03:27muhooas like "playingaround.clj"
03:27wkmanireThat sounds like a good idea.
03:28wkmanireIt'd be nice if I could tell it to grab everything in namespace x and save it to file xyz.clf
03:28muhoothen, when i decide to write some actual code, i think about the structure of namespaces, etc, and put things in a more sensible place
03:28wkmanireclj*
03:28wkmanireI could see namespaces being used in the repl to organize your "thoughts"
03:28muhooyou could probably write some clojure to do that :-)
03:29muhooit's worth reading up on namespaces and what they are, what they do.
03:29wkmanireI read what was written in chapter 1 of Cemerick's book on them.
03:29amalloywkmanire: i generally write anything i might conceivably want to save (ie, everything) in an emacs buffer, and send it to the repl with C-M-x or whatever
03:30wkmanirehmm
03:31amalloyyou can use *scratch* for that buffer if you don't want to "commit" to writing a real file :P
03:31wkmanireGood points.
03:32muhoocraig andera's talk at cljwest on namespaces was good too.
03:32muhooidk if the video is up though.
03:35muhoobasically "require" means "load", "refer" means bring everything from another namespace into the current one, "use" means "require + refer", and he also explains what the (ns) macro does and why.
03:35muhoomight be readable from here: github.com/strangeloop/clojurewest2012-slides
03:36wkmaniremuhoo: Thanks for the link.
03:37wkmanirewhew, my to read favorites list is getting longer and longer.
03:39muhooarrrgh, clj-stacktrace is included in lein 1.7.1, or is otherwise being brought in from somewhere else
03:39muhoocurse you, ted turner!
03:40muhooyep, included in lein. search and destroy time
03:41muhoohmm, no wait, it's not. odd. it's coming from somewhere, i'll find it
03:42muhoohehe, it's hidden inside lein-cljsbuild
03:43muhooand swank-clojure :-/
03:44wkmanireuh oh.
03:44wkmanireGuess I shouldn't try to use read-line from the slime-repl.
03:45muhoono, readline and emacs aren't good together
03:46muhoocool, removed a bunch of lein plugins, and now i have my non-color hack of clj-stacktrace working. i win.
03:47muhoowkmanire: i generally use this elisp to launch a repl: https://refheap.com/paste/2110
03:48wkmanireI see.
03:48muhooif you do M-x ielm, get an elisp repl, dump that code in there, then you can do "M-x lein-local" and start up clojure from that
03:48muhooit's hacky but it works for me
03:48wkmanireThats alright, I just popped open a terminal window and ran clojure code.clj...
03:48wkmanireit worked great
03:48wkmanireI read a line of text from stdin and crapped it back out.
03:48muhooor just add that to your .emacs
03:49muhoonice.
03:49wkmanireNow that I can talk to the keyboard and the hard drive I can start playing.
03:50muhooyeah, there's always cut-and-pasting
03:50muhoo&"hello wkmanire"
03:50lazybot⇒ "hello wkmanire"
03:51wkmanire&(let [x (read-line)] (print x))
03:51wkmanirehe he
03:51wkmanirethought that might get ignored.
03:52lazybotExecution Timed Out!
03:52wkmaniresweet
03:52muhoohaha
03:54amalloy&(binding [*in* (java.io.StringReader. "hello wkmanire\nmore text here\n")] (doall (repeatedly 2 read-line)))
03:54lazybotjava.lang.SecurityException: You tripped the alarm! pop-thread-bindings is bad!
03:54amalloy,(binding [*in* (java.io.StringReader. "hello wkmanire\nmore text here\n")] (doall (repeatedly 2 read-line))) ;; i hate you, lazybot
03:54clojurebot#<ClassCastException java.lang.ClassCastException: java.io.StringReader cannot be cast to java.io.BufferedReader>
03:54amalloyand also i hate java, apparently
03:57wkmanireamalloy: excellent attempt all the same.
04:00muhoo&(doto (Thread. #(println "woo hoo")) .start .join)
04:00lazybot⇒ #<Thread Thread[Thread-7006,5,]>
04:11andyfingerhutIs this a game of abuse-the-lazybot?
04:57laurusWhat do I do in leiningen if I want to include a .jar file that is not available through Maven?
05:00scottjlaurus: install it in your local maven repo ~/.m2
05:01muhoowell, use lein local-repo plugin, even better
05:01laurusscottj, what do you mean "install it"?
05:01muhoohttp://www.google.com/url?q=https://github.com/kumarshantanu/lein-localrepo&amp;sa=U&amp;ei=ejuJT-aVOsSdiQKwsrX2Cw&amp;ved=0CBAQFjAA&amp;usg=AFQjCNGP89lrjM3tY7LZZxFD9jRSUUMujw
05:01muhoogawd DAMN google
05:01muhoohttps://github.com/kumarshantanu/lein-localrepo
05:01laurusmuhoo, ah, thanks.
05:02muhoonp
05:02scottjlaurus: there's a long mvn command maven spits out occasionally in errors, muhoo's solution is probably better though
05:02laurusOh, I am using lein 2. That's why I couldn't install it maybe?
05:04laurusMaybe I should use scottj's solution?
05:04muhoolein2 might have it built in?
05:04laurusmuhoo, when I type "lein plugin install ..." I get "That's not a task."
05:05muhooah, lein2 has different plugin install system
05:05scottjlaurus: http://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html
05:05laurusscottj, I'll use that, thanks.
05:05laurusmuhoo, I see.
05:05muhoolaurus: youadd it to ~/.lein/profiles.clj:
05:06muhoo{:user {:plugins [[lein-newnew "0.2.6"]]}}
05:06muhoowell local-repo, not newnew, but that's the basic thing
05:06laurusmuhoo, ah, ok.
05:06laurusI'm sure I'm not the first person to say this, but all of this is quite complicated.
05:07muhooso i guess add {:user {:plugins [[lein-localrepo "0.3"]]}} to ~/.lein/profiles.clj
05:07muhooyeah, it's complicated, but i find it less so than maven or ant
05:08laurusmuhoo, what do I do after creating that file and adding that line?
05:08muhooi'm new myself 220 hours into learning clojure, just starting to get comfortable with it
05:09scottjlaurus: btw, if you put the jar in your project.clj then lein deps will show you the maven error where it gives you the exact command to run
05:09muhoolein2? i use lein 1.7.1 so i'm not sure if it behaves differently
05:10muhooin 1.7.1, if you have added the plugin, you can do
05:10muhoolein localrepo install <filename> <[groupId/]artifactId> <version>
05:10muhooprobably same for lein2
05:11muhoofor example, i did
05:11muhoolein localrepo install osc-0.7.1.jar local.repo/osc 0.7.1
05:11laurusWhat is this group and artifact stuff?
05:11muhoomaven stuff
05:12muhooit's like a fqdn
05:12laurus"java.io.FileNotFoundException: Could not locate leiningen/util/maven__init.class or leiningen/util/maven.clj on classpath."
05:13muhoohmm, maybe lein localrepo doesn't work at all with lein2.
05:13laurusOK! I will do the "manual" way then.
05:14muhooyeah, can't argue with that :-/
05:15scottjlaurus: I think you can give it whatever group and artifact you want, you'll just have to use that in your project.clj. (someone correct me if wrong here)
05:15muhoooic, lein localrepo has been updated for lein2, in git: https://github.com/kumarshantanu/lein-localrepo/commit/4b69d19b41000f0495441c79eb33db1f53e29da1 but not in the released version yet
05:16scottjlaurus: in project.clj it's [group/artifact "version"] you're probably familiar with that. just fill in the blanks on mvn command
05:16laurusOK, thanks!
05:18laurusWhat should I use for a groupId?
05:18laurusI mean, what is recommended?
05:19scottjsomething descriptive of jar, "laurus" or "org.lauruswebsite" if it's yours
05:20scottjdescriptive or organization that made the jar that is
05:20laurusAh, I see.
05:20laurusThanks!
05:20laurusAnd by the way, what should I put for "packaging"?
05:21scottjjar
05:21laurusThanks :)
05:22laurusBy the way, how do I install Maven so that it will work with Java 7? I am on Debian GNU/Linux.
05:24laurusIs there a way to set which version of Java Maven uses, or is that somehow "built-in"?
05:28helinohi everyone, I'm trying to do some we development using ring, but when I run "lein ring server" using leiningen, I get a ClassCastException. How do I debug this?
05:28scottjhelino: pastebin the entire error
05:29_atolaurus: set the JAVA_HOME environment variable
05:29laurus_ato, thanks.
05:30helinoscottj: http://pastebin.com/qdk07Bcr
05:31scottjhelino: lein --version?
05:32helinoscottj: Leiningen 1.7.1 on Java 1.7.0_03 Java HotSpot(TM) Client VM
05:33helinoscottj: here is the project.clj file: http://pastebin.com/xjbHxCSx
05:35_atothe :ring option needs to be a map I think. At least the example in the lein-ring readme is :ring {:handler hello-world.core/handler}
05:36helino_ato: yes, that was it!
05:36helino_ato and scottj, thanks for your help!
05:38scottjhelino: get a better font :)
05:38scottjsmallest terminus makes very hard to see diff between ( and {
05:39laurusGot the jar installed. Thanks scottj and muhoo!
06:15laurusBy the way, does anyone here use clojure-py?
06:15fliebellaurus: I think it's a bit early to use it, but experiment, yes.
06:16laurusfliebel, to be honest I'm excited about it!
06:16fliebelI was tempted to rewrite a pice of Python software in it, but didn't.
06:16laurusWell why not? :)
06:17fliebelBecause not even all the core functions are there yet, let alone the libraries.
06:17laurusWow. I wish I could donate some money to that project or something.
06:18samaaronfliebel: hey there - how did you send me a mail via lazybot - that's cool
06:18samaaronis that automatic?
06:18fliebellaurus: If yu asked, them, they would probably let you buy them a coffee or bear, i guess, but I think it would be mroe helpfull to take a fn from https://github.com/halgari/clojure-py/blob/master/clojure/untranslated.clj and port it.
06:19fliebelsamaaron: $mail username message ;)
06:19samaaronthat's awesome
06:20samaaronso you do it without the $?
06:20fliebel?
06:20samaaron$mail fliebel hello there - do you read me?
06:20lazybotMessage saved.
06:21samaaronah, got you
06:21samaaronyou were able to use the full command because you prefixed your string with my username
06:21samaaronthis is insanely cool
06:21samaaronlazybot: ftw!
06:22fliebelsamaaron: I ended up using Python though, because I failed horribly at making RxTx work.
06:22samaaronfliebel: but to answer your message, I the RxTx thing only has serial libraries
06:22samaaronand it really is a horribly cobbled together mess
06:22samaaroni tried sooo many different compiled versions before i found one that worked
06:22samaaronand i couldn't compile the beta versions myself
06:23samaaronit was all a real nightmare
06:23fliebelsamaaron: Does RxTx only have serial, or your version?
06:23samaaronso it only has serial natives
06:23fliebelsamaaron: Have a look at PureJavaComm. same API, no natives... only serial :(
06:24samaaronoh nice
06:24samaaroni wonder how effecient it is
06:24samaaroni'm having issues with my monome library with message throughput
06:24samaaroni'm not sure where the issue is
06:24samaaronit will be useful to test out with other libs
06:25fliebelsamaaron: Don't know. It's a JNA wrapper over Terminos, while RxTx uses it via C.
06:25fliebelsamaaron: At which baud rate does the monome run?
06:27samaaronfliebel: to be honest, i'm not exactly sure
06:27fliebelI needed to get my DPScope to work at 500000 baud, which didn't work with any Java lib I tried.
06:27samaaronoh wow
06:27samaaronso what did you end up using?
06:28fliebelPython, as I just said to laurus. Tempting to go for clojure-py though...
06:28samaaron$mail TimMc I totally agree with you regarding Overtone docs. All it needs is someone to make it happen :-)
06:28lazybotMessage saved.
06:29samaaronhow annoying that the JVM can't do something python can
06:29laurusfliebel, I am a beginner at Clojure so I don't think I can contribute to that project though, yet.
06:29fliebelsamaaron: Rather, that the Mac implementation of Terminos doesn't support it. PySerial uses some custom command on Mac to se the baud rate.
06:31fliebellaurus: Porting functions from untranslated.clj shouldn't be to hard, if you stay away from the ones involving concurrency.
06:31samaaronah ok
06:32laurusfliebel, well I will take a look! Thanks for the encouragement.
06:32fliebellaurus: That is, if you know Python. Most of it is just javaisms that need to become pythonisms.
06:33samaaronfliebel: this purejavacomm project looks interesting
06:35samaaronfliebel: so i noticed you threw a commit at them - did you get things working?
06:37fliebelsamaaron: I don't know... I copied what PySerial did, and it it is not completely broken, but it doesn;t work with the DPScope either.
06:37samaaronfair enough
06:38samaaronif i had any further issues with rxtx, my next plan was to wrap up the binaries shipped with Processing
06:38samaaronto be honest, it's super frustrating that there's no standard serial lib shipped with the JVM
06:39fliebelsamaaron: https://github.com/nyholku/purejavacomm/issues/4
06:39fliebelsamaaron: It would be great if you had any serial device around to verify the change is broken or not.
06:42samaaronfliebel: do you have an example of using this lib?
06:42samaaronthat i could just hack with and hook my monome up with?
06:43samaaroni'd love to say goodbye to rxtx
06:44sandbagsguess it's old hate for you guys but i just saw the lighttable demo, pretty nice
06:44fliebelsamaaron: The pull request has my example code: https://github.com/nyholku/purejavacomm/pull/5
06:44sandbagsas someone just getting in to learning clojure, that looks like it would be useful and fun
06:44samaaronfliebel: cool, thanks
06:45samaaronfliebel: btw, I only today realised that you're Pepijn
06:45fliebelsamaaron: It's the same api, just a different namespace.
06:45samaaroni'm terrible with names :-)
06:45fliebelsamaaron: Yea, for historical reasons, this is the only place on the internet my nick is fliebel. Tried to change it once, didn't work well.
06:46samaaronhaha
06:46samaaronoh damn, this API is *nice*
08:12samaaronfliebel: how did you pull down purejavacomm via lein?
08:13fliebelsamaaron: He has his own maven repo, it's on his homepage.
08:13samaaronI tried this to no avail: https://refheap.com/paste/2111
08:13fliebelsamaaron: Just this part: "http://www.sparetimelabs.com/maven2/&quot;
08:14samaaronah cool
08:14samaaronhmm, doesn't seem to work either
08:15samaaroni must be doing something wrong in my project.clj
08:15samaaronit now looks like this: https://refheap.com/paste/2113
10:16yoklovwow, cljs.core.str is very slow.
10:18yoklovmuch slower than (.join (array …) "")
10:19yoklovat least, in chrome.
10:24khaliGI'm wondering how to use this http://clojuredocs.org/clojure_contrib/clojure.contrib.io/write-lines in 1.3?
10:29yoklovHm, you could do (spit the-file (apply str (interleave my-seq (repeat "\n"))
10:30yoklovthough that function is probably somewhere now.
10:30TimMclazybot: Mail for me?
10:30khaliGi've got a hacky version of it but i'd rather use a standard one if it exists? :/
10:30yoklovcontrib is gone
10:30khaliGyoklov :(
10:31yoklovkhaliG, i know its hard, but it's better this way
10:33yoklovyeah i don't think that function made the cut for clojure.java.io
10:34khaliGfair enough, i'm just going to append some "\n"s and then join them together for spit
10:40yoklovyou could also do (cl-format the-file-writer "~{~A~%~}" the-seq)
10:40llasram`Oh yeah, as far as I can tell, all the functions which try to make lazy seqs work with automatically opening and closing files are gone
10:40yoklovafter (use 'clojure.pprint)
10:41llasramThis one doesn't look unreasonable, but read-lines was a file leak waiting to happen
10:41yoklovthat's probably a good thing, sounds like you might run into issues if you dont wrap it in (doall) or something
10:43yoklovkhalig, you could also bind *out* and (dorun (map prn …))
10:43yoklovor println
10:44khaliGyoklov, cheers, thanks for the help :)
10:44yoklovgotta say, i've never had to use it but i'm glad that cl-format is available should i want to replace a loop with a small and unreadable format string
10:45khaliGyoklov, is that from CL?
10:45yoklovit is
10:45khaliGoooh
10:57LauJensenDo we have an fn like .replaceAll, but which takes a pattern instead of a concrete string?
10:59llasramLauJensen: ##(doc clojure.string/replace)
10:59lazybot⇒ "([s match replacement]); Replaces all instance of match with replacement in s. match/replacement can be: string / string char / char pattern / (string or function of match). See also replace-first."
11:00LauJensenExactly what I needed, thanks llasram
11:01llasramnp :-) For future reference, you might find the `clojure.repl/find-doc` macro useful. Also, http://clojuredocs.org/
11:02LauJensenNaah, #clojure is my find-doc, usually has better info :)
11:04xeqitheres also $findfn
11:04xeqi$findfn "asdfxx" #"x" "s" "asdfss"
11:04lazybot[clojure.string/replace]
11:11llasramI always forget about one
11:15mdeboardWhat exactly does clojure.java.io.resource do ? I'm looking at a code snippet here, and trying to reference the API
11:15mdeboardbut the API isn't much help
11:15mdeboardsnippet https://gist.github.com/cad792af9612ddcc060a
11:15mdeboardlines 14-16
11:16mdeboardI'm only familiar with reader/writer from that module
11:17yoklovthat gets the file at "testdata/mol-1000.txt" in the classpath
11:17mdeboardOh I see, returns nil ?
11:17yoklovresource returns the url i think
11:18mdeboardhm
11:18xeqiit will return nil if it can't find it
11:18mdeboardI see
11:18xeqiare you using lein?
11:18mdeboardOh, so even if I provide an absolute path it stil must be on project class path
11:18mdeboard?
11:18yoklovprobably not
11:19yoklovbut you wouldn't use resource
11:20mdeboardxeqi: Yes, I'm using lein
11:23xeqilein uses "resources" as the directory on the classpath by default
11:26mdeboardxeqi: I actually have no such directory, but I see it in the output of `lein classpath`. That snippet I linked is actually someone else's that I'm trying to adapt for my own purposes. Where should this text file sit ?
11:28xeqitest-resources/testdata/mol-1000.txt should work
11:28xeqisince it's test data
11:30mdeboardWell, here's what I'm actually trying to execute https://gist.github.com/45ffc442e4a5f018536b
11:33xeqiI'd recommend moving access.upstream.log.sample into your resources dir
11:33xeqior just using clojure.java.io/file
11:35mdeboardOh, I see, it seems that (resource) fetches the absolute path?
11:36mdeboard(moving to resources and calling `(as-file (resource "access.upstream.log.sample"))` returned `#<File /home/matt/matts-hadoop-interview-test/resources/access.upstream.log.sample>`)
11:37xeqiresource looks through the classpath for the file, and returns a URL to it
11:37xeqiits useful for loading non-source files from a jar
11:38mdeboardGotcha, so could I have just used `(as-file "/absolute/path/to/file")`
11:38xeqiyeah
11:38mdeboardGotcha
11:38xeqiresource is more useful for loading something like images from the classpath
11:43gfrederickswhat's that function that lets you combine predicates in an or fashion?
11:44mdeboardxeqi: Thanks for your help, I was stuck.
11:44xeqior fashion?
11:45RaynesMorning sirs.
11:45gfredericks(def boolean? (or-pred true? false?))
11:45gfredericksRaynes: I woke up this morning wondering why lazybot couldn't allow eval in a recursive fashion
11:46RaynesI was pondering the meaning of the life, but that's cool too.
11:47Raynesgfredericks: What do you mean?
11:47wkmanireMornin' folks.
11:48gfredericksRaynes: I mean if you redef eval to defer to clojail, then I could enter ##(eval '(+ 3 4)) and it would recursively pass the (+ 3 4) back to the clojail-eval mechanism
11:48lazybotjava.lang.SecurityException: You tripped the alarm! eval is bad!
11:48xeqi&((some-fn true? false?) false)
11:48lazybot⇒ true
11:48gfredericksxeqi: dat it
11:48gfredericksthx
11:50Raynesgfredericks: That might be possible.
11:50Raynesgfredericks: Open an issue on clojail about it.
11:50gfredericksokay.
11:51gfredericksdone.
11:54gfredericksI'm working on a macro that allows unquoting just to prove it can be done
12:09yoklovanybody know if cljs's (set! obj.prop val) is supposed to work? looking through the compiler it seems like it might just... happen to work
12:12yoklovhappen to work in such a way that it wouldn't work after being closure compiled
12:27Hali_303hi! I've just read that defrecords cannot act as functions like regular maps. why is that? isn't that problematic, since much code already uses the (map :akey) notation in code?
12:28yoklovi'm not sure that that's true
12:28yoklovhm, seems to be, actually
12:28yoklovwell, you can do
12:29yoklov,(do (defrecord Test [a]) (:a (Test. 4)))
12:29clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
12:29yoklov:(
12:29yoklovwell, that returns 4.
12:29yoklovits not much help for you but it might ease porting.
12:31gfredericksthis has been talked about before; I don't remember the reasoning
12:31gfredericksmight just be to allow other impls of IFn
12:31gfredericksspeaking of which you can probably implement it explicitly
12:31Hali_303yoklov: yeah it works the other way around
12:31yoklovyeah
12:31yoklovoh
12:32yoklovyou can do (defrecord Test [a] clojure.lang.IFn (invoke [this a] (get this a)))
12:32yoklovthen ((Test. 4) :a) will work.
12:32Hali_303whoa, nice :)
12:32ibdknoxwow, dnolen wasn't kidding about doubling my karma
12:33yoklovthats probably not particularly clear because i used a as both a property of Test and the argument to invoke but… yeah.
12:33Hali_303I'm curious what's the official take on this though
12:33yoklovHali_303, I think gfredericks is right.
12:33yoklovits to allow other impls. of IFn
12:34yoklovand if you want the map-like behavior you should explicitly implement it (as above)
12:39yoklovibdknox: you might know, does (set! foo.bar val) work in cljs due to the compiler just emitting exactly "foo.bar = val" or is it actually supposed to work?
12:41wkmanireIs it common for clojure code to be full of Java objects?
12:41llasramwkmanire: It depends on what you're doing. I'd say it isn't uncommon for it to be full of Java objects
12:41wkmanireLet's say I wanted to make a simple CRUD application (don't really wish that on anyone)
12:42wkmanireAn address book that stores information in an SQLite database
12:42wkmanireand provides as simple GUI.
12:42wkmanireWould I be able to do that without newing up a java object?
12:42wkmaniredirectly that is.
12:43ibdknoxyoklov: it works accidentally intentionally I think ;)
12:43yoklovwkmanire: you should use clojure/java.jdbc for the SQL, but the gui portions you will either end up using java objects directly or using a lib like seesaw
12:43lucianwkelly: if you choose the right libraries, probably
12:43llasramwkmanire: Probably not 100%, but mostly. There are nice Clojure bindings for e.g. JDBC SQL and Swing
12:44yoklovibdknox: yeah, i thought so, darn.
12:44mfexyoklov, set! is used a lot in clojurescript itself
12:44ibdknoxyoklov: it won't disappear
12:44llasramwkmanire: That said, unless you're writing code that you want/need to be portable across Clojure implementations, avoiding direct platform interaction for the sake of avoiding it is just shooting yourself in the food
12:44ibdknoxthere's no reason for it to
12:45wkmanirellasram: What a waste of nutrition.
12:45llasramha!
12:45llasrams,food,foot, :-p
12:45yoklovibdknox: it seems like it might be a thing that breaks after the code is closure compiled though
12:45ibdknox?
12:45yoklovactually no, that doesn't make sense.
12:45ibdknoxyeah, that'll be fine
12:45mfexyoklov, it doesn't break clojurescript itself when advanced compiling, so it's save
12:46llasramClojure is designed for solid interop, and it works great. Obviously there are benefits to re-using cleaner abstractions when available, but being able to use rock-solid Java libraries is one of the big benefits of Clojure
12:46yoklovit doesn't work if the var is top-level, as opposed to a let.
12:46yoklovor at least, didnt' used to.
12:46wkmanireWell, one of the draws of clojure is its practicality so going out of my way to avoid using Java interop doesn't make sense.
12:46wkmanireBut I have to admit, reading nice pretty clojure code and then all of sudden running across java.something.something.ANewOneOfThese.
12:47wkmanireIs like putting salt in your coffee.
12:47yoklovwkmanire: well, you can put (:import [java.something.something ANewOneOfThese]) and then just do (ANewOneOfThese.)
12:48yoklov* put in your ns form
12:48wkmanireThat's be a lot better actually.
12:48dnolenibdknox: pretty crazy 1200+ on HN and 1500+ on reddit. congrats!
12:48dnolenibdknox: now what? :)
12:48ibdknoxdnolen: that's a very good question
12:49ibdknoxI applied to YC with a very different idea
12:49ibdknoxI mostly did this thing on a whim
12:49ibdknoxWith the intent primarily of throwing some ideas out there
12:49ibdknoxbut judging by the response, this would be worth a lot of money to a lot of people
12:49dnolenibdknox: I think so.
12:50dnolenibdknox: also much better learning environment than this codeacademy codeschool crap
12:50ibdknoxhaha my first idea before the medical one was Kodowa
12:50wkmanireibdknox: Talking about lightbox?
12:50ibdknoxan environment to teach you how to code
12:50ibdknoxwkmanire: Light Table
12:50wkmanirelighttable
12:50wkmaniresorry
12:51wkmanireibdknox: Any plans for a part 2 of your video?
12:51wkmanireI'd really like to see more about that last view you presented.
12:51ibdknoxI think if there were to be a part 2 it would be showing it working in JS
12:51wkmanireActively showing how what you're hacking on affects the rest of your code.
12:52mdeboardI didn't realize that was ibdknox
12:52mdeboardI didn't even watch the video
12:52ibdknoxdude
12:52ibdknoxhow could you not watch the video? :p
12:52ibdknoxhaha
12:52wkmanireCan't believe I said light box. That cheesy javascript image display that ended up on half of the internet for a few years.
12:52mdeboardI'm typical internet person
12:53ibdknoxdnolen: biggest bang for the buck would be JS don't you think?
12:53dnolenibdknox: yeah definitely should target JS.
12:53ibdknoxI might kickstarter it just to see what happens
12:54dnolenibdknox: there's lots of really fast JS parsers in JS now that generate JSON AST. Now's a good time to try it.
12:54ibdknoxI looked at esprima, any other suggestions?
12:54ibdknoxEsprima looked good
12:54dnolenibdknox: esprima was the new hotness at JSConf
12:54ibdknoxk
12:55ibdknoxlonger term I was thinking closed source until launch, then open maybe with a pay what you want model (assuming kickstarter can make it worth the time I'd have to put into it)
12:56ibdknoxhopefully open source and money don't have to be mutually exclusive lol
12:57wkmanireibdknox: If your IDE is well accepted and becomes a standard tool
12:57wkmanireit'll get stolen one way or another.
12:57ibdknoxyeah
12:58wkmanireMicrosoft manages to get around that by sueing their customers.
12:58wkmanire:D
12:58ibdknoxlol
12:59wkmanireibdknox: What about making it an HTML5 app?
12:59ibdknoxit *is* one :)
12:59wkmanireSo you can start a subscription service.
12:59ibdknoxeh
12:59wkmanireand have levels of features.
12:59ibdknoxyou want to run it locally
12:59ibdknoxreal-time + internet = meh
13:00ibdknoxreal-time + 0latency = win
13:00dnolenibdknox: I would at least try putting it on KickStarter. If you say you will open source it and it will target JS who knows what could happen?
13:01ibdknoxdnolen: yeah, very ambiguous territory
13:01wkmanireibdknox: :) Well one way or another I hope you make money off of it.
13:01wkmanireI want to see people make money for good ideas open-source or not.
13:01wkmanireI'm all for open source but programmers have to eat.
13:03dnolenibdknox: one question is whether you actually want to write the whole thing in JS :)
13:05devnibdknox: id drop a dime into a kickstarter for light table fwiw
13:05mdeboardYeah, ditto.
13:05mdeboardA literal dime, but.
13:06devnibdknox: as long as clojure/script is the first environment and js the second :)
13:06ibdknoxdnolen: yeah, that's the question
13:06yoklovcouldn't you write it in cljs and target js?
13:06mdeboardI'd like to get kenneth reitz, ibdknox and mitchell hashimoto together in a single company
13:06dnolenibdknox: personally I'm not excited about writing big projects in JS anymore.
13:06dnolenibdknox: I do not envy the Meteor guys at all.
13:07ibdknoxdnolen: I never was ;)
13:07dnolenibdknox: wise man
13:07ibdknoxdnolen: I don't have to write it in JS really, just a JS parser service backend
13:07ibdknoxthe cool thing is that the interface will be scriptable in anything that compiles to JS :)
13:07ibdknoxso clojurescript and JS get to work together mostly for free
13:08dnolenibdknox: definitely - but that might probably limit the JS OSS interest.
13:09dnolenibdknox: might not matter at all as long as people can extend via pure JS.
13:09ibdknoxthe architecture I was thinking of would extremely plugin oriented so you could just right your own thing to replace the ClojureScript one if you wanted all JS all the time
13:10dnolenibdknox: ok that's pure win then.
13:10ibdknoxwow that was full of fail. would be* write*
13:10dnolenibdknox: that would be a real gift to JS and CLJ/S
13:10ibdknoxdnolen: yeah
13:10yoklovif you did it in cljs it would boost interest in cljs
13:10ibdknoxit would help everybody
13:10ibdknoxyoklov: definitely
13:11dnolenibdknox: so Noir on Node? ;)
13:11ibdknoxhaha
13:11ibdknoxdo you know if there's a packaging story for the node runtime yet?
13:11ibdknoxthat's the one thing I'm worried about
13:13dnolenibdknox: not really. No one's owned the Node stuff, it could be really awesome I think.
13:14ibdknoxdnolen: hm have to figure out a lot there then :/
13:14dnolenibdknox: what packaging issues do you forsee?
13:17ibdknoxdnolen: nothing specific: just distributing the binary (for each platform) and such
13:18ibdknoxjust a use case that I don't think anyone's had yet and that makes it a little scary - it's always that last 20% that kills you
13:18ibdknoxlol
13:18Hali_303when in emacs REPL, how to make it forget all uses and requires? just as if I've restarted it
13:22dnolenibdknox: well with CLJS you can avoid Node's module system for you own stuff. The only missing bit I think is a good Node REPL, which at most a couple of days of focused work.
13:24ibdknoxso you don't think the distribution will be a problem then? I remember always having to build from source
13:24dnolenibdknox: oh - but as far as shipping Light Table I'm not sure there's much else you would need beyond what CLJS provides.
13:24dnolenibdknox: Node?
13:24dnolenibdknox: binaries for all major platforms now.
13:27ibdknoxah, well then I'm not worried about that anymore
13:50yoklovwell this might be/is an really noobish question but, i'm making a (totally static) cljs page and i'm getting a security error because i'm trying to load an image from elsewhere (e.g. in a local subfolder) and get it's imagedata. I know from experience that this is because i'm not serving anything and i'm just loading the html into my browser, so… what's the best way for me to serve a few static files locally?
13:57dnolenyoklov: probably ring or noir
14:01ibdknoxyoklov: hm.. as long as it's relative to the current file, that should just work
14:02yoklovibdknox: nope. I've had this issue before too
14:02ibdknoxhm
14:02clojurebotexcusez-moi
14:02yoklovit works if served but gives me "Unable to get image data from canvas because the canvas has been tainted by cross-origin data." and "SECURITY_ERR: DOM Exception 18"
14:02yoklovotherwise
14:02ibdknoxbah, stupid browsers
14:03yoklovyup.
14:03ibdknoxwell lein noir new blahblah and drop it in resources/public/ and you're done
14:04ibdknoxthen just go to localhost:8080/myhtml.html
14:09yoklovi actually ended up just using a 6 line node.js script to serve the files, noir seemed like overkill
14:10muhoois there any facility in either lein1 or lein2 to specify :repl-port as a per-USER configuration variable instead of per-project?
14:10yoklovstill, thanks
14:22ibdknoxwell
14:27ibdknoxI think light table is going to happen :)
14:27ibdknoxwith a vision far larger than even the ultimate IDE
14:29crassusibdknox: that's awesome
14:30eggsbyibdknox: SMALLTALK DID IT FIRST!
14:30eggsby:p
14:30ibdknoxman
14:30ibdknoxthat stuff kind of pissed me off
14:30ibdknoxlol
14:30ibdknoxThey didn't do it. If they had, we'd all be using it ;)
14:31ibdknoxI think people underestimate the value of execution when they see such things
14:31ibdknoxof course, now I have to execute to prove that :)
14:31eggsbymeh, if anyone can it's you, certainly have the track record for it
14:36ferdibdknox: yes! you read my mind. Go for kickstarter!
14:36muhoowell, smalltalk did do a lot of it, but it was UGGLAY.
14:37ibdknoxmuhoo: the design of the thing is the thing (to me)
14:37muhooevery used squeak? it's like 80s retro night
14:37ibdknoxhaha
14:38ibdknoxwow
14:38ibdknoxa friend asked me in how many countries that post has been seen in
14:38mdeboardall
14:38ibdknoxthe answer is 156
14:38muhoomost of technology goes in circles. people rediscover and reinvent stuff that existed generations ago. but with a new look, and a new flavor.
14:39ibdknoxthe only large-ish landmasses not accounted for are in central africa
14:39muhoolook, we are using a lisp, ffss!
14:39ibdknoxlol
14:39Bronsalol
14:40muhooso, this is the right time for this. you're in for a wild ride.
14:41ibdknoxindeed
14:42ibdknoxit'll be interesting
14:45ferdso? where's the kickstarter link? The closest match for "light table" is a bed lamp
14:45muhoocompaare and contract lighttable with this: http://bace.s3.amazonaws.com/itwasdonefirst.jpg
14:45muhoocontrast, feh
14:45ibdknoxI would argue that doesn't accomplish the same thing
14:47fliebelsamaaron: Did you find a solution for the serial thing?
14:47muhooit's a non-debate really, anyway, a hipster-ish kind of complaint "i was into it before it was cool!"
14:48ibdknoxhaha
14:48ibdknoxvery true
14:48ibdknoxdamn those smalltalk hipsters ;)
14:49muhoogood luck. success often finds people in places they least expect it.
14:55ibdknoxhttps://twitter.com/#!/ibdknox/status/191236200768610305 :)
14:57LauJensenFine, now kickstart it
14:57radsibdknox. like. I will contribute when the kickstart is up
14:58LauJensenDid you guys catch the Pebble project on Kickstart?
14:59ibdknoxyep
15:03ferdibdknox: I guess you've seen Code Bubbles? http://www.andrewbragdon.com/codebubbles_site.asp just for ideas
15:10autodidaktoferd: ibdknox's voice is much better than the Code Bubbles guy. That's how I decide IDEs, anyway
15:12ferdautodidakto: #-)
15:12gfrederickswhat is a good name for a macro that is like quote but allows ~ and ~@?
15:14xeqilike syntax-quote?
15:14gfredericksbut without the expansion and the foo# stuff
15:15autodidaktoDon't be shy -> fred-quote
15:15gfredericksha
15:15gfredericksquoot
15:16xeqiunhygienic-quote ?
15:16ferdsoft-quote
15:16gfredericksdirty-quote
15:16gfredericksferd: is there something by that name in scheme?
15:16ferddunno
15:16gfredericksgoogle time
15:16gfredericksman that's a worthless search term
15:21ferdregarding quoting: '() is to (quote) as ` is to ... ?
15:21Bronsathere is no macro equivalent
15:21gfredericks&(read-string "`()")
15:21lazybot⇒ (clojure.core/list)
15:22Bronsa` is hard-coded in the reader
15:22xeqiferd: http://stackoverflow.com/questions/3704372/how-does-clojures-syntax-quote-work
15:22gfredericksbut the unquoting feature can be extracted
15:23ferdthanks... hmm that's cheating ;-)
15:27gfredericksthere's always qu00t
15:28ferdgfredericks: misquote
15:28gfrederickshaha
15:28ferdgfredericks: or... scare-quote
15:28gfrederickso_O?
15:28gfredericksoh scarecrow
15:29ferdahh, no... a scare quote
15:29ferdgoogle for it
15:30gfredericksthat is an odd thing to not know about
15:30ferdgfredericks: hey... and English not my native language
15:30gfrederickssometimes that can make you more attentive
15:31ferdgfredericks: it's not that I "think out of the box"... I AM outside of the box ;-)
15:32gfredericksheh
15:32ferdok then, I vote for "misquote"
15:33gfredericksokeedoke
15:33ferdI like soft-quote, but is too formal
15:33gfredericksthe other choice was ##(format "lib-%04d" (rand 10000)), which is what I normally name things
15:33lazybotjava.util.IllegalFormatConversionException: d != java.lang.Double
15:33gfrederickswut
15:33gfredericksthe other choice was ##(format "lib-%04n" (rand 10000)), which is what I normally name things
15:33lazybotjava.util.IllegalFormatWidthException: 4
15:34gfredericksI give up
15:37mfexgfredericks, look into gensym
15:37gfredericksthe function?
15:37mfexyeah for the lib-%04d stuff
15:37ferdgfredericks: it's rand-int
15:38gfredericksferd: oh duh
15:38ferd##(format "lib-%04n" (rand-int 10000))
15:38lazybotjava.util.IllegalFormatWidthException: 4
15:38gfredericks&(lib-%04d" (rand-int 10000))
15:38ferd##(format "lib-%04n" (rand-int 1000))
15:38lazybotjava.lang.RuntimeException: EOF while reading string
15:38lazybotjava.util.IllegalFormatWidthException: 4
15:38ferdhmm
15:38gfredericks&("lib-%04d" (rand-int 10000))
15:38lazybotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
15:38gfredericks&(format "lib-%04d" (rand-int 10000))
15:38lazybot⇒ "lib-9833"
15:38gfredericksfinally
15:39mfex&(gensym "lib-")
15:39lazybot⇒ lib-7119
15:39mfex&(str (gensym "lib-"))
15:39lazybot⇒ "lib-7127"
15:39gfredericksthat's not quite random though
15:40mfexit's unique
15:40gfredericksI'd hate for my lib names to be dependent on lazybot usage history
15:41mfexhmm, not sure what your use-case is :)
15:41gfredericksnaming libraries
15:41Null-Awow light table is still on HN
15:41Null-Ai've never seen something get 1300 points
15:42Null-Ai wonder how many of those people are interested in clojure though
15:53gfredericksOkay, pushed up misquote: https://github.com/fredericksgary/misquote
15:53gfredericksnow to find that guy who needed this yesterday
15:56mdeboardAre '-' characters invalid in namespace definitions?
15:56mdeboarde.g. (ns some-namespace) ?
15:56gfredericksno...
15:56gfredericksthey'se used all the time
15:56mdeboardYeah, I'm just confused about an error I'm getting.
15:57gfredericksare you forgetting where they get converted to underscores?
15:58mdeboardForgetting would imply that at one time I knew
15:58gfredericks:) package names and filepaths
15:58gfredericksi.e., the things java touches
15:58mdeboardhttps://gist.github.com/2677328cfb1dc72c19ec
15:58mdeboardah
15:59gfrederickshm; that's weird
16:02mdeboardI'm stumped as to why I can't run this uberjar.
16:06mdeboardAnyone have any insight into why I get the error message at the bottom here https://gist.github.com/12d2e610c321e1d51dce with the rest of the code above it?
16:07ferdgfredericks: I actually needed "misquote" not long ago for this macro: http://goo.gl/bvUHI . I ended up using '~ all over the place
16:10gfredericksferd: clearly the world has been yearning for it
16:12xeqimdeboard: try adding :impl-ns dat-doop.core to your :genclass
16:14mdeboardxeqi: No change.
16:16mdeboardIt feels like every blog post about Clojure was written in 2010
16:16gfredericksthose are the ones that have been around long enough for google to know that they're good
16:16LauJensenmdeboard: Yea I know. I should really change that :)
16:17mdeboardgfredericks: Yeah, but there have been plenty of changes both to Clj and Lein since then
16:17xeqigen-class is converting the ns to a package (- to _). I guess its then reconverting that to the ns to look for the methods
16:17xeqi*not reconverting
16:20mdeboardxeqi: So that sounds like if I remove the hyphen it should resolve the problem
16:22gfredericksjayunit100: I wrote you a macro for your quoting needs
16:45sgarrett|afkHello #clojure. I'm kind of confused. I'm using bigint however when I try to call methods from the java class I'm getting an error. Does anyone know why this would be happening? I'm getting an error when doing the example code here: http://clojuredocs.org/clojure_core/clojure.core/bigint
16:46gfrederickssgarrett|afk: is it the clojure bigint class instead?
16:46gfredericks&(type (bigint 84))
16:46lazybot⇒ clojure.lang.BigInt
16:47gfrederickswait unless that's what you meant by "the java class"
16:47gfredericksmy point is there's two bigint classes to be confused by
16:48Bronsa,(.isProbablePrime (.toBigInteger (bigint 97)) 1)
16:48clojurebottrue
16:48gfredericks(-> (BigInteger "83492948924398248289489243") .nextProbablePrime)
16:48gfredericks,(-> (BigInteger "83492948924398248289489243") .nextProbablePrime)
16:48clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Expecting var, but BigInteger is mapped to class java.math.BigInteger>
16:48gfredericks,(-> (BigInteger. "83492948924398248289489243") .nextProbablePrime)
16:48clojurebot83492948924398248289489297
16:48gfredericksI love numbers
16:48Bronsa,(.isProbablePrime (biginteger (bigint 97)) 1)
16:48clojurebottrue
16:48Bronsa,(.isProbablePrime (biginteger 97) 1)
16:48clojurebottrue
16:48Bronsaderp
16:51sgarrettI see. Well I'm working with binary numbers is why I guess I'm running into the issue. I was declaring the numbers like 2r1111111111111111000000000000000000000000000000000000000000000000 and then I wanted to call toByteArray so that I could go through each bit. So I have to convert to biginteger?
16:51sgarrettJust want to make sure there isn't a better way I guess.
17:34groovemonkeyquick question, because #leiningen is extremely quiet...
17:34groovemonkeyI just added a /data directory to the root of my lein project.
17:34groovemonkey Now 'lein run' produces a FileNotFound Exception for the files
17:34groovemonkey that I've moved to the new directory. How do I add this
17:34groovemonkey directory to those that Leiningen knows about?
17:39yoklovi think it's something like :resources-path "data/" in project.clj
17:39yoklovor just rename the directory to resources/
17:43sgarrettIs there a way to do a bit-and on a BigInt?
17:44groovemonkeyyoklov: sorry, didn't see until now. Thanks, I'll try that.
17:44yoklovlol, don't worry about it. hope it works.
17:54groovemonkeydidn't work :( -- I tried setting the :resources-path to "resources/" and "data/" respectively -- it seemed to get leiningen looking in the right place, but it still throws a FileNotFound Exception: could not locate <classfile> or <correct/path/to/file.clj> on classpath.
17:55groovemonkeyis there a way to add things manually to the classpath?
18:04jayunit100hmm is there a way i can look up all functions that have args related to a given type ?
18:04jayunit100i.e. All clojure.core functions which operate on sequences .
18:08amalloyfunctions don't have types
18:09jayunit100yeah thats the trouble. But it is true that some functions are type constrained.
18:09RaynesYes, but not in a way that you can actively check for.
18:09jayunit100 (assoc '(1 2 3) 0 1) ---> fails (because lists aren't associative).
18:10jayunit100ok.. oh well i guess i can use doc-find
18:10amalloywell, you can try http://www.clojureatlas.com/, or the clojure cheatsheet
18:10jayunit100(find-doc) i mean. Yeah the atlas is a good resource.
18:14octagonwhoa @clojureatlas
18:14octagonawesome
18:17octagonis there a doc that describes all of the clojure means of abstraction, with a rundown of where each one is and is not appropriate/useful? i'm trying to get the big picture view.
18:18gfredericksjayunit100: did you see my thing-I-said two hours ago?
18:22gfredericksoctagon: some of the essays on clojure.org might be helpful?
18:24octagongfredericks: yes, i was looking for the lazy way; i guess i need to compile my own notes from there, anyway
18:26gfredericks&(let [a (make-array Byte/TYPE 50)] (dotimes [n (count a)] (aset a n 5)))
18:26lazybotjava.lang.IllegalArgumentException: No matching method found: aset
18:26gfrederickswhat on earth is going on there
18:30amalloy(instace? Byte/TYPE 5)
18:30amalloy&(instance? Byte/TYPE 5)
18:30lazybot⇒ false
18:30gfredericksoh hm
18:31gfredericksthat makes total sense in hindsight
18:31amalloy&(let [a (make-array Byte/TYPE 10)] (dotimes [n (count a)] (aset a n (byte 5))) (seq a))
18:31lazybot⇒ (5 5 5 5 5 5 5 5 5 5)
18:31gfredericksI will never know the exact conditions under which java numbers can be converted to other types.
18:31muhoobase 5, eh?
18:32gfrederickssomehow I was convinced I was using dotimes wrong
18:32gfredericksthat it was acting like doto for some perverse reason
18:35amalloygfredericks: well, it's confounded by the fact that clojure has its own type-conversion rules
18:35gfredericksthat does sound confounding
18:37muhoodon't java numbers have their own static Num/toFoo methods for converting to the things they're allowed to be converted to?
18:41amalloyso i learned something new about java today. for some values of Foo and bar, you can write (without causing an NPE):
18:41amalloyFoo x = null;
18:41amalloyx.bar();
18:58huangjshmm... there's lein-clojurescript and lein-cljsbuild, which one would you recommend?
19:06muhoothere's also cljs-template. and clojurescriptone. i'd love to know how all this stuff fits together (or doesn't).
19:18mads-Hi. Does anyone know where I can find clojure.jar if I have downloaded clojure through apt-get install clojure?
19:19lynaghkhuangjs: you want lein-cljsbuild.
19:20amalloymads-: start with apt-get uninstall clojure :P
19:20amalloyor remove, i guess? i don't uninstall stuff that often
19:20mads-amalloy: aaand theen? :)
19:21amalloyhttp://stackoverflow.com/questions/5983427/how-to-install-clojure-on-ubuntu-10-04-from-github-repo-with-no-clojure-jar
19:21amalloysee also the leiningen readme
19:23mads-thanks
19:25muhoowhat's the advantage of using midje versus clojure built-in test machinery?
19:29huangjs`lynaghk: thanks
19:34jayunit100,(assoc (vector-of :char) 0 "s")
19:34clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>
19:34jayunit100odd error message.
19:35jayunit100Understandable... but i think it should simply report that "" is not a char.
19:35gfredericksthat looks like the jvm's doing
19:37jayunit100Well... so is everything :)
19:38jayunit100But the difference here is that, in java, the statement ------ new Vector<Character>().add('c') ; ----- would not compile.
19:38jayunit100I mean, new Vector<Character>().add("c") ; .....
19:39jayunit100So I think it should be a :pre assert ~ that the assoc value is the same type as the assoc enum.
19:40dnolenbbloom: heya, could you create a patch for the column modifications to the Clojure compiler?
19:40bbloomhey
19:40bbloomi'm working on both my patches right now
19:40bbloomthe track-pos patch for the cljs compiler is a pain in the butt to maintain
19:40bbloomeach time you change the compiler, i have a lot of work to redo :-P
19:41dnolenbbloom: yeah sorry about that. that's why I want to get it in now.
19:41bbloomyup
19:41bbloomshouldn't be long, but i may get interrupted
19:41bbloomyou going to be around for a while?
19:41dnolenbbloom: probably not for too much longer this evening - but as soon as you have a new patch I will test and apply.
19:42bbloomok great
19:42bbloomi'll probably finish the cljs change, but i don't know if i'll get to the clj reader one
19:43sparkleshyis there any better way to do C-like static locals than wrapping the defn in a let or using def inside the defn?
19:43bbloomdnolen: do you have good test cases for your recent optimizations? the variadics, the dynamics, etc?
19:43dnolenbbloom: sure, a clj reader patch would be nice so it passes Andy's prescreening script
19:43bbloombecause i don't think my twitter test covers them & i'm merging those conflicts now
19:43amalloysparkleshy: def inside defn is evil and also not anything like static locals
19:44amalloyi don't see how you could want something "better" than wrapping the defn with a let - that's about as good as it could possibly be
19:44bbloomdnolen: i can make a patch for the clj reader, but it's highly untested :-) if the concern is to meet the prescreener, that's no problem
19:44bbloombut if you want it to work… that's another story ;-)
19:44bbloommy patch did build and pass the tests when i made my github branch tho
19:44dnolenbbloom: no tests for the optimizations - my assumption was that all the current tests should just work :)
19:44bbloomi just didn't dig in to make sure it's solid & covers everything i need it to cover
19:44jayunit100what are the limits on lazy-seq ?
19:45jayunit100in terms of its inputs -
19:45raeksparkleshy: you want to maintain state between function calls?
19:45sparkleshyamalloy: I know, it's _so_ evil.
19:45dnolenbbloom: sure but having the patch is a good reference point.
19:45bbloomk
19:45dnolenbbloom: also people can easily apply and get to work on the source mapping stuff.
19:45bbloomk
19:45raekjayunit100: anything seqable is fine
19:46jayunit100so what im wondering though is - how can it gaurantee laziness ?
19:46dnolenbbloom: by actually working on source mapping I think we can discover what's missing.
19:46dnolenbbloom: it was reassuring that you patch was good enough for Light Table ;)
19:47raeksparkleshy: using global state: (def state (atom 0)) (defn next-number [] (swap! state inc))
19:47jayunit100I mean, if I have function which returns a list ... And it precalculates all 10 vals in the list --- then its not really lazy, is it
19:47bbloomdnolen: I didn't realize that it was used for that
19:47bbloomawesome! :-)
19:47sparkleshyraek: Not between; more like (let [rand (java.util.Random.)] (defn gaussian (.nextGaussian rand))). Which is bad code but it's an example.
19:47sparkleshyraek: Er, put a [] after gaussian
19:48raek(def ^{:private true} rand (java.util.Random.)) is another way
19:48jayunit100IS there a "loop-recur" aware lazy seq that invokes the loop, caching state between invocations ? That would be "true" laziness.
19:49raekjayunit100: you can easily translate a function that is implemented using loop, recur, and cons into one that is lazy
19:49jayunit100i.e. something like the python "yield" idiom.
19:49sparkleshyraek: I know, I can do a def outside, but I wish I could keep my internal data inside because it feels cleaner and stuff.
19:49raekI think the let is fine in that case
19:50bbloomdnolen: http://dev.clojure.org/jira/browse/CLJ-960
19:50sparkleshyraek: The real issue is that with code folding, the def is completely hidden by the let.
19:50dnolenbbloom: excellent thx
19:50sparkleshyraek: But the let is part of the implementation of the def, not the other way around
19:50bbloomant succeeds, didn't check anything else
19:51dnolenbbloom: Andy's prescreener will catch problems.
19:51raekjayunit100: let's assume you have this: (loop [n 5, result []] (if (zero? n) result (recur (dec n) (conj result n)))
19:51bbloomcool
19:51bbloomback to untangling this compiler emit stuff :-)
19:52dnolenbbloom: thx very much.
19:52jayunit100raek okay good start -> how to lazify it
19:52jayunit100?
19:53jayunit100The problem of course is that loop/recur will recur all 5 times inside the function body , unless you wrap it in a macro or something .
19:53raekthe lazy variant would then be: (letfn [(f [n] (lazy-seq (if (zero? n) nil (cons n (f (dec n))))))] 5)
19:54raekthe difference is that each step gets wrapped in a lazy-seq
19:54raekand that the recursive call is not done using 'recur'
19:54raekand the result is not built up using an accumulator variable
19:55sgarrett|afkIs there a way to bit-and with a BigInt?
19:55jayunit100hmm but this function would have to be manually iterated.
19:56jayunit100Is there a way to make it more decoupled - so that it simply emits the next value , repeatedly.
19:56raekin a way, that's what f does here
19:56jayunit100hm okay me analyze it some more and get back .
19:57raekyou can think of lazy-seq as yield and seq as a call to a generator
19:57raekwell, rougly
19:58raekhere's a function defined in many equivalent ways: https://gist.github.com/951633
19:58sparkleshysummary: is there any better way to do C-like static locals than wrapping the defn in a let or just doing another def outside? Not for keeping state between calls; more like (let [rand (java.util.Random.)] (defn gaussian [] (.nextGaussian rand))). Which is bad code but it's an example. Since the let is part of the implementation of the def, I want it inside, and I want only the def to appear when using code folding.
19:59raeksparkleshy: no.
20:00gfrederickssparkleshy: (def my-fun (let [rand ...] (fn [] (.nextGaussian rand))))
20:00gfredericksif you can tolerate def instead of defn
20:00sparkleshygfredericks: cool! but I want something better. Like (defn gaussian [] (.nextGaussian (cache (java.util.Random.))))
20:02gfrederickssparkleshy: there are definitely some ugly-ass ways to do something like that
20:02raekit is definitely possible to write such a cache macro, though
20:02gfredericksraek: could even be a function
20:02gfredericksthat just does a bunch of offensive global mutation
20:03sparkleshybut with a function wouldn't it create another Random each time through gaussian?
20:03raekin the current form, it looks like you only would like the argument to 'cache' to be evaluated once
20:03gfrederickssparkleshy: my guess is that at this point every possible way of giving you what you want would be quite unidiomatic
20:04sparkleshygfredericks: So... this thing I want is inherently bad?
20:04gfredericksthe main issue is code folding? i.e., you want the first line to summarize the thing?
20:05raekwell, you could make (cache foo) expand into (cache* (fn [] foo)), where cache* is a function
20:06gfredericksraek: I think you have to do some kind of global mutation, whether it's a macro or function
20:06sparkleshygfredericks: It wouldn't be actually clean without an implementation of the cache macro
20:06sparkleshywhat about (defmacro cache [exp] (let [sym (gensym)] (eval `(def ~sym ~exp)) sym)) ?
20:06raekgfredericks: yes.
20:07raekwhich would add runtime overhead, I guess
20:07raeksince the function would need to check if the value has been calculated
20:09gfredericksI guess it all seems very sneaky
20:10sparkleshyokay. That implementation works.
20:11sparkleshyin (println "hi") (cache (println "beta")) can I rely on hi printing before beta?
20:12sparkleshyalso, is the way it uses def going to cause performance issues vs the previous wrap-the-defn-in-a-let solution?
20:12sparkleshyi mean, in really intensive code. Like, is performance _ever_ something to worry about with the cache macro?
20:14gfredericksI don't think there are any performance issues there
20:14gfredericksit should be equivalent to using an explicit top-level (def)
20:14gfrederickseverything else happens at compile-time
20:17sparkleshyyeah... rephrase: would (let [rand (java.util.Random.)] (defn gaussian [] (.nextGaussian rand))) be any slower than (def rand (java.util.Random.)) (defn gaussian [] (.nextGaussian rand)) ?
20:17gfredericksthe let might be faster since there's no var involved
20:18gfredericksbut I don't know much about those things
20:23bbloom*sigh* waiting on the v8 compile…. i sometimes forget how much i appreciate instantaneous development feedback
20:24dnolenbbloom: haha, though v8 build time isn't so bad.
20:24bbloomi'm on a year old macbook air
20:24bbloommy poor little cpu can't handle it :-)
20:24bbloommy big bad machine is at the office
20:25dnolenbbloom: heh oh yeah. As much as I like the MB Air, having a 2.66 dual core i7 has it's perks.
20:26gfredericksdebugging aleph is hard :(
20:27bbloomdnolen: i'm seeing something a bit odd with cljs compiler output (before my changes), maybe you can explain
20:27dnolenbbloom: it will be a happy day when we can debug CLJS right in the browser.
20:27dnolenbbloom: hopefully browsers will support some JSON syntax highlighting description format.
20:27dnolenbbloom: what's up?
20:27bbloomi'm seeing a few calls to cljs.core.get.SOMEGENSYM
20:27bbloomwhat's that about?
20:28dnolenbbloom: __N, direct multi arity dispatch support
20:28bbloomah ok
20:29bbloomfor my debugging diffs, i have been using sed to rewrite gen syms so they don't show up on diffs
20:29bbloombut it can be confusing b/c ALL THE GEN SYMS LOOK THE SAME :-)
20:29bbloomhehe
20:29bbloomthanks
20:31bbloomand nice work on all the recent perf improvements
20:31bbloomgood stuff!
20:32lynaghkdnolen: yeah, those performance improvements were boss.
20:33dnolenbbloom: lynaghk: thanks!
20:35lynaghkdnolen: what's the story with the GSoC stuff, by the way?
20:36dnolenlynaghk: I just sent out an email about that on clojure-dev, we need to pick up the pace a bit, 9 more days to review and score etc.
20:36dnolenlynaghk: we've been allocated 4 slots, which is nuts for a first time mentoring organization.
20:36lynaghkI sent you an email a while back about the students who contacted me---I dunno if you want me to reproduce that on Melenage. (I thought it'd be safer to send you an email than try and figure out how to write something private on that terrible UI)
20:37lynaghkdnolen: guess Google is excited about the ()'s
20:37dnolenlynaghk: all admins and mentors can leave private comments.
20:37dnolenlynaghk: Melange is so lame.
20:38dnolenlynaghk: I our crop of proposals was surprisingly strong.
20:38dnolenClojure programmers don't mess around.
20:38lynaghkdnolen: okay, I might poke around and put some updates on Melenage then. I really want the students to actually write some code before I feel like moving ahead.
20:38dnolenI "think our proposals" I mean.
20:38lynaghkdnolen: yeah. I particularly liked Chris Granger's difficulty level of "medium to insane".
20:39lynaghkGo big or go home.
20:39ibdknoxlynaghk: it's true
20:39dnolenlynaghk: yes, please go through the proposals thoroughly, even ones you aren't mentoring.
20:39ibdknoxa choose your own adventure of sorts ;)
20:40dnolenanything that doesn't have a mentor at this point isn't something we should consider.
20:40bbloomdnolen: so the column numbers are pretty easy to screw up if with-out-string or anything like that gets used
20:40dnolenbbloom: but nobody should be using that right?
20:40bbloomdnolen: i'm tracking down one new issue now… but i'm trying to think about how to prevent this going forward
20:40bbloomdnolen: right
20:41bbloomk think i got it
20:41bbloommy little column-aligned line number comment trick is good enough for now
20:41bblooma bug or two may creep in before source-maps gets implemented proper
20:41bbloombut visual inspection will do until then
20:42lynaghkIf I write {:a @(future (x)) :b @(future (y))} will the calls to x and y be executed in parallel?
20:42ibdknoxdnolen: light table just passed Meteor in points on HN
20:42dnolenbbloom: cool, your changes are nice, it's a necessary step for decoupling the compiler from JS any how.
20:42dnolenibdknox: not surprising, Light Table is way more impressive IMHO.
20:43bbloomdnolen: thanks. they also clean up a few small things. in the output: a few less random blank lines, eliminates some redundant parens, cleans up spacing. in the compiler code: fewer (println (str ….)) with teh various extra ()() forms :-)
20:49michaelbartonI have a beginner's question. I'm trying to create a lazy sequence from a file but I'm getting either OutOfMemory (heap) errors or stream closed errors. I feel like there must be an idomatic way for this that I'm missing.
20:51michaelbartonThe stream closed errors come when I try to wrap the reader in a with-open block.
20:53bbloomdnolen: ok, ready with patch for track-pos
20:53bbloomstruggling with git format-patch tho :-P
20:54S11001001michaelbarton: dynamic scope and laziness mix weirdly
20:54bbloomhttp://stackoverflow.com/questions/616556/how-do-you-squash-commits-into-one-patch-with-git-format-patch :-)
20:55S11001001if you like, you can do this instead, just note that unless you consume the whole input, the stream won't close: (concat my-lazy-seq (lazy-seq (.close stream) nil))
20:56michaelbartonOK. Thank you for the suggestion.
20:56bbloomdnolen: http://dev.clojure.org/jira/browse/CLJS-176
20:57michaelbartonHow does the concat work in that function?
20:58arohneris there a fn like partition, but splits the seq into n equal sized seqs?
21:01bbloom,(doc partition-all)
21:01clojurebot"([n coll] [n step coll]); Returns a lazy sequence of lists like partition, but may include partitions with fewer than n items at the end."
21:01bbloomthat what you mean?
21:01gfredericksarohner: oh you want something where the partition size is based on the length of the sequence?
21:01arohnergfredericks: yes
21:01gfredericksarohner: I don't think there is anything built in; would not be lazy-friendly
21:02gfredericks(partition (quot (count coll) n) coll)
21:02michaelbartonarohner: Divide the length of the sequence by n, then partition by n size?
21:02arohneryes. I know how to implement it, I was just checking that it didn't exist yet
21:02michaelbartonarohner: OK
21:11dnolenbbloom: thx a million. gotta run but will give this a serious look tomorrow and try to appy then.
21:11dnolenClojure community rocks.
21:11bbloom:-)
21:25socksandsandalsreally n00b question here: if I have (def foo 12) in a file, how does one go about later changing that variable's value?
21:25socksandsandalsshould I just (def) it again later?
21:25S11001001socksandsandals: try not to change it ever
21:26socksandsandalsexactly the answer I wasn't looking for
21:26S11001001socksandsandals: so, as a newbie, you may be reaching for solutions appropriate in other languages, but not clojure
21:26S11001001I can't be sure, so I err on the side of caution
21:26S11001001typically, vars are only changed during development
21:26socksandsandalsI'm a n00b to Clojure, not programming or Lisp
21:27S11001001right, that's what I said
21:27socksandsandalsso I have a shutdown function that isn't determined until runtime
21:27S11001001if your program, while running, requires changes to global state, then setting a var is the wrong solution
21:27socksandsandalsso I need to assign it to something to hold on to it for when I go to shutdown the server
21:28S11001001instead, you probably want an atom, ref, or future, depending on the concurrency semantics you desire
21:28S11001001s/future/agent/
21:28clojurebotTitim gan éirí ort.
21:28S11001001in this case, it sounds like you want an atom
21:28socksandsandalsthere's no concurrency involved in this case which is why I was wondering if I could just rebind the def
21:28socksandsandalsbut an atom would work, too
21:28socksandsandalsthanks S11001001
21:28S11001001np
21:29socksandsandalsS11001001: if an atom holds a function, I can still call it with just @atomname, right?
21:30S11001001(@atomname args...)
21:30socksandsandalsyeah, ok nice, thanks
21:30socksandsandalsright, Clojure is a Lisp1 so no need for apply
21:30socksandsandalsperfect
21:30S11001001funcall, rather
21:30socksandsandalsoh right
21:37S11001001I wish it had funcall, anyway; sometimes it's just what you need for some HOF. Same for this: (defn first-arg [x & _] x)
21:38gfredericks(def first-arg (comp first list))
21:38S11001001gfredericks: strict in the rest
21:38S11001001having written first-arg 3 or 4 times, and $ (funcall) at least once
21:39gfredericksS11001001: you mean it realizes any lazy-seq-args?
21:39S11001001aye
21:40gfredericks,(doc list)
21:40clojurebot"([& items]); Creates a new list containing the items."
21:40gfredericks,(-> (range) (apply list) (first))
21:40clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn>
21:40gfredericks,(->> (range) (apply list) (take 10) last)
21:41clojurebotExecution Timed Out
21:41gfrederickswell wudduyaknow
21:41S11001001clojure.walk depends on it
21:42michaelbartonI'm struggling to process a 2.5m line file.
21:42michaelbartonI'm trying to create a set and a map from the data but I'm running out of memory
21:43S11001001michaelbarton: https://groups.google.com/d/topic/clojure/FC36I1iqZcs/discussion
21:44michaelbartonInteresting, I am working on a graph too.
21:44michaelbartonThank you.
21:45S11001001gfredericks: not only does it realize them, it constructs a proper PersistentList structure, setting aside whatever conses/chunkedseqs/magic bits you had
21:45S11001001(that is what clojure.walk required)
21:46S11001001michaelbarton: especially beware if you first walk the whole list creating the set, then again creating the map. That won't let go of the source lazy sequence, whereas doing them together will
21:46gfredericksthat structure being just a vanilla linked list?
21:46S11001001gfredericks: it is also counted
21:47gfredericksoh nice
21:47S11001001I guess
21:47S11001001I'm against wasting all the bits really, but oh well
21:52fdaoud,(first (map / [1 1] [2 0]))
21:52clojurebot1/2
21:52S11001001huh, weird
21:52S11001001,1/0
21:52clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.ArithmeticException: Divide by zero>
21:52S11001001,(do 1/0 nil)
21:52clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.ArithmeticException: Divide by zero>
21:52fdaoud,(first (map #(%) [#(/ 1 2) #(/ 1 0)]))
21:52clojurebot#<ArithmeticException java.lang.ArithmeticException: Divide by zero>
21:52fdaoudwhy does the first version work but not the second? (lazy)
21:53S11001001oh, right
21:53S11001001because the variadic map doesn't do fancy tricks for chunked
21:53fdaoudhuh?
21:53S11001001you only get fancy tricks in the one-sequence case
21:53S11001001the multi-sequence version is naive, and doesn't do chunking
21:54fdaoudso lazy is only lazy by chunks?
21:55S11001001in general, laziness cannot be relied upon to be "pure". There are exceptions, like iterate
21:55S11001001for efficiency, vectors yield "chunked" sequences, therefore lazy operations on them also "chunk" if someone implemented that
21:56fdaoud,(first (map #(%) (concat (repeat 1000 #(/ 1 2)) [#(/ 1 0)])))
21:56clojurebot1/2
21:56S11001001map, filter, and several other operations special-case for the chunking case
21:56fdaoudI understand, thanks for the explanation S11001001
21:56michaelbartonIs there a way to increase the java memory size from inside a clojure program?
21:56fdaoudif it wasn't for you I would not have slept tonight.
21:57S11001001happy to help then :)
21:57fdaoud,(first (map #(%) (concat (repeat 100 #(/ 1 2)) [#(/ 1 0)])))
21:57clojurebot1/2
21:57fdaoud,(first (map #(%) (concat (repeat 10 #(/ 1 2)) [#(/ 1 0)])))
21:57clojurebot1/2
21:59S11001001,(count (chunk-first (seq (concat [1 2 3] (vec (range 35))))))
21:59clojurebot3
22:00S11001001,(count (chunk-first (seq (chunk-rest (seq (concat [1 2 3] (vec (range 35))))))))
22:00clojurebot32
22:00S11001001,(count (chunk-first (seq (chunk-rest (seq (chunk-rest (seq (concat [1 2 3] (vec (range 35))))))))))
22:00clojurebot3
22:00S11001001,(count (chunk-first (seq (chunk-rest (seq (chunk-rest (seq (concat [1 2 3] (vec (range 39))))))))))
22:00clojurebot7
22:00S11001001concat is good
22:01mdeboardDoes anyone else have trouble with Cascalog in Emacs?
22:01mdeboardGet a lot of weird errors
22:01mdeboardprogram just constantly throws errors after awhile any time I try to run anything.
22:03mdeboardruns out of memory, seems like.
22:04S11001001michaelbarton: if there is, it's probably buried in JMX somewhere, but I really doubt it
22:05mdeboardSpeaking of, how DO You set -Xmx/-Xms for slime ?
22:08S11001001probably by setenv JVM_OPTS in emacs
22:08mdeboardorite
22:12michaelbartonOK. I'm running the script using the clj shebang so I'm not sure how to increase the memory.
22:13S11001001never used that. Never installed clojure, honestly
22:13clojurebotGabh mo leithscéal?
22:13michaelbartonPerhaps java environment arguments.
22:14michaelbartonNever installed clojure?
22:14S11001001nope
22:14michaelbartonHow do you use it?
22:14S11001001I use leiningen
22:15michaelbartonAh, I see.
22:15S11001001you could do this #!/bin/sh\ntrue; SOMEENV=someval clojure-thingy "$0" "$@"
22:15S11001001with an exec in there somewhere
22:16michaelbartonIs it easy to create short scripts with lein?
22:16S11001001maybe not, but I would do it that way anyway
22:17S11001001#!/bin/sh\njava -cp `cd my-proj && lein classpath` clojure.main -e '(run this)'
22:18michaelbartonOK
22:18S11001001I love libraries
22:18S11001001and I bet the #! thing doesn't work well with them
22:19michaelbartonI tried lein previously. I found the learning curve a little steep so I'm using scripts until I'm more comfortable with clojure.
22:19S11001001I can't speak to the efficacy of that approach
22:19michaelbartonOK
22:23mdeboardmichaelbarton: Yeah you really don't want to futz with running clojure itself. Use lein
22:26S11001001I would agree, but I love build systems and emacs, so maybe I am the wrong one to ask
22:27michaelbartonOK
22:27michaelbartonMy script is only 19 lines long so it seemed ling using a clj shebang was simpler
22:29S11001001it may end up 19 lines long, but you also have to write it :)
22:33michaelbartonI guess I'll try playing about with trying to make my script more lazy, then otherwise make in in lein.
22:33S11001001good luck
22:33michaelbartonDoes clojure GC automatically clear up unused variables?
22:34michaelbartonI mean no longer used.
22:34S11001001do you mean vars created by def or bindings created by let?
22:34bbloom4clojure.com is down :-( trying to work through a problem or two a day :-P
22:35michaelbartondef variables after they're used and not referenced again.
22:35S11001001michaelbarton: no
22:36michaelbartonOK
22:36michaelbartonI should use an atom instead, then clear it?
22:36S11001001hmm, what are you trying to do?
22:37aperiodicyeah, if you use an atom and then change its value, the old value will be GC'd if there are no other references to it
22:37michaelbartonI have pairs of key/values and I need to covert them to a network format. The problem is key1-key2 and key2-key1 need to be merged to a single value.
22:38S11001001data in general shouldn't be stored in vars at all; vars are best for your functions, static data, and dynamic context bindings. So if this is intermediate state, you should usually just pass it between functions
22:38michaelbartonOK
22:39bbloommichaelbarton: if you're concerned with leaking memory during interactive development, you can use ns-unmap
22:39bbloomthat will "delete" the Var
22:40michaelbartonOK
22:40michaelbartonThank you both.
23:07TimMc$mail samaaron I don't know if I'll get aorund to making the Overtone instrument-samples doc tool anytime soon, so that idea is free to a good home. :-)
23:07lazybotMessage saved.