#clojure logs

2010-05-12

00:02sidstechnomancy: yea, please -- it's a pain to add it to every single project!
00:02technomancysids: well you'd still have to add swank-clojure as a dev-dep
00:02technomancyI don't think I'm quite ready to make that an automatic dep on every lein project. =)
00:02technomancyas much as I'm tempted
00:03sidstechnomancy: oh. did you consider supporting a "template" project.clj that lein new uses? maybe pick it up from some standard location..
00:03technomancysids: it's on the roadmap
00:03technomancyI need to add user-level plugins first
00:03technomancysince a plugin like that wouldn't make sense if it had to be activated on a per-project level
00:03MadWombatcan someone point me to an example of a servlet using recent version of ring?
00:04MadWombatlike a hello world servlet
00:04sidstechnomancy: cool, template project.clj would allow emacs users to add swank-clojure (or even lein-swank) as a dev-dependency to all projects easily
00:07lancepantzMadWombat: i have one i can put on github for you if you'd like
00:07technomancysids: if you're interested in the functionality it might be a fun little hack to experiment upon
00:07technomancyit'll probably be a while before I get around to it
00:07sidstechnomancy: sure, I'll give it a shot!
00:08technomancysids: I guess there are a couple of things needed for that
00:08MadWombattechnomancy: that would be nice, thanks, or maybe just a quick question, when I replace (run-jetty with (defservice I get an error, that I pass a wrong number of apps to routes function
00:08technomancy0) plugins activated on a per-user basis, probably listed from a ~/.lein.clj file
00:09technomancy1) being able to wrap built-in commands from plugins
00:09technomancy2) the new-template plugin itself
00:09lancepantzMadWombat: the defroutes syntax is different now
00:09MadWombatheh
00:09MadWombatI don't use defroutes, should i?
00:10lancepantzoh, i do, its in compojure not ring though
00:10MadWombatyeah
00:10MadWombatat this point all I have is (defn routes [req] (handle-dump req))
00:11sidstechnomancy: have you done any work on per-user plugins? can't figure it out from the git log
00:11technomancysids: only in my head
00:13technomancysids: the first step would be to hack the bin script to check for jars in (possibly something like) ~/.leiningen/plugins to add to the classpath
00:13technomancythen maybe load ~/.leiningen/init.clj, which would contain calls to require all the plugins you want activated
00:14sidstechnomancy: that should be straightforward, I'll also pour through the leiningen codebase to understand it better
00:14technomancynot sure how you'd get the plugin jars into ~/.leiningen/plugins in the first place though; probably want to symlink them from ~/.m2/repo
00:14technomancythere's not a lot of code there; I think it's only around 700 lines
00:14lancepantzMadWombat: it looks like your munging the syntax of the app and middleware
00:15sidstechnomancy: wouldn't it be better if the the plugins you want to use are also just specified in a .clj file? then they can just be added as dev-dependencies
00:15MadWombatlancepantz: ?
00:15lancepantzcheck out http://github.com/mmcgrana/ring/blob/master/example/wrapping.clj
00:15technomancysids: they can't just be in a .clj file since you need to add them to the classpath before the JVM loads
00:16lancepantzyour middleware is passed app, not a request
00:16sidstechnomancy: ok, got it, these are plugins for lein itself, not the projects
00:17technomancysids: right, activated for all actions the user takes across all project
00:17technomancy*projects
00:17sidsgot it
00:17MadWombatlancepantz: lemme check, it compiled after I removed all wrappers and passed the unchanged routes method to the defservice
00:18MadWombatlancepantz: Ah! Got it, thanks
00:22sidstechnomancy: thank you, I'll try to hack something up later today
00:22technomancysids: lemme know if you run into any problems
00:22technomancyhere or on the lein mailing list
00:23sidswill do
00:25lancepantzMadWombat: http://github.com/lancepantz/lein-war-example
00:25MadWombatlancepantz: thanks
00:26dnolenhow do you pad a vector in clojure again? (1 2) -> (1 2 3 nil nil nil), since count is only 2 and I want 5 elements.
00:27bmasontechnomancy: http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml
00:27sexpbot"Hugo Duncan : Swank Clojure gets a Break with the Local Environment"
00:27bmasonwhat version of swank will this be included in?
00:27technomancybmason: it's in 1.2.0-SNAPSHOT, which will become 1.2.0 very soon
00:27technomancy(couple days maybe)
00:28bmasonI'm running snapshots of clojure and clojure-contrib... any reason not to do swank as well?
00:30technomancybmason: not really, it'll make your "lein deps" runs take longer is all.
00:31dnolen,(take 5 (concat [1 2] (repeat nil))
00:31clojurebotEOF while reading
00:31dnolen,(take 5 (concat [1 2] (repeat nil)))
00:31clojurebot(1 2 nil nil nil)
00:31bmasoncool, I'm gonna try it out then
00:31technomancybmason: it's worth it. =)
00:31technomancyalso I just pushed out xref support
00:31bmasonyeah, I burned two days trying to troubleshoot a stack trace
00:32technomancyso you can say "I want to see all the functions that call partial" and boom; there you go
00:32bmasondebug tools are definitely welcome
00:32bmasonnice
00:32technomancy(that was all tcrayford)
00:32bmasonwell great job on swank... I use that every day
00:33technomancyeh; I don't really do much these days
00:33technomancyI'm mostly just the PHB who applies patches and decides when the release is going to happen =)
00:39danlarkinxref sweeeeeetness
00:39bmasontechnomancy: how's that open door policy working out?
00:40technomancybmason: better than you'd think
00:40technomancythe rubinius project actually gives full commit rights for anyone who has a patch accepted
00:40technomancyI'm not quite that gutsy
00:40bmasonwow
00:41technomancyyeah, I could totally just go in and delete half the implementation if I wanted to
00:41bmasonwell Ruby breaks backwards compatibility with every release anyway
00:41bmasonpeople are used to it ;)
00:41technomancyreverting is cheap, and people respect it when you trust them
00:41technomancyheh; that too
00:41technomancydanlarkin: try it out! I am excited.
00:42danlarkinno more M-x rgrep! well, less
00:42bmasonhow does the xref stuff work?
00:43bmasonI understand that in terms of XML... not sure what it means for clojure
00:46technomancyit's a little fuzzy; it just opens the original .clj file for every var and sees if the source includes the symbol that names the function in question
00:46technomancyprobably gets a lot of false positives
00:46technomancyand is really slow for large projects
00:47technomancyit's basically a brute-force search, but it works
00:48bmasonso it takes you to the place the symbol was def'd?
00:50technomancyit takes you to the caller
00:51bmasonah right
00:52bmasonapologies if it's a dumb question, but are there docs on this somewhere?
00:52bmasonlike a way to get recent release notes?
00:52technomancyI'll try to put together some when the actual release happens. for now it's just the git log.
00:52bmasonk
00:52bmasonwhat
00:53bmasonoops
00:53bmasonwhat's the syntax for actually using the xpath stuff?
00:53technomancyxref, not xpath
00:53bmasondo you use M-x something?
00:53technomancyit's C-c C-w c
00:53bmasonah
00:53technomancyxref for cross-reference
01:09ataggartanyone know where the browse-url function used by c.c.repl-utils is defined? Or how c.c.repl-utils works without declaring a ns?
01:12MadWombatis there a way to make lein copy dependency jars from a local directory?
01:12MadWombatwithout doing ugly maven install commands?
01:14bmasonlein install
01:15MadWombathmm
01:16bmasonworks with clojure projects at least
01:16bmasonI don't know what you'd do with regular jars that aren't in a repo
01:16bmasonmight be stuck with maven
01:17lancepantzi thiink you can manually put them in ~/.m2
01:17MadWombat:(
01:18bmasonyeah it looks like inside my .m2 directory are just jars and poms
01:23MadWombatthanks
01:24technomancyMadWombat: you need to do mvn install:install-file, but if you just declare the dependency before running mvn install, lein deps will print out the necessary invocation as part of the error message
01:24MadWombattechnomancy: cool
01:24MadWombatis there a way to use ant targets from lein?
01:25MadWombator for that matter define your own lein targets?
01:26MadWombatI am trying to setup an environment to play around with GAE and clojure
01:27MadWombatbut all the ready setups are sort of dated, so I am coming up with my own
02:11MadWombatseems like each additional leiningen task requires its own leiningen.* namespace, is this correct?
02:11lancepantzyes
02:17MadWombatlancepantz: thanks
02:54MadWombathow do you add new task to the list leiningen displays as help
02:54MadWombat?
03:05LauJensenMorning team
03:33MadWombathttp://blog.mitechki.net/2010/05/12/short-tutorial-on-extending-leiningen/
03:33sexpbot"Short tutorial on extending Leiningen « Angry UNIXoid’s Humble Abode"
03:41tomojMadWombat: did you write that?
03:41MadWombatyup
03:41tomojthanks a lot, that subject has always been a mystery to me
03:42tomojone strange thing is that you used "namespace" instead of "ns" in the second code block -- intentional?
03:42tomojs/second/third/
03:42sexpbotone strange thing is that you used "namespace" instead of "ns" in the third code block -- intentional?
03:42tomojs/third/fourth/
03:42MadWombattomoj: no, I iwll fix in a sec
03:42sexpbots/second/fourth/
03:42tomojit's so simple now that someone has explained it :D
03:43MadWombattomoj: I am still looking for a reliable way to transfer code into wordpress, so I cut-paste and edit manually for now
03:43RaynesI love how people always double take when they discover that by accident.
03:43MadWombatRaynes: :)
03:44MadWombattomoj: yeah, it was a mystery to me too, up to about 2 hours ago, when I figured I had some time and I might as well read some leiningen source :)
05:31_extermhi everybody
05:32_extermI want to add a method to a class generated by gen-class, but I want to do it at runtime, and I don't know the prefix there
05:32_extermIs there a way to get the prefix from a class?
05:38spariev_exterm: you could name your class as you want, like (gen-class :name my.ns.ClassName)
05:49_extermI need the prefix, e.g. (gen-class :name my.ns.ClassName :prefix "foo")
05:49_extermso I can define class methods outside of the gen-class
05:58LauJensen_exterm: gen-class is for AOT compilation.
06:08_extermIsn't it possible to add methods add runtime to classes that were generated AOT?
06:17tomojdon't the methods really just proxy to clojure fns?
06:18tomojand clojure fns can be added at runtime?
06:23LauJensentomoj: Clojure makes stubs for the classes. You can definitely override after the fact with proxy but Im just sure that you can add w/o using reify or something similar
06:30SandGorgonare s-expressions the same as clojure "forms" ?
06:31ChousukeI wonder. can s-expressions contain vectors and maps?
06:32SandGorgonChousuke, would'nt that be implementation detail - I can argue that vectors are arbitrarily growable lists . Am I wrong ?
06:32Chousukewell, yeah
06:32Chousukebut clojure has both lists and vectors appearing in forms
06:33tomojregular old lists aren't arbitrarily growable?
06:34ChousukeI suppose the set of all clojure forms it not equal to the set of s-expressions, but a superset
06:37SandGorgonChousuke, ahh
06:38SandGorgontomoj, yes I worded it wrong - for me vectors are as defined by C++ STL
06:44SandGorgonI have a question about internals - (def a) creates a var ... when I refer to :somesymbol is it being created ? So, if I do (def pp [:a :b :c]) - is clojure creating references to the symbols ?
06:46tomoj,(class :a)
06:46clojurebotclojure.lang.Keyword
06:46tomojthat Keyword's gotta come from somewhere
06:46tomojor from nowhere, rather
06:47tomojI mean, :aoeuaoeuaoeuaoeuaoeu certainly isn't sitting around in every clojure jvm
06:51tomojnot too different from the way 361 isn't sitting around in memory in every jvm, I think
07:18jfieldsdo you guys have any favorite blogs that have a fair amount of clojure related content?
07:19liebkejfields: http://planet.clojure.in/
07:19sexpbot"Planet Clojure"
07:21jfieldsliebke: thanks.
08:37Hodappmaybe if I put some Lisp books on my desk at work I'll stop crying when I have to use C++...
08:46chouserI have a couple situations where I think I want to write macros that macroexpand their args before returning.
08:46chouserDoes the desire to do this mean I'm thinking about the problem incorrectly?
08:46chouserI've not needed to do this before, so I'm suspicious.
08:47jfieldschouser: example?
08:47chouserit's to apply static typing in a DSL (maybe that's the problem there...)
08:48chouserso for example I have a macro lookup: (lookup :foo an-obj)
08:48chouserit would expand to something like: #^{:mytype "FooType"} (:foo an-obj)
08:49chouserthat is it would know at compile time that :foo of an-obj returns something of FooType
08:50chouserthen I want an equality test that throws at compile time if it knows the types of its args don't match
08:50chouser(typed= (lookup :foo an-obj) (lookup :foo other-obj))
08:51chouserthe knowedge exists at compile-time to verify both lookups will return the same type of object, but I'm failing to think of how to extract/apply that information
08:52chouser...except to have typed= macroexpand its args, examine their metadata, throw (or not), and finally emit a regular =
08:57mabeshey all, who else is at the clojure training now?
08:58clojurebotpcl → clojure is http://blog.thinkrelevance.com/2008/09/16/pcl-clojure
09:02_fogus_,Q
09:02clojurebot<-nil-<
09:03jfieldschouser is :foo really a FooType? or are you defining your own "types"?
09:03chouserthese are probably my own types
09:04jfieldscan you put a type as part of the metadata, and have (typed=) check and compare the metadata?
09:06chouseryes, but that requires knowing the (generated) metadata of the args when the outer macro expands. normally the outer macro only has access to the input metadata
09:06mabesif you are using defrecrod I think you can use isa?
09:07Licenser_,A
09:07clojurebotjava.lang.Exception: Unable to resolve symbol: A in this context
09:07chouserI want to do this type check at *compile* time, not runtime.
09:07Licenser_,Q
09:07clojurebot<-nil-<
09:07Licenser_why is Q nil with an arrow?
09:07jfieldschouser: gotcha. I'm definitely not the guy with the answer, I'm sure. But, I thought I'd try to help. :)
09:07chouser:-) thanks.
10:11ArkRosthi! Tell me please the way I can create thread-local var.
10:13PloujArkRost: http://java.ociweb.com/mark/clojure/article.html#Vars
10:13sexpbot"Object Computing, Inc. - Java News Brief - March 2009"
10:14stuartsierraArkRost: Any (binding ...) of a Var will be thread-local.
10:18technomancyLicenser_: it's a fancy/awesome way for printing clojure.lang.PersistentQueue/EMPTY
10:22The-Kennytechnomancy: How was this way of printing called? <something>-fish, if I remember correctly
10:25spariev,(conj clojure.lang.PersistentQueue/EMPTY "°}))>")
10:25clojurebot<-("�}))>")-<
10:28SynrGcute
10:28cemerickI guess I don't get the joke.
10:31sparievI wanted it to print smth like <-°}))>-< , but parens and quotes ruined my ascii art :)
10:32cemerickNo, I see what you were doing there, I just don't know the backstory behind fish ~ queues. *shrug*
10:33technomancycemerick: in stock clojure queues are visually indistinguishable from lists
10:33technomancynice to spice these up a little
10:34cemerickbut why fish?
10:34technomancyjust a visual indicator of which end stuff goes onto and which it comes off of
10:34technomancy"queued elements, please step right this way"
10:34cemerickoh, head and tail
10:36technomancyI think it's just a print-method hack hiredman tossed into clojurebot, dunno if it'll get mainlined.
10:36_fogus_it's in JoC though. ;-)
10:36technomancynice
11:11Licenser_technomancy: ah thank you!
11:15LauJensenstuartsierra: I think http-agent might be broken, since its shadowing core/bytes
11:23stuartsierrait's not broken, it just needs a refer-clojure
11:23stuartsierrabut 'bytes' should probably be renamed
11:25Licenser_stuartsierra: I picked up your temp converter post and played around a bit with wrapping the stuff needed for it, interested to have a look?
11:26stuartsierrabusy right now, but feel free to post
11:27Licenser_okay :)
11:31dsopis there a downloadable version of the complete clojure api?
11:31dsopof the documentation
11:32dsopah got it
11:34LaPingvinohttp://github.com/richhickey/clojure/tree/gh-pages
11:34LaPingvinogreat :)
11:35jfieldswhat's the feeling on watches? I have some a simple application that gets messages, updates a total and publishes out the new total. I've implemented it by listening for a message, updating the atom and then publishing the new total. I guess I could add a watch to the atom and publish from the watch, but having no experience with watches I wasn't sure if that was a good route.
11:49Licenser_$doc writer
11:49sexpbotCommand not found. No entiendo lo que estás diciendo.
11:49Licenser_$doc clojure.contrib.duck-streams/writer
11:49sexpbotCommand not found. No entiendo lo que estás diciendo.
11:49Licenser_(doc clojure.contrib.duck-streams/writer)
11:49clojurebot"([x]); Attempts to coerce its argument into an open java.io.PrintWriter wrapped around a java.io.BufferedWriter. Argument may be an instance of Writer, PrintWriter, BufferedWriter, OutputStream, File, URI, URL, Socket, or String. If argument is a String, it tries to resolve it first as a URI, then as a local file name. URIs with a 'file' protocol are converted to local file names. Should be used inside with-open to ensure
11:55mabesjfields: I'm not an expert by any means, but I've used watches before with good success
11:57hiredman,(doc writer)
11:57clojurebot"clojure.contrib.duck-streams/writer;[[x]]; Attempts to coerce its argument into an open java.io.PrintWriter wrapped around a java.io.BufferedWriter. Argument may be an instance of Writer, PrintWriter, BufferedWriter, OutputStream, File, URI, URL, Socket, or String. If argument is a String, it tries to resolve it first as a URI, then as a local file name. URIs with a 'file' protocol are converted to local file names. Shoul
11:59jfieldsmabes: thanks.
12:32bmasonif I want to do (keys {:a :foo :b :bar}) and (vals {:a :foo :b :bar}) do I need to use a sorted map to ensure the order is the same?
12:43ataggartor you could seq the map
12:43ataggartthat'll give you key/value tuples
12:46ataggartor you could get the keys, then build the value seq from the keys seq
12:47ataggartor it could very well be that values returns the same order as keys
12:47ataggartwhich would make sense
12:48wlangstrothbmason: out of curiosity - what are you trying to do?
12:49bmason(defn run-insert "Given a :table and {values}, insert values into table."
12:49bmason [table values]
12:49bmason (with-connection db
12:49bmason (transaction
12:49bmason (insert-values table (keys (first values))
12:49bmason (map vals values))
12:49bmason (last-created-id))))
12:49bmasonoops :)
12:49bmasonwill use pastie next time...
12:53chouser'keys', 'vals', and 'seq' on the same map will all return items in the same order
12:55replacaI'm implementing support for PersistentQueue in pprint. Should I do it fish-style?
12:59replacaI'm thinking just <-(1 2 3)-<. Anyone care?
12:59technomancyreplaca: yeah!
12:59Licenser_replaca: sounds good
13:00Licenser_will (<- 1 2 3) return a new queue?
13:00replaca(I don't want extra parens and brackets cause that will throw off anyone navigating the results
13:00technomancyunless you can come up with an ascii-art version of this: http://i196.photobucket.com/albums/aa159/apashin/arrowed.jpg
13:00replacano, this is just about pprint
13:00hiredman,Q
13:00clojurebot<-nil-<
13:01replacahiredman: my version would be <-()-<
13:01clojurebothiredman is slightly retarded
13:01technomancyif queue-fish gains a widespread community following there will be more pressure for reader support. =)
13:01Licenser_heh
13:01replacasince there's a seq under there (sort of)
13:01DuneMan*wants blocking persistent queue*
13:02hiredmanDuneMan: not possible
13:02replacaDuneMan: what does that mean? The queue is immmutab;e
13:02DuneManwants it anyway!
13:02Licenser_a persistent queue?
13:03DuneManreplaca: DETAILS
13:03Licenser_DuneMan: you have that it's called list?
13:03ataggartis there any chance of getting a literal queue?
13:03chouserwe have a blocking queue. we have a persistent queue. I don't see how a queue could be both.
13:03DuneManactually what I really want is java's blockingqueue, which I'm using. carry on.
13:04replacaDuneMan: but look at fill-queue
13:04hiredmanwhy are you missing it?
13:04hiredman,java.util.concurrent.LinkedBlockingQueue
13:04clojurebotjava.util.concurrent.LinkedBlockingQueue
13:04hiredmanit's right there
13:05DuneManRight, which is why I said "Which I am using"
13:05DuneManI just got to my desk and typed some shit, ignore me.
13:05hiredmanright
13:05hiredmanI somehow misread that
13:05hiredmanas "I'm missing"
13:05DuneManreplaca: Yeah, I can see that being handy for some things in the future, but unfortunately not this exact thing.
13:06DuneManI was happy to find fill-queue
13:06DuneManit's that level of abstraction which I think will make me increasingly productive in clojure.
13:06wlangstrothbmason: so you know the order, but not necessarily the columns you're entering, and that's why you use insert-values?
13:07DuneManThough I do wish LinkedBlockingQueue could push a buffer of messages with only grabbing the lock once.
13:08replaca(pprint (reduce conj e (range 10)))
13:08replacagives:
13:08replaca<-(0 1 2 3 4 5 6 7 8 9)-<
13:08replacawhere e is PersistentQueue/EMPTY
13:09TakeVSo, with assoc, if the key already exists that I'm passing to the function, then the map that gets returned just has the new value for the key I pass?
13:09chouserTakeV: yep
13:09TakeVCool.
13:09chouser,(assoc {:a 1} :a 2)
13:09clojurebot{:a 2}
13:13wlangstrothbmason: (I only ask because the whole process seems more work than simply concatenating a sql string yourself)
13:14bmasonsorry, got distracted
13:14bmasonlet me read up
13:16bmasonwlangstroth: is there a more convenient way to insert a map into a table?
13:16bmasonwlangstroth: I only saw insert-values, which takes vectors
13:18wlangstrothbmason: insert-rows takes a vector of the values in order, but I'm assuming you know the order of your columns (insert-rows is just a convenience wrapper around insert-values)
13:21bmasonwlangstroth: this is for a RESTful API... I have a PUT request coming in, and values will be in the :params map of the Request object... I need to take that map and insert the values into the DB
13:22wlangstrothbmason: oh, okay - I wasn't sure why you didn't know the order coming in
13:23bmasonah, alright
13:23bmasondoes my approach make sense then?
13:23wlangstrothbmason: and you're using ... mysql? and that's why you have to programmatically insert the id, rather than having the database do it?
13:23bmasonyes
13:23bmasonI'm considering using clj-record instead
13:23bmasonwill probably do that long term
13:24bmasonbut atm I'm just using clojure.contrib.sql
13:30wlangstrothbmason: yeah, I suppose that's how you would have to do it.
13:31wlangstrothIt was only jarring to me because I'm a database guy, so having the transaction enforced by middleware, etc. looked weird to me
13:35ataggartregarding REST, query params really shouldn't be used as a substitute for the body on a PUT
13:36wlangstrothbmason: I forgot about clj-record - it looks pretty good - haven't used it yet, but thanks for reminding me
13:37patrkriswhat is the reason that
13:37patrkrisoops
13:37bmasonyeah, I've seen how productive the Ruby ORMs are... I'm excited to try out clj-record
13:38patrkriswhat is the (probably very logical reason) that commutes after alter/ref-set are allowed in transactions but not vice versa?
13:39wlangstrothataggart: do people do that?
13:40ataggartbased on what bmason said, I guess so.
13:40ataggart"this is for a RESTful API... I have a PUT request coming in, and values will be in the :params map of the Request object"
13:40bmasonoh
13:41bmasonyeah, I'm not particularly clear on where my values will be coming from I suppose
13:41ataggartquery params are for querying, for narrowing the scope of the response representation
13:41bmasonI haven't implemented that part yet
13:41bmasonyeah, I didn't mean to use query params
13:41ataggartwhat lib are you using for the rest stuff?
13:41bmasonwhat does the body look like?
13:41bmasoncompojure-rest
13:42ataggartthe body of a PUt is whatever representation you want and that the server can handle, e.g., a json object, xml, whatever
13:42bmasongotcha
13:42bmasonso I'd then have to parse that... that makes sense
13:42ataggartyeah
13:43ataggartI have rest framework I worte in java for my company. been meaning to comjureize it
13:43ataggarterm
13:43wlangstrothoh, haha
13:43ataggartclojureize
13:43bmasoncompojurize?
13:43bmason:-D
13:43ataggart<-- not a good typist
13:43bmasonShakespear invented words, we can too
13:44ataggartI'll check out compojure-rest
13:44bmason*Shakespeare?
13:44ataggartsee ifI like it
13:44ataggart'Twas brillig and the slithy toves did gyre and gimble in the wabe.
13:44bmasonindeed
13:46DuneManneat, compjure-rest, that will be useful shortly
13:46DuneManThis is the most helpful irc channel ever.
13:47bmasonYES
13:47DuneManand I spent 8 years of my life in #C++/EfNet ;-)
13:47wlangstrothoi
13:48bmasonI'm doing a spike of CRUD operations for a RESTful API... I will probably post it up on github when I'm done to get some feedback and so other people can use it as an example
13:48ataggartmeh, not a fan of compjoure-rest
13:48BorkdudeJust wondering, is there a clip function in Clojure that returns n if it is between a and b, a if less than a and b if greater than b?
13:48ataggartIlike my lib better ;)
13:48Drakesonis swank-clojure broken since yesterday?
13:48bmasonataggart: link?
13:48ataggartbmason: none yet. proprietary
13:48ataggartwill be opening it up shortly
13:48wlangstrothataggart: translating from Java to Clojure can be disconcerting - the result is so much shorter
13:49bmasonataggart: send me an email or something, I'd like to check it out when you do
13:49DuneManhah, agreed. the clojure implementation I have of this thing is even shorter than the python
13:49DuneManand does more.
13:49bmason:)
13:49ataggartthe parts I've rewritten in clojure are an order of magnitude more concise
13:50wlangstrothI was porting parts of Jetty as a learning exercise, and it turned out that so much of what they were doing was already in the contrib library that I started feeling silly
13:50bmasonlol
13:50bmasonthat's a great sign
13:51bmasonthat means we could have a really light weight webserver done in clojure
13:51ataggartI thought there was one
13:51ataggartring
13:51ataggartiirc
13:51bmasonring isn't a webserver, is it?
13:51wlangstrothring uses jetty
13:51clojurebotthe answer is 42
13:51ataggartah
13:51bmasonyeah
13:51bmasonand compojure is based on ring
13:52wlangstrothand Jetty is ridiculous
13:52bmasonwell... correction would be ring *can* use jetty
13:52bmasonit's one option
13:52wlangstrothit works, it's awesome, whatever - the code is ridiculous
13:52ataggartI'd guess my rest lib would obviate ring. Right now it's built to run on a servlet system.
13:52wlangstrothbmason: quite right
13:53wlangstrothring is often used with jetty
13:54ataggartdefprotocol/deftype/defrecord are making my life a lot easier
13:54bmasonhttp://github.com/mmcgrana/ring
13:54bmasonhttpcore (Apache?) is another built in option
13:54ataggartI really just wish I didn't hate git as much as I do.
13:55bmasonand it's probably not difficult to add new adapters
13:55wlangstrothataggart: are you used to something else?
13:55ataggartsvn, but via the subclipse plugin. haven't had to mess with the commandline for ages.
13:55ataggartthe lack of tool support / visualization gets to me
13:56bmasongit clone *some repo* is pretty easy
13:56ataggartyeah
13:56ataggarteverythign after that is a pain
13:56DuneManlack of visualization?
13:56DuneManGitX, sir.
13:57ataggartgitx fails
13:57wlangstrothI live in white-on-black - more work done that way (not for everyone, of course)
13:57ataggartfor example: http://subclipse.tigris.org/servlets/ProjectProcess?pageID=rr1TIx
13:57sexpbot"subclipse: Screenshots"
13:57DuneManI also live in a terminal and don't use an IDE for anything
13:57DuneManan IDE is almost necessary for java
13:57ataggartit's not the ide that OI care about
13:58DuneManbut I never code in java.
13:58ataggartit's the lack of a visual diff
13:58DuneManYou can use any visual diff tool you want with git
13:58ataggartcommitting a file without first seeing the changes on the server is madness imo
13:58DuneManI use vimdiff, but there are better 3-way diff tools out there
13:58bmasonhow would I take 'vec' and 'keys' and combine them to a single function?
13:58bmasonwould 'partial' work for that?
13:58wlangstrothgit status?
13:58ataggartI've yet to find a tool that provides a visual diff for git that compares to what's available for svn
13:58technomancy,((comp vec keys) {:a :b :c :d})
13:58clojurebot[:a :c]
13:58bmasonit doesn't seem quite right...
13:59bmasonah comp
13:59bmasonthank you
13:59DuneMangit status; git&fetch && git merge origin/branch
13:59DuneMangit diff
13:59ataggartclearly you and I have different definitions of "visual diff"
13:59DuneManataggart: Just pipe the output of git diff to your favorite 3-way diff tool.
13:59DuneMansure, but I don't think that has anything to do with git.
14:00DuneManGit gives you a raw diff, view it in the tool of your choice.
14:00ataggartit has to do with the immaturity of the git ecosystem
14:00wlangstroththat's an interesting way to say "the pictures aren't pretty enough"
14:00DuneManAnd the type of people who work on the ecosystem.
14:00ataggartit's not just about pictures
14:00wlangstrothataggart: I'm teasing - I know what you mean
14:01ataggartthe feature set in subclipse is a high bar, which nothing in the git ecosystem even comes close to
14:01bmasonI agree ataggart
14:01DuneManI mean, I suppose it might be handy if there was a gui tool that had a built in 3-way diff viewer?
14:01DuneManThough I never leave my terminal so I wouldn't use it.
14:02wlangstrothright
14:02ataggartplus I'm constantly annoyed by the useless multi-step dance one needs to do to update the repo
14:02DuneMangit fetch && git merge?
14:02wlangstrothwhich dance?
14:03DuneManI work on stuff that makes heavy use of branching, and in that case there is much less dance than with svn/cvs. So, depends on how you're using things?
14:03ataggartI have a file on my system. I change it. I right-click the file and hit "Commit...". One logical step.
14:03DuneManor you can git pull
14:04DuneManAh, yes, there's your problem
14:04DuneMantouching your mouse.
14:04DuneMan*runs*
14:04ataggartfor git it seems I have to do a half a dozen command line incantations
14:04DuneManyou just have to do git commit -m "Message" file.
14:04ataggartbut that doesn't put it in github
14:04DuneManand then push that branch if you're ready to distribute that branch.
14:05ataggartyup, multi-step dance
14:05DuneManThough not a useless one.
14:05ataggartin my day we called git's commit "saving a file"
14:05DuneManVery useful
14:05DuneManIt's just a matter of being used to a different workflow
14:05technomancyataggart: if you want to combine two distinct steps into one that's easy enough to do with a shell alias
14:05ataggartyep, more sutff I need to write and not have avaiable on other machines
14:06technomancywhat, you don't keep your dotfiles in version control?
14:06DuneManI have all my stuff availablwe on all my machines
14:06DuneMangit checkout git@github:pgebheim/config.git
14:06DuneManer, git clone
14:06ataggartha!
14:06ataggartsee...
14:06ataggartbad names
14:06DuneManThat I can agree with
14:06DuneManthe git command line interface is poorly designed
14:06ataggartprecisely
14:07DuneManMaybe someone will get around to fixing that at some point
14:07DuneManIt was clearly designed as linus added features he needed
14:07DuneManso it has some logic to it, its just not transparent if you're new to it.
14:07ataggartfrom what I've read of the history, it's first goal was to make patching easier
14:07wlangstrothoh, I see your objection. Yeah, I've already written short scripts around that
14:08DuneManI almost always want to commit locally
14:08DuneManand NOT push
14:08DuneManI commit locally and do diffs on working sets constantly
14:08ataggartyeah, save a file
14:08ataggartI do that too
14:08technomancymagit makes it easy to forget how bad the git CLI experience is
14:08DuneManNo,that's not saving a file.
14:09wlangstrothataggart: you mean you want a daemon to monitor changes on the working branch and commit on each save?
14:09ataggartno I mean "commit" in my worldview means "push this change out to the canonical repo"
14:09maravillassimply saving a file doesn't keep the local history, whereas committing to your local repo in git does
14:09ataggartwhat git calls "commit" I call "saving a file locally"
14:09DuneManExcept it's different
14:09DuneManbecause you can have vrersioned local saves.
14:09ataggartmaravillas: that depends entirely on what you're using to edit
14:09ataggarteclipse has local history
14:10maravillason a per file basis, right?
14:10wlangstrothoh, I see - this is a distributed vs. centralized discussion
14:10DuneManyeah, it is
14:10DuneManjust different workflows
14:10DuneManI'm getting used to git's over time, and finding it useful
14:10DuneMan:-)
14:10ataggartwlangstroth: a distinction without a difference as everyone seems to use github anyway
14:11Drakesontechnomancy:
14:11Drakesonoops!
14:11technomancyataggart: not at all, see http://github.com/technomancy/gitjour
14:11Drakesontechnomancy: the latest swank-clojure push does not work here
14:12wlangstrothataggart: I dunno - I prefer to commit a bunch, then go over it, and maybe push to github once a day.
14:12technomancyDrakeson: the xref merge?
14:12Drakesonit nags about not being able to turn PrintStream to StreamWriter or something like that. it points at the fall-back flatten definition in util.clj
14:13ataggartwlangstroth: so do I, I just call it saving files a bunch, then go over it, and maybe commit to the repo once a day.
14:13DuneManwlangstroth: Agree. I found that a weird workflow until I started using it.
14:13technomancyDrakeson: which Clojure version?
14:13Drakesonlatest
14:13technomancyI'll take a look at it tonight
14:13DuneManI also got used to being able to pull working sets to other machines
14:14ataggartin any case, my main problem with git is its ecosystem is less useful ot me than svn's
14:14DuneManand do complex multi-branch merging
14:14Drakesontechnomancy: thanks
14:14DuneManataggart: Part of that is just a workflow problem, of course. But yes, there's less developed tools.
14:14wlangstrothataggart: but if you have a bunch of different branches, it's not just saving.
14:15ataggartwlangstroth: I have multiple branches on my machine right now. It's not an issue.
14:15ataggartI will of course grant that svn's branch/merge feature isn't as nice as git's
14:15maravillasand i suspect if you were to want to back out your latest change, which might span multiple files, doing so using your eclipse history wouldn't be a trivial task
14:16ataggartbut I do that far less than I check-in files, and so not being able to have a nice diff view is more of a liability
14:16DuneManagain, git diff > your favorite diff tool
14:16ataggartfalse
14:16DuneManI don't see what the issue is :-)
14:16ataggartclearly
14:16ataggartuse subclipse
14:16ataggartyou'll see
14:16wlangstrothI don't think it's an issue, really. I've adapted to both, but I don't use a gui
14:16maravillasi think that's a redirect operator, not a greater than :)
14:17DuneManindeed, maravillas
14:17ataggartah lol
14:17ataggartvery well then
14:17DuneManhahaha
14:17DuneManreading inline diffs can be really painful
14:17DuneManespecially 3-way diffs
14:17DuneManI'm used to it, but wouldn't exactly recommend it
14:18ataggartfor example: http://subclipse.tigris.org/images/sync-ss.png
14:18DuneManthat gui makes me want to cry
14:18ataggartbear in mind it's a tiny window to the actually files are too small to be useful
14:18DuneManI loath eclipse.
14:18ataggartthat gui contains useful info
14:18wlangstrothhaha - we're definitely arguing gui vs terminal now
14:19ataggartthe set of all files changed, the directionality of the changes, a diff of a particular file, and the revision history
14:19DuneManyeah, we are. just differing workflows. maybe someone will make a good git gui to accomodate ataggart's
14:19ataggartnot likely
14:19wlangstrothI think it's called gitk
14:19ataggarthow anyone can commit files to a repo without having all that info in front of them beforehand... I just don't understand
14:19DuneMangitk/gitx are sorta half useful still
14:20ataggartno one in my office does a blind commit. everything gets reviewed thru the "synchronize view" so we all can know exactly what's changing
14:20wlangstrothataggart: well, it's all text, so I use a text reader
14:20ataggartdo you ave a screenshot showing what that looks like for multiple files?
14:21DuneManataggart: Because you basically get used to checking things in order.
14:21ataggart"in order"?
14:21DuneManWe also have a custom deployment system
14:21DuneManwhich keeps track of branches for us.
14:21ataggartI'm not talking about branches
14:21wlangstrothit looks like diffs - what do you mean?
14:21ataggartI'm talking about, I change 5 files, someone else concurrently chnged 5 files, some of those changes overlap
14:22DuneManOh. That's easy.
14:22ataggartwhat does that diff look lke for you?
14:22DuneManif the push fails, you pull and see what happened.
14:22ataggart...
14:22DuneManit looks like git diff.
14:22DuneMangit wont push revisions on top of each other that haven't been merged.
14:22DuneManunless you do some really whacky dancing
14:22DuneManwith git merge and cherry picking commits
14:22ataggartso you trust the merge logic of git to understand how your changes will interact with the changes someone else made?
14:23DuneManno, you pull and do the merge.
14:23ataggartbut do you ever look at the changes side by side before a merge?
14:23DuneManconstantly.
14:23DuneManYou have to.
14:23ataggartok, I'm asking what does that look like
14:23ataggartin the terminal
14:23DuneManit looks like git difff
14:23wlangstrothhaha
14:23fliebelCan Clojure(or any Java language) run on mobile devices?
14:23DuneManI look at the changes inline.
14:24wlangstrothataggart: it looks like a lot of white text on a black screen
14:24wlangstrothI'm thinking you wouldn't like it
14:25ataggartperhaps not.
14:25ataggartI like not being constrained to 1980s tech
14:25Drakesonis there a standard way (i.e., one that can be done programmatically) to find the documentation of a fully-qualified class (e.g. java.io.File)?
14:25DuneManI use vimdiff for side-by-side diff
14:25DuneManif my diff is complicated
14:25technomancyataggart: and yet you're using lisp... =)
14:25wlangstrothhaha - it's still all text, dude
14:25DuneManand sometimes a 3-way diff tool
14:25ataggartnot really just text
14:25ataggartthere's deeper meanign there
14:26Drakesontechnomancy: removing that flatten def fixes it here.
14:26fliebelWhat are the requirements(Java) for running Clojure?
14:26technomancyDrakeson: so it's giving you problems even though it's nested inside a when-not?
14:27Drakesonyes.
14:27stuartsierrafliebel: Java 1.5
14:27BorkdudeAm I right when saying that Clojure is closer to Haskell than Scala is to Haskell? I don't want to force a discussion
14:28fliebelstuartsierra: I see… so I guess I'll forget about mobile and very mobile devices :D ( http://lejos.sourceforge.net/ )
14:28sexpbot"LeJOS, Java for Lego Mindstorms"
14:28DuneManBorkdude: Why do you say that?
14:28DuneManI actually don't know much about scala...
14:28BorkdudeDuneMan: because of this question: http://stackoverflow.com/questions/2820801/yet-another-haskell-vs-scala-question
14:28sexpbot"Yet another Haskell vs. Scala question - Stack Overflow"
14:28wlangstrothBorkdude: I'd say it just to see the fur fly
14:29DuneManbut like... linguistically... a lisp isn't really like haskell.
14:29BorkdudeHe mentions Clojure briefly, but if he feels that Scala feels clunky wrt e.g. partial application, then he definitly should go for Clojure imho
14:30BorkdudeDuneMan: if you compare the characteristics? immutibility, laziness, pattern matching?
14:31BorkdudeIt was just my feeling, I don't know Haskell and Scala that well, so.
14:31DuneManType systems seem far more.... ingrained than any of those.
14:31Dawgmatixwhats a good clojure web framework to look at ?
14:31fliebelDawgmatix: good question, I'm also interested :)
14:32BorkdudeDawgmatix: isn't Compojure one?
14:32fliebelI think compojure, thats the only one I heard of
14:32Dawgmatixokay
14:32fliebelOr Spring maybe :)
14:32BorkdudeDuneMan: I think he's not after a type system, but after a nice language in which he also can use Java stuff
14:33ober2compojure is pretty nice. we moved some sinatra stuff over easily
14:33DuneManThen that's a totally different question than "What's more like Haskell"
14:33Dawgmatixi am looking to move from django, because I finally feel confident about my clojure skills
14:33mabesDawgmatix: compojure uses a framework called Ring which you can also use independently..
14:33ober2very simular
14:33DuneManI've never used Scala :-)
14:33Dawgmatixokay mabes
14:35joshua-choiI have some questions on how Leiningen works. What version of Clojure does it use, and where is it stored? When I "lein self-install", from what source does it download from?
14:35joshua-choiI'm asking this because I'm encountering some problems with Leiningen that I suspect has to do with Clojure 1.2.
14:36ataggartby default lein seems to pull down 1.1.0
14:36ataggartbut if you add a dep to 1.2.0-Master in your project.clj then it will pull that version
14:36DuneManluckily technomancy is here
14:36ataggartyeah, ignore me. I'm mostly guessing :)
14:36DuneManbut yes, uses 1.1 by default
14:36joshua-choiI see, thank you
14:37joshua-choiI'm encountering two problems
14:37technomancyjoshua-choi: leiningen's clojure version is independent of the clojure version your project uses (with the notable exception of the lein repl task in lein 1.1)
14:38DuneManwhich reminds me I should fix my lein version so lein repl works right
14:38DuneManhah
14:38joshua-choitechnomancy: I see. I'm encountering two errors in Lein. One is, in a project using Clojure 1.2's snapshot and Autodoc 0.7.1, using "lein autodoc" throws a bunch of errors...
14:39joshua-choiBut the other is stranger: simply running "lein help" gives similar errors.
14:39joshua-choiI've pasted the output: http://gist.github.com/398271
14:39wlangstrothScala is kind of like almost-functional java. F# does a better job on the functional side, it seems
14:40technomancyjoshua-choi: there are some unresolved issues with autodoc I think. it's tightly coupled to a single clojure version, so I think it might only work with lein 1.2.0-SNAPSHOT (from git) right now.
14:40technomancysince it uses the lein version of clojure, not the project's version
14:40wlangstroth(Of course, Clojure isn't purely functional, either, but ...)
14:40joshua-choitechnomancy: "lein help" should not be affected by autodoc, though
14:41joshua-choi...as far as I can tell.
14:41technomancyjoshua-choi: lein help tries to load all lein plugins in order to show their docstrings
14:41technomancybut it should be resilient to broken plugins, you're right
14:41joshua-choiAh. That would explain it.
14:42Dawgmatixi just heard about leiningen from the above discussion - is it similar to what asdf is in lisp ?
14:42Dawgmatixnvm, the github page has a good description :)
14:47joshua-choitechnomancy: What is the relationship between the Clojure versions of Leiningen and its plugins? Does Leiningen itself currently always use 1.1?
14:47joshua-choiAlso, is there a Leiningen 1.2.0? I cannot find it on its GitHub website.
14:54DuneManThe method described in *Hacking* doesn't seem to work right
14:54DuneManafter I do lein self-install with a stable checkout
14:54DuneMan(on the stable branch)
14:54DuneManI try to do lein deps
14:55DuneManand it says "Your Leiningen development checkout is missing its dependencies" etc
14:56DuneManAnd.... it installed 1.1.0
14:57DuneMantips technomancy?
15:00technomancyDuneMan: sounds like you're confusing lein with lein-stable?
15:03Dawgmatixdoes "lein swank" not work with plain slime ?
15:05dataangelanyone know where I could find an overview of how to implement a persistent binary tree? I only ask here since clojure is my first exposure to persistent stuff ;p
15:05dataangelpersistent binary search tree rather
15:12Winstons55should the following code work (running off of clojure-1.2.0-master-20100507.230258-69)? I'm getting a compile error complaining about not resolving % in this context on the post condition.
15:12Winstons55(defprotocol TestProto
15:12Winstons55 (simple-func [arg]))
15:12Winstons55(deftype TestType [test-val]
15:12Winstons55 TestProto
15:12Winstons55 (simple-func [arg]
15:12Winstons55 {:pre [(= 0 arg)]
15:12Winstons55 :post [(= 1 %)]}
15:12Winstons55 1))
15:12Winstons55whoa, my bad on the formatting/multi-lines
15:15stuartsierraWinstons55: datatype methods don't have all the features of fn
15:16stuartsierrawhich appears to include pre/post conditions
15:16Winstons55ah ok, good to know
15:16Winstons55thanks!
15:27raekdataangel: this article has an example implementation of a persistent binary tree: http://www.infoq.com/articles/in-depth-look-clojure-collections
15:27sexpbot"InfoQ: An In-Depth Look at Clojure Collections"
15:29raekto bad the formatting messed up the code examples including "<"
15:31chouserhttp://www.developer.com/print.php/3874551 -- same article, but apparently less broken formatting
15:31sexpbot"Clojure: Immutability at the Language Level — Developer.com"
15:32raekchouser: thanks!
15:33chouserquite welcome
15:33chouserhttp://joyofclojure.com/buy -- same article, but longer and more expensive
15:33sexpbot"Manning: The Joy of Clojure"
15:33chouser:-)
15:33raek:)
15:37raekhrm, how does this work? it is available as an ebook now, but the physical one comes this fall?
15:37chouserright
15:37chouserwell, parts are available as PDF now
15:38raekah, I see
15:38chouserall of it should be available this fall in printed form and in several ebook formats (pdf and epub at least, I think)
15:39LauJensenDoes anybody know the name of a function which turns all of this %40 into @ and %2F into / and so forth ?
15:40raeksomething like java.net.URLEncoder?
15:40Dawgmatixi am one of the people who bought the book as an early release
15:40Dawgmatixits pretty fascinating to read the updated pdfs as they are written :)
15:41LauJensenraek: java.net.URLDecoder/decode - Thanks, just what I needed
15:45BorkdudeI am reading it too
16:01ninjuddchouser: i heard that you may or may not be working on a pure clojure version of protocol buffers...
16:05chouserninjudd: hm... no, "pure clojure" isn't quite right
16:07ninjuddchouser: oh, have you looked at my implementation? http://github.com/ninjudd/clojure-protobuf
16:08ninjuddbasically just a clojure wrapper around the official google java implementation
16:08DuneManseems reasonable
16:08chouserninjudd: yes, I believe I glanced through your code a while ago
16:10chouserI hadn't seen your set/map extensions. Those look neat
16:10chouserthough it suggests we may have different usage profiles in mind. Not surprising, I suppose.
16:10ninjuddchouser: i've thought about rewriting PersistentProtocolBufferMap using deftype, but i don't want to duplicate work you may or may not be doing
16:11ninjuddchouser: how so?
16:11DuneMantechnomancy: lein-stable is just bin/lein of the stable branch, no?
16:12DuneManbecause the "Hacking" section refers to lein-stable, but nothing else does
16:12chouserI'm using protobufs defined by others for contexts other than clojure, just providing clojure interop with them. So I have no need for such extensions.
16:13ninjuddi see. makes sense. though the extensions are still usable by someone outside of clojure
16:13chousersure
16:13ninjuddthey just appear as repeated fields
16:13chouseroh, I see.
16:13ninjuddthough a protobuf implementation in another language could choose to read the metadata and make them sets or maps
16:14chouserwell, you shouldn't worry about duplicating effort. I'm not at liberty to opensource this code at the moment.
16:14ninjuddah, i see
16:15chouserI'm pushing for it and management is open to the idea, but has more pressing priorities...
16:16ninjuddchouser: did you implement it the same way? by wrapping the google implementation?
16:16chouseryes, the version that works today wraps generated Message objects
16:16ninjuddor did you write your own implementation from scratch?
16:16ninjuddi see
16:18ninjuddok well, i'll let you know if i get around to rewriting it to use deftype
16:19chousermine doesn't have any .java code
16:19ninjuddother than the google code
16:19chouserright. I mean I managed to avoid writing any .java code. :-)
16:20ninjudddo you use deftype? or gen-class/proxy
16:21chouserit generates code (at compile time if it can, or runtime if necessary) so that (:field msg) is a straight call the java accessor generated by protoc
16:21DuneMantechnomancy: I mean, I symlinked leingingen/bin/lein to lein-stable, but apparently that's not the way to go
16:21chouserthe generated message-wrappers implement IKeywordLookup to tie into clojure's call-site caching
16:21ninjuddnice, so yours is probably faster
16:22chouserI haven't done much benchmarking -- I mostly wanted to make sure the API was such that it could be made fast if needed
16:22chouserand it gave me an excuse to play with IKeywordLookup
16:22ninjuddwell i use DynamicMessage rather than the generated message classes, so i assume there is some cost to that
16:22ninjuddi'm not familiar with IKeywordLookup
16:23chouseryeah, it's not really documented. hence the fun in playing with it ;-)
16:23DuneMantechnomancy: And the lein script linked to from the website installs 1.1.0 in ~/.m2/repository/leiningen
16:24ninjuddchouser: looking at the clojure code now... so it is part of deftype?
16:24chouserI think it only makes sense for when you're trying to expose a statically-typed thing (like a defrecord or protobuf) to Clojure
16:24chouserninjudd: yeah, it's how defrecord field lookups can be as fast as a direct java field lookup
16:25DuneMantechnomancy: So... I don't understand what I'm supposed to be doing differently.
16:25chouser(:foo thing) as fast as (.foo #^Thing thing)
16:25DuneManoh, I bet I have to build the jar
16:25DuneManduh
16:25chousernote it's just as fast even though no type hint, which is rhickey just showing off.
16:26ataggartlol
16:26ninjuddi see.. hehe
16:26ataggartI'm hearing praise from a co-worker in at the clojure thing in NC
16:26ninjuddchouser: i may look into doing it this way (if you don't mind). the serialization/deserialization speed is very important for our application
16:27chouserninjudd: I don't mind. I wish I could share my code. :-/
16:27ninjuddme too!
16:27chouserfor what it's worth, after I got all that working I realized we'd sometimes need to deal with dynamic messages
16:28ninjuddhmm
16:28chouserthat is, we have a DescriptorProtos$DescriptorProto, but no generated java code for this particular message.
16:28ninjuddwell i'd be really interested in a speed comparison between mine and yours if you get the time
16:28chouserwe likely have the DescriptorProto at compile-time for any piece of clojure code using it, but not at java compile time.
16:29chouserso I've started reworking my code to provide an API as close as I can to what we are currently using, but to allow for these dynamic messages.
16:29chouserninjudd: hm, yeah I should do that.
16:29chouseryay microbenchmarks. heh.
16:31ninjuddwell, i'm sure yours will be faster, but it's hard to know how much
16:31ninjudddepends on the size of the messages and number of fields etc though
16:31chouserI'm sure
16:31chouserand how many reads per write, stuff like that.
16:33ninjuddi have a benchmark for our use case, but i'm trying to judge whether the work would be worth the increase
16:33ninjuddwould be a good learning experience though
16:34chouserif you want to send me something I could run and then tweak to use our lib instead, I could do that and send you both sets of numbers.
16:34ninjuddthanks
16:36ninjuddthere is some proprietary code in the benchmark, but i may be able to come up with a reasonable benchmark that doesn't have it
16:37chouserok
16:37ninjuddi'm benchmarking our application code that depends on jiraph which depends on protobufs
16:37ninjuddi should probably write a direct benchmark for jiraph anyway
16:47technomancyDuneMan: lein-stable doesn't belong in a checkout at all. just wget the script directly.
16:48technomancyDuneMan: it can tell if it's running from a checkout or not. if it is, it assumes it's a dev version
16:48DuneManI had just not done a lein-stable jar in my checkout
16:49DuneManso it obviusly wasn't findind the jar
16:49DuneManbecause I was a tard.
16:50technomancyI guess that might work too, but it's not what I meant
16:50DuneManI basically just misread what the hacking section was telling ,me.
16:50DuneManBecause I didn't run lein-stable deps (lein-stable jar, of course, does this)
16:50DuneManin my leiningen checkout
16:50DuneManI was running it in my project
17:12ska2342Hi. Maybe this is a stupid question to ask, but... has there been a discussion yet on nth vs. get, especially when it comes to lists?
17:23chouserget is always fast (that is O(log n) or faster). nth is sometimes not always (sometimes O(n))
17:26ska2342get falls back on nth, but only for types where it can keep its performance guarantee, as far as I can see. Granted. However, I have a bad feeling having two functions doing almost the same (and actually the same sometimes) just for the performance guarantee. In addition to that: get silently returns nil for lists where nth raises an exception for maps. (The topic is related to the contains?-discussion, but I'd like to focus on lists this ti
17:28ataggartget is used when you have a "key" (loosely defined)
17:28ataggart,(get 1 '(:foo :bar))
17:28clojurebotnil
17:28ataggarterm
17:28ataggart,(get '(:foo :bar) 1)
17:28clojurebotnil
17:28DeusExPikachuin the documentation for defprotocol, shouldn't the method definitions in the deftype example include a first argument for this? I'm getting errors in the repl copypasting this code http://richhickey.github.com/clojure/clojure.core-api.html#clojure.core/defprotocol
17:29ska2342ataggart: I know :-), but e.g. for strings it falls back to nth
17:29ataggartska2342: that's probably because strings have "keys"
17:30ataggarti.e. the index of the char in the array
17:30DeusExPikachunote that in http://clojure.org/protocols, the 'this' field is supplied with the name 'x'
17:30DeusExPikachufor deftype
17:31ataggartdon't worry about implementation. get is for ~O(1) access by keys. nth gets the nth element which may end up being ~O(1) or O(n)
17:31ataggartuse the function that logically applies
17:32ska2342ataggart: yes, I can see that. I think I understood the implementation. I question the fact that two fn exists for basically the same thing (acessing elements of a collection) seemingly just for the performance guarantee. And that for lists get quietly return nil every time
17:32ska2342is the performance guarantee part of a function or a datastructure?
17:33ataggartboth
17:34ataggartnth and get are different
17:34ataggartfor example:
17:34ataggart,(nth {:a :b, :c :d} 1)
17:34clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap
17:35ska2342,(get '(1 2 3) 0)
17:35clojurebotnil
17:35ataggart,(nth (seq {:a :b, :c :d}) 1)
17:35clojurebot[:c :d]
17:35AWizzArdThey are different, but is such a difference required?
17:36AWizzArdAs I see it, the point of ska2342 is: for lists nth and get could be the same
17:36ataggartyes because the performance characteristics for different datastructures are different
17:36ska2342,(get '(1 2 3) nil)
17:36clojurebotnil
17:36ataggartget on lists would not be ~O(1)
17:36AWizzArdataggart: O(n) for nth for lists
17:36AWizzArdso, no nth for lists then?
17:36ska2342,(get '(1 2 3) :whatever)
17:36clojurebotnil
17:36ataggartnth works on sequential structures
17:36ataggartget works on associative structures
17:36ataggartthey're different
17:37ataggartonly you can know which structures you're working with
17:37AWizzArd,(get '[10 20 30 40] 2)
17:37clojurebot30
17:37AWizzArd,(get '(10 20 30 40) 2)
17:37clojurebotnil
17:37ataggartand you don't need to quote vectors
17:37AWizzArdI know.
17:37ska2342what about raising an exception if you pass a sequential thing to get?
17:37ataggartk :)
17:37AWizzArdthat would not be a good thing
17:38AWizzArdIt was part of rhickeys descisions to return nil instead of throwing exceptions
17:38ataggartif you need to check for that case (instead of relying on nil) then use contains?
17:38AWizzArdso you don't have to scatter your code everywhere with (try (get ..) (catch Exception e nil))
17:38ska2342AWizzArd: like nth for associatives? ;-P
17:39ataggartmight be an oversight
17:39AWizzArdnth on maps is one thing, it could be discussed, but well, for get the situation is different. I don't see why get can not be like nth on lists
17:39ska2342ataggart: contains? quietly returns nil for lists, every time. I this time it could get the result in O(1) just like it does for vectors
17:40ataggartAWizzArd: because get is contractually fast. You cannot be fast on lists.
17:40ataggartska2342: nil == false in that context
17:40AWizzArdIs there an argument why get should be contractually fast?
17:40ska2342I am not a language desinger (IANALD? ;-) but this is fishy
17:41AWizzArdMaybe usabilty could come before efficiency here
17:41ska2342ataggart: don't ever try to argue with a newcomer to lisp-likes about nil not being false anytime :)
17:42mmarczykAWizzArd: there might be a general argument to support the notion that any core library function performing basic data structure manipulation duties should have its performance guarantees included in its contract
17:42ataggartsince get returns nil for structures where get is not ~O(1), if you're worried about whether that nil is the "not able" nil, or the "here's the value, which happens to be nil" nil, then use contains?
17:43mmarczykonly contains? happens to be the predicate counterpart of get :-)
17:43ataggartAWizzArd: that's a great way for people to write slow code and blame the new language. Pick your datastructures with forethought instead.
17:43ska2342ataggart: but (as I said) contains? does the same thing as get with lists
17:43mmarczyk,(contains? '(1 2 3) 1)
17:43clojurebotfalse
17:43mmarczyk,(contains? [1 2 3] 1)
17:43clojurebottrue
17:43mmarczyk,(contains? [1 2 3] 3)
17:43clojurebotfalse
17:44ataggartthe question being answered by contains? is "is it meaningful to use get"
17:44mmarczyk,[(get [1 2 3] 1) (get [1 2 3] 3)]
17:44clojurebot[2 nil]
17:44AWizzArdataggart: how would get be slower than nth?
17:44mmarczykataggart: ah, I see the point you're making now
17:44ska2342please don't get into the old contains? checks for index discussion now...
17:44ataggartI'm conveying what I understand to be Rich's POV
17:44ataggartnot my own
17:44AWizzArdnewcomer wants to get element 5000 out of a list. (get elements 5000) ==> slow, so Clojure must be blamed?
17:45mmarczykska2342: not getting into any discussion on this, just point out the current state of afairs
17:45ska2342ataggart: perfectly fine, I try to understand it :-)
17:46mmarczykAWizzArd: well hopefully people no better than to expect less than O(n) from linked list lookup :-)
17:46mmarczykknow better
17:46mmarczykbut still, if it is a totally different operation to, say, vector lookup by index
17:47mmarczykwhy overload a single function with both tasks
17:47ska2342mmarczyk: that's one of my points. If I feed a list to the element-getter-function, I know the penalty. I don't really see the reason for having both
17:47ataggartif you want the nth item, use nth
17:47ataggartif you want to lookup by key, use get
17:47mmarczykwhat ataggart said :-)
17:47ataggartit's not hard
17:48mmarczykit's conceivable that we could have just one name in core for both things
17:48ataggartbtw, regarding the need for contains?...
17:48ataggart,(get '(:a :b) 1)
17:48mmarczykI don't see how that would be helpful in anything
17:48clojurebotnil
17:48AWizzArdwell, a list is also a mapping, from its position (key) to the element that is referenced there (val)
17:48ataggart,(get [:a nil :b] 1)
17:48clojurebotnil
17:48ska2342mmarczyk: overloading because then I can change the type later easily. Me, coming from lisp not java, likes to do experiments with lists. And I hated the changes I had to do in CL when I changed the implementation
17:48mmarczykAWizzArd: not at all
17:48ataggartAWizzArd: incorrect
17:48mmarczykska2342: a-ha! you see, there's the point of "having both" for you :-)
17:49mmarczykska2342: to force you out of your "listy" comfort zone into using the could-be-correct data structures from the get-go
17:49mmarczykwhich is perfectly easy to do in Clojure, since you've got first class vectors, on par with lists, functionally "updatable"
17:49ska2342mmarczyk: sorry, I don't get that. Could you please elaborate?
17:50mmarczykska2342: there's no point at all, in Clojure, to experimenting with lists first
17:50mmarczykwhen a vector is actually the better data structure
17:50mmarczykbecause you gain nothing in syntactic convenience or "natural feel" of your programme
17:50AWizzArdif lists can be used to implement maps, then they offer semantically the same, so, yes, lists are mappings
17:50mmarczykthat's in contrast to Scheme / CL where lists are obviously the only first class citizens
17:50AWizzArdyou can implement classes and maps with lists, and vice versa
17:50ska2342mmarzyk: Point taken. And I already adapted my habits. It's just the remembrance of things that makes me shudder
17:51ataggartAWizzArd: maps are not implemented with lists
17:51mmarczykwell, lists and very similar abstractions like Scheme's streams
17:51AWizzArdI know, of course they are not
17:51AWizzArdfor sake of efficiency
17:51AWizzArdbut conceptually they can express the same thing
17:51ataggartand efficiency is the entire point of the get function
17:51AWizzArdfrom turing point of view
17:51ska2342It feels like in Clojure lists are only created for containing code.
17:51mmarczykska2342: yeah, I actually find I miss nice vector support in Scheme nowadays :-)
17:52AWizzArdI would say that the point of get is to get the value behind the key
17:52ataggartska2342: bingo!
17:52AWizzArdwith the best performance possible
17:52ataggart"key" has no meaning for lists
17:53AWizzArdit has the same meaning as it has for vectors or maps
17:53ataggartexcept the synthetic one you impute by position
17:53ataggartfalse
17:53mmarczykska2342: actual lists / conses, yeah, but list-like seqs are used all over the place
17:53AWizzArdataggart: can you explain it?
17:53ataggartapparently not
17:53AWizzArd(:
17:53mmarczyk:-)
17:53ska2342mmarzyk: seqs are a different beast. But get just returns nil for them, too ,-)
17:54hiredman~ping
17:54clojurebotPONG!
17:54ataggartbut to back up, certain functions are provided precisely for their performance characteristics.
17:54ataggartget os one of those functions
17:54mmarczykska2342: for the same reasons as with lists :-)
17:55chouserone could try to implement all abstractions on all concrete types: use lists as maps and sets, maps as lists and vectors, etc.
17:55AWizzArdI don't mind having two fns, get and nth. Though in the end it would be totally acceptable to only have a "get" which works as efficient as possible on its specific type.
17:55ska2342ataggart: that kinda feels wrong for me, since I happen to think Big-O when I think about datastructures, not functions. I still hold my point with the exception
17:55chouserthings would "just work" but with less clear performance profiles.
17:55AWizzArdchouser: yes, this is possible
17:55AWizzArdexactly
17:55chouserbut that language is not Clojure
17:56AWizzArdyes, this is more in the category of turing completness
17:56ataggartwhat does turing completeness have to do with any of this?
17:56AWizzArdin principle lists would be enough to do calculations, numbers are not needed
17:57ataggartsure, and the performance profile would be crap. Still not clear on what this has to do with TC
17:57AWizzArdthe magic word here is "category"
17:57ska2342chouser: then, why have lists at all? Because Clojure is a lisp? Just for code?
17:58ataggartska2342: you use them in macros
17:58chouserlists are useful
17:58Borkdudeska2342: I asked that question one time, then I came up with a GW-Basic version of Clojure where you can do goto to step into the nth instruction
17:58chouserif you want to pop and seq in the same direction, for example
17:59ska2342wouldn't anything implementing Sequential suffice?
17:59mmarczyklists are basically finite sequences
17:59mmarczykif you're going to have lazy, potentially infinite seqs
17:59mmarczykit makes sense to allow for the finite case to
17:59ska2342Oh, sorry, the interface Sequential seems to be empty here
18:00Borkdudemaybe you can say that lists are literal seqs in Clojure?
18:00raekalso, lists can be partially garbage collected
18:00mmarczykand as chouser points out, LIFOs "are" lists (are naturally implemented as)
18:01mmarczykraek: anything that has parts can be partially garbage collected
18:01mmarczykraek: for lists, you have to lose the head for that to happen, for vectors -- the trie root, which happens all the time
18:01AWizzArdbtw, as vectors are tries under the hood, is conj as efficient for vectors as it is for lists?
18:02mmarczykconj is the one op which is implemented for all Clojure data structures
18:02mmarczykand is efficient across the board
18:02raekdon't vector seqs have a reference to the trie root?
18:02ataggartbut, they do have *slightly* different chartacteristics
18:02mmarczykbut it does different things: cons for lists, push-at-tail for vectors
18:02AWizzArdataggart: yes, this is what i would intuitively thing
18:02AWizzArdi am going to try this now :)
18:03raek(drop 999 (seq 1000-element-vector))
18:03ataggartO(1) vs O(log32n)
18:03mmarczykraek: ah, possibly
18:03ataggartclose enough
18:03raekwon't that retain all the elements?
18:04ataggartraek: nope, nothign holds the head
18:04ataggartof the 100-element-vector
18:04mmarczykraek: but if you do (assoc [...] ix :foo), the old version of the vector might be garbage collected
18:04mmarczykraek: so there's partial GC for you
18:04AWizzArd,(time (dotimes [i 1000000] (conj [] 10)))
18:04clojurebot"Elapsed time: 226.984 msecs"
18:04Borkdudemaybe it would be nice to include some big-O information as metadata and some functions that can deduce how your functions will perform... just thinking aloud
18:04AWizzArd,(time (dotimes [i 1000000] (conj () 10)))
18:04arohnerif 1000-element-vector is a local or var, doesn't that hold head?
18:04clojurebot"Elapsed time: 148.905 msecs"
18:04ataggarttry not to kill clojurebot
18:04ataggart:)
18:04mmarczykBorkdude: wow, this is really cool :-)
18:04AWizzArdthe bot is pretty well secured by now
18:05mmarczykataggart: on the contrary, we should all endeavour to kill clojurebot so that clj-sandbox might be improved :-)
18:05AWizzArdnow Licenser should step in :)
18:05mmarczykor is this one not based on clj-sandbox, I forget... state-of-the-art in Clojure sandboxing, anyway
18:07Borkdudemmarczyk: don't know if it's possible though
18:07Borkdudejust an interesting thought
18:08mmarczykBorkdude: well, I suppose a general big-O calculator would be impossible, as it would have to determine stuff like no. of iterations per element etc.
18:08mmarczykBorkdude: but having an extra piece of meta data would be cool :-)
18:08mmarczyk{:big-O "n"} for O(n)? :-)
18:09ataggartbig-O's usefulness is often overstated
18:09BorkdudeFor example, or maybe :big-O {:get "1" :nth "n"}
18:09ataggartcase in point:
18:09ataggart,(type {:foo :bar})
18:09clojurebotclojure.lang.PersistentArrayMap
18:10ska2342the meta-tag would need a better name, though. :landau ? ;-)
18:10arkahnfor the following ;;; (defn read-a-file [#^String f] (with-open [#^BufferedReader r (FileReader. f)] (.r readline))) ;;; does the #^String help or is it unnecessary?
18:10ataggarttake it away and call (set! *warn-on-reflection* true)
18:10mmarczykska2342: yeah :-)
18:10ataggartclojure will tell you
18:10ataggartpremature type-hinting is...
18:11arkahnstarted, the noob-clojure programming has ... : (
18:11arkahn: )
18:12mmarczykataggart: I'm not sure if this perfectly valid point has any bearing on whether big-O is useful :-)
18:12Faredoes clojure run on Android?
18:12lancepantzFare: yes
18:12Fareyay.
18:12ataggartclojure run where java runs (more or less)
18:12mmarczykFare: I remember reading an entry on some blog describing how to set up a repl for use on an android phone :-)
18:13Fare(yes, but Android has its own set of Java libraries, so I was wondering)
18:45arkahnshould 'when' be avoided if side-effects are not being introduced
18:46Fareuse and ?
18:46arkahnFare: I'm sorry - I'm not sure what you mean
18:47arkahnFare: use a pred?
18:48raek'when' is useful whenever you would put nil in the false branch of an if
18:48tomoj,(if nil 3)
18:48clojurebotnil
18:48tomojguess it's just a better name than 'if' for this case
18:48raekhrm, yes
18:49arkahnok ... so side effects are not required in a stylistic sense
18:49tomojwait, huh?
18:49tomojpeople use side-effects with when?
18:49raek(when pred do-a do-b do-c)
18:49arkahnI was reading that using 'do' suggests that "side effects follow" and 'when' is an if + do
18:49technomancyyes, that's why "when" has an implicit "do"
18:50technomancyarkahn: that's quite right.
18:50tomojoh, weird, I never got that
18:50arkahncool - thanks all
18:50tomojI always just used it to replace an if with no else
18:50arkahnI read it's used then, too, but apparently only when you want to introduce side effects (?)
18:51arkahnnot enforced by clojure, but programming style
18:55chouserno, 'when' is fine in pure code for "ifs" with no "elses"
18:57arkahnchouser: Programming Clojure (p. 48) suggests what technomancy said, but that's the only authoritative source I have to go off of
19:00arkahnchouser: at least, it refers to 'do' in that example, so does that implicitly apply to 'when' when it's just an 'if ? do-a do-b do-c'? I'm just learning ; )
19:01arkahnI feel like I'm learning basketball and all I've done so far is learn dribbling a basic passing o.0
19:08arkahnfwiw, I checked Joy of Clojure and they don't use 'when' only for forms including side effects. Clojure is my first lisp; is 'if' so gimpy because of lisp heritage, so 'when' was created? 'if' doesn't seem like it would be commonly used.
19:09Chousukehm?
19:09Chousukewhen is just a convenient form for an if that has no else-clause
19:10Chousukethe syntax for is is (if pred then else) whereas when is (when pred then-expr*)
19:11Chousukeit also conveys the intent better
19:11arohnerarkahn: 'when' is also useful as a hint to the reader that there should be no else clause
19:11arohneras opposed to (if p true-clause)
19:12arkahnok - thank you
19:17tomojwhy does if seem like it would be uncommon?
19:17tomojit's quite common
19:19ataggartperhaps he's asking because if isn't in the api?
19:19arkahnmost of the code I've read doesn't use it but that's not saying much - what I said really doesn't make sense, including the "gimpy" label
19:19arkahnall this has been helpful to think over though
19:28DuneManone thing is that the normal places that you see lots of if/elses in imperative code get shoved into things like (filter...) in clojure. There tends to be somewhat less boiler-plate conditional checking construction.
19:31DuneManneither am I.
19:31DuneManbut I do like how "when" reads.
19:36maxhodakno matter what i do amap always throws java.lang.IllegalArgumentException on me
19:40defnCould someone explain the whole Q thing?
19:40defn,Q
19:40clojurebot<-nil-<
19:40defn,`Q
19:40clojurebotsandbox/Q
19:40defn,``Q
19:40clojurebot(quote sandbox/Q)
19:41arkahnit's shorthand for clojure.lang.PersistentQueue/EMPTY I think, but I've only seen it used with clojurebot and/or sexpbot
19:42ataggart(conj 5 Q)
19:42ataggart,(conj 5 Q)
19:42clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection
19:42ataggart,(conj Q 5)
19:42clojurebot<-(5)-<
19:43ataggartinteresting
19:43ataggart,(pop *1)
19:43clojurebotjava.lang.IllegalStateException: Var clojure.core/*1 is unbound.
19:44tomojwhat about the whole <-*-< thing?
19:45tomojis that how PersistentQueues print now?
19:45arkahnthat's bot specific because I haven't seen that at the repl when using those
19:46arkahnit makes me think they're there to show where elements enter and exit the queue
19:49arkahnI was looking at a way to share data between two threads and at first thought I wanted to use clojure.lang.PersistentQueue but am now thinking agents might be more idiomatic ... and hoping I don't take a performance hit for agents over PersistantQueue
19:52ninjudd,(class Q)
19:52clojurebotclojure.lang.PersistentQueue
19:53tomojarkahn: I don't think the choice is between PersistentQueue and agents
19:54tomojif you use a PersistentQueue, don't you need a reference type anyway?
19:54arkahnyes
19:56ninjuddthat reminds me, i have a patch i need to submit to make PersistentQueue count O(1)
19:56arkahnI was thinking of it as a way to pass data: a thread could stuff it in a shared data structure or could send-off messages to an agent which ends up being a fifo-style anyway
19:56ninjuddright now, if you call count, it iterates through the list portion of the queue to count it
19:58ninjuddarkahn: all persistent data structures are a way to share data
20:00ninjuddyou still need a time construct to modify a persistent queue... a ref or an agent or an atom
20:01ninjuddif you want another thread to see the change
20:02DuneManarkahn: SynchronousBlockingQueue can actually make more sense for that use case
20:03DuneManbut it depends on what you're doing
20:03DuneManIf you're just doing like... spin up a bunch of threads and process messages on them
20:03DuneManthen just use agents
20:03DuneMan'cause that's what they are.
20:03arkahnI guess I was going to use the PersistentQueue or agent (scalar? just passing strings) for raw data to communicate between the threads and another data structure for parsed data
20:04DuneManAtom + watchers
20:04DuneManor a SynchronousBlockingQueue
20:05DuneMandepending on what behavior you need.
20:05arkahnFor my first clojure program, I wanted to write something that tailed a log file and then parsed the data, perhaps in two threads but I was still debating that "design". Just starting out with clojure.
20:05DuneMantake a look at fill-queue
20:05arkahnok
20:06ninjuddarkahn: PersistentQueue and agent are two different types of things. PersistentQueue is a data structure whereas agents are a mechanism for changing a reference in a thread-safe way
20:06ninjuddthe reference could be to a PersistentQueue
20:07arkahnninjudd: yes - I didn't mean to confuse the two ... I should finish up some code and show that - it'd be easier for me to explain ; )
20:07ninjuddok :)
20:07tomojare there any good examples of fill-queue out there?
20:08tomojI believe I understand how it works, but that I don't really get it
20:32mmarczyktomoj: clojure.contrib.lazy-seq uses it
20:33tomojthanks
20:34mmarczykaaaa, wait, wrong lib
20:34mmarczykI meant c.c.lazy-xml
20:34mmarczykin parse-seq
20:35RaynesMichael Kohl alerted me a little while ago to the fact that someone is considering presenting an IRC bot based on Irclj at a functional programming user group this Monday. :>
20:35RaynesThis makes me a happy Rayne.
20:35mmarczykRaynes: cool :-)
20:54alexykgiven two maps with keys which are integers, what's the cutest way to get the merged deduped list of keys in sorted order?
20:54alexykdon't need values here, just the keys
20:55alexykI guess adding them to sorted set?
20:56alexykforgot, how do add things to a set?...
20:56alexyk.(sorted-set 1 2 3)
20:56alexyk,(sorted-set 1 2 3)
20:56clojurebot#{1 2 3}
20:57alexyknow how do we add 4?
20:58ninjudd,(keys (merge (sorted-map) {2 3 7 6} {19 2 1 3}))
20:58clojurebot(1 2 7 19)
20:58alexykninjudd: no merge before keys!
20:59alexykmaps are huge, think graphs :)
20:59rdsrHi all, can I define a let within the bindings of for
20:59rdsr?
20:59mmarczyk,(reduce into [(sorted-set) (keys {2 3 7 6}) (keys {19 2 1 3})])
20:59clojurebot#{1 2 7 19}
21:00rdsrsomething like this (for [i ... j ... :let n (* i j)] ...
21:00mmarczykrdsr: :let [n (* i j)]
21:01alexykmmarczyk: warmer, can we tuck both keys into a map to operate on a list of maps?
21:01ninjuddmmarczyk: nice
21:01alexyki.e. say keys once :)
21:01mmarczyksure
21:01alexykok :)
21:01mmarczyk,(reduce into (cons (sorted-set) (map keys [{2 3 7 6} {19 2 1 3}])))
21:01clojurebot#{1 2 7 19}
21:01alexykyay!
21:01mmarczyk:-)
21:02alexykhow about we do (apply sorted-set (concat...)) instead?
21:02alexykthen the set will be sorted at creation time
21:02mmarczykum, nope, try it
21:03mmarczykalso, the set *is* sorted at creation time
21:03mmarczykof course it's also empty :-)
21:03ninjudd,(apply sorted-set (mapcat keys [{2 3 7 6} {19 2 1 3}]))
21:03clojurebot#{1 2 7 19}
21:03mmarczykah yes, mapcat helps :-)
21:04DuneMan*enjoys watching these types of discussions*
21:04MadWombatHello
21:04mmarczykbut anyway, it's the same thing
21:04mmarczykwith the sorted set being built incrementally by a Java loop
21:04mmarczykwho knows, maybe that's a bit faster :-)
21:05alexyk,(apply sorted-set (apply concat (map keys [{2 3 7 6} {19 2 1 3}])))
21:05clojurebot#{1 2 7 19}
21:05mmarczykDuneMan: me too :-)
21:05mmarczykalexyk: mapcat = (apply concat (map ...))
21:05alexykah!
21:05alexykmapcat should be clojure mascot
21:06DuneMan*pictures a really lame logo*
21:06mmarczykohhh, and you mentioned concat above
21:06alexykand... the Oscar goes to ninjudd!
21:06mmarczyksorry, missed that
21:06DuneManaha, I'm in IRC, I can actually use /me, doh
21:06ataggartcdr shdr wdr
21:07DuneManugh
21:07alexykwho stole car/cdr from clojure?
21:07DuneManAn ex-coworker of mine made and sold a bunch of t-shirts with just "()" on them
21:07alexyk,(doc car)
21:07clojurebotI don't understand.
21:07DuneManI see the occasional nerd in the bay are wandering around with one
21:07DuneManarea*
21:08ataggart"my other car is a cdr."
21:08mmarczyk:-)
21:08ataggartsomeone's bumpersticker
21:08DuneMan*shakes head*
21:09DuneManI almost got a custom license plate with SFINAE on it... but I decided only 4 people would get it
21:11mmarczykis the *jure ban due to the Great or the Dear part? ;-)
21:12alexykmmarczyk: meaning Great Dear Leader's reluctance to use *jure-suffixed names?
21:12ataggartthere are only so many puns
21:12ataggartseajure
21:12ataggartI like the best
21:13mmarczykalexyk: no, meaning his reluctance to allow people to use those names with their projects with current snapshots of lein :-P
21:14alexykmmarczyk: that's the dear part, since it's endearing :)
21:15mmarczykalexyk: isn't that "endangering", with who knows how many *jure partisans lurking around?
21:16alexykmmarczyk: then it's Great since it imposes an iron will on an unruly and anarchical mob!
21:16alexykwith the unabashed bold display of stylistic preferences
21:19mmarczykfine :-)
21:20_brian2_noob question > I want to develop patches to a library, what do to my project file, etc?
21:20ninjuddlancepantz: maybe we should name our NativeClassLoader project classlojure just to spite him
21:21ninjuddor is classloadjure better?
21:21mmarczykI'd say, go with loajure
21:21mmarczyk;-)
21:22ninjuddclasslojure is nice because you take the c from clojure and replace it with class
21:22mmarczyktrue!
21:27ninjuddhttp://github.com/ninjudd/classlojure
21:27mmarczykway to go!
21:28mmarczyk:-)
21:28mmarczyknice Gist (NCL), by the way
21:29ninjuddmmarczyk: thanks. now we just need to figure out how to make it work without changing Clojure internals
21:31mmarczykyou think that's possible? (I really wouldn't know, my Java-fu is rather weak)
21:33ninjuddi think that *use-context-classloader* is supposed to allow you to use your own classloader
21:33ninjuddbut it doesn't seem to work for import for whatever reason
21:38hugodninjudd: *use-context-classloader* is true by default, you just need to set the thread context class loader to the one you want
21:39ninjuddhugod: yeah, but for some reason it doesn't work for import
21:39ninjuddhere's my code that doesn't work: http://github.com/ninjudd/classlojure/blob/master/src/clj/classlojure.clj
21:45MadWombatcan anyone point me in the right direction to load and call ant tasks from an XML file in clojure/java?
21:45MadWombatsome sort of factory class perhaps?
21:47hugodninjudd: you trying that AOT'd ?
21:47ninjuddhmm, no
21:47ninjuddi was just trying it on the repl
21:52_brian2_noob question, if I want to develop patches for a pre-existing library, do I git the library to my computer and put [lein-clojars "0.5.0"] into my project file, do I have to take the original dependencies out?
21:56hugodninjudd: it looks to me as if the context class loader is not used if Compiler.LOADER.isBound(), which is the case inside an eval or a load. I have only ever tried setting the classloader before calling into clojure from java.
21:57brweber2so I created a gateway drug to help people get into clojure
21:57brweber2http://github.com/brweber2/clojure/tree/master/examples/
21:57brweber2mostly b/c I wanted to start messing around with the source code
21:57brweber2it is NOT intended to be serious
21:57brweber2but any feedback is appreciated
21:57brweber2it is a full fork of clojure on github
21:57brweber2but the changes are very minimal
22:01brweber2rhickey How was day 1?
22:04hugodsome clojure mojo : http://github.com/hugoduncan/clojure-mojo-example/blob/master/src/main/clojure/maven/clojure/example/plugin.clj
22:14lancepantzhow do i get emacs to always use paredit in clojure-mode?
22:17_brian2_DuneMan : do you know.. if I want to develop patches for congomongo, whats the idiomatic way, do I git it to my computer, put [lein-clojars "0.5.0"] in project file and take congomongo dependenicies out, or leave in, or am I on the wrong track?
22:50joshua-choiPerhaps this has been asked before, but... I want to know if there's a fast, standard function that transforms a map: (= (transform f m) (into {} (for [[k v] m] [k (f val)]))).
22:50joshua-choiPerhaps one that uses transients. This function would be very useful to me.
22:53hiredman,(doc fmap)
22:53clojurebot"clojure.contrib.generic.functor/fmap;[[f s]]; Applies function f to each item in the data structure s and returns a structure of the same kind."
22:55tomojawesome
22:55joshua-choiEh...that's a multimethod. Thank you, though.
23:06powr-toclancepantz: http://gist.github.com/399438
23:06lancepantzthank you :)
23:12joshua-choiIs there a for-like macro that iterates specifically through nested maps?
23:14powr-tocjoshua-choi: the closest I can think of is building something with tree-seq
23:14joshua-choi(map-for [x {:a {:a 1, :b 3}, :b {:a 2, :b 2}}, y x] (+ (count x) y))
23:14joshua-choiHmm
23:15powr-toccan you not just call seq on the maps?
23:15powr-tocand treat them as pairs?#
23:16joshua-choipowr-toc: Yeah, but it's a pain to do (into {} (for [[x-k x-v] {...}] [x-k (into {} (for [[y-k y-v] x-v] [y-k (+ (count x-v) y-v)]))])).
23:17powr-tocyeah
23:17joshua-choiI'm surprised that this isn't much in demand yet
23:18joshua-choiI want things like this all the time
23:18powr-tocwhat do you want it for?
23:19joshua-choiI have a nested map, and I want to transform it into a similar nested map with modified inner vals
23:20powr-toccan you use merge-with?
23:20joshua-choiHow would I do that?
23:21joshua-choiI don't think I can, no.
23:22tomojcan't you just take the fmap for maps and make it a function?
23:23tomojhuh, seems fmap doesn't even do what you want
23:24powr-tocjoshua-choi: I'm struggling to see what your idea for map-for is doing... is the destructuring right?
23:24joshua-choiI believe the do-monad of the map-m monad does what I want, though it's not very well-supported
23:25tomojand certainly not fast, I'd think?
23:25joshua-choipowr-toc: The bound variable x is bound to each val of the {:a ..., :b ...} map, and the subsequent bound variable y is bound to each val of x.
23:26joshua-choiIdeally, it'd use transients or something
23:26joshua-choiIf I wrote my own, could I submit it to clojure-contrib?
23:30joshua-choiIf monads are good at one thing, it's making it easier to write let/for-like macros.
23:31tomojoh, so you'd use map-m just to generate the macroexpansion which would be fast code?
23:33joshua-choitomoj: Yes, I would—except map-m doesn't yet exist in clojure.contrib.monads.
23:34tomojI was wondering earlier whether protocols would help
23:34joshua-choiI'm glad Rich Hickey showed an interest in eventually integrating monads into clojure's main namespaces
23:34powr-toche did?
23:34joshua-choiI think it was on the clojure-dev Google group.
23:34tomoj"Number of monads in Clojure 1.0: Zero. In 1.1: Zero. In 1.2: Zero. Monads are not idiomatic (via @stuarthalloway)"
23:35tomojheh
23:35joshua-choiYeah, I read that too.
23:35joshua-choiBut anyways, it seems that there's currently no standard way to transform a map's vals easily, which is annoying
23:35joshua-choiOh well
23:35joshua-choi(into {} (map ...))
23:35tomojI've run into that problem before as well
23:35tomojand I think it's come up in here before
23:36joshua-choiI would think this would be a common thing to do with maps...:|
23:36rdsrhey All, I once saw a cheat sheet which detailed the time complexity of various functions in clojure. I can't seem to find it now, does any one know about it
23:36rdsr?
23:37powr-tochttp://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html
23:37sexpbot"Clojure Performance Guarantees - Stefan Tilkov's Random Stuff"
23:38rdsrpowr-toc: thanks