#clojure logs

2011-01-05

00:01devnclizzin: check out line 4762 in core.clj for clojure-1.2.0 stable
00:01clizzindale, devn: okay, nvm, dale is correct. the only caveat is that y is accessible either as y or f/y
00:02daleclizzin: Heh, yeah, that. Was just typing up https://gist.github.com/765957 .
00:03devnoh my god.
00:03daleclizzin: So that ClojureDocs example is correct but not complete, I'd say.
00:03devni just realized SLIME has this cross-reference capability
00:03devnM-. on (loo|p) for instance in the SLIME REPL where | is my cursor
00:04devnC-c C-w c Who Calls: loop RET
00:04daleclizzin: Continuing on from that example you could also reference anything in clojure.string, not just the stuff named in :only. Ex: s/escape works.
00:05clizzindevn: M-. is insanely useful
00:05devnyeah M-. is pretty much why i extoll the virtues of lisp
00:06devnthe tools around it are just insane.
00:06devn(in a good way, of course)
00:06clizzinesp. precisely because namespace require/use-ing often make it really confusing where any particular function came from
00:13amalloyclizzin: that's why you're discouraged from use-ing libraries wholesale
00:14amalloyif you use..only or require..as, it's unambiguous where a given function comes from
00:16clizzinamalloy: true, but some people are not always so clean with their code. =(
00:16amalloyclizzin: go on a github crusade like devn :)
00:17clizzinamalloy: haha, is devn just making lots of pull requests that fix that precise issue?
00:17amalloyno, he has his own set of pet peeves, but that's the idea
00:42amalloyinteresting: ##{a b (comment c d)} throws a CompilerException caused by an ArrayIndexOutOfBoundsException; i'd have expected slightly friendlier handling
00:59Raynesamalloy: It might be useful to add { and [ to the list of things that ## sets off, don't you think?
00:59amalloyRaynes: heh. it didn't occur to me that was the problem
01:20tomojwhy ever use rest?
01:24tomojI mean, say rest were removed and we were stuck with next. a loss?
01:24tomoj..besides backward-compatibility issues
01:27amalloytomoj: laziness
01:28amalloyin particular suppose my lazy-seq has side effects (gross, i know)
01:29amalloythen if map uses rest, (first (map f myseq)) will result in only one set of side effects; if map uses next, it will result in two sets of side effects
01:36tomojah, right
01:36tomojI expected to find corroboration in LazySeq, but don't..
01:37tomojoh, I wasn't looking hard enough
01:44tomojhuh
01:45tomoj(when x) == (when-not x) == (do x nil)
01:45tomojof those I guess I have to prefer (do x nil), any better?
01:46hiredman((constantly nil) x)
01:49tomojI name (constantly nil) "nilf"
01:51tomojis there any use of (constantly constantly)?
01:52tomojhard to imagine it being useful
02:07clizzinis there an rsplit function anywhere in core or contrib? (that is, behaves like split, but goes from the right instead of from the left)
02:07clizzinto clarify: i'm talking about splitting strings
02:12amalloy&(let [s "hello there!"] (map (partial apply str) (split-at (- (count s) 3) s))) is kinda ugly :P
02:12sexpbot⟹ ("hello the" "re!")
02:15amalloyclizzin: ^ if you're just looking for something that works
02:17clizzinamalloy: was looking for something that splits on a delimiter rather than on an index
02:18amalloy&(let [s "hello there!"] (map (partial apply str) (split-with #{\space} s)))
02:18sexpbot⟹ ("" "hello there!")
02:18amalloy&(let [s "hello there!"] (map (partial apply str) (split-with (complement #{\space}) s)))
02:18sexpbot⟹ ("hello" " there!")
02:19tomoj"goes from the right?"
02:19amalloyclizzin: still not simple; if you just want to use a simple delimiter, what about one of the regex functions?
02:20clizzintomoj: i.e. (rsplit "hello there pardner!" #" " 2) -> ("hello there" "pardner!")
02:21_na_ka_na_clizzin, how about reverse, then reverse again ?
02:21clizzinamalloy: took a look at the pattern class...it doesn't have a similar function, but what i can maybe try is writing a regex where the delimiter regex requires that it be followed by a series of non-delimiter chars, then the end of the line
02:22clizzinand then split on that regex
02:22tomojclizzin: ah
02:23clizzin_na_ka_na: that seems like it would work but have poor performance
02:23clizzinand the function that has to do this splitting is the main bottleneck in the code, so keeping its performance snappy would be nice
02:24clizzin_na_ka_na_*
02:24clizzinlet me play around a bit, and i'll report back if i figure out something good
02:24_na_ka_na_clizzin, I'm not sure it would be that bad, coz in any case a splitting from right means non lazy
02:25_na_ka_na_so you have to start at the back
02:25amalloyclizzin: and you want the numeric argument to be the maximum number of splits?
02:25tomojhow do you propose to reverse the string?
02:25clizzinamalloy: yes
02:25clizzintomoj: i assume using the reverse function, no?
02:25tomoj(apply str (reverse s)) doesn't exactly look snappy to me
02:25clizzinthe reverse strategy only works if the delimiter is whitespace
02:26clizzintomoj: yeah, that was my concern as well
02:26clizzinthe proper way to do this is properly with some java code that essentially does the same thing as Pattern/split but iterating in the opposite direction
02:26clizzinis probably with*
02:27_na_ka_na_do you have the string to be split in one single huge string?
02:27clizzin_na_ka_na_: er, what do you mean by that?
02:27_na_ka_na_clizzin, I mean the first arg to your rsplit, how do you get that?
02:29clizzin_na_ka_na_: hm, still not sure what you mean. my ideal rsplit usage would be (rsplit s delimiter max-num-pieces) where s is the string to be split, delimiter is the string to split on, and max-num-pieces is the number of pieces i end up with. dose that answer your question?
02:29clizzindoes*
02:30_na_ka_na_clizzin, yes it does
02:31tomojit does?!
02:31tomojwasn't the question where these strings are coming from?
02:32clizzintomoj: yeah, i don't really get what's being asked either, but apparently what i said answered it. =P
02:33clizzintomoj: the strings are coming from arbitrary input land
02:33clizzinwhere the edge cases roam
02:34_na_ka_na_,(clojure.contrib.string/split #"ab" 3 "1111ab2222ab3333ab44444ab55555")
02:34clojurebot("1111" "2222" "3333ab44444ab55555")
02:34_na_ka_na_,(map clojure.string/reverse (clojure.contrib.string/split #"ba" 3 (clojure.string/reverse "1111ab2222ab3333ab44444ab55555")))
02:34clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: clojure.string
02:34_na_ka_na_no clojure.string ?
02:34_na_ka_na_&(map clojure.string/reverse (clojure.contrib.string/split #"ba" 3 (clojure.string/reverse "1111ab2222ab3333ab44444ab55555")))
02:34sexpbot⟹ ("55555" "44444" "1111ab2222ab3333")
02:36_na_ka_na_what I basically wanted to ask is the signature of rsplit, whether it takes its first arg as a string
02:36tomojthat looks probably a lot snappier
02:37_na_ka_na_but the trouble is you have to "reverse" the regex also
02:37_na_ka_na_#"ab" --> #"ba"
02:37clizzin_na_ka_na_: yeah, that was what i was going to say
02:38tomoj&(let [s (apply str (repeat 1000000 \0))] (time (when (clojure.string/reverse s))))
02:38sexpbot⟹ "Elapsed time: 14.803962 msecs" nil
02:38tomoj&(let [s (apply str (repeat 1000000 \0))] (time (when (apply str (reverse s)))))
02:38sexpbot⟹ "Elapsed time: 1324.168299 msecs" nil
02:38clizzintomoj: what's the when for?
02:38_na_ka_na_tomoj, hmm it uses a stringbuilder
02:39tomojto avoid returning the return value
02:39_na_ka_na_that's a neat trick :P
02:40clizzintomoj: haha cool
02:40tomojthat's not at all idiomatic
02:41tomojjust a cheap trick I discovered a while ago to save keypressed compared to (do x nil)
02:42tomojonly 2 keypresses, I guess..
02:42tomojsomehow (when ) still feels easier than (do nil)
02:43tomojjust a simpler sexp I suppose
02:43clizzinit's because you don't have to remember to put the nil at the end -- once you type the when, you can concentrate on the actual thing you want to test
02:43amalloytomoj: (= ) saves still more keystrokes
02:44tomoj:D
02:44clizzinamalloy: oohhh. but my pinky has to extend farther then =/
02:44amalloy&(= (apply str (repeat 1000000 \0)))
02:44sexpbot⟹ true
02:44tomojfor me, = is index finger, so perfect, thanks!
02:45_na_ka_na_clizzin, if your regexes are simple enuf, maybe you can reverse the pattern yourself :P
02:45_na_ka_na_,(.pattern #"ab")
02:45clojurebot"ab"
02:45tomojunary = also seems even more delightfully mysterious than a body-less when
02:46devnI'd like to build a refactoring tool for clojure that helps you reorganize your functions and split them out into different files
02:47_na_ka_na_also: (dorun ["huge string"])
02:47devnim not sure what i'm thinking makes sense...
02:47devnfor instance, if i require, are those requires obeyed in terms of their order?
02:47devn(in the ns macro)
02:48tomojwhat does order matter?
02:48devn(:use [foo.bar] [fred.green])
02:48devnwhat about there?
02:49tomojlast wins I think
02:49_na_ka_na_devn, don't think you can rely on any ordering
02:49_na_ka_na_why do you want ordering
02:49devnmaybe im "doing it wrong"(tm), but I write clojure top-down and then the file eventually becomes big enough that id like to split it out
02:50devnthere are like-functions which could be grouped, but they are now interwoven into the single large file
02:50_na_ka_na_devn, you mean splitting into different nses or the same ns
02:50devndifferent
02:50devndifferent files, different nses
02:51_na_ka_na_but isn't that a decision only you can take, on what to name the nses & grouping of fns
02:51devn_na_ka_na_: yes but it could be automated
02:52_na_ka_na_oh i see, maybe a dag of fns .. then split by connected components ?
02:52_na_ka_na_hmm
02:52amalloy_na_ka_na_: i think he just means "okay tool, please move functions XYZ into ns foo"
02:52devni could say (organize {:defn "foo" :def "buzz"}) or something
02:52_na_ka_na_oh that
02:52devnand it would split the function and the def out into a new file that i specify there
02:53_na_ka_na_ya that might not be difficult to do i guess
02:53devn(organize {:defn "foo" :def "buzz"} "path/to/new/file.clj")
02:53devnand then have it rewrite the (ns) macro on the current file im reading these from
02:54devnto point to file.clj and have it rewrite calls to foo and buzz so they are now namespaced :as k/foo, k/buzz
02:54devni think it would be nice to be able to toy with the organization -- i find breaking out a large clojure file to be a bit tedious, but like i said maybe im doing it wrong
02:55devnfor instance, clojure.core is like 6000 lines of code, so it can't be that bad, right? :)
02:55_na_ka_na_devn, clojure.core is an exception :P
02:55tomoj(defn foo [] (let [foo (fn [] 2)] (+ (foo) 3)))
02:55tomojgood luck
02:56devnoh...right... :X
02:56devnmaybe tcrayford has solved this much for me?
02:57devnhttps://github.com/tcrayford/clojure-refactoring
02:59devntomoj: that's not so hard to parse, though, is it?
02:59devni mean i can imagine a few rules that you continuously apply as descend
02:59tomojmaybe, I dunno
02:59devnas you* descend
03:00tomojI know there's some undocumented compiler api that can help
03:00tomojwhich it looks like tcrayford is thankfully not using
03:00bobo_oh, i like that clojure-refactoring. ive been wanting something like it!
03:00devnif var-in-question occurs after the most recent let and is the first of the args inside a [] you can ignore the replacement of this var until you reach the end of the let's scope
03:00devnsomething like that?
03:01devnbobo_: it's great. really fun to play with to refactor thread-first/last and test it out and see where it fits without rewriting your code
03:01tomojlet is not the only form that introduces local bindings
03:01tomojbut maybe you could hack it
03:01devnabsolutely not, but you could enumerate those
03:01amalloytomoj: stole my thunder there
03:01bobo_but why do i need to add it as a dev-dependency? shouldnt i just have to add it to emacs?
03:02devnyou'd need something like ctags or something along those lines...
03:02devnactually swank has that "Who Calls?" functionality
03:02tomojyes, but it's dumb
03:02devndumb or not it does a good job of laying out the options i have in front of me
03:02tomojfor clojure at least
03:03tomojI mean that it will pick up (foo) as calling foo even if it's really a local binding
03:03devnyeah -- hm
03:03devnany other ideas on how you'd do it?
03:04devnmaybe meta-data...
03:05devnthat'd be easy to do as you were hacking, simple tagging based on functionality, :functionality 'utils'
03:05devn'support/utils' etc.
03:06tomojI find that my big files usually require skilled chainsaw operation, sometimes dynamite
03:08_na_ka_na_tomoj, how is that foo above a problem?
03:08_na_ka_na_i would like something like this: (defn bar ..) (defn foo .. (let [bar ..] (bar ..))) would be a problem
03:08amalloydevn: metadata wouldn't help you resolve anything, and nobody would want to type it out. why write ^{:group :utils} "just in case", instead of just making utils.clj now?
03:08_na_ka_na_amalloy, i'm with you on that
03:09tomojthat local binding that clobbered the function name occurred inside the function was just a curiosity of brevity
03:09tomojthat _the_ local binding...
03:11devntomoj: of course, but it would be nice to make it work there as well
03:11devnive seen that happen more than one
03:11_na_ka_na_tomoj, would you know if that compiler API you mentioned above gives: what all fns a given fn depends upon
03:12tomojabsolutely not
03:12tomojI mean, absolutely.
03:12devnunless i hacked it to do so
03:12tomojI absolutely know that it absolutely does not
03:12tomojit's far more low level than that
03:13devndoes it occur after a defn or a def, is it part of a binding context?
03:13devni think those are two things you can figure out... no?
03:14tomojare you working with unmacroexpanded code?
03:14devnI mean -- "Who Calls" should respond in that fashion...
03:14devnyes
03:14tomojthen defmacro kinda screws things up, doesn't it?
03:14tomoj..still, you can probably get most cases right without too much trouble
03:14_na_ka_na_ya unmacroexpanded code will be much tougher to deal with
03:16_na_ka_na_tomoj, does that mean that IDE refactoring tools for Clojure are a distant dream
03:18tomojc-in-c I think will bring the dream a bit closer, but it's not my dream and so I don't really know anything about it
03:19bobo_it is alot harder to make IDE refactoring tools for any dynamic language.
03:20_na_ka_na_that's kind of sad
03:20tomojI guess I should have done the IDE thing before
03:20LauJensenMorning all
03:21tomojhard to understand the attraction never having used one
03:26amalloytomoj: eclipse's java support is a tremendous boon; emacs is equally good for CL but in different ways
03:26amalloyit's not as good for clojure, yet, but it's still a huge improvement over, say, gedit
03:27tomojI remember some blog post which tried to set up a dichotomy here
03:27tomojand suggested the excuse "clojure's so good we don't need an IDE"
03:27amalloytomoj: between what and what?
03:28tomojfocus on language and focus on tools
03:29tomojmaybe this one http://osteele.com/archives/2004/11/ides
03:30amalloythere's some function around that returns a reversed view of a vector in constant time, isn't there?
03:30amalloy$findfn [1 2 3 4] [4 3 2 1]
03:31tomojrseq?
03:31sexpbotExecution timed out.
03:31sexpbot[clojure.core/rseq clojure.core/reverse]
03:31amalloyah, thanks tomoj (and sexpbot eventually)
03:31clojurebotsexpbot is not a clojurebot
03:31_na_ka_na_:P
03:32_na_ka_na_someone's jealous
03:32tomojI was peeking at that and subseq/rsubseq earlier
03:32tomojwonder why I never noticed the latter two even though their metadata says 1.0G
03:33Fossiwth does findfn do?
03:34amalloy$findfn 3 2 1
03:34sexpbot[clojure.core/bit-xor clojure.core/rem clojure.core/- clojure.core/unchecked-subtract clojure.core/quot clojure.core/compare clojure.core/mod clojure.core/unchecked-remainder clojure.core/bit-and-not clojure.core/unchecked-divide]
03:34amalloyFossi: finds functions f such that (f 3 2) == 1
03:36tomoj$findfn *ns* '+ nil
03:36sexpbot[clojure.core/ns-unalias clojure.core/ns-unmap clojure.core/extend clojure.core/descendants clojure.core/prn clojure.core/print clojure.core/alter-meta! clojure.core/parents clojure.core/get clojure.core/underive clojure.core/ancestors clojure.core/println clojure.core/pr]
03:36tomoj&(+ 1 2)
03:36sexpbot⟹ 3
03:36tomojimpressive
03:36amalloy*chuckle*
03:37amalloytomoj: i think there actually is a vulnerability in there if you work hard enough
03:38amalloyi'm not sure exactly where it is, but ns-unmap isn't as carefully sandboxed as the eval plugin
03:48amalloys/ns-unmap/findfn
03:48sexpbot<amalloy> i'm not sure exactly where it is, but findfn isn't as carefully sandboxed as the eval plugin
03:50tomojhuh..
03:50tomoj&*ns*
03:50sexpbot⟹ #<Namespace sandbox6382>
03:50tomoj$findfn *ns* "sandbox6382"
03:50sexpbot[clojure.string/trim clojure.string/lower-case clojure.core/munge clojure.core/str clojure.core/namespace-munge clojure.contrib.string/as-str]
03:50tomoj$findfn 'clojure.core :only () nil
03:50sexpbot[clojure.core/prn clojure.core/print clojure.core/refer clojure.core/apply clojure.core/println clojure.core/pr clojure.core/print-special-doc]
03:50tomoj&(+ 1 2)
03:50sexpbot⟹ 3
03:50tomojhow???
03:53tomojguess it's a good thing so I didn't totally bork sexpbot..
04:59LauJensenIs there anything in clojure-/javaland which has the same capabilities as Solr but is suited for use in a desktop client?
05:01Fossistandalone solr?
05:03LauJensenFossi: Havent come across that before, looking into it
05:10LauJensenFossi: AFAIK there is no option to run Solr outside of a servlet container of some sort
05:14Fossihmm. i thought there was a standalone version
05:16Fossibut maybe i'm confusing using it in your own servlet vs in it's own
05:16Fossiso there's still a container (just your own)
05:17Fossibut i guess one could at least use lucene
05:20Fossiwell, i guess you could also deploy with a standalone jetty
05:22LauJensenJetty is an option, but Im afraid that on certain clients that will spawn some firewall warnings
05:22Fossimight be
05:23bobo_LauJensen: you could use lucene without solr?
05:24LauJensenbobo_: How much does solr add to lucene?
05:24bobo_not sure, mostly the restfull stuff i think
05:24bobo_never used solr
05:24LauJensenInteresting, I'll check it out
05:26LauJensenIt doesnt say so under features, but can I assume that Lucene reads .doc, .pdf, etc as Solr?
05:26LauJensenah wait, no. Thats one of the things Solr adds
05:27bobo_seems weird to require a servletcontainer for things like that
05:28LauJensenSolr imports Tika, http://tika.apache.org/0.8/formats.html
06:41mduerksenchouser: [14:17:26] chouser: isn't there another way to say (iterate inc 0) ? yes, there is: (range) ##(doc range)
06:41sexpbot⟹ "([] [end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0, step to 1, and end to infinity."
07:09LauJensenmduerksen: It seems odd that chouser would ask that question, since I know, he knows the answer
07:17mduerksenLauJensen: rereading the conversation, i think i might have got the context of that question wrong,
07:22mduerksennow i feel kinda goofy :)
07:30LauJensenhehe, it happens a lot on IRC - Though I think you're the first to educate an author of Clojure books on the use of range :)))
07:43Berengal_workIn interfacing with some Java code, I need to subclass an abstract class and pass that class into a method. Is there a better way of doing this than gen-class?
07:43cemerickBerengal_work: proxy is your only other built-in option for concrete inheritence.
07:44Berengal_workcemerick: proxy doesn't give me a class, it gives me an instance
07:44cemerickIt produces instances of an anonymous class, so you'll not be able to refer to the class by name (if that happens to be important to you).
07:44Berengal_workThe method in question takes in a class object
07:44Fossihmm nice design
07:44cemerickBerengal_work: which API is this?
07:45Berengal_workcemerick: It's a homemade one... -_-
07:45FossiBerengal_work: then hit whoever designed that with a large stick
07:45cemerickBerengal_work: is the passed class going to be doing e.g. .newInstance, etc?
07:45Fossiwon't solve the problem, but makes you feel better
07:45Berengal_workcemerick: Yes, that's the idea
07:46Berengal_workFossi: There are legitimate cases for passing class objects around in Java (even though this isn't one)
07:47Fossiyeah, and most of them are crude workarounds for generic problems :(
07:47Fossior problems with generics rather
07:47cemerickBerengal_work: looks like proxy classes don't respond well to .newInstance. gen-class would appear to be your best bet.
07:48cemerickOr, you can use the ASM built into Clojure to build a concrete inheritence class-generation form. ;-)
07:48Berengal_workcemerick: gen-class works, but it sucks for dynamic development. I have to compile the project AOT to be able to play with it
07:48Berengal_workcemerick: mind you, once I have the class, redefining the methods works fine
07:49cemerickBerengal_work: When one needs externally-referenceable classnames, that's the tradeoff currently involved. *shrug*
07:50Berengal_workcemerick: deftype seems to manage, but it only does interfaces
07:52Berengal_workcemerick: Was the ASM comment in jest, or is it a legitimate way of doing things_
07:52Berengal_work)
07:52Berengal_work?
07:52cemerickBerengal_work: I meant statically-referenceable classnames
07:53Berengal_workThey don't need to be statically referenceable, as in I don't need them to be available from inside Java code
07:53Berengal_workI just need a class that's a subclass of an abstract class, and that I can call newInstance on
07:54cemerickBerengal_work: deftype, definterface, etc are all built on top of ASM, so you certainly *could* build a form that generated concrete classes.
07:55cemerickNot many people touch the ASM stuff directly, though. You need to know bytecode well. :-P
07:55cemerickBerengal_work: deftype/record not supporting concrete inheritence was an intentional design decision
07:56Fossiwell, asm isn't *that* lowlevel
07:56Berengal_workcemerick: I'm well aware of that, and I support that decision, but in this case it doesn't work out that well.
07:57cemerickFossi: well, it certainly helps to know what's going on under the covers :-)
07:57cemerickBerengal_work:
07:57FossiBerengal_work: could you subclass/change the receiver of the class param?
07:57cemerickbah
07:57Berengal_workAnyway, gen-class /works/, just not as seamlessly as I'd want it to.
07:57Fossior is that out of your control as well?
07:57Berengal_workFossi: It's a static method, so no
07:58Fossiyeah, well, sounds like a heap of trouble :)
07:58Fossigood luck, time for more javascript now ;)
07:59cemerickBerengal_work: Yeah, it's a blind spot in the interop stuff, but also an edge case AFAICT.
08:00cemerickPerhaps someone will eventually need to do that sort of thing a lot, and a dynamic defclass (or whatever) form will result.
08:01Berengal_workcemerick: Maybe. I don't know much about the clojure internals, but from what little I've seen it seems it should be possible to make a modified gen-class that loaded the resulting class instead of writing it to disk
08:01Berengal_workIf that's the case then making defclass would be rather easy
08:03Berengal_workAnyway, it doesn't hinder anything. It just makes things a little bit uncomfortable during development
08:03cemerickSure, though I suspect most people would probably prefer inline method bodies.
08:11LauJensenDoes anybody know what a letter of "no objection" is ?
08:20Berengal_workcemerick: Hillarious, (if (not *compile-files*) (compile (symbol (str *ns*))) `(macro expansion ...)) works :P
08:21anarsLauJensen: if you have a letter of no objection for, say, a building, thenit's a confirmation than you can continue to use the building.
08:21anarsthen it's*
08:21anarsthat*
08:21cemerickBerengal_work: what do you mean, "works"?
08:21Berengal_workcemerick: That way it'll generate the class
08:21LauJensenanars: okay. So the one sending the letter is giving up his right to object to something?
08:22anarsLauJensen: exactly
08:22anarsare you in luck?
08:22LauJensenRight, thanks a lot
08:22cemerickBerengal_work: you mean, from a gen-class?
08:22Berengal_workcemerick: yes
08:22cemerickThat doesn't sound right at all.
08:24Berengal_workcemerick: No, it's an absolute kludge, but it does what I wanted
08:24cemerickBerengal_work: yeah, there's no provision at all for loading gen-class-generated classes at runtime.
08:25cemerickBerengal_work: either I entirely misunderstood what you're trying to do, or you're seeing a previously-generated class
08:25Berengal_workcemerick: I'm not seeing a previously generated class at least
08:26Berengal_workcemerick: I have a macro that, if called when *compile-files* is false, compiles the current namespace, else it expands to the gen-class definition
08:28cemerickBerengal_work: Perhaps I'm just dense this morning. I'm not sure what that gets you -- compiling the current ns isn't going to give you a class at runtime.
08:31Berengal_workcemerick: It does give me the class in the repl
08:38cemerickBerengal_work: My confusion stems from the fact that gen-class is a no-op if *compile-files* is false. https://github.com/clojure/clojure/blob/master/src/clj/clojure/genclass.clj#L612 Given that, compiling the current ns won't produce the class named in any gen-class form.
08:41cemerickBerengal_work: ah, see gen-and-load-class. It's exactly what you're looking for.
08:41cemerickI'd forgotten about that. :-(
08:42apgwoz`hey all, so, i'm using clojure 1.2, and i thought for sure that (duck-streams/with-in-reader socket (read-line)) should work, but it doesn't. looking at the source seems that it works with a BufferedReader or LineNumberingPushBackreader.. does this sound right?
08:47Berengal_workcemerick: Ah, thanks
08:49fliebelmorning
08:53Berengal_workcemerick: Also, compile sets *compile-files* to true
08:53cemerickgood point :-)
08:54cemerickBerengal_work: in any case, compiling a namespace simply won't give you a corresponding class at runtime, unless your macro is doing something extraordinarily clever.
08:56Berengal_workcemerick: When compiling, the macro emits a gen-class declaration. I don't know exactly how class-loading works, but it seems it's loading it when it's first referenced.
08:56Berengal_work... and I can't find gen-and-load-class ...
08:57chousergen-and-load-class has been gone for a long time
08:58chouserit did what you want, except apparently behaved badly enough in some circumstances to warrant removal.
09:00Berengal_workchouser: Probably because evaluating the same declaration more than once causes the jvm to throw a hissy-fit
09:01chouserI think it may have had logic that attempted to avoid that by printing a warning if you changed the def and reloaded it
09:01cemerickchouser: it's in head right now?
09:02chousergen-and-load-class is??
09:02cemerickyup
09:02cemerickhttps://github.com/clojure/clojure/blob/master/src/clj/clojure/genclass.clj#L700
09:03chouserwrapped in (comment)
09:03chousertook me a moment too
09:03cemerickOK, that's it, I'll be back in an hour. :-P
09:05Berengal_workYou could maybe get around it by loading each class defined this way in a separate classloader
09:06Berengal_work... I seem to be full of awful hacks today...
09:08LauJensenClojureQL 1.0.0 is now released, info on http://clojureql.org
09:12fliebelLauJensen: Congrats!
09:13LauJensenthanks :)
09:14fliebelThis is going to give people a hard time, deciding what is more 'cool', to use a noSQL db, or a functional DSL on a SQL db. ;)
09:14LauJensenSo you're saying I should write a nosql backend for cql ? :)
09:15fliebelLauJensen: If that makes sense, it would be total awesomeness. Otherwise: no, just that both noSQL and CQL are cool :)
09:16LauJensenWell, relational algebra was cooked up for relational databases. But it would be fun to see if I could make the connection. The interfaces are über pleasant to work with, if I do say so myself
09:17fliebelLauJensen: You should have a look at Django, someone managed to get their ORM to work with CouchDB, IIRC.
09:18LauJensenI'll take a look at Couch and see what can be done
09:18Berengal_workCouch is pretty much "object" oriented already, isn't it?
09:18fliebelLauJensen: FYI: Clutch has a Clojure view server.
09:18Berengal_workAt least compared to relational databases
09:19LauJensenBerengal_work: I think they call it 'document oriented'
09:19fliebelBerengal_work: I'd say document orientated. But they use map/reduce.
09:20bobo_A column database is probably more suitable for relational algebra then a document store? ie maybe redis rather than couch?
09:23LauJensenbobo_: You might be right, but I'll have to check both of them out to see if it makes sense at all
09:23fliebelbobo_: I don't know Redis, but from Wikipedia, it seems like a kay-value store: http://en.wikipedia.org/wiki/Redis_(data_store)
09:24Berengal_workLauJensen: Would it be a good idea to make it possible to bind columns selected to names?
09:24LauJensenBerengal_work: Im not sure
09:24bobo_fliebel: yes, and key value stores can be treated as column databases
09:25bobo_maybe cassandra is even more suitable? never used it
09:25Berengal_workLauJensen: Having to manually get the values out of records after I've just namned them all the select statement is one of my major annoyances with SQL
09:25Berengal_work*in the select
09:25bobo_the biggest annoynace in rdbm is to create tables and change tables
09:26LauJensenBerengal_work: Well, with ClojureQL you can count down on the work some
09:27LauJensenJust looked at redis - It looks like you could somewhat quickly write a backend for CQL.. I'll see if I can find some time this week unless somebody else does it first *hint* *wink*
09:27Berengal_workLauJensen: Well, writing the SQL has never really been an issue with me. What's annoying is dealing with the ceremony around the result sets and records
09:28bobo_LauJensen: i toyed with the idea to write one. but i never have any time =(
09:28LauJensen(let [cols [:id :name :wage]] (with-results [r (project (table :users) cols)] ......)) that way you only write your columns once Berengal_work
09:28bobo_Berengal_work: well, that depends on the language? in java if you use simplejdbcTemplate its kinda pleasant
09:29fliebelLauJensen: If I was to attempt it, I'd do Couch anyway. Not for any technological reason whatsoever. This is the Django thing, btw: https://github.com/benoitc/couchdbkit
09:29Berengal_workLauJensen: Ah, so with-results binds the columns? I missed that
09:30LauJensenBerengal_work: No, Im just showing you, that your var containing the column names, can both be pushed into the sql statement, and extracted later, like [{:keys cols}] so you save the added layer of extraction
09:30LauJensenwith-results is just lazy eval of f on the resultset
09:31LauJensenfliebel: looks simple enough
09:32fliebelLauJensen: Until I actually need it, it's on my somewhere-in-the-next-ten-years list.
09:35Berengal_workLauJensen: I must be missing something. Are you talking about destructuring the record using {:keys cols}?
09:35raekanyone have a recommendation of how to quickly render a preview of one's README.md file?
09:36fliebelraek: Uhm, take a Markdown parser, and open it in your browser?
09:37raekfliebel: yes, something like that. is there any good command line program for that?
09:38fliebelraek: Probably just the original Perl version, or something in Clojure. One moment...
09:38fliebelraek: There's markdownj, Showdown via Rhino, and Pegdown.
09:39Berengal_workpandoc's also neat
09:39raekfliebel: ok, thanks!
09:45fliebelharhar, Bash rulz! Clojure took ages to compute irc chat lines/user and ran out of memory. Bash did it instantaneously: ls . | xargs cat | grep "<b>fliebel" | wc -l 2437
09:46Obviousthat's not bash, that's xargs, grep and wc.
09:48fliebelObvious: When I wrote something that (println "something"), would you say I used Clojure, or println?
09:49LauJensenraek: http://github.github.com/github-flavored-markdown/preview.html
09:50raekLauJensen: oh. that's exatctly what I needed. thanks!
09:50Obviousfliebel, you could write calls to xargs, grep and wc with Runtime.exec from clojure, you can't write a call to clojure's println with bash.
09:51LauJensenraek: np, you can also roll your own quite quickly if you like
09:51LauJensen(defn markdown-to-html [txt]
09:51LauJensen (let [cx (Context/enter)
09:51LauJensen scope (.initStandardObjects cx)
09:51LauJensen input (Context/javaToJS txt scope)
09:51LauJensen script (str showdown
09:51LauJensen "new Showdown.converter().makeHtml(input);")]
09:51LauJensen (try
09:51LauJensen (ScriptableObject/putProperty scope "input" input)
09:51LauJensen (let [result (.evaluateString cx scope script "<cmd>" 1 nil)]
09:51LauJensen (Context/toString result))
09:51LauJensen (finally (Context/exit)))))
09:54fliebelWho wrote the #clojure statistics thing?
09:55lpetithello
09:56fliebellpetit: hi
09:56abedrayou mean encanter?
09:56fliebelabedra: No, http://clojurewise.blogspot.com/2011/01/clojure-in-2010.html
09:56abedraah
09:56fliebelHe uses encanter though.
09:56abedrayes
09:58LauJensenIs encanter an alternative to incanter?
09:59fliebelLauJensen: Not that I know, I think it was a typo.
09:59LauJensenI thought so at first, but when you both said it, it got me wondering
10:01abedrayep typo
10:02abedraearly morning
10:08raekwhat would be a good name of an 'assoc' that throws an exception if the key is already in the map?
10:08blablubbhey all, do you know of any time schedule for the stable clojure 1.3 release?
10:09fliebelblablubb: Clojure/core doesn't seem to like roadmaps, so I guess no-one know, not even Rich.
10:10fliebelraek: assoc-once?
10:10blablubbthe alpha releases seemed to have a month distance it seemed ;)
10:11fliebelraek: Or just add?
10:11raekhrm
10:14fliebelraek: Or (assoc-unless map identity key)
10:15raekI like assoc-once
10:15blablubbit's definitely very precise ;)
10:17fliebelraek: The oposite would be fun for ad-hock records. e.g. you can't add new keys.
10:20blablubbhmm I am currently involved to perform perfomance tuning of my code which is pretty slow right now
10:21fliebelblablubb: Slow compared to what?
10:21blablubbdo you know any resources that discuss issues of performance pitfals in clojure?
10:21fliebelblablubb: Sure, one moment.
10:23fliebelhttps://groups.google.com/group/clojure/browse_thread/thread/3c759739c265d14d/1daa9744a3e19704
10:24blablubbthanks. I am going to read into it :)
10:24fliebelblablubb: I short: Clojure boxes primitive data, on long sequences be sure not to hold onto the head, do no more work than is needed, multithreading does not always pay off.
10:24fliebelblablubb: This is the second page, fyi.
10:25fliebelStarts here: https://groups.google.com/group/clojure/browse_thread/thread/3c759739c265d14d/073475ace2810b94
10:31Berengal_workThe jvm needs some support for lightweight preemptive multitasking
10:31chouserin some way that is different from threads?
10:31Berengal_workIn a way that's more lightweight than native threads
10:32raekthe executors framework might solve some of the problems
10:32Berengal_workraek: Not preemptive...
10:32chouseragents solve some related problems
10:33Berengal_workagents too aren't preemptive
10:35chouserin what way?
10:35Berengal_workPut enough agents in an infinite loop and the entire agent system stops
10:36chouserif you have one processor and an agent running on it, and send an action to another agent, both agents will share the one processor
10:36Berengal_workYes, using two different native threads
10:36Berengal_workUnless I've missed something
10:36chouseryes, but the 1000 other idle agents aren't using any native threads at all
10:36Berengal_workIndeed, but what if they're not idle?
10:37chouserthen they are. :-)
10:37chouserI only said that agents solve *some* related problems.
10:37chouserthere are cases when raw Java threads or Executors are too heavy where agents are not.
10:37Berengal_workYes, but the preemptive part is important
10:38chouserthere may be other cases where agents are also too heavy
10:38Berengal_workI thought agents used executors behind the scenes?
10:38raekthey do
10:38Berengal_workSo you spare yourself the cost of booting one up then
10:39Berengal_workAnyway, I don't really use it often, but I miss the semantics of Haskell's forkIO...
10:39raeksend uses a j.u.c.Executors.newFixedThreadPool and a j.u.c.Executors.newCachedThreadPool
10:40raekhrm, I think I'm starting to realize what you are thinking about
10:41Berengal_workThere aren't many multitasking frameworks where you can fire up 100000 threads and still have a useable machine
10:42raeka fixed number of native threads, but still preemptive?
10:42Berengal_workraek: Yes. Haskell preempts on gc. Erlang too works in a similar fashion, but I'm not familiar with it
10:43Berengal_workgc as in both allocation and collection, that is
10:43raekI don't think java/the jvm has any way of pausing the a running in one thread and resuming it in another
10:44raek(if I'm wrong, please tell me)
10:44Berengal_workNo, I've looked for a way the last hour. The only relevant thing I found was a paper from about 10 years ago
10:45Berengal_workhttp://www.xcf.berkeley.edu/~jmacd/cs262.pdf
10:45raeksomething like that could perhaps be accomplished by thread interruption, but that would only work for your own code
10:47Berengal_workIf it requires code mofification, you could get away with a custom trampoline and a manual cps transformation
10:47Berengal_workmodification*
10:48Berengal_workWhich wouldn't be that comfortable to program in
10:58fliebelBerengal: That sounds nice… a trampoline that returns onto a queue, so you can do cooperative stuff.
11:14StartsWithKwhat would be the easiest way to load all forms from file so that line numbers metadata is attached to them but forms are not evaluated?
11:15Berengalfliebel: Still not preemptive on the runtime level. Context switching still happens at predetermined points in the code.
11:20fliebelBerengal: I'll have to google preemptive to see what you mean I think...
11:20Berengalfliebel: preemptive is the alternative to cooperative
11:21Berengalfliebel: Basically, where cooperative tasks say "I'm done for now, someone else run", preempted tasks get told by the runtime "Your time is up, it's someone else's turn now"
11:21fliebelBerengal: But that is like regular threads work, right?
11:22Berengalfliebel: Yes, they're preempted
11:22BerengalBut kernel threads are also pretty expensive
11:23BerengalFor example, my machine starts becoming slow when I start about 1000 Java threads, even when they all mostly sleep
11:23chouseris there any option other than (a) the OS interrupting (therefore a real OS thread) or (b) having something in userspace periodically checking to see if it needs to give up control?
11:23BerengalWhile it manages 100,000 Haskell lightweight threads just fine, even when they all do some work
11:24fliebelchouser: Haskell is the user space in this case I think. Is this what they call 'green threads'?
11:25Berengalfliebel: Yes, but I think that's mainly a java term. They're called lightweight threads in Haskell at least
11:25chouserI don't know about Haskell. I think ruby and python check periodically in userspace to allow multiple "threads" to make "simultaneous" progress.
11:25Berengal(Other terms include user threads and fibers, I think)
11:26BerengalHaskell does scheduling on allocation, gc and IO. Maybe some other times as well
11:27BerengalRuby and Python reschedule every few VM "tick", if I remember correctly
11:27fliebelSo what about sending tasks to a thread pool?
11:27chouserI would expect there to be a Java lib for this actually, though I'm not seeing one.
11:28Berengalfliebel: They're not preempted.
11:28Berengalfliebel: If you fill up the pool, new tasks are put in a queue and don't make any progress at all until some other task finish
11:29chouserhm, nevermind
11:29chouserwithout continutaion support, it may not be possible on the JVM.
11:29fliebelBerengal: You are right. So it's a JVM limitation then?
11:30fliebel(not so related: what is clojure.langRT doing?)
11:30Berengalchouser: The paper I linked to earlier did a CPS transform on the code, but there seemed to be severe limitations. A limited form is possible, but you can't have the entire cake without changes to the jvm it seems
11:31chouserClojure rejected CPS transform in favor of host-compatible calling conventions.
11:32BerengalI think you could get away with just changing the jvm implementation though, but I'm not intimately familiar with the specs
11:32BerengalIt would have some consequences for code that expects a thread to always run on the same native thread though
11:33Berengal(Haskell has a separate forkOS call to fork a native thread when e.g. interfacing with C)
11:41fliebelWhat is 'the' way to use PersistentQueue in Clojure? JoC uses EMPTY and conj to add things to them. If I wanted to convert or add a sequence to a PersistenQueue, would I reduce conj over the items?
11:50blablubbhumm if I have (deftype my-type ...) what exactly is the constructor "(my-type. ...)" in clojure? is it a function?
11:52StartsWithKblablubb, a real java class constructor where ctor args match your fields
11:53StartsWithK(deftype Foo [a b c]) (Foo. 1 2 3)
11:56blablubboh it's a macro expanding to new...
11:56blablubbfound it ^^
11:57pdloganfliebel: if you want to "add all" from another collection there is an addAll method - unless you want more control over the order in which elements are added I don't see a reason not to use that.
11:57pdloganfliebel: oh, except that method throws an exception
11:57fliebelright...
12:00raekreduce + conj = into
12:00fliebelraek: Oh, right :)
12:01raekso yeah, it seems like (into empty-queue some-coll) is the easiest way
12:01raek(assuming (def empty-queue clojure.lang.PersistentQueue/EMPTY))
12:03fliebelWould this make sense, or is there a better way? (into clojure.lang.PersistentQueue/EMPTY (concat [f1 f2] fs))
12:05raekmaybe you could replace the concat call with the somewhat unknown list
12:05raeklist*
12:05raek(into clojure.lang.PersistentQueue/EMPTY (list* f1 f2 fs))
12:05fliebeloh, nice :)
12:11raekit would be nice to have (defn queue [& elems] (into clojure.lang.PersistentQueue/EMPTY elems)) in core
12:11raekto complement 'vector', 'hash-set', etc...
12:11chousersuch a thing is so simple and obvious, there must be some reason it isn't.
12:12raeksure. *shrugs*
12:22chouserI think it's because of the potential to confuse a persistent queue and a blocking queue -- similar terms, but very different things.
12:24islonhow do I create a map programaticaly in clojure? something like (create-map ([:a 1] [:b 2]))
12:25amalloy&(into {} [[:a 1] [:b 2]])
12:25sexpbot⟹ {:a 1, :b 2}
12:25islonoh thanks amalloy
12:25islontotaly forget about into
12:25amalloyislon: or ##(zipmap [:a :b] (rest (range)))
12:25sexpbot⟹ {:b 2, :a 1}
12:25mrBlissislon: there's also hash-map and array-map
12:26islonthanks
12:34raekfogus`: marginalia is wonderful.
12:35fogus`raek: Thank you. :-)
12:37raeknot only does it present everything in a very readable form, but also in a very stylish one
12:38raekoh no! the unicode snowman looks broken now...
12:39Crowb4rlol
12:39raekfogus`: I would suggest adding <meta charset="UTF-8"> to the head element
12:39raeksince clojure code is in UTF-8
12:39fogus`OK. Will do. Thanks
12:39raekand browser most often default to something else
12:39raeks
12:50islonhow do you check if a vector contains an element?
12:50raekislon: some
12:51raek&(some #{3} [1 2 3 4 5])
12:51sexpbot⟹ 3
12:51raek&(some #{7} [1 2 3 4 5])
12:51sexpbot⟹ nil
12:51islonweird
12:51raekthis operates in linear time, since it might have to look through every element in the vector
12:52raekif you want to check this for many elements, consider using a set instead
12:52raeksince they have nearly-constant-time lookup
12:53raekas you probably have seen, contains? works on vectors, but does something else
12:53isloni was hoping for something like (exists? 4 [1 2 3 4]) -> true but some will do the job
12:55raekyes, 'some' is a bit more general. it not only tells you if it found it, but also returns the "whitness"
12:56islonand receives a function as parameter
12:57raekyup. that function should return the argument if it is "it", and nil otherwise
12:58raekwhich is what sets do when you use them as functions
12:58islonunderstood
13:22StartsWithKhttp://paste.pocoo.org/show/315430/ when i try to get line numbers from LineNumberingPushbackReader i am getting line number where forms end and not where they start
13:22StartsWithKam i doing something wrong here?
13:24StartsWithKhttp://paste.pocoo.org/show/315431/ clojure.lang.Compiler has this kind of strange looking loop where it first collects where form ended and then where is started, hmm..
13:27hiredmanbecause you are reading the loop backwards
13:27hiredmanor, the loop is written backwards
13:28StartsWithKwhat do you mean by backwards?
13:29StartsWithKlines increment, but they report line where form ends
13:35midsLauJensen: gratz on ClojureQL 1.0.0
13:35LauJensenmids: thanks! :)
13:48hiredmanStartsWithK: if you write the loop out and unroll it from the for syntax it makes more sense
13:58rata_hi all
14:00amalloyhiredman: i guess i'm dense; i don't see what's backward there. it looks to me like get-line is always being called before get-form, and res is clearly associating each form with its corresponding meta
14:01hiredmanamalloy: looking at the java code from Compiler
14:01amalloyoh
14:05amalloyhiredman: yeah, although doesn't this result in the first form being read not having its LINE_BEFORE set? i guess it's out of context: LINE_BEFORE is probably initialized to zero somewhere
14:05StartsWithKamalloy, yes, default to zero
14:06StartsWithKi think its all good, only thing it is missing is to manualy slupr all whitespace before reading next form
14:06StartsWithKso i can mark start position, i think LispReader will do that internally
14:07StartsWithKso, thanks ppl for help
14:20fliebelchouser, Berengal: Cooperative concurrency experiment: http://pepijndevos.nl/cooperative-concurrency-in-clojure
14:21chouserParsistentQueue -> PersistentQueue
14:21chouserinteresting.
14:21fliebelchouser: I'm still checking for errors myself as well. I must get used to posting to draft@posterous.com :S
14:31Berengalfliebel: That's interesting, and shows how simple custom execution semantics can be
14:35fliebelBerengal: :)
14:36fogus`fliebel: Really cool.
14:36fliebelfogus`: Thanks :)
14:38tipairOh hi friends. Has anyone here embedded Clojure into a C# or Java app before?
14:39tipair(i.e. use clojure as a scripting language)
14:40fliebeltipair: I read about someone who made an wrapper for Clojure that allows it to be used in the JSR 323(or whatever) scripting bridge. You know… what Rhino runs in.
14:41amalloytipair: someone posted to the mailing list recently about writing a ClojureREPL component for swing
14:41amalloybut it was a closed-source project
14:41clojurebotproject euler is http://ProjectEuler.net
14:42amalloyclojurebot: your mom is http://ProjectEuler.net
14:42clojurebotIk begrijp
14:44fliebeltipair: http://code.google.com/p/clojure-jsr223/
14:45fliebelamalloy: Do you have a link to that thread? Or do you know of any generic JSR 223 REPL?
14:45cemerickamalloy: really? The enclojure REPL component is out there already: http://www.enclojure.org/The+Enclojure+REPLs+%28Not+just+for+Netbeans!%29
14:45amalloycemerick: they were doing something special with their repl. i didn't read very carefully
14:46amalloycemerick, fliebel: http://groups.google.com/group/clojure/browse_thread/thread/e4f7e37d3306daa4/4ce34bbcc3d8d59c?show_docid=4ce34bbcc3d8d59c
14:47amalloytipair: ^
14:50Berengalfliebel: http://hpaste.org/42769/lightweight_threads_and_stm <- example of Haskell's lightweight threads in action, by the way
14:51ossarehI love that clojure has ratio's... I hate that nothing else has ratios.
14:51ossarehnothing else == riak and javascript
14:52fliebelossareh: Riak? That's a DB, right?
14:52ossarehfliebel: ye
14:52ossarehfliebel: a nosql db - pretty cool imho
14:53fliebelossareh: Don't know about it. Does it have a REST API? Anyway, I guess you can implement ratio in JS yourself.
14:54ossarehfliebel: it does. I'm not of the thinking that writing a json parser in javascript to run on their db is a good idea.
14:54fliebelossareh: Javascript IS a JSON parser… Javascript Object Notation ;)
14:57ossarehfliebel: I know, I'm pretty conversant with javascript. The issue here is that if you tell c.c.json to produce json of 3/4 it will spit it out as a number string mishmash which cases parsers to barf.
14:57ossarehparsers other than c.c.json.
14:58ossarehc.c.json switches over to a clojure form reader when it finds a number - since Ratio falls into that category it can parse and consume its own json but other things cannot parse it - like Riak.
14:59ossarehon one hand this is fine -I'm asking it to jsonify something that doesn't exist in the json spec and it does the best it can. on the other hand it json has a well defined format and this breaks it.
14:59fliebelossareh: If you use Riak only from Clojure, you can store your own representation for a ratio, like {"denominator":4,"devider":5} or whatever they're called.
15:00ossarehyeah, exactly. This is probably what I'll end up doing.
15:00fliebelossareh: You know the Clojure functions the pull them out of a ration?
15:01ossareh(doc denominator)
15:01clojurebot"([r]); Returns the denominator part of a Ratio."
15:01tipairfliebel, amalloy: Cool, thanks. We're actually using ClojureCLR, truth be told, but that's awesome.
15:01ossareh(doc numerator)
15:01clojurebot"([r]); Returns the numerator part of a Ratio."
15:01fliebelossareh: Ah, numerator was what I wanted to know :)
15:02fliebeltipair: Heh, you should do a Clojure blog about the CLR. There is currently very little about CLR trick with Clojure :(
15:03tipairfliebel: If this works, it will be blogged about. :)
15:03fliebelBerengal: I am not yet able to read that kind of Haskell. If you feel like explaining it line-by-line, cool. Otherwise, I believe you on your word it's awesome :)
15:04fliebeltipair: Where is the blog?
15:06Berengalfliebel: The short of it is it's making numThread (command line arg) threads. These wait for the ref runFlag to become True, before decrementing the counter. The main thread then waits a bit, to allow the other threads to settle in. It then sets the runFlag to True, and waits for the counter to reach zero
15:08Berengalfliebel: 100,000 threads doing this takes 1.3 seconds in the interpreter (0.5 when compiled and run with 3 native threads)
15:08fliebelBerengal: Thanks :) What is <- for?
15:08RaynesPulls a value out of the IO monad, iirc.
15:08BerengalRaynes: Well, any monad, but yes
15:08RaynesRight.
15:09markskilbeckAnyone know why I'm getting a 'unable to resolve symbol: setLayout in this context' exception? http://pastebin.com/EDtjsn7n
15:09BerengalIt's basically assignment, except it can only do name shadowing
15:09amalloymarkskilbeck: you want .setLayout
15:09amalloyand .add, and .setSize...
15:09fliebelBerengal: Does this means it runs all those threads in a tight loop? when (not doRun) retry
15:11Berengalfliebel: It's a bit smarter than that. When an STM transaction fails, it doesn't actually retry until any of the vars touched change
15:11Berengalfliebel: At least I think that's how it works. I'm not too familiar with the internals
15:11markskilbeckamalloy: of course. Danke!
15:11fliebelBerengal: Thanks :)
15:12BerengalSpeaking of retry, does clojure have that?
15:12fliebelBerengal: Refs have hooks, so you could write it :)
15:13chouserAn explicit retry for STM transactions? no.
15:13chouseryou can throw an exception yourself and start the transaction over again if you'd like.
15:14Berengalfliebel: Could you also implement orElse?
15:15fliebelBerengal: Dunno… what does it do?
15:15Berengalfliebel: it takes two transactions as arguments. If the first one retries, it runs the second
15:16BerengalIt allows for nice select-like transactions
15:17ossarehwoo - haskell kinda looks like python and erlang had a kid.
15:17fogus`Berengal: It also requires read-tracking
15:19Berengalfogus`: orElse, you mean?
15:20fogus`Beregal: Yes. It also conflates flow control and transactions.
15:20Berengalfogus`: I think orElse only chooses on an explicit retry. If a transaction discovers it won't be able to commit, there's no use in trying the second transaction, since that won't be able to commit either. The entire transaction as a whole has touched dirty bits and needs to be redone
15:22BerengalI could be mistaken. As I said, I'm no expert on the internals
15:24fogus`I am not an expert in Haskell's impl (or Clojure for that matter), but I believe that I my points describe why orElse was excluded.
15:25BerengalClojure transactions see a snapshot of the refs from when the transaction started, right?
15:25fogus`The flow control should happen outside of a transaction to determine if work is needed, then if it is, then it should be done in a transaction
15:26amalloyBerengal: unless you modify the ref inside the transaction, in which case you see that value
15:26fogus`Berengal: And without orelse, there is no real need for retry (as you alluded to) :-)
15:26Berengalfogus`: It's rather the other way around. Retry by itself can be useful for waiting on a value
15:27Berengalamalloy: Does this mean that a transaction won't fail until it tries to commit?
15:27fogus`Berengal: That would require blocking no?
15:28Berengalfogus`: It would block the thread, yes
15:28amalloyBerengal: correct
15:28BerengalWhich is the point of waiting
15:28amalloybecause it's okay to have two transactions modify the same ref, so long as they both commit the same value
15:28Berengalamalloy: Or they use commute
15:29Berengalfogus`: If you see my earlier Haskell example, I use retry twice to wait. First to wait for a runFlag to become true, then to wait for the counter to reach zero
15:30fogus`Beregal: If you want to block for a value then something other than a transaction is likely better.
15:31Berengalfogus`: Not if you want to block for several values
15:32Berengalfogus`: That's sort of the point of transactions: atomic changes to multiple shared states
15:32BerengalIn this case, atomic reads of multiple shared states
15:32hiredmanBerengal: you can easily return a collection of a consistent set of read values from a transaction and block outside of the transaction
15:33Berengalhiredman: How can you block on multiple values at the same time outside of a transaction?
15:33fogus`The point of Clojure transactions are that they should never block the world
15:34Berengalfogus`: The world, no, but the thread?
15:34hiredmanBerengal: you read, return the collection, if the values are not what you want you read again
15:35Berengalhiredman: But once you exit the transaction, those values could become inconsistent in relation to eachother again
15:37fogus`Berengal: Well, time keeps on going. It never stops. :p
15:37hiredmanBerengal: uh, no they wouldn't
15:37hiredmanvalues are immutable
15:38hiredmanthe refs may end up pointing to different values, but they would with retry inside a transaction anyway
15:38Berengalhiredman: Are you familiar with the dining philosophers problem?
15:39hiredmanBerengal: how does that require blocking?
15:39Berengalhiredman: Each philosopher has to wait for both his forks to become available
15:39hiredmanhttp://rosettacode.org/wiki/Dining_philosophers#Clojure
15:39BerengalSo each fork is a ref containing either :available or :unavailable...
15:40Crowb4rlol, rosetta code. the guy who made that lives in the same town as me.
15:40Berengalhiredman: That implementation uses spinning
15:41hiredmanBerengal: as opposed to?
15:42Berengalhiredman: Waiting, as in wait/notify
15:42hiredmanwhat do you think retrying a transaction is?
15:42Crowb4rwhich the STM takes care of automatically correct?
15:42BerengalCrowb4r: Not in this case
15:45hiredmanBerengal: so you are saying that doing whatever you do in haskell to retry a transaction waits on the references to be changed before retrying the transaction?
15:46Berengalhiredman: Yes, basically
15:46BerengalIt can spin, of course, if the values still aren't what you expected them to be
15:46hiredmanyou can do that with watchers on refs if you like
15:46hiredman,(doc add-watch)
15:46clojurebot"([reference key fn]); Alpha - subject to change. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any ...
15:47hiredmanyou can add a watch to the refs you care about then block on those watches being called
15:47BerengalI guess that's true
15:48BerengalAnyway, compare the related Haskell version http://rosettacode.org/wiki/Dining_philosophers#Haskell
15:49hiredmanwhy?
15:49clojurebothttp://clojure.org/rationale
15:50hiredmanclojurebot: bzzt
15:50clojurebotHuh?
15:51Berengalhiredman: It's just where I'm coming from regarding explicit retry.
15:52BerengalIt's not explicit in the code, but it's inside the TMVar related functions, as opposed to in commit conflicts
15:52hiredmanat work (biggest clojure code base I am familar with) we don't use the stm at all, little to no coordination between threads
15:53BerengalWhat kind of system is that?
15:54hiredmanemail processing
15:55hiredmananytime the idea of cross thread coordination comes up we quickly remember that infact we have more than one machine we need to coordinate across and maybe there is some way to do with out
15:59solussdwhy?
15:59clojurebotwhy not?
15:59solussdwhy?
15:59clojurebotwhy not?
15:59solussdwhy not?
15:59shortcircuitwhy?
15:59clojurebothttp://clojure.org/rationale
16:01solussd,(println "why?")
16:01clojurebotwhy?
16:01solussdhaha!
16:01solussdI'll ask the questions clojurebot.
16:03Berengalhiredman: Anyway, it's your comment about retry and orElse conflating control-flow and transactions is true, and it /does/ bother me somewhat, but on the other hand they're useful to have inside a transaction, and I'm not sure you could build them out of other primitives
16:05BerengalThen again, Clojure and Haskell have different concurrency primitives. Maybe Clojure doesn't need retry and orElse
16:19bendlasFun clojure quirk of the day:
16:19bendlas,[do 1 2 3]
16:19clojurebot3
16:19bendlas,#{do do do}
16:19clojurebotDuplicate key: do
16:20bendlas,#{do}
16:20clojurebotnil
16:20hiredmaninteresting
16:20amalloy&(let [do 10] #{do})
16:20sexpbot⟹ #{10}
16:20fliebelbendlas: Why does that wok?
16:20hiredmanlooks like a bug
16:21bendlasCompiler.java:6209
16:21bendlasif (form instanceof IPersistentCollection)
16:21bendlasinstead of
16:21bendlas,(class '())
16:21clojurebotclojure.lang.PersistentList$EmptyList
16:22hiredmanwell, you want clojure.lang.ISeq
16:23bendlasISeq?
16:23hiredmanyes
16:23hiredmanISeq is more or less everthing that prints with parens
16:24bendlasyes, but I'm quite sure that special forms are supposed work only as source literals
16:24bendlaswhich means PersistentList
16:24hiredmanno
16:24hiredmanbecause macros can produce seqs
16:24bendlasoh
16:25pdk`producing seqs is pretty much what makes macros tick
16:25pdloganit might be easier to ask than search... a while back I had a link to an early implementation of clojure in common lisp... anyone have that handy?
16:25bendlasbut seqs are no IPersistentCollections, are they?
16:25hiredmanthey are, I believe
16:26hiredmanwell, at least concrete instances typically are
16:26hiredmanISeq may not be
16:26fliebelbendlas: Pretty much everything is a IPersistentCollections, except maybe numbers :P
16:26hiredmanthat whole if seems suspect
16:26hiredman[def x 1] seems like it would run too
16:27bendlasindeed, ISeqs are IPersistentCollections
16:27bmhI just came across assoc-in, is there anything confounding the existence of a dissoc-in?
16:27bendlasbmh, it's already in contrib afair
16:27bmhbendlas: oh. That's convenient. Where in contrib?
16:29bendlashttp://richhickey.github.com/clojure-contrib/core-api.html#clojure.contrib.core/dissoc-in
16:29hiredmanclojure and contrib have moved to the clojure github account
16:30bendlasyes, just noticed & updated bookmark
16:37lambdatronicHowdy folks. I'm running into trouble with a macroexpansion that works on 1.1.0 and 1.2.0 but not on 1.0.
16:37qbglambdatronic: Whats the macro?
16:38qbgAnd what are you using Clojure 1.0 for?
16:39lambdatronichttp://pastebin.com/0HV9SKng
16:39lambdatronicI'm working with a legacy project that is build on 1.0. It's headed by someone else who doesn't want to change it.
16:39qbgAre you getting an exception?
16:40lambdatronicAnyway, it seems like kind of a strange thing, as I don't think I'm using any syntax that's not 1.0 friendly. Clearly I'm mistaken.
16:40lambdatronicYeah, the exception is: java.lang.ExceptionInInitializerError
16:40lambdatronicNo fun stacktrace info to go with that.
16:40ossarehwhat if you macroexpand-1 - same issue?
16:40qbgWhy are you using eval?
16:41hiredmanew
16:41hiredmanthat is a horrible macro
16:41lambdatronicAlright, provide a better one that does the same thing.
16:42hiredmanhard to even read it, what is it supposed to do?
16:43lambdatronicThe macroexpansion works fine as expected and returns the same result as with 1.1.0 and 1.2.0, so the problem is in the eval stage.
16:44qbg(defmacro defsource [name & body] `(defn ~(with-meta name {:source-code `(defn ~name ~@body)}) ~name ~@body))
16:44hiredmanright, the macro is garbage, rewrite it to be clearer and it will work
16:44qbgUntested, something like that
16:44hiredmanbut it is so bad that, I am unable to get a clear picture of what you want from it, so if you have specs for what you want in english...
16:45qbgIt seems to attach the source of the function to its var
16:45lambdatronichiredman: The macro with-source-code is wrapped around any arbitrary def form to capture the source code of that form at read time and attach it to the metadata of the def'd var.
16:45hiredmanit seems like you want to store the form in metadata
16:45lambdatronichiredman: no need to be a troll. It was a simple engineering question.
16:45hiredmanI am not trolling
16:47lambdatronichiredman: Then you could offer a practical solution, or try testing the macro to see what it does.
16:47lambdatronichiredman: The pastebin example is pretty english readable.
16:47lambdatronichiredman: What do you think (get-source-code foobar) does?
16:47hiredmanwhat do you expect it to do?
16:48bendlaslambdatronic: have you looked at clojure.repl/source in 1.2 or clojure.contrib.repl-utils/source?
16:48hiredmanreturn the form? return the entire function body? I see eval called in the macro and the level of quoting is not immediately obvious
16:49qbgI wonder if porting source would be a better solution
16:50bendlasand yes the macro is ugly and non obvious
16:51hiredmanfor get-source-code I wouldn't even use a macro
16:51hiredman(get-source-code #'foobar)
16:52lambdatronicAlright, I just solved it myself.
16:53lambdatronichttp://pastebin.com/2c0n1Tvs
16:54bendlas`and mutation means lurking bugs
16:54lambdatronicThe solution was simply replacing ~(var-get (eval form)) with (var-get ~form).
16:54lambdatronicDone
16:55lambdatronicqbg: Your solution is limited to only defn statements. I want a general solution for arbitrary def-based forms. This is required because I am working in a domain-specific language with additional macros like defmodel, defcontext, defscenario that need to be wrapped genearlly.
16:56lambdatronichiredman: whether or not to make get-source-code a macro is a matter of opinion. I find the macro solution perfectly elegant in this case because I don't want to expose the internals of where I'm storing the source code in my public API. Again, this is part of a DSL for modellers who don't know clojure and are certain to screw up the #' reader-macro syntax.
16:57hiredman*shrug*
16:57qbglambdatronic: Have you thought about having your own def* forms add :source-code themselves and then provide your own versions of the def forms from core that do the same thing?
16:57lambdatronicbendlas`: The only mutation happening here is that the var being def'd is interned twice in succession, first without the :source-code metadata and then by it. However, as these forms are chained in the same macro, I don't see any holes where bugs could get though.
16:58qbglambdatronic: take a look at the result of (doc foobar) with your solution
16:59lambdatronicqbg: By abstracting this task into the with-source-code macro, I can embed it in all of my def* forms without having to repeat the logic an arbitrary number of times.
16:59bendlas`lambdatronic: yes, but as your solution proves, it does make a difference *when* the interning happens
17:00bendlas`with the eval, it happened *during* macroexpansion (as opposed to ~ which splices forms)
17:00lambdatronicbendlas`: I do see that now. For some magical reason 1.1 and 1.2 didn't seem to mind the compile-time interning, but 1.0 certainly is upset by it. Now it's resolved.
17:00qbglambdatronic: This solution requires you use with-source-code everywhere
17:01lambdatronicqbg: I don't see your distinction. I place with-source-code in each of my def* macro definitions, and then it propagates perfectly well.
17:01lambdatronicWithout having to rewrite the core library or repeat the logic over and over in different def* macro definitions.
17:03lambdatronicThus (defmodel mymodel ...) would be defined as (defmacro defmodel [modelname ...] (with-source-code (def ...)))
17:03lambdatronicAnd no one has to ever worry about it.
17:04qbgDo you really want the source of mymodel to be in terms of def and not defmodel?
17:04qbgAlso, you macro drops docstring/arglists
17:05lambdatronicqbg: I had them in an earlier version that used gensyms, and it works fine in 1.1 and 1.2. This was a simplified version for 1.0.
17:07lambdatronicqbg: I eval-ed the form at compile-time and captured the metadata off the interned var (which holds the docstring and arglists) and then assoc-ed the :source-code field onto that before reattaching it to the var.
17:08qbgI modified the second paste to a form that should work
17:08qbgYou don't need eval here
17:08lambdatronicqbg: There isn't an eval anywhere in there. What are you referencing?
17:09qbgTo get the docstring/arglists
17:09lambdatronicI didn't use eval.
17:09qbg"qbg: I eval-ed the form at compile-time and captured the metadata off the interned var"
17:10lambdatronicYes, because you can't attach metadata to a def-ed symbol in a defmacro statement.
17:10lambdatronicThe metadata reader-macro is lost during macroexpansion.
17:11lambdatronicWhere is your pastie?
17:11lambdatronicI don't see it at the link I provided.
17:12qbglambdatronic: Unless that was a bug in 1.0, you can add metadata to a def'ed symbol in defmacro
17:13qbghttp://pastebin.com/6LQzaenX
17:14qbgYou use with-meta, not the reader macro
17:15hiredmanwell you want alter-meta
17:16naeuif I have compiled Foo.java to Foo.class and the class file is on the classpath and Foo isn't explicitly associated with any namespace, how do I refer to it from within clojure?
17:17qbgnaeu: is Foo in the default package?
17:17naeuqbg: I'm not sure - how would I determine that?
17:17lambdatronichiredman: you are thinking of vary-meta.
17:18qbgnaeu: Do you use the package keyword in Foo.java?
17:18naeunope - should I?
17:18qbgDefault package in Java = bad
17:18hiredmanwhichever
17:19qbgYou can't import from it
17:19naeuqbg: ah ok...
17:19qbgAnd you need to import Foo in Clojure to use it
17:19naeuqbg: so i just need to make up a package name for it
17:20qbgThat should work
17:20naeucan I just say package foo;
17:20qbgShould work
17:21qbgThen Foo.class needs to be in foo on the classpath
17:21naeuah..
17:22naeuyou mean Foo.class needs to be in a dir called foo which needs to be a sub dir of one of the dirs in the classpath?
17:22qbgCorrect
17:23naeuthe repl says it's looking for foo__init.class
17:24qbgUse (import 'foo.Foo)
17:24naeuwhen i just have foo/Foo.class
17:24qbgSounds like you are trying to use or require it instead
17:24naeuqbg: yeah, i was doign (use 'foo.Foo)
17:25qbguse/require are for Clojure namespaces only
17:25naeuqbg: i got it working
17:25naeuqbg: thanks very much :-)
17:25qbgGood
17:30lambdatronicqbg: Thanks for the help. I like replacing (first `('~form)) with `'~form. That's the solution I was looking for, but I somehow missed that particular combination while testing at the repl. Otherwise, the version you provided looks pretty much exactly like the one I created before I tried to solve the problem of preserving the previous metadata liks arglists and docstrings.
17:31lambdatronicqbg: That led me down the path of gensyms, compile-time evaling the passed in form so I could extract the metadata off of the returned var and then using plain old def to attach the new metadata onto the original stuff.
17:33lambdatronicqbg: Not sure where I slipped up back there with the simpler solution to capture the metadata after all, but ah, live and learn.
17:45qbgMaybe I should try Marginalia, but my willingness to type documentation seems to be negatively correlated to the distance my cursor is from code...
17:47vIkSiThi all
17:59ossarehgiven an arbitrarily deep datastructure (of maps and vectors) how best to transform values of a particular type?
17:59amalloyossareh: clojure.walk/postwalk?
18:00ossarehdude, you can have my first born. You help me that much.
18:00ossareh(and I'm not excited about a first born)
18:03ossareh(inc amalloy)
18:03sexpbot⟹ 2
18:04ossarehI think it would be cool if sexpbot actually tracked this value and provided a league table - somewhat like stackoverflow does.
18:09Raynesossareh: That wouldn't be very difficult.
18:09ossarehRaynes: happy to help if you'd rather not do it.
18:11RaynesAll of the values are stored in MongoDB, so they should be very easy to extract. Feel free to take a shot at it. The relevant plugin is https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/karma.clj
18:12lpetithi, enlive gurus there?
18:12Raynesossareh: http://github.com/Raynes/sexpbot/wiki/Plugin-quick-start-guide Might be helpful if your unfamiliar with how sexpbot does things.
18:16lpetiti have a tree made of maps, following clojure.xml conventions, so it's consumable by enlive w/o problems. I have this parsley grammar which produces things for "(ns foo)" like {:tag :list :content [{:tag :symbol :content ["ns"]} {:tag :symbol :content ["foo"]}]}
18:16lpetit(simplifying a little the tree)
18:17lpetitwith enlive selectors, I'm able to get the namespace name by doing smt like : (html/select m [ :list :symbol])
18:19lpetitbut where things get interesting, is when I introduce handling of metadata: "(ns ^:foo ^:bar name)"
18:19lpetitNow the name "name" can theoretically be nested within 0..n metas.
18:20lpetitAnd the question: I'm having a hard time figuring out how to write the selector for this (if even possible in one pass) ?
18:22amalloylpetit: i don't know anything about enlive, but could you get xpath involved?
18:24lpetitif you know of a library which can consume clojure.xml datastructures, maybe (I cannot afford the time penalty of transforming clojure.xml datastructures back to DOM)
18:24amalloy/ns/**/symbol/last() or something like that - it's been a long time since i used it
18:25lpetitnot so simple. I don't want to match e.g. fake in "(ns ^{:baz 'fake} ns-name)"
18:26erikcw1In my main namespace, I have a var named settings which is an empty {}. My -main fn sets the contents of settings with another def and conj based on some command line args. I'm trying to access the contents of this map from another namespace to pull out some of the settings. When I try to compile with lein into an uberjar, I get a traceback saying "No such var: lb/settings". What am I missing? Is there a better way to handle app wid
18:26erikcw1settings?
18:26amalloylpetit: there's a difference between symbol/last() and symbol[last()]
18:28lpetitamalloy: the real use case will be more like "(ns ^{:doc "bleh" :deprecates old-name} new-name (:require baz) ...)" :-(
18:29lpetitamalloy: need to think about it more, I guess. To understand the possibilities of each "selector language"
18:29amalloyokay, granted, it's not as trivial as my expr
18:29amalloylpetit: /ns/first()/**/symbol/last() i guess
18:30lpetitamalloy, yes, maybe, thanks for the food for thought (will go to bed now)
18:30lpetitcu
18:31amalloynight
18:33daleCalling (.submit an-ExecutorService #(+ 1 1)) throws "More than one matching method found." Is (cast Runnable #(+ 1 1)) the right way to fix that? ^Runnable #(...) didn't work.
18:33dale(There's submit(Runnable) and submit(Callable<T>) according to the Java docs, and I'm guessing Clojure callables implement both.)
18:34amalloydale: yeah, i think it is right
18:36amalloybtw dale: ##(-> [] fn class supers)
18:36sexpbot⟹ #{java.io.Serializable java.lang.Object java.util.concurrent.Callable clojure.lang.AFn clojure.lang.AFunction clojure.lang.IObj java.lang.Runnable clojure.lang.IMeta java.util.Comparator clojure.lang.Fn clojure.lang.IFn}
18:37daleNice, thanks. I just called instance? in my REPL a minute ago to confirm I was right about Runnable and Callable. I like (supers).
18:38daleI have to confess that I often find -> quite unreadable, though. I hope I'm not alone in that.
18:38RaynesWhy?
18:38clojurebothttp://clojure.org/rationale
18:38daleMaybe easier reading of -> will come to me with time, but for example I find (supers (class #())) easier to read.
18:39amalloydale: well, my usage there isn't exactly idiomatic. but yes, you'll find it easier with time
18:39RaynesIn his example, it suffices to just read it backwards.
18:40daleI saw -> used in zippers and there it seemed very readable, but elsewhere I've been a little frustrated by it.
18:40Raynes&(#() class supers)
18:40sexpbotjava.lang.IllegalArgumentException: Wrong number of args (2) passed to: sandbox6382$eval8909$fn
18:40Raynes&(-> #() class supers)
18:40sexpbot⟹ #{java.io.Serializable java.lang.Object java.util.concurrent.Callable clojure.lang.AFn clojure.lang.AFunction clojure.lang.IObj java.lang.Runnable clojure.lang.IMeta java.util.Comparator clojure.lang.Fn clojure.lang.IFn}
18:40daleRaynes: Actually, yeah, that helps.
18:40amalloytechnomancy's favorite code-transforming macro is ##(macroexpand '(doto myproj.foo require in-ns))
18:40sexpbot⟹ (let* [G__8923 myproj.foo] (require G__8923) (in-ns G__8923) G__8923)
18:40daleamalloy: Sorry, didn't mean to pick on your example. :)
18:41amalloydale: no worries. i have a heart of stone; your mockery leaves me unmoved
18:42daleAnother example from nREPL: (-> submit class (.getResourceAsStream "/clojure/tools/nrepl/version.txt"))
18:43amalloydale: that makes more sense if you're familiar with classloaders
18:43daleAnd actually I'm still having trouble seeing what the hell that does.
18:43daleAsks a class of a semi-randomly-chosen function for a resource from the Jar file from which it was loaded?
18:43amalloyyeah
18:44amalloy&(use 'clojure.javadoc)
18:44sexpbotjava.io.FileNotFoundException: Could not locate clojure/javadoc__init.class or clojure/javadoc.clj on classpath:
18:45amalloy&(use 'clojure.java.javadoc)
18:45sexpbotjava.security.AccessControlException: access denied (java.util.PropertyPermission os.name read)
18:45amalloyhuh
18:45amalloy&(javadoc Class)
18:45sexpbotjava.lang.Exception: Unable to resolve symbol: javadoc in this context
18:45daleIn my head I think just end up translating that to (.getResourceAsStream (class submit) "...") anyway, so I'm just not fond of the -> form there. Anyway, like I said, maybe I'll become accustomed to it over time.
19:08amalloydale: ##(macroexpand '(->> (range) (filter even?) (take 100) (reduce +)))
19:08sexpbot⟹ (reduce + (take 100 (filter even? (range))))
19:09amalloythe former seems a lot clearer to me: "take the first hundred even integers and add them up" vs "add up the first hundred elements of the list of even elements in the set of integers"
19:09daleamalloy: Oh, now I see what you were getting at with macroexpand like that, nice.
19:11dalePerhaps years of programming, including dabbling in things like CL and toy languages, have predisposed me to reading and understanding inside out? Dunno.
19:11amalloydale: there are some things that read better inside out and some that don't
19:12amalloyboth styles take some practice
19:12daleI could believe that, and I don't have enough exposure to ->/->>, sure.
19:13amalloymy (-> [] fn class supers) is, imo, less legible the way i wrote it, but it involved less reaching for the shift and () keys
21:43qbgCombinators are awesome. It was painful moving my syntax-rules lib over to them, but it was well worth it.
21:49cnatarenqbg: do you know of any good article or reference about them?
21:49qbgYou could start with http://en.wikipedia.org/wiki/Parser_combinator
21:50qbgThe idea is beautifully simple
21:53qbgIn my case, I have a number of functions which operate on match states, and then I have various combinators which combine them in useful ways
21:56duck1123Does anyone know why the Java library I'm using (Abdera) will pick one XMLInputFactory if I run my code through a REPL, but pick another if I use the Lazytest Maven Plugin?
21:58duck1123The lazytest plugin is causing an immutable factory to be picked, which then throws an exception when a property is set on it
22:01talioslazytest maven plugin?
22:03duck1123yeah, the 2.0 one
22:03taliosMy guess is different class path ordering
22:03duck1123if I use clojure:swank to get a repl, and then run the tests, they all pass
22:03taliosI didnt know there was a lazytest maven plugin - only my clojure-maven-plugin:test goal
22:03duck1123yeah, I had to go to 1.3 for it
22:04duck1123I figured I needed to make the leap sooner or later
22:04taliosahh - I didn't realise stuart had made a plugin for it :)
22:05taliosMy guess is that classpath ordering is screwing you over and that Abdera is finding a different impl first
22:10abedracemerick: are you around?
22:11cemerickabedra: for the nonce. What's up?
22:11talios'lo cemerick
22:11cemerickhowdy :-)
22:11abedraI created you a user cemerick on build.clojure.org
22:11abedraI wanted to get you the password
22:11abedraand some info
22:12cemericktalios: I'm falling behind on my c-m-p homework :-(
22:12abedraSS said he needed your help with some stuff
22:12cemerickabedra: you didn't want to just use my key as before?
22:12talioscemerick: you and me both. I did some experimenting with the javax.scripting bridge into clojure and is looking nice.
22:12abedracemerick: I do, but you will still need the password for sudo
22:13cemerickah, ok
22:13talioscemerick: but if your behind, you won't have read about me looking at that :)
22:22cemericktalios: that sounds interesting; this is http://code.google.com/p/clojure-jsr223/ ?
22:22taliosyep! using that same binary but with 1.3-alpha4 dep. listed worked FINE.
22:23taliosyou don't get a separate scope of clojure tho, but you can have seperate scopes bindings into the user ns
22:24taliosmight propose we graft that into clojure-core itself as an standard embedding strategy, as it seems to work rather nicely, run in the same vm, or fork a vm but still call via jsr223
22:24talios(the author already has a contrib agreement signed it seems - handy)
22:28cemericktalios: is this part of a plan to hoist some or all of the c-m-p impl into clojure?
22:30qbgcemerick: What is c-m-p?
22:30cemerickclojure-maven-plugin
22:34duck1123I like maven. I like having that extra bit of structure to project building, because as your app gets bigger and bigger, you start to want it
22:41cemerickgaaaah! :-P
22:42cemerickI always try to use the hyphens; not sure if anyone ever gets the hint.
23:25fmeyer