#clojure logs

2011-05-20

00:00dnolenzakwilson: the bad experiences w/ Clojure seems generally low - if they exist they're always of the obvious variety - "too many parens!"
00:01zakwilsonI'm not new to Clojure, but I haven't used it for a customer project yet. Parens don't bother me. If I'm going to complain about something, it's the lack of user-defined reader macros.
00:02dnolenzakwilson: seems like a minor nit, a good overall design choice.
00:02zakwilsonAnd maybe that exceptions feel too Java-ish (I'd rather have conditions that don't unwind the stack)
00:03dnolenzakwilson: but do conditions make sense w/ interop?
00:03zakwilsonNot sure. Somebody did them as a library, and I haven't actually tried using it.
00:03amalloydnolen: it sounds like that's not an issue for him, since he says jvm isn't a requirement
00:03amalloyzakwilson: cc.condition is not recommended, is my understanding
00:04amalloycore team really want a better exception/error system but afaik haven't figured out a good way to make it happen yet
00:04zakwilsonActually, the one I remembered was cc.error-kit
00:04dnolenzakwilson: so you would leverage Java libs in this project?
00:04dnolens/would/wouldn't
00:04sexpbot<dnolen> zakwilson: so you wouldn't leverage Java libs in this project?
00:05zakwilsonI can't say that I won't. I will prefer Clojure libs or wrapped Java libs, but I'm sure there will be a bit of interop here and there.
00:06zakwilsonI'm just saying, there's no reason I couldn't do it in a language that isn't hosted on the JVM.
00:06dnolenzakwilson: so who are the competitiors? CL? Racket? Haskell?
00:07zakwilsonRoR is the main competition. I'm sure that will be easier at first, but I suspect Clojure will provide more flexibility later on.
00:07dnolenzakwilson: so it's website w/ templates and all that?
00:08zakwilsonYes. CRUD app with sugar on top.
00:08dnolenzakwilson: for a full blown website w/ templates, ORM, I don't really think Clojure competes much, but I think it depends on project timeline.
00:09dnolenIf the competition was say ... Sinatra, I would say Clojure 100%
00:09zakwilsonORM isn't a requirement, and I kinda don't like ORM. ClojureQL seems like a nicer compromise between writing SQL by hand and ORM.
00:11dnolenzakwilson: My point is simply that if you want RoR convenience - Clojure ain't there yet. If you understand that RoR convenience is actually a low ceiling, then yes Clojure is attractive.
00:12zakwilsonIsn't that what I said when I mentioned RoR?
00:15dnolenzakwilson: heh, you did. But it's hard to make any kind of judgment w/o any understanding of project scope. Rails is now a somewhat shared domain of understanding. Clojure not so much.
00:16zakwilsonI know. I was mostly looking for any known big problems. I've done a website with similar scope in CL before and did run in to trouble, namely that SBCL had issues with the virtualization used by some VPS hosts.
00:20dnolenzakwilson: perhaps others can chime in about JDK differences between platforms, there's been some mutter about it in the past, but not at the level of SBCL issues I think.
00:21zakwilsonI don't forsee that sort of deployment difficulty with Clojure, and as platforms go, I'm hoping to do all development and production on Debianoids of some sort.
00:24dnolenzakwilson: well, I do RoR at work, and my experience is that most of what I do would be simpler, shorter, and faster in Clojure.
00:24zakwilsonThat has been my experience with non-trivial RoR as well. You have failed to talk me out of Clojure. Good job.
00:26tomojzakwilson: so, pallet, chef, or..?
00:28zakwilsonI'm honestly not familiar with either of them.
00:30zakwilsonA quick look gives me the general idea of pallet. That sounds potentially useful for a project still on the drawing board.
00:37nathanmarztomoj zakwilson: i'm a big fan of pallet. i use it for a lot of stuff
00:40tomojguess I should try doing what chef does now with pallet
00:40tomojalways felt it would be better in clojure
00:41nathanmarzit has a learning curve, but is worth it
00:41nathanmarzand hugod is very helpful
00:43tomojnathanmarz: was it you who pointed me to the bixo list?
00:46nathanmarzi don't remember
01:11amalloyseancorfield: we've added some new features to make it impossible for you to ever take your eyes off 4clojure
01:12seancorfielduh-oh
01:12seancorfieldi've managed to get some work done over the last couple of weeks...
01:12amalloyi guess you're following @4clojure so you knew that already though
01:16amacwhenever I try to jar my project with lein it blows away my lib and re-fetches the deps -- but in the process wipes out the mysql-connector.jar file I need in there. Is there a way to tell lein that this file is friendly and shouldn't be removed?
01:17raekamac: yes, there is an option you can add to the project.clj file (see the sample project.clj in the leiningen github repo)
01:18symboleIs it possible to force an evaluation of a macro parameter during macroexpansion time, i.e., outside a backquote?
01:19raekamac: also, I'm fairly certain that mysql-connector is in some maven repo (unless you need a homebrew version)
01:19amacI don't need a homebrew, I just couldn't find where it was hosted
01:19raekhttp://jarvana.com/ <-- good site for searching in maven repos
01:20raekhttp://jarvana.com/jarvana/archive-details/mysql/mysql-connector-java/5.1.14/mysql-connector-java-5.1.14.jar
01:21amacsweet
01:21amacthanks for that
01:21amacalso; :disable-implicit-clean true did the trick
01:21amac:)
01:21seancorfieldamalloy: actually i filtered out 4clojure because of all the annoying tweets about how xyz solved a problem :)
01:22seancorfieldbtw, Leagues links to http://4clojure.com/login/update is that intentional?
01:22amalloyyeah, the leagues page is kinda lame
01:23amalloyi wanted to add a new link so people would know the feature exists
01:23seancorfieldi've slipped to 48th... *sigh* ...i guess i need to start solving puzzles again at some point :(
01:24amalloyseancorfield: incidenally, you can follow @4clojure (the user, not the hashtag) to get only meaningful site updates. plus, we started using the #clojure tag at most once an hour, so you can't get annoying floods all at once
01:29seancorfieldi'm off to amit rathore's day of clojure macros training on saturday :)
01:29seancorfieldshould be fun
01:30seancorfieldand right now, i'm off to... bed! g'nite
01:30amalloyah, enjoy
01:33technomancyamac: you can try "lein search" in the latest git
01:33technomancygit lein
01:35amactechnomancy: neat
01:48desertmanhi, i am trying to get compore running (this is on cygwin) , following https://github.com/weavejester/compojure/wiki/Getting-Started, I added to prj file, then lein clean, lein deps, and lein ring server, , get class exception for compojure.core
01:55amalloydesertman: on the information provided it all sounds fine, but not much information has been provided. gist up your error message and/or your project.clj and/or the code you're using, and maybe someone can help
02:18desertmanthis is my compojure issue : https://gist.github.com/982438
02:20raekdesertman: you have your :use clause outside the ns form
02:21desertmanok, thnks
02:21raeksince ns is a macro, it defines new meaning to the (:use compojure.core) code
02:22raekusing the normal clojure evaluation rules, it means "look up the :use key in compojure.core", where compojure.core is a class name literal
02:22raekand there is no java class with the name compojure.core, hence the error
02:22amalloysame for the :require clause, btw
02:24raekif you just remove the right paren at the end of line 21, it should be fine
02:42amalloyraek: it's surprising how many beginners can fix their problem by removing some parens :). see, lisp's not that bad
06:14clgvwhat is the easiest way to store clojure data structures in a file for later reading and analysing?
06:20fliebelclgv: JSON? Or just… clojure, if it's safe data.
06:20clgvfliebel: just found amalloys blog entry about using pr or pr-str
06:20fliebelright :)
06:20raekclgv: (spit file (pr-str x)) or (binding [*out* (clojure.java.io/writer file)] (pr x))
06:22raekthe latter is problably better, since it won't make one huge string for the whole value
06:22clgvthx, raek
06:23raek("file" can be a filename as a string or a java.io.File (a file path object), among other things. look at this page for more info on that: http://clojuredocs.org/clojure_core/clojure.java.io)
06:25raekthe reverse would then be (read-string (slurp file)) or (binding [*in* (clojure.java.io/reader file)] (read))
07:55patspHi, have anyone already read the 4clojure.com problem "Graph Tour"? I don't understand why the second testcase should be false. Can anyone explain?
07:59clgvpatsp: I think you can remove the double edges since you can visit one and return on the other
08:00clgvpatsp: if you do that you have a graph were only one edge remains from d to each of the other nodes
08:01clgvpatsp: so there is no possibility to use all of them, since you will get stuck in one of the 3 nodes (a, b or c) and you wont be able to visit the last remaining one
08:03clgvpatsp: I think I remember a rules that states a necessary criterion for such an euler tour but quoting that one would spoil you the fun of solving the problem ;)
08:03patspbut the path a->c->d->b->a->d visits all edges
08:04patspand I don't think that we should find a tour but a path because otherwise the first testcase is wrong
08:04clgvpatsp: no it does not! there are two remaining edges [a b] and [a c] that you did not include
08:05clgvpatsp: the spedicifation as a clojure set might be the error in the problem test cases
08:05patspbut the edges are representet as a set --> double edges are not possible
08:05patspyes exactly
08:06clgvthey use a set but mean to have more than one edge per node pair
08:06patspok, then it's clear, thx
08:07clgvmaybe you have to write them if you cant get that problem solved due to this error
08:08patspdo you think an issue on github would be appropriate, or just email?
08:35patspJust a note to my previous conversation: now the testcases for the 4clojure.com problem "Graph Tour" are correct.
08:45wastrel /win 19
09:34gfrlogokay so
09:34gfrlogif I want a (doall) that works on arbitrarily nested structures
09:35gfrlogi.e., ensure that nothing in my object is unevaluated
09:35gfrlogis my best bet to combine (doall) with something from (clojure.walk)?
09:35gfrlogor does this already exist?
09:35chouserhm
09:36chouseryou don't really care about the return value, since you can just use the original objects
09:36chouserso I think you could use tree-seq instead, if you wanted
09:36raekI recall that someone made such a function
09:36gfrlog,(doc tree-seq)
09:36clojurebot"([branch? children root]); Returns a lazy sequence of the nodes in a tree, via a depth-first walk. branch? must be a fn of one arg that returns true if passed a node that can have children (but may not). children must be a fn of one arg that returns a sequence of the children. Will only be called on nodes for which branch? returns true. Root is the root node of the tree."
09:37raekgfrlog: btw, what situation led to this problem?
09:37gfrlograek: I am using Jena
09:37gfrlogum
09:37gfrlogI guess any database could have the same issue
09:37gfrlogI just need to make sure the results are all consumed before closing the connection, essentially
09:38gfrlogthe fact that it's jena just explains why I'm not using clojureql or c.c.sql
09:38gfrlogI've got a number of data-access functions I've written, and I'd rather wrap them all in a general-purpose solution than reason through each one and add (doall) as needed
09:39raekif you have control over the code that builds the data structure, then one possibility is to let it call doall on all lazy-seqs it puts in the data structure
09:40gfrlogright
09:40gfrlogthat's what I'm hoping to avoid
09:40gfrloggiven that my automated tests are not likely to catch this
09:40gfrlogI'm already using a macro to def the data access functions, so adding it at that point seems simplest
09:41raeknot likely to catch missing doalls in the generating code?
09:42gfrlogwell I could do it if I really focused, but that's rather brittle, especially if I start changing things
09:42raekwouldn't (is (= [1 2 3] (with-... <generate sequence here>))) work
09:42gfrlogfor testing you mean?
09:42raekyes
09:43stuartsierraa sequence won't be = to a vector
09:43raekwhere "with-..." is a macro like "with-open" that closes the connection before it retusn
09:43gfrlogstuartsierra: yes
09:43raek,(= [1 2 3] '(1 2 3))
09:43clojurebottrue
09:43stuartsierraoops
09:43gfrlog,(= [1 2 3] (range 1 4))
09:43clojurebottrue
09:43gfrlogstuartsierra: I take back my agreement
09:44stuartsierraI take back my assertion.
09:45gfrlograek: yes I guess I ought to test for this too :(
09:46raekbut laziness and resource management is indeed tricky
09:46gfrlogthe trap is built into c.c.sql
09:47gfrlogI'm glad clojureql came along cause I was tired of typing (into [] (with-query-results r [...])) or making ad-hoc utility functions for it
09:47gfrlogalso I was tired of not using clojureql
09:48raekif you don't need the random access of the vector, then doall is preferred here, I think
09:49gfrlogoh for c.c.sql? yeah that makes sense.
09:49gfrlogold habit I guess
09:49gfrlogprobably saw it somewhere and never decided to think past "it works"
09:51raekin one of my libraries, I provide two variants of a function that parses lines from a socket: one that takes a sequence of lines and returns a lazy-seq of the parsed lines and one that uses the first which also ensures that the sequence is forced and that the stream is closed
09:52gfrlogand next you're going to say that you have a very intuitive way of naming the two?
09:52raekif the user wants to process the lines lazily, then he can use the low-level one and do the resource management himself
09:53raekthe naming is always the trickiest part :-)
09:53gfrlogparse-lines and parse-lines~
09:53raekI called them "directory-seq" and "read-directory", I think
09:54raekthe first one in analogy to "line-seq"
09:55gfrlogthat seems good
09:56raekI think I considered "fetch-directory" for the second one. I looked for a word that implies that you get the whole thing at once
09:56gfrloginjest?
09:56gfrlogdevour?
09:56Fossigulp ;D
09:57gfrlogslurp
09:57cemerickjeez, what a shit-storm on the ML
09:58cemerickI guess we were due
09:58stuartsierranow what?
09:58raekheh. "slurp" is not that bad... it has the right connotations if you are used to clojure.core/slurp
09:59TimMcslurp-dir?
09:59Fossicemerick: got an archive link?
10:00cemerickhttp://groups.google.com/group/clojure/browse_frm/thread/f97699164e9be29e I gues
10:00cemerickguess*
10:00Fossithanks
10:02Fossiah, that thing again
10:02edwtechnomancy: You around?
10:03TimMccemerick: Oh, "Mailing List". I kept looking for ML-the-language stuff. >_<
10:03cemerickFossi: Just a vessel for everyone's particular gripes.
10:03Fossiyes
10:03Fossigot the same feeling from that last discussion
10:04cemerickTimMc: yeah, damn that ML shit-storm. Stupid language anyway!
10:04cemerick;-)
10:04Fossikinda peintless as well
10:04Fossi*o
10:04cemerickFossi: which means it's a shoe-in for a 100-message thread
10:06Fossihaving some experience with clojure in a java environment with lots of smart people all i can say is: lisp is not for everybody ;)
10:06edwFossi: I have trouble believing that.
10:06Fossithe ide won't be the major problem
10:07TimMcFossi: And tehrefore is doomed to never have widespread acceptance?
10:07gfrlogFossi: what about people who learn FP before OOP?
10:07Fossiand it's still *way* harder to get a customer let you use anything but plain java anyway
10:07Fossiat least it's a possibility
10:07TimMcFossi: Why should they care what's in the JAR?
10:07gfrlogsomebody write a clojure-to-java translator
10:08Fossii don't necessarily believe in unlimited growth
10:08edwFossi: Lisp with an IDE that lacks a REPL sort of misses the point. Lisp is different from what most people know. *Un*learning is the most important part of transitioning people to a Lisp.
10:08FossiTimMc: because they pay and own the code
10:08TimMcOh, that kind of customer.
10:08Fossiand they want to have at least the illusion of taking it somewhere else
10:09Fossi*being able
10:09edwFossi: Just say, "I'll deliver a jar with source."
10:09TimMcheh
10:09Fossiwon't cut it
10:09gfrloglinguistic tricks are the best way to get referrals
10:09TimMcI don't see why any competant dev couldn't learn Clojure.
10:09TimMcgfrlog: haha
10:09Fossiat least not with "bigger" ()500+ persondays projects
10:10gfrlogTimMc: once you define "competant" so as to make that a tautology, I agree
10:10FossiTimMc: well, that's part of the problem
10:10Fossiyes :)
10:10edwIn my experience, if you want freedom to use tools that let you be productive, you're best off in an envrionment that isn't a development shop. I work for a marketing agency, and they don't care what I use.
10:10Fossipeople are commonly having problems grokking java :)
10:11Fossiedw: well, i guess those aren't the target of the "enterprise integration cloud buzzword" group that typesafe targets
10:12gfrlogon a totally unrelated note, why doesn't (memoize) use soft references?
10:12Fossithat sentence makes no sense whatsoever :)
10:13raekgfrlog: memoization and caches are not the same thing
10:13edwFossi: The enterprise. Sigh. So sad.
10:14Fossitrue
10:14Fossibig moneys though
10:14`fogusgfrlog: That would be rude. ;-)
10:14Fossiand interesting problems too sometimes
10:14raekgfrlog: http://groups.google.com/group/clojure-dev/browse_thread/thread/227859e14deb0d7c/21414bdd6991dec6?lnk=gst&amp;q=memoize#21414bdd6991dec6
10:14gfrlograek: thank you sir
10:14Fossiat least when it comes to pure numbers/traffic (me being a web developer ;) )
10:16gfrlograek: I guess the next question is why would anybody want to memoize when they could cache?
10:16edwFossi: There's too much insecurity and arrogance in enterprisey environments.
10:17gfrlogmaybe it makes the GC have to think harder?
10:21gfrlogis it strange that (with-open) uses (let) instead of (binding)?
10:22TimMcgfrlog: Because "memoize" sounds like "memorize" as pronounced by the priest from The Princess Bride.
10:22TimMcAnd "cachify" doesn't.
10:22gfrlogmaybe it is not so strange
10:23TimMcMakes sense to me.
10:23gfrlogI just find it unusable with my *model* var
10:37TimMcOh man, this is going to be interesting.
10:38TimMcI just started full-time at a company with a large-ish Java codebase. How long do you think it will be before I start trying to write Java macros? :-P
10:42TimMcActually, there is some interest here in rewriting one internal app in Clojure.
10:45alandipertTimMc: do it!
10:45TimMcWell, it's a matter of priorities -- if the app as it currently stands doesn't suck too much to maintain, it's not gonna happen. :-P
10:46TimMcBut the CEO and some other higher-ups have LISP background, so it's a definite possibility.
10:48TimMcHow does Clojure's licensing interact with commercial products? I notice that core and contrib would be distributed with the product.
10:49edwDo something that actually works and does something useful and show some buiness owner. They'll get a hard-on and will want you to add a few features. Say, "Oh, this little thing? It's something I was working on in my spare time. You'll have to ask my boss to let me spend some more time on it." And then you're off and running...
10:54lucianTimMc: it's EPL afaict, so it shouldn't
10:55lucianTimMc: http://en.wikipedia.org/wiki/Eclipse_Public_License like a weaker LGPL
10:56gfrlogI wrote a bit of code for a blog post the other day and somebody commented asking what the license of the code was :-|
10:56gfrlognever had to think about that before
10:57Fossihate people licensing javascript with gpl :>
10:57TimMcFossi: My apologies.
10:57edwAnd did they complain that you're a willing accomplice to capitalism by not GPL'ing it?
10:57`fogusRelated to the memoization dircussion: https://github.com/fogus/unk
10:57FossiTimMc: huh? :)
10:57TimMcFossi: I do that a lot.
10:57Fossiit makes no sense
10:57Fossiwhatsoever :D
10:57lucianmeh, i use GPL when i think it's appropriate. or AL 2.0 otherwise, usually
10:58TimMcIt's easy to just slap on "GPL" when I have a random piece of software I want to release.
10:58Fossieven gpl people at the fsfe weren't able to fully grok what that means when i asked
10:58lucianthe EPL is kinda braindead, though. it's sad that clojure uses it
10:58TimMcFossi: What do you think makes the most sense for JS libs?
10:58Fossidunno, bsd or epl or such
10:58lucianFossi: i'd say LGPL
10:58TimMcHow about LGPL?
10:59Fossiit's better than gps
10:59TimMcI can always relicense my stuff anyway.
10:59lucianno library should use an application license
10:59Fossibut still, what's "linking"?
10:59lucianFossi: derivative work, same thing
10:59Fossiand what's "you have to distribute the source"
10:59lucianthe GPL is enforceable for python just as much as for C, it's been established
10:59TimMcFossi: That's the easy part.
10:59lucianwhy would JS be different?
11:00Fossibecause you always ship the source to your "customers"
11:00lucianif you ship a runnable version
11:00Fossiand "linking" happens in their browsers
11:00lucianFossi: not necessarily. it's a derivative work if it's designed to work with that, in the client's browser
11:01Fossithe most common interpretation was that you have to also serve an unminified version
11:01Fossi /unobfuscated
11:01lucianyes, minification counts as obfuscation, which GPL forbids
11:01lucianwell, sort of
11:01lucianGPL3 makes it clearer
11:01TimMcFossi: Oof, forgot about minification.
11:01Fossiit's all not that clear
11:01Fossiso it's a pita :)
11:02lucianit's less of a PITA than a proprietary license
11:03Fossino, my client has to buy those, if i need them
11:03Fossithat's easy
11:03Fossibut i'm liable if i use something "free" and misuse it
11:03TimMcHell, how does commercial licensing work with JS?
11:03Fossiat least it's a danger
11:03TimMccopyign and whatnot
11:03lucianTimMc: same as with anything else. most things are easily decompiled
11:03FossiTimMc: they ship obfuscated personalised versions
11:04Fossiand some phone back
11:04lucianFossi: but it's not necessarily easier. even if you pay, there's strings
11:04Fossior only work on specific hostnames
11:04lucianGPL also has strings, seems fairplay to me
11:04lucianwow, that's evil
11:04TimMcNo, I mean when a company buys a JS thingy and serves it on their site.
11:04Fossilucian: yes, but those are mostly clearly defined in some contract
11:05lucianFossi: again, they're reasonably clearly defined in the license
11:05lucianif in doubt, contact the copyright owner
11:05Fossiyeah, i did so a whole lot, you can believe me :)
11:05Fossiand most people react like TimMc :)
11:05lucianwell, it is sad that many people don't understand licensing, or simply don't care
11:06Fossisometimes it's hard to reach people though
11:06Fossiat least in a timely manner
11:06lucianyes, i know
11:06lucianbut we have the advantage of few licenses
11:06lucianGPL is always GPL
11:06Fossitoo bad that the js world never concurred to a saner standard than gpl :/
11:07Fossimost intepreted language communities did
11:07luciani guess you'd say that if you disliked the GPL
11:08lucianbut really, there's no ambiguity with GPL and interpreted languages
11:08lucianJS's distribution is slightly different, but even that's not terribly important
11:10Fossii just dislike the ambiguities of linking and minification
11:10lucianbut there aren't any! :)
11:10luciana derivative work is not defined by linking
11:11lucianand minification is considered runnable code, not source, usually
11:11Fossithe question isn't whether i have to commit back
11:11Fossithat's easy
11:11luciani suppose the second is slightly ambiguous, but you'd offer non-minified code anyway
11:11Fossiit's whether my code (that's proprietary) can call a part of gpl'd js
11:12Fossiin the users browser
11:12TimMclucian: I guess the central question is whether using JS on a web page counts as distribution.
11:12lucianFossi: can't, it's a derivative work. simple
11:12TimMcThat's the only difference, really.
11:12lucianTimMc: it does
11:12Fossithe distribution part is kinda okayish
11:12luciandoes it get to the client, and run there? it's distributed
11:14TimMcI like the approach of having minification on the fly with versioned files -- foo-1.2.min.js is a minified + cached copy of foo-1.2.js, both of which are available over HTTP.
11:14TimMcI call that "providing source".
11:14FossiTimMc: well, you also want to concat those, but yeah, mostly stays the same
11:15TimMcfoo-1234$bar-7654.min.js
11:15TimMcLiveJournal was doing that at one point.
11:41edwIs there an idiomatic way to handle debug logging? I've written my own DEBUG function that takes a log level and a message and the message is logged if the current log level is equal to or higher than the passed in log level. I'd like to like clients of my project get this ability but don't want to unleash any new wheel designs upon the earth.
11:42edwclojure.logging, perhaps?
11:47dnolenedw: https://github.com/clojure/tools.logging
11:48edwSorry, that's what I meant. It's been placed in my project.clj...
11:54edwParedit and Clojure mode are not playing nicely using the clojure-jack-in command: C-k is bound to kill-line, not paredit-kill-line, and I'm getting "unbalanced parens" errors when I try to kill a line.
11:55edwDo I need to make sure one loads before the other?
12:40amalloyedw: does the modeline mention paredit?
12:41technomancyedw: those should be orthogonal
12:49edwtechnomancy: Hey.
12:51wastreli got vimclojure working with indenting
12:51wastreli just had to blow away my entire ~/.vim and install it fresh
12:51edwtechnomancy: If I start-up emacs with '-q' and install paredit and clojure-mode I get the same (problematic) behavior. I have a traditional SLIME, Clojure, Paredit set-up that works fine. To be specific typing C-k where the X is in here "(ns Xfoo.core)" will cause an unbalanced paren error.
12:51Rayneswastrel: You earn a shiny gold VimClojure medal! :D
12:51wastrel:p
12:51wastreli still want that fancy repl
12:53lucianwastrel: i'm trying out vimana right now
12:53TimMcedw: But is paredit-mode on in that situation?
12:53technomancyedw: clojure-mode 1.9.0 and paredit 22?
12:53edwTimMc: Yes.
12:53edwtechnomancy: I followed your screencast instructions, and yes, Paredit 22.
12:54wastrellucian: never heard of it
12:54lucianwastrel: it's a perl utility for managing vim packages/thingies
12:54lucianlike pip/gem/etc
12:54lucianbut for vim
12:55edwtechnomancy: This happens regardless of whether I set the set a clojure-mode hook or enable paredit-mode manually.
12:56amalloyedw: does M-x paredit-kill work?
12:57edwamalloy: 1. It is being invoked but 2. it will not kill if it means intelligently not killing part of the line due to the existence of parens that are needed for balancing.
12:57amalloyuh. that second sentence has a lot of words but i can't put them together in a meaningful way
12:58edwamalloy: In other words, C-k is being bound to paredit-kill. It's just not working properly.
12:58amalloyhm
12:59edw(foo |bar) + C-k should result in (foo |) but paredit reports an error and fails to kill "bar".
13:00edw(Pipe = "point on next character")
13:00amalloyedw: yeah, i know. what error does it report? and does it work for (foo baz |bar)?
13:01edwIt reports an unbalanced paren error. And no, doesn't work for any kill that requires intelligently killing a partial line.
13:02amalloyand if you switch to lisp-mode+paredit it works?
13:03edwHold on... Lemme write some elisp...
13:04edwYup, it works fine in elisp mode.
13:05edwWith paredit...
13:05amalloybummer
13:07edwIn fact, if I switch the buffer from clojure-mode to lisp mode, paredit works fine.
13:08amalloywell, i'll try upgrading to latest git and see if i have problems
13:08edwI pulled from github like 30 min ago.
13:09amalloyright. i pulled a few days ago, and it looks like there are one or two irrelevant changes
13:09amalloyrather, i suppose i pushed a few days ago :P
13:09gfrlogdo defrecords have to be (import)ed?
13:09gfrlogthat seems strange to me because I always thought of (import) as an interop thing
13:10TimMcgfrlog: they do
13:10gfrlogokeedokes then
13:10gfrlogthings are not always what they seem
13:10amalloygfrlog: defrecord is an interop thing too
13:10amalloyit defines a java class
13:11gfrlogbut isn't there reason to use it even when you're not otherwise interacting with Java?
13:11ataggart_With the defrecord changes in 1.3, I suspect less need to import the record classes
13:11amalloygfrlog: it's a point you could argue either way on
13:11ataggart_gfriog: records are java classes, hence importing
13:12ataggart_but master branch has factory functions, so you could just require/use the relevant ns
13:12gfrlogyeah, I know that they're java classes; I just figured that they were also clojurey things and so might have some...special stuff....
13:12amalloyedw: unfortunately for you, still works for me on 1.9.0
13:13ataggart_gfriog: try out clojure master. Also see http://dev.clojure.org/display/design/defrecord+improvements
13:13technomancyedw: I'm getting that with 1.9.0 too =\
13:13amalloytechnomancy: getting what? the buggy behavior?
13:13technomancyamalloy: yeah, error on C-k
13:14amalloywth. why would it work for me, then. can one of you try checking out b53390 and see if it's still broken?
13:16gfrlogman now I feel bad for using records pre 1.3
13:17technomancyamalloy: works fine on b53390
13:18gfrlog,(doc print-dup)
13:18clojurebot"; "
13:18amalloyrrrrgh. then it's probably my fault *somehow*
13:19technomancyamalloy: confirmed it's 4495e =\
13:19dnolengfrlog: amalloy: defrecord, type, protocols are definitely not "an interop thing"
13:19technomancynot sure how I didn't catch it sooner
13:19amalloytechnomancy: that one is known to be buggy. db908 fixes a bug in that
13:20dnolengfrlog: defrecord has a lot of clojurey stuff
13:20technomancyhuh
13:20gfrlogdnolen: yeah, this improvements doc is exactly the kind of stuff I was thinking about
13:21amalloyif i could, i would rebase-squash db908 into 4495e so nobody can ever use it :P
13:33gfrlogrecords are making me consider using (get) for all map accesses :(
13:34amalloygfrlog: (:foo m) is easier than (m :foo) since it works for records too
13:34gfrlogit is
13:34gfrlogI guess that's good when I have literals
13:34amalloygfrlog: it works when you don't, too?
13:34gfrlogbut if it's a generic algorithm that can't assume the keys are keywords
13:34amalloyah
13:35gfrlogthen traditionally I would use (m k) instead of (k m)
13:35gfrlogbut now it could be a record in which case (m k) doesn't work either
13:35gfrlogstuff about to get clunky
13:36amalloyyeah, get is the only real choice. you want to get things from an arbitrary k/v store
13:36gfrlogI can't think of a reason why records shouldn't be IFns just like maps...
13:36gfrlogoh wait
13:36gfrlogI guess you might want to do IFn yourself for some unrelated purpose?
13:37amalloygfrlog: you lose perf
13:37amalloyrecords don't encourage slow usages of them
13:37gfrlogyou lose performance if they're IFns at all, or just if you use them that way?
13:37amalloyand treating them as ifn couldn't be nearly as fast as using the keyword and/or hinted field access
13:37amalloythe latter
13:38gfrlogdon't we prefer slick-looking code before performance?
13:38amalloyyes. so use a hash-map, not a record, please :P
13:38amalloyrecords exist *specifically* for perf
13:38gfrlogoh.
13:38gfrlog...and for programming to interfaces?
13:39amalloyreify, deftype...i mean, yes, they're good for interop too
13:39gfrlogI guess you can do that with maps too...
13:40amalloyyay
13:40gfrlogman I was feeling all good about having safer and more structured code
13:41amalloyyou didn't really, though
13:41cemerickIf the keys in your domain aren't "names" (broadly writ), then records were never really appropriate.
13:41amalloyyou can still assoc/get arbitrary fields in a record
13:42gfrlogit does all feel a little loose. Maybe getting older and retreating to static languages is like getting older and becoming a conservative
13:43gfrlogI was just thinking the other day it'd be nice to have a jvm language that's static like scala and immutable/concurrent like clojure and something like haskell
13:43dnolenamalloy: gfrlog: you might want to do IFn yourself, has nothing to do w/ perf.
13:44dnolenamalloy: those things aren't for interop, you gotta stop saying that.
13:44gfrlogdnolen: what's not for interop? records?
13:44amalloydnolen: explain?
13:44dnolengfrlog: deftype/record, protocols have nothing to do w/ interop.
13:44gfrlogyeah I never thought they did
13:45gfrlogI thought protocol/record was about programming to interfaces, while deftype was about clojure-in-clojure
13:45dnolengfrlog: deftype is not about clojure-in-clojure tho it's useful for that too.
13:46gfrlogwhat else is it about?
13:46dnolengfrlog: light weight data structures.
13:46cemerickgfrlog: Horse's mouth: http://clojure.org/datatypes :-)
13:46amalloyedw: what version of emacs are you using?
13:46gfrlogcemerick: yeah, that's where I got my impressions from
13:46gfrlogcemerick: any discrepancies are due to cognitive limitations
13:47edw24.0.50.1. Ubuntu + OS X.
13:47cemerickgfrlog: welcome to the club. We're having jackets made.
13:47edw(Just got back, btw,(
13:47gfrlogcemerick: gonna think real hard about what color mine should be, but not sure if I can figure it out
13:49edwWhen I tried it under Ubuntu and flakiness resulted, I went to my OS X install and tried it. Same problem.
13:53dnolengfrlog: amalloy: the statement that IFn will be slower than the provided keyword access is also not true.
13:53gfrlogdnolen: he was probably contrasting with direct field access
13:53gfrlogbut that's a good point, since keyword access is provided
13:54gfrlogI'm not sure whether it's better to leave off the IFn implementation for consistency, or allow the user to override it
13:55dnolengfrlog: done properly IFn can be made nearly as fast as direct access. milliseconds of difference even at 1e8 iterations.
13:56gfrlogthat sounds like a good thing.
13:59amalloyedw: update: it works on emacs 23, but not 24. working on figuring out why
14:00dnolengfrlog: amalloy: https://gist.github.com/983429
14:02gfrlogdnolen: Think I'm gonna have to run that more like 100000 times before the numbers mean anything to me
14:02gfrlogoh wait
14:02gfrlogI just saw the outer bit
14:02edwamalloy: Thanks for looking into this. FWIW, clojure-plug-in fails on the Emacs that ships with Snow Leopard, but does anyone even use that?
14:03technomancyedw: emacs 22?
14:03edwAh yes.
14:04technomancythat's 4 years old; strongly considering dropping support for it across the board
14:04gfrlogdnolen: when I run it, the direct access version gets up to ten times faster
14:05edwtechnomancy: The 18 yo, comp sci freshman from '91 in me cries a little tear.
14:05gfrlognow that I think about it these numbers are rather disturbing...
14:06dnolengfrlog: not on my setup, OS X 10.6 JDK 7 64bit
14:06gfrlogit is saying that clojure did something 100,000,000 times in 0.002374 milliseconds?
14:07ataggartlazy?
14:07clojurebotlazy is hard
14:07gfrlogataggart: nope, dotimes
14:07ataggartquantum computer?
14:07dnolengfrlog: my point is simply that this is the kind of thing that the JVM can detect and aggressively optimize.
14:08dnolenmethod dispatch is cheap, if is cheap, identical? is cheap.
14:08gfrlogdnolen: that sounds plausible, but 1) my computer reports different times, and 2) how the hell are these times so low for so many operations?
14:08amalloydnolen: case is surely faster than cond there?
14:08dnolenamalloy: it is not.
14:08amalloybut yes, fair point
14:09dnolengfrlog: vtable lookup, 3 branch tests, integer comparison, doesn't sound like the computer has to do much.
14:10gfrlogdnolen: I changed it from 1e8 to 1e9 and it got faster
14:10gfrlogI don't think those are physically realizable times even in assembly
14:11gfrlogdnolen: times for 1e5 are about the same as 1e9
14:11gfrlogsomething else is going on
14:11dnolengfrlog: not on my machine, 1e5 is 0.08 milliseconds for me.
14:11gfrlogso 1e8 should be 80 milliseconds
14:12TimMcgfrlog: 1.763 sec and 0.358 sec for me (1e8)
14:12dnolengregh: it's 70ms on my machine which is what you'd expect.
14:12dnolenoops.
14:13gfrlogI'm getting 0.005 msecs for just about everything
14:13gfrlogwhich is insane.
14:13dnolengfrlog: what's your setup?
14:13technomancyedw: is 22 commonly used? I guess I honestly don't know.
14:13TimMcgfrlog: Can you factor some numbers for me? :-P
14:13gfrloguh some kinda thinkpad
14:13gfrlogubuntu 64 bit
14:13gfrlogokay let's see
14:13gfrlogif something does 100 million operations in 0.01 milliseconds
14:13gfrloglemme ask wolfram alpha what that is
14:14TimMc10 GHz
14:14gfrlogthat's all?
14:14ataggartdnolen: case should be faster than cond for keywords and (in master) int-sized integers.
14:14dnolenataggart: yeah I'm on alpha7
14:15gfrlogTimMc: WA says 10 terahertz
14:15TimMcgfrlog: Ah, you're right... milliseconds, not seconds.
14:15gfrloghttp://www.wolframalpha.com/input/?i=1e8+%2F+%280.01+milliseconds%29
14:16gfrlogso like I said, this is not physically realizable even if we optimize it to one instruction per field access
14:16TimMcgfrlog: So... you can crack some rar files for me, yeah? :-P
14:16gfrlognobody else is getting those numbers?
14:17gfrloghere's my output: https://gist.github.com/983477
14:18dnolengfrlog: perhaps your JVM sees that the loop doesn't do anything.
14:18gfrlogthat's the only thing I can conclude
14:18gfrlogso I think we need a different way to compare the performance
14:18gfrlogI was watching disclojure the other day and he did something similar
14:19gfrlogwas measuring the performance of different (rotate) functions, but they were both lazy and I don't think he ever consumed them
14:59manutterpart
14:59manutterdoh, that's the second time I've done that.
15:00offby1could have been worse
15:10arjdoes anyone know how to handle java.nio.channels.ClosedChannelException in aleph?
15:26gfrlogis there a strong use case for reader-evaluation?
15:59TimMcgfrlog: What is reader-evaluation?
16:00amalloyyes
16:00amalloyit lets you define print-dup for new types
16:00amalloyTimMc: #= notation
16:02TimMcAh, that.
16:03gfrloghuh.
16:04ataggartdisabled by binding *read-eval* to false
16:06TimMcHow do I get a reader again?
16:06amalloy&(read-string "1")?
16:06sexpbot⟹ 1
16:06TimMcthanks
16:06TimMcI tried read and read-str. :-P
16:06gfrlogamalloy: does "defining print-dup for new types" mean serializing something as a string that starts with #=(...)?
16:07amalloyyes
16:07amalloy$google amalloy xml json clojure
16:07sexpbotFirst out of 14 results is: Don't use XML/JSON for Clojure-only persistence/messaging
16:07sexpbothttp://hubpages.com/hub/Dont-use-XML-JSON-for-Clojure-only-persistence-messaging
16:07gfrlogokay. I guess that is a good use.
16:07amalloygfrlog: ^ has an example
16:08TimMcAnd I suppose the de-serializer has to have the right environment for the evaluation to succeed.
16:08gfrlogamalloy: that there is a good dang example
16:08ataggartrecently added to master is support for literal construction of arbitrary types, so you don't need to add a print-dup
16:08gfrlogyeah that part is not immediately clear
16:08gfrlogI at first assumed you'd just get clojure.core etc.
16:09ataggartcorrection, don't need to use the read-eval macro
16:09gfrlogwhat? we got a finger-tree syntax now?
16:09amalloy&(binding [*print-dup* true] (pr-str *ns*)) ;; gfrlog
16:09sexpbot⟹ "#=(find-ns sandbox11964)"
16:09amalloyTimMc: how do you mean?
16:09gfrlogamalloy: holy cow!
16:10TimMcamalloy: Oh, for instance your constructor function would need to be in scope.
16:10TimMcAnd isn't there something about eval not getting lexical stuff?
16:10gfrlogyeah it's probably just the deffed stuff
16:10amalloyyes, print-dup is very much not intended for use with lexical anything
16:10gfrlogbut I think that'd be okay
16:10amalloyit's for persisting objects
16:11amalloy&`String
16:11sexpbot⟹ java.lang.String
16:11TimMc&(type `String)
16:11sexpbot⟹ clojure.lang.Symbol
16:11TimMcright
16:12amalloyTimMc: that's why the recommended way to implement print-dup is like ##(str "=#" `(String. 10))
16:12sexpbot⟹ "=#(java.lang.String. 10)"
16:12amalloymeans you don't need to have String imported in order for reading to work
16:13TimMcI bet it works even better with #= instead of =#. :-)
16:13TimMcAh, nice trick.
16:13ataggartis there a bot running master?
16:13amalloyataggart: neither sexpbot nor clojurebot
16:13ataggartk
16:16hiredmanI'd like to have clojurebot's sandbox run has a seperate process, possibly connected via queue, which would make changing the version of clojrue available much easier, and possibly support multiple versions, just have work and five or six other projects and life competing for time :/
16:17amalloyataggart: what's needed to get master running? git fetch, compile, mvn install, then depend on that version?
16:18ataggartI think alpha7 is only one commit back from master, you can just use that
16:18amalloyi'll fire up my fork of sexpbot with alpha7 if you want
16:18ataggartbut otherwise, yes
16:18ataggartoh I was just curious. no need to bother
16:18amalloyotoh it uses contrib stuff and i don't know how to migrate
16:18amalloyah
16:19ataggartI have master local anyway. bugs aren't gonna close themselves.
16:19amalloyataggart: since i have you here, what is the story for using contrib in 1.3? if i have a project that needs pr-xml, can i just use alpha7 and contrib 1.2?
16:20ataggartthinking...
16:20arohneramalloy: I think I had problems with that because of some AOT code
16:20ataggartthe only issue you might run into is that *foo* won't be dynamically rebindable
16:22ataggartacually there are quite a few breaking changes, but you're unlikely to run into them. the ^:dynamic thing is main one.
16:22amalloyyeah, i've been tagging my code with :dynamic in preparation for eventually migrating
16:22amalloythough pr-xml probably doesn't
16:23amalloyyeah, looks like it doesn't. i guess i can patch that myself, except i don't know where i'd send the patch to
16:25ataggartamalloy: is this what you're referring to? http://richhickey.github.com/clojure-contrib/prxml-api.html
16:31amalloyyes
16:31gfrlogamalloy: print-dup couldn't be used to print reconstructible lazy seqs could it? because there's already a seq implementation?
16:31amalloyataggart: in contrib 1.2.0 it includes things like (def ^{:private true} *prxml-tag-depth* 0)
16:34amalloygfrlog: print-dup is a multimethod; you can derive it
16:34amalloybut it would be hard, if not impossible, to do in general
16:34gfrlogright, I'm just thinking special cases like iterate
16:35amalloygfrlog: and if the base case of iteration is itself a lazy-seq?
16:35gfrlogpunt
16:35arohneranyone have experience using c.c.zip-filter.xml?
16:36amalloyarohner: very briefly, several months ago
16:36amalloygfrlog: six. i'm a terrible kicker
16:36gfrlogyou could get half of a two-point-conversion
16:36arohneramalloy: I can't figure out why chouser's examples in c.c.z-f.x.clj don't require zf/descendants, but all of my code does
16:38amalloyarohner: possibly xml1-> instead of xml->?
16:39TimMcclojure.core.zermelo-fraenkel.xml ?
16:39gfrlogTimMc: of course
16:39gfrlogthat's the version without AOC
16:39TimMcwith, I believe
16:40gfrlogno with you want "zfc"
16:40TimMcAh! Right.
16:40dnolenso who's gonna implement Generic Zippers for Clojure? http://okmij.org/ftp/continuations/zipper.html
16:40arohneramalloy: that only seems to affect whether I get "foo" or ("foo"), it doesn't change whether descendants is needed
16:40TimMcFrom an infinite directory of XML file, pick one element from each.
16:41amalloyarohner: i'm short on psychic powers. can you gist some of your code and a sample of your xml?
16:41gfrlogTimMc: and then use them to duplicate a spherical xml file
16:42hiredmandnolen: what is the difference between that and clojure.zip?
16:42dnolenhiredman: clojure.zip doesn't work w/ all data structures right?
16:42amalloydnolen: it's pluggable, no?
16:43hiredman,(doc clojure.zip/zipper)
16:43clojurebot"([branch? children make-node root]); Creates a new zipper structure. branch? is a fn that, given a node, returns true if can have children, even if it currently doesn't. children is a fn that, given a branch node, returns a seq of its children. make-node is a fn that, given an existing node and a seq of children, returns a new branch node with the supplied children. root is the root node."
16:43wastrelis clojurebot written in clojure
16:43amalloyyes
16:44gfrlogis sexpbot witten in sexp?
16:44ataggartdnolen: clojure.zip should make sense for any structure for which left/right/up/down make sense
16:44dnolenhiredman: amalloy: doesn't the returned zipper only work on one type?
16:44wastrelsexybot eh.
16:44amalloydnolen: define branch as a multimethod if you have mixed data types?
16:44TimMcgfrlog: Why yes it is.
16:44dnolencorrect me if I'm wrong, but there is no zipper for [{}]
16:45ataggartdnolen: maps don't fit since left/right doesn't apply
16:45dnolenataggart: k no zipper for [()]
16:45hiredmansome people have done zippers for maps, but there is not universal accepted zipper for them
16:46amalloy&(clojure.zip/zipper sequential? seq list [()])
16:46sexpbot⟹ [[()] nil]
16:46amalloydnolen: ^ should be able to traverse that structure just fine
16:46dnolenamalloy: does the zipper preserve the types?
16:46amalloyyes
16:47hiredmanamalloy: I don't think it will
16:47ataggartnewly added child types depend on what make-node fn you gave it
16:47amalloyi could be wrong, then
16:47hiredmanany edits will turn the outer [] into a list
16:47hiredmansince you gave it the list function for constructing nodes
16:47amalloyhiredman: ah. yes, you're right for edits
16:47amalloyit should preserve types for walking though, right?
16:49dnolenanyways, good argument for real generic zipper. would also put walk to it's much needed rest.
16:50gfrlogbuncha clojure folk going to strange loop?
16:50timvisherhey all
16:50hiredman,(require '[clojure.zip :as z])
16:50clojurebotnil
16:50timvisheris it possible to import package.foo.*?
16:51ataggartno
16:51dnolentimvisher: no
16:51timvisherwhoo!
16:51timvisherok
16:51hiredman,(-> [()] (zipper sequential? seq list))
16:51clojurebotjava.lang.Exception: Unable to resolve symbol: zipper in this context
16:51timvisherthanks :)
16:51amalloyhiredman: ->>, btw
16:51hiredmanah, right, ahem
16:52ataggarttimvisher: if you're using emacs, check out https://github.com/technomancy/slamhound
16:52ataggartor nvm, emacs not required
16:52amalloylein, though
16:52ataggarttime to go stock up for the canucks game
16:53hiredmanclojure.zip also tends to have bugs, since it isn't used a lot
16:53technomancyyou can use it from the repl; kinda a pita though
16:54amalloyi wonder if whatever was breaking my slamhound/emacs integration has fixed itself yet
16:55hiredman,(-> (z/zipper sequential? seq list '(())) z/next (z/replace ()) z/root)
16:55clojurebot((()) (()))
16:55amalloyhiredman: that's not a bug, is it?
16:56hiredmanamalloy: I believe it is, should result in (())
16:56amalloyoh. i was assuming root returned the zipper, not the node
16:56hiredman,(-> (z/zipper sequential? seq list '(())) z/nex z/node)
16:56clojurebotjava.lang.Exception: No such var: z/nex
16:57hiredman,(-> (z/zipper sequential? seq list '(())) z/next z/node)
16:57clojurebot()
16:57hiredmanif I replace () with () I should get (()) out again
16:57amalloyyeah, i think you're right
16:57hiredmanlots or corner cases
16:58amalloyhiredman: might be caused by (seq ()) yielding nil instead of (), i dunno
16:58amalloy,(-> (z/zipper sequential? identity list '(())) z/next (z/replace ()) z/root)
16:58clojurebot((()) (()))
16:59amalloyguess not
16:59hiredman*shrug*
16:59amalloyoh. my use of (list) is what's broken
16:59amalloy,(-> (z/zipper sequential? identity identity '(())) z/next (z/replace ()) z/root)
16:59clojurebotjava.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$identity
17:00amalloy,(-> (z/zipper sequential? identity (fn [node children] children) '(())) z/next (z/replace ()) z/root)
17:00clojurebot(())
17:00hiredmanah, so you could use multimethods to create a generic zipper
17:00amalloyyes, it looks like
17:01hiredmandnolen: so done
17:01amalloyhiredman: the power of clojure: you and i implemented a generic zipper in just ten minutes :)
17:01amalloythe time it took to discover that one already exists
17:06amalloydnolen: anyway the conclusion is you can make a fully generic zipper in the existing framework with just multimethods or protocols
17:11stuartsierra1Announcement: Clojure builds on JRockit 1.5, but the tests don't pass.
17:11dnolenstuartsierra1: very cool.
17:13dnolenstuartsierra1: is there a specific nature to those tests that fail?
17:13hiredmanso far the only difference is jrockit is slower to start
17:14arjclojure is jrockingIt :-)
17:14stuartsierra1dnolen: something related to I/O classes, but I'm not sure what yet.
17:14dnolenhiredman: benefits?
17:15dnolenamalloy: ah, I follow now, cool!
17:15hiredmandnolen: none so far
17:16dnolengeneric zipper via protocols blogpost brewing ...
17:16pjstadigcan someone explain to me why i should be excited about jrockit?
17:16amalloythe name sounds a lot like rocket
17:16amalloythat's exciting enough for me
17:17seancorfielddoes alex taggart hang out here much? i have a Q about clojure.tools.logging
17:17hiredman~seen ataggart
17:17stuartsierra1I think the excitement is about the potential for various JVM commercial enhancements becoming open source in the near future.
17:17clojurebotataggart was last seen in #clojure, 24 minutes ago saying: time to go stock up for the canucks game
17:17amalloyseancorfield: he's here pretty often. was here just half an hour ago or so
17:17seancorfielddarn... my timing sucks :)
17:19pjstadigstuartsierra1: ok...so that leads to my next question...why should i be excited about jrockit?
17:19pjstadigare there actual features that add value?
17:19stuartsierra1Probably not yet.
17:20stuartsierra1For certain applications, it may offer faster performance and better garbage collection strategies.
17:20pjstadigok ... that's cool
17:20pjstadigthat sounds more incremental to me than revolutionary...the way people have been raving about the announcement
17:21pjstadigthe JRockit Virtual Edition looks kinda cool
17:21technomancypjstadig: maybe it has more to do with shock that oracle is doing something right
17:21stuartsierra1yes, what technomancy said
17:21stuartsierra1It's a positive sign for the future of the JVM under Oracle, which had a lot of people nervous.
17:21pjstadigduly noted
17:33wastrelthe clojure list is filling up my inbox :p
17:34technomancydigest mode. it changed my life.
17:34amalloyi just subscribe to the rss feed and tell it not to email me
17:35pjstadigyeah i've done digest mode for a while
17:35pjstadigclojure-dev is low volume and high enough signal-to-noise that i'll take that as single messages
17:39amalloyi don't get it. do you receive them straight in your regular inbox mingled with the rest of your mail? that's the only way i could see the volume being prohibitive, and it's easily fixed by adding a filter
17:39danlarkinaye, I filter all mailing lists into their own folders
17:39danlarkinand browse at my convenience
17:39danlarkindon't be a slave to your email!
17:40technomancysometimes it's hard to ignore the fact that there's a number in the sidebar!
17:40amalloyi try to avoid receiving mail from mailing lists, and read them as rss/news, but same idea
17:40technomancyeven if it isn't in the inbox
17:40pjstadigyeah but if it's not coming into your inbox then you may never read it
17:40amalloypjstadig: sounds like that's exactly what you want :P
17:40pjstadigso you might as well take a digest
17:40danlarkinI have 33 thousand unread emails in my clojure mailing list folder
17:40pjstadigor just unsubscribe and search for what you want
17:40pjstadigdanlarkin: my point exactly
17:40pjstadigjust do the digest
17:41amalloydigests aren't as easy to work with. you can't have your mail client filter by thread, for example
17:41danlarkinexactly
17:41technomancyyeah... once I get back to gnus I'll probably go back
17:41amalloyor by sender. one day soon i'll get tired of ken wesson
17:41pjstadigi scan the ToC for any interesting threads an click the links to read them on the google groups site
17:41technomancygnus lets you just chew through mailing lists like nobody's bizniss
17:41pjstadigi can scan 10's of messages in the blink of an eye
17:42danlarkinI only read threads I'm interested in
17:42danlarkinto each his own I guess
17:42pjstadigright...
17:42pjstadigso just do the digest
17:42danlarkin...but my way is obviously better
17:42pjstadigno its not
17:42pjstadigit's worse
17:42amalloy*baffled*
17:42pjstadigactually i don't really care
17:49dnolenit's funny because according to google groups the peak of ML activity happened around Jan 09.
17:51technomancyback in the day you couldn't really use clojure without following the list though
17:51dnolenaround which time I was posting horrible dribble about adding OO inheritance to structs.
17:52danlarkinsilly, silly times
17:52technomancywe all have our embarassing pasts
17:53pjstadighehe
17:57amalloyone of my first posts was about how to create circular structures for quickly looking up "all Xs in group G" and "what group is element X in"
17:57amalloyi'm still not entirely sure how i ought to have done that
17:58danlarkintwo hash maps
17:58amalloydanlarkin: i might prefer one hashmap
17:59hiredmanwith some kind of composite keys?
18:00amalloyhiredman: there was no danger in my use-case of needing the same key more than once. eg, all Xs have "ids" that are strings, and all Gs have "ids" that are ints
18:00hiredman{[:group 'G] 'xs [:element 'x] [:group 'G]}
18:01amalloy*nod*
18:01amalloybut you don't even need the :element/:group classifiers if there's never any overlap
18:01amalloy{'G 'xs 'x 'G}
18:02amalloytwo hashmaps might be less unwieldy in practice, though. i don't remember exactly how i was going to use them; i haven't touched that project in a while
18:03danlarkinyou could use the crazy db code I wrote for subrosa!
18:03danlarkinit "indexes" hash maps
18:04danlarkinI think it's actually pretty cool
18:04danlarkinI just have no documentation for it
18:04danlarkinwhich makes it pretty useless to anyone else
18:11technomancyte
18:11technomancyoops
19:53seancorfieldataggart: i missed you earlier... had some Q's about tools.logging
19:53ataggartshoot
19:54seancorfieldi have an app that currently does some fairly complex logging stuff - different levels going to different log appenders, including a DB log appender and an email log appender for different levels
19:54seancorfieldit's not written in clojure right now
19:54seancorfielddo you think it's worth creating a LogFactory for that and using tools.logging as i migrate the code around it to clojure
19:55seancorfieldor should i just write custom logging functions
19:55ataggartwhat's the underlying implementation?
19:55ataggarte.g., log4j
19:56seancorfieldcurrently? mostly custom log appenders... the rotating file log appender may be based on log4j, possibly
19:56seancorfieldthe main difference i could see in approach is that what i'm using right now allows you to specify multiple log appenders per namespace
19:57ataggartwell let's clear one thing up first, clojure.tools.logging doesn't actually do any logging. If your logging is based on log4j, then you can make your logging calls via tools.logging and it will automatically use log4j
19:57seancorfieldso i figured i needed a custom LogFactory but i'm not sure whether it's worth the effort for the amount of customization we have in our app :(
19:57seancorfieldi understand that
19:57ataggartk
19:58ataggartI bring it up because the notion of appenders, etc., deals with the underlying implementation config
19:58ataggartwhich is orthogonal to tools.logging
19:59ataggartso the app you currently have is using its own custom stuff for logging or log4j?
19:59seancorfieldlike i say, i think part of it is using log4j
19:59seancorfieldbut it also has logging to the database and logging via email, all for different levels
19:59ataggartis the latter stuff also configured via log4j?
20:00seancorfieldand the ability to have logging for a specific namespace go to multiple places
20:00seancorfieldnot yet... but if i can standardize it all on log4j it might be worth the effort
20:00ataggartyeah, I'd suggest that
20:00seancorfieldi'm not familiar enough with log4j (yet)
20:00ataggartthen you let the config do the work of routing stuff around.
20:00seancorfieldso i'd hate to write a bunch of custom code, only to find i _could_ leverage something standard :)
20:01seancorfieldso i might not even need to write a LogFactory...?
20:01ataggartI'm fairly sure any logging you want to do someone has already done an appender for
20:01ataggartand yeah, no need to write a custom LogFactory
20:01ataggartlog4j is already provided
20:02ataggartas is apache commons-logging, slf4j, and java.util.logging
20:02seancorfieldat some point we want to be able to log arbitrary maps of data to a noSQL store as one of the appenders...
20:02ataggarttools.logging doesn't force anything to be a string
20:03ataggartunless the underlying impl requires it
20:03ataggartso if the "message" is a map, that object should make it to the underlying impl
20:04seancorfieldas long as i use (log ...) and not (trace ...) etc?
20:04seancorfieldthose seem to call (logp ...)
20:04ataggartya
20:04seancorfield'k, good to know
20:04seancorfieldlog4j doesn't seem to support logging to a DB...?
20:05seancorfieldah, that's an optional extra...
20:07seancorfieldvery optional it seems... hmm... maybe i will end up writing my own log appenders after all...
20:08seancorfieldthere's a DBAppender available but it uses a very specific format that doesn't match what we want / already use
20:09ataggartit's been a while since I looked but it was fairly straightforward
20:09seancorfieldit'll be a nice challenge to write a log appender in clojure for use with log4j :)
20:10seancorfieldor i might just write a custom LogFactory and wrap log4j so i can still delegate to it for all the things it can do...
20:11ataggarthow is the db appender currently configured?
20:16seancorfieldnot thru log4j
20:16seancorfieldthe current logging implementation mimics a lot of log4j it seems
20:16seancorfieldit's a 3rd party logging library
20:17seancorfieldlooks like i can do most / all of what i want with standard log4j as long as i don't mind writing a custom appender for some of our more esoteric stuff...
20:17seancorfieldit'll be a long weekend of research i suspect :(
20:19seancorfieldugh! now i dig into this third party code, it does not actually use log4j, it pretty much replicates the entire thing :(
20:20seancorfieldgood grief... it's a near-complete port of log4j... why oh why would they do that :(
20:21seancorfieldoh well, dinner and a few beers and then i'll start to tackle that...
20:22ataggartheh have fun
20:22ataggart,(doc with-meta)
20:22clojurebot"([obj m]); Returns an object of the same type and value as obj, with map m as its metadata."
20:23amalloyataggart: the only with-* in clojure.core that doesn't establish dynamic scope
20:28ataggartamalloy: elaborate please
20:28amalloyataggart: with-open, with-bindings, etc, all deal with dynamic vars
20:29ataggarthmm, yeah, some form of "set" seems appropriate
20:30amalloy&(->> (ns-map *ns*) (map (comp name first)) (filter #(.startsWith % "with-")))
20:30sexpbotjava.lang.SecurityException: You tripped the alarm! ns-map is bad!
20:30amalloy,(->> (ns-map *ns*) (map (comp name first)) (filter #(.startsWith % "with-")))
20:30clojurebot("with-open" "with-in-str" "with-meta" "with-out-str" "with-loading-context" "with-bindings*" "with-precision" "with-local-vars" "with-bindings")
20:31amalloyataggart: this is not my own insight; chouser posed it as a puzzle some time ago
20:43hiredmanyou could argue that the meta data create with with-meta has dynamic extent, even more dynamic than bindings created with binding, while the metadata created with-meta has no scope limitations
20:44hiredmanbut that would be a ridiculous argument
21:54hugodseancorfield: you might also want to look at logback http://logback.qos.ch/, which has an slf4j api - it has a sifting appender, and allows multiple contexts for a log message (MDC)
22:01davidplumptonAnybody got a couple of minutes to give me some feedback on how to make this code more idiomatic? https://github.com/davidplumpton/alert-sim/blob/master/sa.clj
22:20seancorfieldthanx hugod
22:27jweissis there a way to 'flatten' that also will flatten sets?
22:27jweissi want to flatten a sexp to get all the symbols out of it, including those used in list/map/set literals.
23:19seancorfieldquick java interop Q: i have an abstract class (in java) that I want to complete in clojure - possible? how? (a pointer to an example or the appropriate bit of docs is fine)
23:19seancorfieldi thought reify would work but that requires an interface
23:20seancorfieldis it proxy?
23:22seancorfieldthis seems to work: (def test-logger (proxy [AppenderSkeleton] [] (append [event] (println (.getMessage event)))))
23:22seancorfieldnow i just need to figure out how to get log4j to use my clojure appender :)
23:42mprenticei added clojure-contrib to the classpath in ~/.lein/bin/swank-clojure, so i could develop one-off scripts with lein oneoff but still have contrib in my repl
23:42seancorfieldw00t!!! log4j is now using my clojure "class"
23:42mprenticeis there a plugin like swank-clojure that includes contrib already?