2010-05-12
| 00:02 | sids | technomancy: yea, please -- it's a pain to add it to every single project! |
| 00:02 | technomancy | sids: well you'd still have to add swank-clojure as a dev-dep |
| 00:02 | technomancy | I don't think I'm quite ready to make that an automatic dep on every lein project. =) |
| 00:02 | technomancy | as much as I'm tempted |
| 00:03 | sids | technomancy: oh. did you consider supporting a "template" project.clj that lein new uses? maybe pick it up from some standard location.. |
| 00:03 | technomancy | sids: it's on the roadmap |
| 00:03 | technomancy | I need to add user-level plugins first |
| 00:03 | technomancy | since a plugin like that wouldn't make sense if it had to be activated on a per-project level |
| 00:03 | MadWombat | can someone point me to an example of a servlet using recent version of ring? |
| 00:04 | MadWombat | like a hello world servlet |
| 00:04 | sids | technomancy: 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:07 | lancepantz | MadWombat: i have one i can put on github for you if you'd like |
| 00:07 | technomancy | sids: if you're interested in the functionality it might be a fun little hack to experiment upon |
| 00:07 | technomancy | it'll probably be a while before I get around to it |
| 00:07 | sids | technomancy: sure, I'll give it a shot! |
| 00:08 | technomancy | sids: I guess there are a couple of things needed for that |
| 00:08 | MadWombat | technomancy: 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:08 | technomancy | 0) plugins activated on a per-user basis, probably listed from a ~/.lein.clj file |
| 00:09 | technomancy | 1) being able to wrap built-in commands from plugins |
| 00:09 | technomancy | 2) the new-template plugin itself |
| 00:09 | lancepantz | MadWombat: the defroutes syntax is different now |
| 00:09 | MadWombat | heh |
| 00:09 | MadWombat | I don't use defroutes, should i? |
| 00:10 | lancepantz | oh, i do, its in compojure not ring though |
| 00:10 | MadWombat | yeah |
| 00:10 | MadWombat | at this point all I have is (defn routes [req] (handle-dump req)) |
| 00:11 | sids | technomancy: have you done any work on per-user plugins? can't figure it out from the git log |
| 00:11 | technomancy | sids: only in my head |
| 00:13 | technomancy | sids: 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:13 | technomancy | then maybe load ~/.leiningen/init.clj, which would contain calls to require all the plugins you want activated |
| 00:14 | sids | technomancy: that should be straightforward, I'll also pour through the leiningen codebase to understand it better |
| 00:14 | technomancy | not 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:14 | technomancy | there's not a lot of code there; I think it's only around 700 lines |
| 00:14 | lancepantz | MadWombat: it looks like your munging the syntax of the app and middleware |
| 00:15 | sids | technomancy: 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:15 | MadWombat | lancepantz: ? |
| 00:15 | lancepantz | check out http://github.com/mmcgrana/ring/blob/master/example/wrapping.clj |
| 00:15 | technomancy | sids: they can't just be in a .clj file since you need to add them to the classpath before the JVM loads |
| 00:16 | lancepantz | your middleware is passed app, not a request |
| 00:16 | sids | technomancy: ok, got it, these are plugins for lein itself, not the projects |
| 00:17 | technomancy | sids: right, activated for all actions the user takes across all project |
| 00:17 | technomancy | *projects |
| 00:17 | sids | got it |
| 00:17 | MadWombat | lancepantz: lemme check, it compiled after I removed all wrappers and passed the unchanged routes method to the defservice |
| 00:18 | MadWombat | lancepantz: Ah! Got it, thanks |
| 00:22 | sids | technomancy: thank you, I'll try to hack something up later today |
| 00:22 | technomancy | sids: lemme know if you run into any problems |
| 00:22 | technomancy | here or on the lein mailing list |
| 00:23 | sids | will do |
| 00:25 | lancepantz | MadWombat: http://github.com/lancepantz/lein-war-example |
| 00:25 | MadWombat | lancepantz: thanks |
| 00:26 | dnolen | how 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:27 | bmason | technomancy: http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml |
| 00:27 | sexpbot | "Hugo Duncan : Swank Clojure gets a Break with the Local Environment" |
| 00:27 | bmason | what version of swank will this be included in? |
| 00:27 | technomancy | bmason: it's in 1.2.0-SNAPSHOT, which will become 1.2.0 very soon |
| 00:27 | technomancy | (couple days maybe) |
| 00:28 | bmason | I'm running snapshots of clojure and clojure-contrib... any reason not to do swank as well? |
| 00:30 | technomancy | bmason: not really, it'll make your "lein deps" runs take longer is all. |
| 00:31 | dnolen | ,(take 5 (concat [1 2] (repeat nil)) |
| 00:31 | clojurebot | EOF while reading |
| 00:31 | dnolen | ,(take 5 (concat [1 2] (repeat nil))) |
| 00:31 | clojurebot | (1 2 nil nil nil) |
| 00:31 | bmason | cool, I'm gonna try it out then |
| 00:31 | technomancy | bmason: it's worth it. =) |
| 00:31 | technomancy | also I just pushed out xref support |
| 00:31 | bmason | yeah, I burned two days trying to troubleshoot a stack trace |
| 00:32 | technomancy | so you can say "I want to see all the functions that call partial" and boom; there you go |
| 00:32 | bmason | debug tools are definitely welcome |
| 00:32 | bmason | nice |
| 00:32 | technomancy | (that was all tcrayford) |
| 00:32 | bmason | well great job on swank... I use that every day |
| 00:33 | technomancy | eh; I don't really do much these days |
| 00:33 | technomancy | I'm mostly just the PHB who applies patches and decides when the release is going to happen =) |
| 00:39 | danlarkin | xref sweeeeeetness |
| 00:39 | bmason | technomancy: how's that open door policy working out? |
| 00:40 | technomancy | bmason: better than you'd think |
| 00:40 | technomancy | the rubinius project actually gives full commit rights for anyone who has a patch accepted |
| 00:40 | technomancy | I'm not quite that gutsy |
| 00:40 | bmason | wow |
| 00:41 | technomancy | yeah, I could totally just go in and delete half the implementation if I wanted to |
| 00:41 | bmason | well Ruby breaks backwards compatibility with every release anyway |
| 00:41 | bmason | people are used to it ;) |
| 00:41 | technomancy | reverting is cheap, and people respect it when you trust them |
| 00:41 | technomancy | heh; that too |
| 00:41 | technomancy | danlarkin: try it out! I am excited. |
| 00:42 | danlarkin | no more M-x rgrep! well, less |
| 00:42 | bmason | how does the xref stuff work? |
| 00:43 | bmason | I understand that in terms of XML... not sure what it means for clojure |
| 00:46 | technomancy | it'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:46 | technomancy | probably gets a lot of false positives |
| 00:46 | technomancy | and is really slow for large projects |
| 00:47 | technomancy | it's basically a brute-force search, but it works |
| 00:48 | bmason | so it takes you to the place the symbol was def'd? |
| 00:50 | technomancy | it takes you to the caller |
| 00:51 | bmason | ah right |
| 00:52 | bmason | apologies if it's a dumb question, but are there docs on this somewhere? |
| 00:52 | bmason | like a way to get recent release notes? |
| 00:52 | technomancy | I'll try to put together some when the actual release happens. for now it's just the git log. |
| 00:52 | bmason | k |
| 00:52 | bmason | what |
| 00:53 | bmason | oops |
| 00:53 | bmason | what's the syntax for actually using the xpath stuff? |
| 00:53 | technomancy | xref, not xpath |
| 00:53 | bmason | do you use M-x something? |
| 00:53 | technomancy | it's C-c C-w c |
| 00:53 | bmason | ah |
| 00:53 | technomancy | xref for cross-reference |
| 01:09 | ataggart | anyone 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:12 | MadWombat | is there a way to make lein copy dependency jars from a local directory? |
| 01:12 | MadWombat | without doing ugly maven install commands? |
| 01:14 | bmason | lein install |
| 01:15 | MadWombat | hmm |
| 01:16 | bmason | works with clojure projects at least |
| 01:16 | bmason | I don't know what you'd do with regular jars that aren't in a repo |
| 01:16 | bmason | might be stuck with maven |
| 01:17 | lancepantz | i thiink you can manually put them in ~/.m2 |
| 01:17 | MadWombat | :( |
| 01:18 | bmason | yeah it looks like inside my .m2 directory are just jars and poms |
| 01:23 | MadWombat | thanks |
| 01:24 | technomancy | MadWombat: 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:24 | MadWombat | technomancy: cool |
| 01:24 | MadWombat | is there a way to use ant targets from lein? |
| 01:25 | MadWombat | or for that matter define your own lein targets? |
| 01:26 | MadWombat | I am trying to setup an environment to play around with GAE and clojure |
| 01:27 | MadWombat | but all the ready setups are sort of dated, so I am coming up with my own |
| 02:11 | MadWombat | seems like each additional leiningen task requires its own leiningen.* namespace, is this correct? |
| 02:11 | lancepantz | yes |
| 02:17 | MadWombat | lancepantz: thanks |
| 02:54 | MadWombat | how do you add new task to the list leiningen displays as help |
| 02:54 | MadWombat | ? |
| 03:05 | LauJensen | Morning team |
| 03:33 | MadWombat | http://blog.mitechki.net/2010/05/12/short-tutorial-on-extending-leiningen/ |
| 03:33 | sexpbot | "Short tutorial on extending Leiningen « Angry UNIXoid’s Humble Abode" |
| 03:41 | tomoj | MadWombat: did you write that? |
| 03:41 | MadWombat | yup |
| 03:41 | tomoj | thanks a lot, that subject has always been a mystery to me |
| 03:42 | tomoj | one strange thing is that you used "namespace" instead of "ns" in the second code block -- intentional? |
| 03:42 | tomoj | s/second/third/ |
| 03:42 | sexpbot | one strange thing is that you used "namespace" instead of "ns" in the third code block -- intentional? |
| 03:42 | tomoj | s/third/fourth/ |
| 03:42 | MadWombat | tomoj: no, I iwll fix in a sec |
| 03:42 | sexpbot | s/second/fourth/ |
| 03:42 | tomoj | it's so simple now that someone has explained it :D |
| 03:43 | MadWombat | tomoj: I am still looking for a reliable way to transfer code into wordpress, so I cut-paste and edit manually for now |
| 03:43 | Raynes | I love how people always double take when they discover that by accident. |
| 03:43 | MadWombat | Raynes: :) |
| 03:44 | MadWombat | tomoj: 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 | _exterm | hi everybody |
| 05:32 | _exterm | I 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 | _exterm | Is there a way to get the prefix from a class? |
| 05:38 | spariev | _exterm: you could name your class as you want, like (gen-class :name my.ns.ClassName) |
| 05:49 | _exterm | I need the prefix, e.g. (gen-class :name my.ns.ClassName :prefix "foo") |
| 05:49 | _exterm | so I can define class methods outside of the gen-class |
| 05:58 | LauJensen | _exterm: gen-class is for AOT compilation. |
| 06:08 | _exterm | Isn't it possible to add methods add runtime to classes that were generated AOT? |
| 06:17 | tomoj | don't the methods really just proxy to clojure fns? |
| 06:18 | tomoj | and clojure fns can be added at runtime? |
| 06:23 | LauJensen | tomoj: 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:30 | SandGorgon | are s-expressions the same as clojure "forms" ? |
| 06:31 | Chousuke | I wonder. can s-expressions contain vectors and maps? |
| 06:32 | SandGorgon | Chousuke, would'nt that be implementation detail - I can argue that vectors are arbitrarily growable lists . Am I wrong ? |
| 06:32 | Chousuke | well, yeah |
| 06:32 | Chousuke | but clojure has both lists and vectors appearing in forms |
| 06:33 | tomoj | regular old lists aren't arbitrarily growable? |
| 06:34 | Chousuke | I suppose the set of all clojure forms it not equal to the set of s-expressions, but a superset |
| 06:37 | SandGorgon | Chousuke, ahh |
| 06:38 | SandGorgon | tomoj, yes I worded it wrong - for me vectors are as defined by C++ STL |
| 06:44 | SandGorgon | I 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:46 | tomoj | ,(class :a) |
| 06:46 | clojurebot | clojure.lang.Keyword |
| 06:46 | tomoj | that Keyword's gotta come from somewhere |
| 06:46 | tomoj | or from nowhere, rather |
| 06:47 | tomoj | I mean, :aoeuaoeuaoeuaoeuaoeu certainly isn't sitting around in every clojure jvm |
| 06:51 | tomoj | not too different from the way 361 isn't sitting around in memory in every jvm, I think |
| 07:18 | jfields | do you guys have any favorite blogs that have a fair amount of clojure related content? |
| 07:19 | liebke | jfields: http://planet.clojure.in/ |
| 07:19 | sexpbot | "Planet Clojure" |
| 07:21 | jfields | liebke: thanks. |
| 08:37 | Hodapp | maybe if I put some Lisp books on my desk at work I'll stop crying when I have to use C++... |
| 08:46 | chouser | I have a couple situations where I think I want to write macros that macroexpand their args before returning. |
| 08:46 | chouser | Does the desire to do this mean I'm thinking about the problem incorrectly? |
| 08:46 | chouser | I've not needed to do this before, so I'm suspicious. |
| 08:47 | jfields | chouser: example? |
| 08:47 | chouser | it's to apply static typing in a DSL (maybe that's the problem there...) |
| 08:48 | chouser | so for example I have a macro lookup: (lookup :foo an-obj) |
| 08:48 | chouser | it would expand to something like: #^{:mytype "FooType"} (:foo an-obj) |
| 08:49 | chouser | that is it would know at compile time that :foo of an-obj returns something of FooType |
| 08:50 | chouser | then I want an equality test that throws at compile time if it knows the types of its args don't match |
| 08:50 | chouser | (typed= (lookup :foo an-obj) (lookup :foo other-obj)) |
| 08:51 | chouser | the 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:52 | chouser | ...except to have typed= macroexpand its args, examine their metadata, throw (or not), and finally emit a regular = |
| 08:57 | mabes | hey all, who else is at the clojure training now? |
| 08:58 | clojurebot | pcl → clojure is http://blog.thinkrelevance.com/2008/09/16/pcl-clojure |
| 09:02 | _fogus_ | ,Q |
| 09:02 | clojurebot | <-nil-< |
| 09:03 | jfields | chouser is :foo really a FooType? or are you defining your own "types"? |
| 09:03 | chouser | these are probably my own types |
| 09:04 | jfields | can you put a type as part of the metadata, and have (typed=) check and compare the metadata? |
| 09:06 | chouser | yes, 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:06 | mabes | if you are using defrecrod I think you can use isa? |
| 09:07 | Licenser_ | ,A |
| 09:07 | clojurebot | java.lang.Exception: Unable to resolve symbol: A in this context |
| 09:07 | chouser | I want to do this type check at *compile* time, not runtime. |
| 09:07 | Licenser_ | ,Q |
| 09:07 | clojurebot | <-nil-< |
| 09:07 | Licenser_ | why is Q nil with an arrow? |
| 09:07 | jfields | chouser: gotcha. I'm definitely not the guy with the answer, I'm sure. But, I thought I'd try to help. :) |
| 09:07 | chouser | :-) thanks. |
| 10:11 | ArkRost | hi! Tell me please the way I can create thread-local var. |
| 10:13 | Plouj | ArkRost: http://java.ociweb.com/mark/clojure/article.html#Vars |
| 10:13 | sexpbot | "Object Computing, Inc. - Java News Brief - March 2009" |
| 10:14 | stuartsierra | ArkRost: Any (binding ...) of a Var will be thread-local. |
| 10:18 | technomancy | Licenser_: it's a fancy/awesome way for printing clojure.lang.PersistentQueue/EMPTY |
| 10:22 | The-Kenny | technomancy: How was this way of printing called? <something>-fish, if I remember correctly |
| 10:25 | spariev | ,(conj clojure.lang.PersistentQueue/EMPTY "°}))>") |
| 10:25 | clojurebot | <-("�}))>")-< |
| 10:28 | SynrG | cute |
| 10:28 | cemerick | I guess I don't get the joke. |
| 10:31 | spariev | I wanted it to print smth like <-°}))>-< , but parens and quotes ruined my ascii art :) |
| 10:32 | cemerick | No, I see what you were doing there, I just don't know the backstory behind fish ~ queues. *shrug* |
| 10:33 | technomancy | cemerick: in stock clojure queues are visually indistinguishable from lists |
| 10:33 | technomancy | nice to spice these up a little |
| 10:34 | cemerick | but why fish? |
| 10:34 | technomancy | just a visual indicator of which end stuff goes onto and which it comes off of |
| 10:34 | technomancy | "queued elements, please step right this way" |
| 10:34 | cemerick | oh, head and tail |
| 10:36 | technomancy | I 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:36 | technomancy | nice |
| 11:11 | Licenser_ | technomancy: ah thank you! |
| 11:15 | LauJensen | stuartsierra: I think http-agent might be broken, since its shadowing core/bytes |
| 11:23 | stuartsierra | it's not broken, it just needs a refer-clojure |
| 11:23 | stuartsierra | but 'bytes' should probably be renamed |
| 11:25 | Licenser_ | 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:26 | stuartsierra | busy right now, but feel free to post |
| 11:27 | Licenser_ | okay :) |
| 11:31 | dsop | is there a downloadable version of the complete clojure api? |
| 11:31 | dsop | of the documentation |
| 11:32 | dsop | ah got it |
| 11:34 | LaPingvino | http://github.com/richhickey/clojure/tree/gh-pages |
| 11:34 | LaPingvino | great :) |
| 11:35 | jfields | what'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:49 | Licenser_ | $doc writer |
| 11:49 | sexpbot | Command not found. No entiendo lo que estás diciendo. |
| 11:49 | Licenser_ | $doc clojure.contrib.duck-streams/writer |
| 11:49 | sexpbot | Command not found. No entiendo lo que estás diciendo. |
| 11:49 | Licenser_ | (doc clojure.contrib.duck-streams/writer) |
| 11:49 | clojurebot | "([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:55 | mabes | jfields: I'm not an expert by any means, but I've used watches before with good success |
| 11:57 | hiredman | ,(doc writer) |
| 11:57 | clojurebot | "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:59 | jfields | mabes: thanks. |
| 12:32 | bmason | if 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:43 | ataggart | or you could seq the map |
| 12:43 | ataggart | that'll give you key/value tuples |
| 12:46 | ataggart | or you could get the keys, then build the value seq from the keys seq |
| 12:47 | ataggart | or it could very well be that values returns the same order as keys |
| 12:47 | ataggart | which would make sense |
| 12:48 | wlangstroth | bmason: out of curiosity - what are you trying to do? |
| 12:49 | bmason | (defn run-insert "Given a :table and {values}, insert values into table." |
| 12:49 | bmason | [table values] |
| 12:49 | bmason | (with-connection db |
| 12:49 | bmason | (transaction |
| 12:49 | bmason | (insert-values table (keys (first values)) |
| 12:49 | bmason | (map vals values)) |
| 12:49 | bmason | (last-created-id)))) |
| 12:49 | bmason | oops :) |
| 12:49 | bmason | will use pastie next time... |
| 12:53 | chouser | 'keys', 'vals', and 'seq' on the same map will all return items in the same order |
| 12:55 | replaca | I'm implementing support for PersistentQueue in pprint. Should I do it fish-style? |
| 12:59 | replaca | I'm thinking just <-(1 2 3)-<. Anyone care? |
| 12:59 | technomancy | replaca: yeah! |
| 12:59 | Licenser_ | replaca: sounds good |
| 13:00 | Licenser_ | will (<- 1 2 3) return a new queue? |
| 13:00 | replaca | (I don't want extra parens and brackets cause that will throw off anyone navigating the results |
| 13:00 | technomancy | unless you can come up with an ascii-art version of this: http://i196.photobucket.com/albums/aa159/apashin/arrowed.jpg |
| 13:00 | replaca | no, this is just about pprint |
| 13:00 | hiredman | ,Q |
| 13:00 | clojurebot | <-nil-< |
| 13:01 | replaca | hiredman: my version would be <-()-< |
| 13:01 | clojurebot | hiredman is slightly retarded |
| 13:01 | technomancy | if queue-fish gains a widespread community following there will be more pressure for reader support. =) |
| 13:01 | Licenser_ | heh |
| 13:01 | replaca | since there's a seq under there (sort of) |
| 13:01 | DuneMan | *wants blocking persistent queue* |
| 13:02 | hiredman | DuneMan: not possible |
| 13:02 | replaca | DuneMan: what does that mean? The queue is immmutab;e |
| 13:02 | DuneMan | wants it anyway! |
| 13:02 | Licenser_ | a persistent queue? |
| 13:03 | DuneMan | replaca: DETAILS |
| 13:03 | Licenser_ | DuneMan: you have that it's called list? |
| 13:03 | ataggart | is there any chance of getting a literal queue? |
| 13:03 | chouser | we have a blocking queue. we have a persistent queue. I don't see how a queue could be both. |
| 13:03 | DuneMan | actually what I really want is java's blockingqueue, which I'm using. carry on. |
| 13:04 | replaca | DuneMan: but look at fill-queue |
| 13:04 | hiredman | why are you missing it? |
| 13:04 | hiredman | ,java.util.concurrent.LinkedBlockingQueue |
| 13:04 | clojurebot | java.util.concurrent.LinkedBlockingQueue |
| 13:04 | hiredman | it's right there |
| 13:05 | DuneMan | Right, which is why I said "Which I am using" |
| 13:05 | DuneMan | I just got to my desk and typed some shit, ignore me. |
| 13:05 | hiredman | right |
| 13:05 | hiredman | I somehow misread that |
| 13:05 | hiredman | as "I'm missing" |
| 13:05 | DuneMan | replaca: Yeah, I can see that being handy for some things in the future, but unfortunately not this exact thing. |
| 13:06 | DuneMan | I was happy to find fill-queue |
| 13:06 | DuneMan | it's that level of abstraction which I think will make me increasingly productive in clojure. |
| 13:06 | wlangstroth | bmason: so you know the order, but not necessarily the columns you're entering, and that's why you use insert-values? |
| 13:07 | DuneMan | Though I do wish LinkedBlockingQueue could push a buffer of messages with only grabbing the lock once. |
| 13:08 | replaca | (pprint (reduce conj e (range 10))) |
| 13:08 | replaca | gives: |
| 13:08 | replaca | <-(0 1 2 3 4 5 6 7 8 9)-< |
| 13:08 | replaca | where e is PersistentQueue/EMPTY |
| 13:09 | TakeV | So, 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:09 | chouser | TakeV: yep |
| 13:09 | TakeV | Cool. |
| 13:09 | chouser | ,(assoc {:a 1} :a 2) |
| 13:09 | clojurebot | {:a 2} |
| 13:13 | wlangstroth | bmason: (I only ask because the whole process seems more work than simply concatenating a sql string yourself) |
| 13:14 | bmason | sorry, got distracted |
| 13:14 | bmason | let me read up |
| 13:16 | bmason | wlangstroth: is there a more convenient way to insert a map into a table? |
| 13:16 | bmason | wlangstroth: I only saw insert-values, which takes vectors |
| 13:18 | wlangstroth | bmason: 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:21 | bmason | wlangstroth: 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:22 | wlangstroth | bmason: oh, okay - I wasn't sure why you didn't know the order coming in |
| 13:23 | bmason | ah, alright |
| 13:23 | bmason | does my approach make sense then? |
| 13:23 | wlangstroth | bmason: and you're using ... mysql? and that's why you have to programmatically insert the id, rather than having the database do it? |
| 13:23 | bmason | yes |
| 13:23 | bmason | I'm considering using clj-record instead |
| 13:23 | bmason | will probably do that long term |
| 13:24 | bmason | but atm I'm just using clojure.contrib.sql |
| 13:30 | wlangstroth | bmason: yeah, I suppose that's how you would have to do it. |
| 13:31 | wlangstroth | It was only jarring to me because I'm a database guy, so having the transaction enforced by middleware, etc. looked weird to me |
| 13:35 | ataggart | regarding REST, query params really shouldn't be used as a substitute for the body on a PUT |
| 13:36 | wlangstroth | bmason: I forgot about clj-record - it looks pretty good - haven't used it yet, but thanks for reminding me |
| 13:37 | patrkris | what is the reason that |
| 13:37 | patrkris | oops |
| 13:37 | bmason | yeah, I've seen how productive the Ruby ORMs are... I'm excited to try out clj-record |
| 13:38 | patrkris | what is the (probably very logical reason) that commutes after alter/ref-set are allowed in transactions but not vice versa? |
| 13:39 | wlangstroth | ataggart: do people do that? |
| 13:40 | ataggart | based on what bmason said, I guess so. |
| 13:40 | ataggart | "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:40 | bmason | oh |
| 13:41 | bmason | yeah, I'm not particularly clear on where my values will be coming from I suppose |
| 13:41 | ataggart | query params are for querying, for narrowing the scope of the response representation |
| 13:41 | bmason | I haven't implemented that part yet |
| 13:41 | bmason | yeah, I didn't mean to use query params |
| 13:41 | ataggart | what lib are you using for the rest stuff? |
| 13:41 | bmason | what does the body look like? |
| 13:41 | bmason | compojure-rest |
| 13:42 | ataggart | the body of a PUt is whatever representation you want and that the server can handle, e.g., a json object, xml, whatever |
| 13:42 | bmason | gotcha |
| 13:42 | bmason | so I'd then have to parse that... that makes sense |
| 13:42 | ataggart | yeah |
| 13:43 | ataggart | I have rest framework I worte in java for my company. been meaning to comjureize it |
| 13:43 | ataggart | erm |
| 13:43 | wlangstroth | oh, haha |
| 13:43 | ataggart | clojureize |
| 13:43 | bmason | compojurize? |
| 13:43 | bmason | :-D |
| 13:43 | ataggart | <-- not a good typist |
| 13:43 | bmason | Shakespear invented words, we can too |
| 13:44 | ataggart | I'll check out compojure-rest |
| 13:44 | bmason | *Shakespeare? |
| 13:44 | ataggart | see ifI like it |
| 13:44 | ataggart | 'Twas brillig and the slithy toves did gyre and gimble in the wabe. |
| 13:44 | bmason | indeed |
| 13:46 | DuneMan | neat, compjure-rest, that will be useful shortly |
| 13:46 | DuneMan | This is the most helpful irc channel ever. |
| 13:47 | bmason | YES |
| 13:47 | DuneMan | and I spent 8 years of my life in #C++/EfNet ;-) |
| 13:47 | wlangstroth | oi |
| 13:48 | bmason | I'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:48 | ataggart | meh, not a fan of compjoure-rest |
| 13:48 | Borkdude | Just 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:48 | ataggart | Ilike my lib better ;) |
| 13:48 | Drakeson | is swank-clojure broken since yesterday? |
| 13:48 | bmason | ataggart: link? |
| 13:48 | ataggart | bmason: none yet. proprietary |
| 13:48 | ataggart | will be opening it up shortly |
| 13:48 | wlangstroth | ataggart: translating from Java to Clojure can be disconcerting - the result is so much shorter |
| 13:49 | bmason | ataggart: send me an email or something, I'd like to check it out when you do |
| 13:49 | DuneMan | hah, agreed. the clojure implementation I have of this thing is even shorter than the python |
| 13:49 | DuneMan | and does more. |
| 13:49 | bmason | :) |
| 13:49 | ataggart | the parts I've rewritten in clojure are an order of magnitude more concise |
| 13:50 | wlangstroth | I 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:50 | bmason | lol |
| 13:50 | bmason | that's a great sign |
| 13:51 | bmason | that means we could have a really light weight webserver done in clojure |
| 13:51 | ataggart | I thought there was one |
| 13:51 | ataggart | ring |
| 13:51 | ataggart | iirc |
| 13:51 | bmason | ring isn't a webserver, is it? |
| 13:51 | wlangstroth | ring uses jetty |
| 13:51 | clojurebot | the answer is 42 |
| 13:51 | ataggart | ah |
| 13:51 | bmason | yeah |
| 13:51 | bmason | and compojure is based on ring |
| 13:52 | wlangstroth | and Jetty is ridiculous |
| 13:52 | bmason | well... correction would be ring *can* use jetty |
| 13:52 | bmason | it's one option |
| 13:52 | wlangstroth | it works, it's awesome, whatever - the code is ridiculous |
| 13:52 | ataggart | I'd guess my rest lib would obviate ring. Right now it's built to run on a servlet system. |
| 13:52 | wlangstroth | bmason: quite right |
| 13:53 | wlangstroth | ring is often used with jetty |
| 13:54 | ataggart | defprotocol/deftype/defrecord are making my life a lot easier |
| 13:54 | bmason | http://github.com/mmcgrana/ring |
| 13:54 | bmason | httpcore (Apache?) is another built in option |
| 13:54 | ataggart | I really just wish I didn't hate git as much as I do. |
| 13:55 | bmason | and it's probably not difficult to add new adapters |
| 13:55 | wlangstroth | ataggart: are you used to something else? |
| 13:55 | ataggart | svn, but via the subclipse plugin. haven't had to mess with the commandline for ages. |
| 13:55 | ataggart | the lack of tool support / visualization gets to me |
| 13:56 | bmason | git clone *some repo* is pretty easy |
| 13:56 | ataggart | yeah |
| 13:56 | ataggart | everythign after that is a pain |
| 13:56 | DuneMan | lack of visualization? |
| 13:56 | DuneMan | GitX, sir. |
| 13:57 | ataggart | gitx fails |
| 13:57 | wlangstroth | I live in white-on-black - more work done that way (not for everyone, of course) |
| 13:57 | ataggart | for example: http://subclipse.tigris.org/servlets/ProjectProcess?pageID=rr1TIx |
| 13:57 | sexpbot | "subclipse: Screenshots" |
| 13:57 | DuneMan | I also live in a terminal and don't use an IDE for anything |
| 13:57 | DuneMan | an IDE is almost necessary for java |
| 13:57 | ataggart | it's not the ide that OI care about |
| 13:58 | DuneMan | but I never code in java. |
| 13:58 | ataggart | it's the lack of a visual diff |
| 13:58 | DuneMan | You can use any visual diff tool you want with git |
| 13:58 | ataggart | committing a file without first seeing the changes on the server is madness imo |
| 13:58 | DuneMan | I use vimdiff, but there are better 3-way diff tools out there |
| 13:58 | bmason | how would I take 'vec' and 'keys' and combine them to a single function? |
| 13:58 | bmason | would 'partial' work for that? |
| 13:58 | wlangstroth | git status? |
| 13:58 | ataggart | I've yet to find a tool that provides a visual diff for git that compares to what's available for svn |
| 13:58 | technomancy | ,((comp vec keys) {:a :b :c :d}) |
| 13:58 | clojurebot | [:a :c] |
| 13:58 | bmason | it doesn't seem quite right... |
| 13:59 | bmason | ah comp |
| 13:59 | bmason | thank you |
| 13:59 | DuneMan | git status; git&fetch && git merge origin/branch |
| 13:59 | DuneMan | git diff |
| 13:59 | ataggart | clearly you and I have different definitions of "visual diff" |
| 13:59 | DuneMan | ataggart: Just pipe the output of git diff to your favorite 3-way diff tool. |
| 13:59 | DuneMan | sure, but I don't think that has anything to do with git. |
| 14:00 | DuneMan | Git gives you a raw diff, view it in the tool of your choice. |
| 14:00 | ataggart | it has to do with the immaturity of the git ecosystem |
| 14:00 | wlangstroth | that's an interesting way to say "the pictures aren't pretty enough" |
| 14:00 | DuneMan | And the type of people who work on the ecosystem. |
| 14:00 | ataggart | it's not just about pictures |
| 14:00 | wlangstroth | ataggart: I'm teasing - I know what you mean |
| 14:01 | ataggart | the feature set in subclipse is a high bar, which nothing in the git ecosystem even comes close to |
| 14:01 | bmason | I agree ataggart |
| 14:01 | DuneMan | I mean, I suppose it might be handy if there was a gui tool that had a built in 3-way diff viewer? |
| 14:01 | DuneMan | Though I never leave my terminal so I wouldn't use it. |
| 14:02 | wlangstroth | right |
| 14:02 | ataggart | plus I'm constantly annoyed by the useless multi-step dance one needs to do to update the repo |
| 14:02 | DuneMan | git fetch && git merge? |
| 14:02 | wlangstroth | which dance? |
| 14:03 | DuneMan | I 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:03 | ataggart | I have a file on my system. I change it. I right-click the file and hit "Commit...". One logical step. |
| 14:03 | DuneMan | or you can git pull |
| 14:04 | DuneMan | Ah, yes, there's your problem |
| 14:04 | DuneMan | touching your mouse. |
| 14:04 | DuneMan | *runs* |
| 14:04 | ataggart | for git it seems I have to do a half a dozen command line incantations |
| 14:04 | DuneMan | you just have to do git commit -m "Message" file. |
| 14:04 | ataggart | but that doesn't put it in github |
| 14:04 | DuneMan | and then push that branch if you're ready to distribute that branch. |
| 14:05 | ataggart | yup, multi-step dance |
| 14:05 | DuneMan | Though not a useless one. |
| 14:05 | ataggart | in my day we called git's commit "saving a file" |
| 14:05 | DuneMan | Very useful |
| 14:05 | DuneMan | It's just a matter of being used to a different workflow |
| 14:05 | technomancy | ataggart: if you want to combine two distinct steps into one that's easy enough to do with a shell alias |
| 14:05 | ataggart | yep, more sutff I need to write and not have avaiable on other machines |
| 14:06 | technomancy | what, you don't keep your dotfiles in version control? |
| 14:06 | DuneMan | I have all my stuff availablwe on all my machines |
| 14:06 | DuneMan | git checkout git@github:pgebheim/config.git |
| 14:06 | DuneMan | er, git clone |
| 14:06 | ataggart | ha! |
| 14:06 | ataggart | see... |
| 14:06 | ataggart | bad names |
| 14:06 | DuneMan | That I can agree with |
| 14:06 | DuneMan | the git command line interface is poorly designed |
| 14:06 | ataggart | precisely |
| 14:07 | DuneMan | Maybe someone will get around to fixing that at some point |
| 14:07 | DuneMan | It was clearly designed as linus added features he needed |
| 14:07 | DuneMan | so it has some logic to it, its just not transparent if you're new to it. |
| 14:07 | ataggart | from what I've read of the history, it's first goal was to make patching easier |
| 14:07 | wlangstroth | oh, I see your objection. Yeah, I've already written short scripts around that |
| 14:08 | DuneMan | I almost always want to commit locally |
| 14:08 | DuneMan | and NOT push |
| 14:08 | DuneMan | I commit locally and do diffs on working sets constantly |
| 14:08 | ataggart | yeah, save a file |
| 14:08 | ataggart | I do that too |
| 14:08 | technomancy | magit makes it easy to forget how bad the git CLI experience is |
| 14:08 | DuneMan | No,that's not saving a file. |
| 14:09 | wlangstroth | ataggart: you mean you want a daemon to monitor changes on the working branch and commit on each save? |
| 14:09 | ataggart | no I mean "commit" in my worldview means "push this change out to the canonical repo" |
| 14:09 | maravillas | simply saving a file doesn't keep the local history, whereas committing to your local repo in git does |
| 14:09 | ataggart | what git calls "commit" I call "saving a file locally" |
| 14:09 | DuneMan | Except it's different |
| 14:09 | DuneMan | because you can have vrersioned local saves. |
| 14:09 | ataggart | maravillas: that depends entirely on what you're using to edit |
| 14:09 | ataggart | eclipse has local history |
| 14:10 | maravillas | on a per file basis, right? |
| 14:10 | wlangstroth | oh, I see - this is a distributed vs. centralized discussion |
| 14:10 | DuneMan | yeah, it is |
| 14:10 | DuneMan | just different workflows |
| 14:10 | DuneMan | I'm getting used to git's over time, and finding it useful |
| 14:10 | DuneMan | :-) |
| 14:10 | ataggart | wlangstroth: a distinction without a difference as everyone seems to use github anyway |
| 14:11 | Drakeson | technomancy: |
| 14:11 | Drakeson | oops! |
| 14:11 | technomancy | ataggart: not at all, see http://github.com/technomancy/gitjour |
| 14:11 | Drakeson | technomancy: the latest swank-clojure push does not work here |
| 14:12 | wlangstroth | ataggart: I dunno - I prefer to commit a bunch, then go over it, and maybe push to github once a day. |
| 14:12 | technomancy | Drakeson: the xref merge? |
| 14:12 | Drakeson | it 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:13 | ataggart | wlangstroth: 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:13 | DuneMan | wlangstroth: Agree. I found that a weird workflow until I started using it. |
| 14:13 | technomancy | Drakeson: which Clojure version? |
| 14:13 | Drakeson | latest |
| 14:13 | technomancy | I'll take a look at it tonight |
| 14:13 | DuneMan | I also got used to being able to pull working sets to other machines |
| 14:14 | ataggart | in any case, my main problem with git is its ecosystem is less useful ot me than svn's |
| 14:14 | DuneMan | and do complex multi-branch merging |
| 14:14 | Drakeson | technomancy: thanks |
| 14:14 | DuneMan | ataggart: Part of that is just a workflow problem, of course. But yes, there's less developed tools. |
| 14:14 | wlangstroth | ataggart: but if you have a bunch of different branches, it's not just saving. |
| 14:15 | ataggart | wlangstroth: I have multiple branches on my machine right now. It's not an issue. |
| 14:15 | ataggart | I will of course grant that svn's branch/merge feature isn't as nice as git's |
| 14:15 | maravillas | and 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:16 | ataggart | but 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:16 | DuneMan | again, git diff > your favorite diff tool |
| 14:16 | ataggart | false |
| 14:16 | DuneMan | I don't see what the issue is :-) |
| 14:16 | ataggart | clearly |
| 14:16 | ataggart | use subclipse |
| 14:16 | ataggart | you'll see |
| 14:16 | wlangstroth | I don't think it's an issue, really. I've adapted to both, but I don't use a gui |
| 14:16 | maravillas | i think that's a redirect operator, not a greater than :) |
| 14:17 | DuneMan | indeed, maravillas |
| 14:17 | ataggart | ah lol |
| 14:17 | ataggart | very well then |
| 14:17 | DuneMan | hahaha |
| 14:17 | DuneMan | reading inline diffs can be really painful |
| 14:17 | DuneMan | especially 3-way diffs |
| 14:17 | DuneMan | I'm used to it, but wouldn't exactly recommend it |
| 14:18 | ataggart | for example: http://subclipse.tigris.org/images/sync-ss.png |
| 14:18 | DuneMan | that gui makes me want to cry |
| 14:18 | ataggart | bear in mind it's a tiny window to the actually files are too small to be useful |
| 14:18 | DuneMan | I loath eclipse. |
| 14:18 | ataggart | that gui contains useful info |
| 14:18 | wlangstroth | haha - we're definitely arguing gui vs terminal now |
| 14:19 | ataggart | the set of all files changed, the directionality of the changes, a diff of a particular file, and the revision history |
| 14:19 | DuneMan | yeah, we are. just differing workflows. maybe someone will make a good git gui to accomodate ataggart's |
| 14:19 | ataggart | not likely |
| 14:19 | wlangstroth | I think it's called gitk |
| 14:19 | ataggart | how anyone can commit files to a repo without having all that info in front of them beforehand... I just don't understand |
| 14:19 | DuneMan | gitk/gitx are sorta half useful still |
| 14:20 | ataggart | no 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:20 | wlangstroth | ataggart: well, it's all text, so I use a text reader |
| 14:20 | ataggart | do you ave a screenshot showing what that looks like for multiple files? |
| 14:21 | DuneMan | ataggart: Because you basically get used to checking things in order. |
| 14:21 | ataggart | "in order"? |
| 14:21 | DuneMan | We also have a custom deployment system |
| 14:21 | DuneMan | which keeps track of branches for us. |
| 14:21 | ataggart | I'm not talking about branches |
| 14:21 | wlangstroth | it looks like diffs - what do you mean? |
| 14:21 | ataggart | I'm talking about, I change 5 files, someone else concurrently chnged 5 files, some of those changes overlap |
| 14:22 | DuneMan | Oh. That's easy. |
| 14:22 | ataggart | what does that diff look lke for you? |
| 14:22 | DuneMan | if the push fails, you pull and see what happened. |
| 14:22 | ataggart | ... |
| 14:22 | DuneMan | it looks like git diff. |
| 14:22 | DuneMan | git wont push revisions on top of each other that haven't been merged. |
| 14:22 | DuneMan | unless you do some really whacky dancing |
| 14:22 | DuneMan | with git merge and cherry picking commits |
| 14:22 | ataggart | so you trust the merge logic of git to understand how your changes will interact with the changes someone else made? |
| 14:23 | DuneMan | no, you pull and do the merge. |
| 14:23 | ataggart | but do you ever look at the changes side by side before a merge? |
| 14:23 | DuneMan | constantly. |
| 14:23 | DuneMan | You have to. |
| 14:23 | ataggart | ok, I'm asking what does that look like |
| 14:23 | ataggart | in the terminal |
| 14:23 | DuneMan | it looks like git difff |
| 14:23 | wlangstroth | haha |
| 14:23 | fliebel | Can Clojure(or any Java language) run on mobile devices? |
| 14:23 | DuneMan | I look at the changes inline. |
| 14:24 | wlangstroth | ataggart: it looks like a lot of white text on a black screen |
| 14:24 | wlangstroth | I'm thinking you wouldn't like it |
| 14:25 | ataggart | perhaps not. |
| 14:25 | ataggart | I like not being constrained to 1980s tech |
| 14:25 | Drakeson | is 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:25 | DuneMan | I use vimdiff for side-by-side diff |
| 14:25 | DuneMan | if my diff is complicated |
| 14:25 | technomancy | ataggart: and yet you're using lisp... =) |
| 14:25 | wlangstroth | haha - it's still all text, dude |
| 14:25 | DuneMan | and sometimes a 3-way diff tool |
| 14:25 | ataggart | not really just text |
| 14:25 | ataggart | there's deeper meanign there |
| 14:26 | Drakeson | technomancy: removing that flatten def fixes it here. |
| 14:26 | fliebel | What are the requirements(Java) for running Clojure? |
| 14:26 | technomancy | Drakeson: so it's giving you problems even though it's nested inside a when-not? |
| 14:27 | Drakeson | yes. |
| 14:27 | stuartsierra | fliebel: Java 1.5 |
| 14:27 | Borkdude | Am I right when saying that Clojure is closer to Haskell than Scala is to Haskell? I don't want to force a discussion |
| 14:28 | fliebel | stuartsierra: I see… so I guess I'll forget about mobile and very mobile devices :D ( http://lejos.sourceforge.net/ ) |
| 14:28 | sexpbot | "LeJOS, Java for Lego Mindstorms" |
| 14:28 | DuneMan | Borkdude: Why do you say that? |
| 14:28 | DuneMan | I actually don't know much about scala... |
| 14:28 | Borkdude | DuneMan: because of this question: http://stackoverflow.com/questions/2820801/yet-another-haskell-vs-scala-question |
| 14:28 | sexpbot | "Yet another Haskell vs. Scala question - Stack Overflow" |
| 14:28 | wlangstroth | Borkdude: I'd say it just to see the fur fly |
| 14:29 | DuneMan | but like... linguistically... a lisp isn't really like haskell. |
| 14:29 | Borkdude | He 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:30 | Borkdude | DuneMan: if you compare the characteristics? immutibility, laziness, pattern matching? |
| 14:31 | Borkdude | It was just my feeling, I don't know Haskell and Scala that well, so. |
| 14:31 | DuneMan | Type systems seem far more.... ingrained than any of those. |
| 14:31 | Dawgmatix | whats a good clojure web framework to look at ? |
| 14:31 | fliebel | Dawgmatix: good question, I'm also interested :) |
| 14:32 | Borkdude | Dawgmatix: isn't Compojure one? |
| 14:32 | fliebel | I think compojure, thats the only one I heard of |
| 14:32 | Dawgmatix | okay |
| 14:32 | fliebel | Or Spring maybe :) |
| 14:32 | Borkdude | DuneMan: I think he's not after a type system, but after a nice language in which he also can use Java stuff |
| 14:33 | ober2 | compojure is pretty nice. we moved some sinatra stuff over easily |
| 14:33 | DuneMan | Then that's a totally different question than "What's more like Haskell" |
| 14:33 | Dawgmatix | i am looking to move from django, because I finally feel confident about my clojure skills |
| 14:33 | mabes | Dawgmatix: compojure uses a framework called Ring which you can also use independently.. |
| 14:33 | ober2 | very simular |
| 14:33 | DuneMan | I've never used Scala :-) |
| 14:33 | Dawgmatix | okay mabes |
| 14:35 | joshua-choi | I 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:35 | joshua-choi | I'm asking this because I'm encountering some problems with Leiningen that I suspect has to do with Clojure 1.2. |
| 14:36 | ataggart | by default lein seems to pull down 1.1.0 |
| 14:36 | ataggart | but if you add a dep to 1.2.0-Master in your project.clj then it will pull that version |
| 14:36 | DuneMan | luckily technomancy is here |
| 14:36 | ataggart | yeah, ignore me. I'm mostly guessing :) |
| 14:36 | DuneMan | but yes, uses 1.1 by default |
| 14:36 | joshua-choi | I see, thank you |
| 14:37 | joshua-choi | I'm encountering two problems |
| 14:37 | technomancy | joshua-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:38 | DuneMan | which reminds me I should fix my lein version so lein repl works right |
| 14:38 | DuneMan | hah |
| 14:38 | joshua-choi | technomancy: 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:39 | joshua-choi | But the other is stranger: simply running "lein help" gives similar errors. |
| 14:39 | joshua-choi | I've pasted the output: http://gist.github.com/398271 |
| 14:39 | wlangstroth | Scala is kind of like almost-functional java. F# does a better job on the functional side, it seems |
| 14:40 | technomancy | joshua-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:40 | technomancy | since it uses the lein version of clojure, not the project's version |
| 14:40 | wlangstroth | (Of course, Clojure isn't purely functional, either, but ...) |
| 14:40 | joshua-choi | technomancy: "lein help" should not be affected by autodoc, though |
| 14:41 | joshua-choi | ...as far as I can tell. |
| 14:41 | technomancy | joshua-choi: lein help tries to load all lein plugins in order to show their docstrings |
| 14:41 | technomancy | but it should be resilient to broken plugins, you're right |
| 14:41 | joshua-choi | Ah. That would explain it. |
| 14:42 | Dawgmatix | i just heard about leiningen from the above discussion - is it similar to what asdf is in lisp ? |
| 14:42 | Dawgmatix | nvm, the github page has a good description :) |
| 14:47 | joshua-choi | technomancy: What is the relationship between the Clojure versions of Leiningen and its plugins? Does Leiningen itself currently always use 1.1? |
| 14:47 | joshua-choi | Also, is there a Leiningen 1.2.0? I cannot find it on its GitHub website. |
| 14:54 | DuneMan | The method described in *Hacking* doesn't seem to work right |
| 14:54 | DuneMan | after I do lein self-install with a stable checkout |
| 14:54 | DuneMan | (on the stable branch) |
| 14:54 | DuneMan | I try to do lein deps |
| 14:55 | DuneMan | and it says "Your Leiningen development checkout is missing its dependencies" etc |
| 14:56 | DuneMan | And.... it installed 1.1.0 |
| 14:57 | DuneMan | tips technomancy? |
| 15:00 | technomancy | DuneMan: sounds like you're confusing lein with lein-stable? |
| 15:03 | Dawgmatix | does "lein swank" not work with plain slime ? |
| 15:05 | dataangel | anyone 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:05 | dataangel | persistent binary search tree rather |
| 15:12 | Winstons55 | should 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:12 | Winstons55 | (defprotocol TestProto |
| 15:12 | Winstons55 | (simple-func [arg])) |
| 15:12 | Winstons55 | (deftype TestType [test-val] |
| 15:12 | Winstons55 | TestProto |
| 15:12 | Winstons55 | (simple-func [arg] |
| 15:12 | Winstons55 | {:pre [(= 0 arg)] |
| 15:12 | Winstons55 | :post [(= 1 %)]} |
| 15:12 | Winstons55 | 1)) |
| 15:12 | Winstons55 | whoa, my bad on the formatting/multi-lines |
| 15:15 | stuartsierra | Winstons55: datatype methods don't have all the features of fn |
| 15:16 | stuartsierra | which appears to include pre/post conditions |
| 15:16 | Winstons55 | ah ok, good to know |
| 15:16 | Winstons55 | thanks! |
| 15:27 | raek | dataangel: this article has an example implementation of a persistent binary tree: http://www.infoq.com/articles/in-depth-look-clojure-collections |
| 15:27 | sexpbot | "InfoQ: An In-Depth Look at Clojure Collections" |
| 15:29 | raek | to bad the formatting messed up the code examples including "<" |
| 15:31 | chouser | http://www.developer.com/print.php/3874551 -- same article, but apparently less broken formatting |
| 15:31 | sexpbot | "Clojure: Immutability at the Language Level — Developer.com" |
| 15:32 | raek | chouser: thanks! |
| 15:33 | chouser | quite welcome |
| 15:33 | chouser | http://joyofclojure.com/buy -- same article, but longer and more expensive |
| 15:33 | sexpbot | "Manning: The Joy of Clojure" |
| 15:33 | chouser | :-) |
| 15:33 | raek | :) |
| 15:37 | raek | hrm, how does this work? it is available as an ebook now, but the physical one comes this fall? |
| 15:37 | chouser | right |
| 15:37 | chouser | well, parts are available as PDF now |
| 15:38 | raek | ah, I see |
| 15:38 | chouser | all of it should be available this fall in printed form and in several ebook formats (pdf and epub at least, I think) |
| 15:39 | LauJensen | Does anybody know the name of a function which turns all of this %40 into @ and %2F into / and so forth ? |
| 15:40 | raek | something like java.net.URLEncoder? |
| 15:40 | Dawgmatix | i am one of the people who bought the book as an early release |
| 15:40 | Dawgmatix | its pretty fascinating to read the updated pdfs as they are written :) |
| 15:41 | LauJensen | raek: java.net.URLDecoder/decode - Thanks, just what I needed |
| 15:45 | Borkdude | I am reading it too |
| 16:01 | ninjudd | chouser: i heard that you may or may not be working on a pure clojure version of protocol buffers... |
| 16:05 | chouser | ninjudd: hm... no, "pure clojure" isn't quite right |
| 16:07 | ninjudd | chouser: oh, have you looked at my implementation? http://github.com/ninjudd/clojure-protobuf |
| 16:08 | ninjudd | basically just a clojure wrapper around the official google java implementation |
| 16:08 | DuneMan | seems reasonable |
| 16:08 | chouser | ninjudd: yes, I believe I glanced through your code a while ago |
| 16:10 | chouser | I hadn't seen your set/map extensions. Those look neat |
| 16:10 | chouser | though it suggests we may have different usage profiles in mind. Not surprising, I suppose. |
| 16:10 | ninjudd | chouser: i've thought about rewriting PersistentProtocolBufferMap using deftype, but i don't want to duplicate work you may or may not be doing |
| 16:11 | ninjudd | chouser: how so? |
| 16:11 | DuneMan | technomancy: lein-stable is just bin/lein of the stable branch, no? |
| 16:12 | DuneMan | because the "Hacking" section refers to lein-stable, but nothing else does |
| 16:12 | chouser | I'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:13 | ninjudd | i see. makes sense. though the extensions are still usable by someone outside of clojure |
| 16:13 | chouser | sure |
| 16:13 | ninjudd | they just appear as repeated fields |
| 16:13 | chouser | oh, I see. |
| 16:13 | ninjudd | though a protobuf implementation in another language could choose to read the metadata and make them sets or maps |
| 16:14 | chouser | well, you shouldn't worry about duplicating effort. I'm not at liberty to opensource this code at the moment. |
| 16:14 | ninjudd | ah, i see |
| 16:15 | chouser | I'm pushing for it and management is open to the idea, but has more pressing priorities... |
| 16:16 | ninjudd | chouser: did you implement it the same way? by wrapping the google implementation? |
| 16:16 | chouser | yes, the version that works today wraps generated Message objects |
| 16:16 | ninjudd | or did you write your own implementation from scratch? |
| 16:16 | ninjudd | i see |
| 16:18 | ninjudd | ok well, i'll let you know if i get around to rewriting it to use deftype |
| 16:19 | chouser | mine doesn't have any .java code |
| 16:19 | ninjudd | other than the google code |
| 16:19 | chouser | right. I mean I managed to avoid writing any .java code. :-) |
| 16:20 | ninjudd | do you use deftype? or gen-class/proxy |
| 16:21 | chouser | it 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:21 | DuneMan | technomancy: I mean, I symlinked leingingen/bin/lein to lein-stable, but apparently that's not the way to go |
| 16:21 | chouser | the generated message-wrappers implement IKeywordLookup to tie into clojure's call-site caching |
| 16:21 | ninjudd | nice, so yours is probably faster |
| 16:22 | chouser | I haven't done much benchmarking -- I mostly wanted to make sure the API was such that it could be made fast if needed |
| 16:22 | chouser | and it gave me an excuse to play with IKeywordLookup |
| 16:22 | ninjudd | well i use DynamicMessage rather than the generated message classes, so i assume there is some cost to that |
| 16:22 | ninjudd | i'm not familiar with IKeywordLookup |
| 16:23 | chouser | yeah, it's not really documented. hence the fun in playing with it ;-) |
| 16:23 | DuneMan | technomancy: And the lein script linked to from the website installs 1.1.0 in ~/.m2/repository/leiningen |
| 16:24 | ninjudd | chouser: looking at the clojure code now... so it is part of deftype? |
| 16:24 | chouser | I think it only makes sense for when you're trying to expose a statically-typed thing (like a defrecord or protobuf) to Clojure |
| 16:24 | chouser | ninjudd: yeah, it's how defrecord field lookups can be as fast as a direct java field lookup |
| 16:25 | DuneMan | technomancy: So... I don't understand what I'm supposed to be doing differently. |
| 16:25 | chouser | (:foo thing) as fast as (.foo #^Thing thing) |
| 16:25 | DuneMan | oh, I bet I have to build the jar |
| 16:25 | DuneMan | duh |
| 16:25 | chouser | note it's just as fast even though no type hint, which is rhickey just showing off. |
| 16:26 | ataggart | lol |
| 16:26 | ninjudd | i see.. hehe |
| 16:26 | ataggart | I'm hearing praise from a co-worker in at the clojure thing in NC |
| 16:26 | ninjudd | chouser: i may look into doing it this way (if you don't mind). the serialization/deserialization speed is very important for our application |
| 16:27 | chouser | ninjudd: I don't mind. I wish I could share my code. :-/ |
| 16:27 | ninjudd | me too! |
| 16:27 | chouser | for what it's worth, after I got all that working I realized we'd sometimes need to deal with dynamic messages |
| 16:28 | ninjudd | hmm |
| 16:28 | chouser | that is, we have a DescriptorProtos$DescriptorProto, but no generated java code for this particular message. |
| 16:28 | ninjudd | well i'd be really interested in a speed comparison between mine and yours if you get the time |
| 16:28 | chouser | we likely have the DescriptorProto at compile-time for any piece of clojure code using it, but not at java compile time. |
| 16:29 | chouser | so 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:29 | chouser | ninjudd: hm, yeah I should do that. |
| 16:29 | chouser | yay microbenchmarks. heh. |
| 16:31 | ninjudd | well, i'm sure yours will be faster, but it's hard to know how much |
| 16:31 | ninjudd | depends on the size of the messages and number of fields etc though |
| 16:31 | chouser | I'm sure |
| 16:31 | chouser | and how many reads per write, stuff like that. |
| 16:33 | ninjudd | i have a benchmark for our use case, but i'm trying to judge whether the work would be worth the increase |
| 16:33 | ninjudd | would be a good learning experience though |
| 16:34 | chouser | if 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:34 | ninjudd | thanks |
| 16:36 | ninjudd | there 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:37 | chouser | ok |
| 16:37 | ninjudd | i'm benchmarking our application code that depends on jiraph which depends on protobufs |
| 16:37 | ninjudd | i should probably write a direct benchmark for jiraph anyway |
| 16:47 | technomancy | DuneMan: lein-stable doesn't belong in a checkout at all. just wget the script directly. |
| 16:48 | technomancy | DuneMan: it can tell if it's running from a checkout or not. if it is, it assumes it's a dev version |
| 16:48 | DuneMan | I had just not done a lein-stable jar in my checkout |
| 16:49 | DuneMan | so it obviusly wasn't findind the jar |
| 16:49 | DuneMan | because I was a tard. |
| 16:50 | technomancy | I guess that might work too, but it's not what I meant |
| 16:50 | DuneMan | I basically just misread what the hacking section was telling ,me. |
| 16:50 | DuneMan | Because I didn't run lein-stable deps (lein-stable jar, of course, does this) |
| 16:50 | DuneMan | in my leiningen checkout |
| 16:50 | DuneMan | I was running it in my project |
| 17:12 | ska2342 | Hi. 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:23 | chouser | get is always fast (that is O(log n) or faster). nth is sometimes not always (sometimes O(n)) |
| 17:26 | ska2342 | get 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:28 | ataggart | get is used when you have a "key" (loosely defined) |
| 17:28 | ataggart | ,(get 1 '(:foo :bar)) |
| 17:28 | clojurebot | nil |
| 17:28 | ataggart | erm |
| 17:28 | ataggart | ,(get '(:foo :bar) 1) |
| 17:28 | clojurebot | nil |
| 17:28 | DeusExPikachu | in 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:29 | ska2342 | ataggart: I know :-), but e.g. for strings it falls back to nth |
| 17:29 | ataggart | ska2342: that's probably because strings have "keys" |
| 17:30 | ataggart | i.e. the index of the char in the array |
| 17:30 | DeusExPikachu | note that in http://clojure.org/protocols, the 'this' field is supplied with the name 'x' |
| 17:30 | DeusExPikachu | for deftype |
| 17:31 | ataggart | don'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:31 | ataggart | use the function that logically applies |
| 17:32 | ska2342 | ataggart: 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:32 | ska2342 | is the performance guarantee part of a function or a datastructure? |
| 17:33 | ataggart | both |
| 17:34 | ataggart | nth and get are different |
| 17:34 | ataggart | for example: |
| 17:34 | ataggart | ,(nth {:a :b, :c :d} 1) |
| 17:34 | clojurebot | java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap |
| 17:35 | ska2342 | ,(get '(1 2 3) 0) |
| 17:35 | clojurebot | nil |
| 17:35 | ataggart | ,(nth (seq {:a :b, :c :d}) 1) |
| 17:35 | clojurebot | [:c :d] |
| 17:35 | AWizzArd | They are different, but is such a difference required? |
| 17:36 | AWizzArd | As I see it, the point of ska2342 is: for lists nth and get could be the same |
| 17:36 | ataggart | yes because the performance characteristics for different datastructures are different |
| 17:36 | ska2342 | ,(get '(1 2 3) nil) |
| 17:36 | clojurebot | nil |
| 17:36 | ataggart | get on lists would not be ~O(1) |
| 17:36 | AWizzArd | ataggart: O(n) for nth for lists |
| 17:36 | AWizzArd | so, no nth for lists then? |
| 17:36 | ska2342 | ,(get '(1 2 3) :whatever) |
| 17:36 | clojurebot | nil |
| 17:36 | ataggart | nth works on sequential structures |
| 17:36 | ataggart | get works on associative structures |
| 17:36 | ataggart | they're different |
| 17:37 | ataggart | only you can know which structures you're working with |
| 17:37 | AWizzArd | ,(get '[10 20 30 40] 2) |
| 17:37 | clojurebot | 30 |
| 17:37 | AWizzArd | ,(get '(10 20 30 40) 2) |
| 17:37 | clojurebot | nil |
| 17:37 | ataggart | and you don't need to quote vectors |
| 17:37 | AWizzArd | I know. |
| 17:37 | ska2342 | what about raising an exception if you pass a sequential thing to get? |
| 17:37 | ataggart | k :) |
| 17:37 | AWizzArd | that would not be a good thing |
| 17:38 | AWizzArd | It was part of rhickeys descisions to return nil instead of throwing exceptions |
| 17:38 | ataggart | if you need to check for that case (instead of relying on nil) then use contains? |
| 17:38 | AWizzArd | so you don't have to scatter your code everywhere with (try (get ..) (catch Exception e nil)) |
| 17:38 | ska2342 | AWizzArd: like nth for associatives? ;-P |
| 17:39 | ataggart | might be an oversight |
| 17:39 | AWizzArd | nth 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:39 | ska2342 | ataggart: 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:40 | ataggart | AWizzArd: because get is contractually fast. You cannot be fast on lists. |
| 17:40 | ataggart | ska2342: nil == false in that context |
| 17:40 | AWizzArd | Is there an argument why get should be contractually fast? |
| 17:40 | ska2342 | I am not a language desinger (IANALD? ;-) but this is fishy |
| 17:41 | AWizzArd | Maybe usabilty could come before efficiency here |
| 17:41 | ska2342 | ataggart: don't ever try to argue with a newcomer to lisp-likes about nil not being false anytime :) |
| 17:42 | mmarczyk | AWizzArd: 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:42 | ataggart | since 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:43 | mmarczyk | only contains? happens to be the predicate counterpart of get :-) |
| 17:43 | ataggart | AWizzArd: that's a great way for people to write slow code and blame the new language. Pick your datastructures with forethought instead. |
| 17:43 | ska2342 | ataggart: but (as I said) contains? does the same thing as get with lists |
| 17:43 | mmarczyk | ,(contains? '(1 2 3) 1) |
| 17:43 | clojurebot | false |
| 17:43 | mmarczyk | ,(contains? [1 2 3] 1) |
| 17:43 | clojurebot | true |
| 17:43 | mmarczyk | ,(contains? [1 2 3] 3) |
| 17:43 | clojurebot | false |
| 17:44 | ataggart | the question being answered by contains? is "is it meaningful to use get" |
| 17:44 | mmarczyk | ,[(get [1 2 3] 1) (get [1 2 3] 3)] |
| 17:44 | clojurebot | [2 nil] |
| 17:44 | AWizzArd | ataggart: how would get be slower than nth? |
| 17:44 | mmarczyk | ataggart: ah, I see the point you're making now |
| 17:44 | ska2342 | please don't get into the old contains? checks for index discussion now... |
| 17:44 | ataggart | I'm conveying what I understand to be Rich's POV |
| 17:44 | ataggart | not my own |
| 17:44 | AWizzArd | newcomer wants to get element 5000 out of a list. (get elements 5000) ==> slow, so Clojure must be blamed? |
| 17:45 | mmarczyk | ska2342: not getting into any discussion on this, just point out the current state of afairs |
| 17:45 | ska2342 | ataggart: perfectly fine, I try to understand it :-) |
| 17:46 | mmarczyk | AWizzArd: well hopefully people no better than to expect less than O(n) from linked list lookup :-) |
| 17:46 | mmarczyk | know better |
| 17:46 | mmarczyk | but still, if it is a totally different operation to, say, vector lookup by index |
| 17:47 | mmarczyk | why overload a single function with both tasks |
| 17:47 | ska2342 | mmarczyk: 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:47 | ataggart | if you want the nth item, use nth |
| 17:47 | ataggart | if you want to lookup by key, use get |
| 17:47 | mmarczyk | what ataggart said :-) |
| 17:47 | ataggart | it's not hard |
| 17:48 | mmarczyk | it's conceivable that we could have just one name in core for both things |
| 17:48 | ataggart | btw, regarding the need for contains?... |
| 17:48 | ataggart | ,(get '(:a :b) 1) |
| 17:48 | mmarczyk | I don't see how that would be helpful in anything |
| 17:48 | clojurebot | nil |
| 17:48 | AWizzArd | well, a list is also a mapping, from its position (key) to the element that is referenced there (val) |
| 17:48 | ataggart | ,(get [:a nil :b] 1) |
| 17:48 | clojurebot | nil |
| 17:48 | ska2342 | mmarczyk: 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:48 | mmarczyk | AWizzArd: not at all |
| 17:48 | ataggart | AWizzArd: incorrect |
| 17:48 | mmarczyk | ska2342: a-ha! you see, there's the point of "having both" for you :-) |
| 17:49 | mmarczyk | ska2342: to force you out of your "listy" comfort zone into using the could-be-correct data structures from the get-go |
| 17:49 | mmarczyk | which is perfectly easy to do in Clojure, since you've got first class vectors, on par with lists, functionally "updatable" |
| 17:49 | ska2342 | mmarczyk: sorry, I don't get that. Could you please elaborate? |
| 17:50 | mmarczyk | ska2342: there's no point at all, in Clojure, to experimenting with lists first |
| 17:50 | mmarczyk | when a vector is actually the better data structure |
| 17:50 | mmarczyk | because you gain nothing in syntactic convenience or "natural feel" of your programme |
| 17:50 | AWizzArd | if lists can be used to implement maps, then they offer semantically the same, so, yes, lists are mappings |
| 17:50 | mmarczyk | that's in contrast to Scheme / CL where lists are obviously the only first class citizens |
| 17:50 | AWizzArd | you can implement classes and maps with lists, and vice versa |
| 17:50 | ska2342 | mmarzyk: Point taken. And I already adapted my habits. It's just the remembrance of things that makes me shudder |
| 17:51 | ataggart | AWizzArd: maps are not implemented with lists |
| 17:51 | mmarczyk | well, lists and very similar abstractions like Scheme's streams |
| 17:51 | AWizzArd | I know, of course they are not |
| 17:51 | AWizzArd | for sake of efficiency |
| 17:51 | AWizzArd | but conceptually they can express the same thing |
| 17:51 | ataggart | and efficiency is the entire point of the get function |
| 17:51 | AWizzArd | from turing point of view |
| 17:51 | ska2342 | It feels like in Clojure lists are only created for containing code. |
| 17:51 | mmarczyk | ska2342: yeah, I actually find I miss nice vector support in Scheme nowadays :-) |
| 17:52 | AWizzArd | I would say that the point of get is to get the value behind the key |
| 17:52 | ataggart | ska2342: bingo! |
| 17:52 | AWizzArd | with the best performance possible |
| 17:52 | ataggart | "key" has no meaning for lists |
| 17:53 | AWizzArd | it has the same meaning as it has for vectors or maps |
| 17:53 | ataggart | except the synthetic one you impute by position |
| 17:53 | ataggart | false |
| 17:53 | mmarczyk | ska2342: actual lists / conses, yeah, but list-like seqs are used all over the place |
| 17:53 | AWizzArd | ataggart: can you explain it? |
| 17:53 | ataggart | apparently not |
| 17:53 | AWizzArd | (: |
| 17:53 | mmarczyk | :-) |
| 17:53 | ska2342 | mmarzyk: seqs are a different beast. But get just returns nil for them, too ,-) |
| 17:54 | hiredman | ~ping |
| 17:54 | clojurebot | PONG! |
| 17:54 | ataggart | but to back up, certain functions are provided precisely for their performance characteristics. |
| 17:54 | ataggart | get os one of those functions |
| 17:54 | mmarczyk | ska2342: for the same reasons as with lists :-) |
| 17:55 | chouser | one could try to implement all abstractions on all concrete types: use lists as maps and sets, maps as lists and vectors, etc. |
| 17:55 | AWizzArd | I 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:55 | ska2342 | ataggart: 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:55 | chouser | things would "just work" but with less clear performance profiles. |
| 17:55 | AWizzArd | chouser: yes, this is possible |
| 17:55 | AWizzArd | exactly |
| 17:55 | chouser | but that language is not Clojure |
| 17:56 | AWizzArd | yes, this is more in the category of turing completness |
| 17:56 | ataggart | what does turing completeness have to do with any of this? |
| 17:56 | AWizzArd | in principle lists would be enough to do calculations, numbers are not needed |
| 17:57 | ataggart | sure, and the performance profile would be crap. Still not clear on what this has to do with TC |
| 17:57 | AWizzArd | the magic word here is "category" |
| 17:57 | ska2342 | chouser: then, why have lists at all? Because Clojure is a lisp? Just for code? |
| 17:58 | ataggart | ska2342: you use them in macros |
| 17:58 | chouser | lists are useful |
| 17:58 | Borkdude | ska2342: 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:58 | chouser | if you want to pop and seq in the same direction, for example |
| 17:59 | ska2342 | wouldn't anything implementing Sequential suffice? |
| 17:59 | mmarczyk | lists are basically finite sequences |
| 17:59 | mmarczyk | if you're going to have lazy, potentially infinite seqs |
| 17:59 | mmarczyk | it makes sense to allow for the finite case to |
| 17:59 | ska2342 | Oh, sorry, the interface Sequential seems to be empty here |
| 18:00 | Borkdude | maybe you can say that lists are literal seqs in Clojure? |
| 18:00 | raek | also, lists can be partially garbage collected |
| 18:00 | mmarczyk | and as chouser points out, LIFOs "are" lists (are naturally implemented as) |
| 18:01 | mmarczyk | raek: anything that has parts can be partially garbage collected |
| 18:01 | mmarczyk | raek: for lists, you have to lose the head for that to happen, for vectors -- the trie root, which happens all the time |
| 18:01 | AWizzArd | btw, as vectors are tries under the hood, is conj as efficient for vectors as it is for lists? |
| 18:02 | mmarczyk | conj is the one op which is implemented for all Clojure data structures |
| 18:02 | mmarczyk | and is efficient across the board |
| 18:02 | raek | don't vector seqs have a reference to the trie root? |
| 18:02 | ataggart | but, they do have *slightly* different chartacteristics |
| 18:02 | mmarczyk | but it does different things: cons for lists, push-at-tail for vectors |
| 18:02 | AWizzArd | ataggart: yes, this is what i would intuitively thing |
| 18:02 | AWizzArd | i am going to try this now :) |
| 18:03 | raek | (drop 999 (seq 1000-element-vector)) |
| 18:03 | ataggart | O(1) vs O(log32n) |
| 18:03 | mmarczyk | raek: ah, possibly |
| 18:03 | ataggart | close enough |
| 18:03 | raek | won't that retain all the elements? |
| 18:04 | ataggart | raek: nope, nothign holds the head |
| 18:04 | ataggart | of the 100-element-vector |
| 18:04 | mmarczyk | raek: but if you do (assoc [...] ix :foo), the old version of the vector might be garbage collected |
| 18:04 | mmarczyk | raek: so there's partial GC for you |
| 18:04 | AWizzArd | ,(time (dotimes [i 1000000] (conj [] 10))) |
| 18:04 | clojurebot | "Elapsed time: 226.984 msecs" |
| 18:04 | Borkdude | maybe 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:04 | AWizzArd | ,(time (dotimes [i 1000000] (conj () 10))) |
| 18:04 | arohner | if 1000-element-vector is a local or var, doesn't that hold head? |
| 18:04 | clojurebot | "Elapsed time: 148.905 msecs" |
| 18:04 | ataggart | try not to kill clojurebot |
| 18:04 | ataggart | :) |
| 18:04 | mmarczyk | Borkdude: wow, this is really cool :-) |
| 18:04 | AWizzArd | the bot is pretty well secured by now |
| 18:05 | mmarczyk | ataggart: on the contrary, we should all endeavour to kill clojurebot so that clj-sandbox might be improved :-) |
| 18:05 | AWizzArd | now Licenser should step in :) |
| 18:05 | mmarczyk | or is this one not based on clj-sandbox, I forget... state-of-the-art in Clojure sandboxing, anyway |
| 18:07 | Borkdude | mmarczyk: don't know if it's possible though |
| 18:07 | Borkdude | just an interesting thought |
| 18:08 | mmarczyk | Borkdude: 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:08 | mmarczyk | Borkdude: but having an extra piece of meta data would be cool :-) |
| 18:08 | mmarczyk | {:big-O "n"} for O(n)? :-) |
| 18:09 | ataggart | big-O's usefulness is often overstated |
| 18:09 | Borkdude | For example, or maybe :big-O {:get "1" :nth "n"} |
| 18:09 | ataggart | case in point: |
| 18:09 | ataggart | ,(type {:foo :bar}) |
| 18:09 | clojurebot | clojure.lang.PersistentArrayMap |
| 18:10 | ska2342 | the meta-tag would need a better name, though. :landau ? ;-) |
| 18:10 | arkahn | for 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:10 | ataggart | take it away and call (set! *warn-on-reflection* true) |
| 18:10 | mmarczyk | ska2342: yeah :-) |
| 18:10 | ataggart | clojure will tell you |
| 18:10 | ataggart | premature type-hinting is... |
| 18:11 | arkahn | started, the noob-clojure programming has ... : ( |
| 18:11 | arkahn | : ) |
| 18:12 | mmarczyk | ataggart: I'm not sure if this perfectly valid point has any bearing on whether big-O is useful :-) |
| 18:12 | Fare | does clojure run on Android? |
| 18:12 | lancepantz | Fare: yes |
| 18:12 | Fare | yay. |
| 18:12 | ataggart | clojure run where java runs (more or less) |
| 18:12 | mmarczyk | Fare: I remember reading an entry on some blog describing how to set up a repl for use on an android phone :-) |
| 18:13 | Fare | (yes, but Android has its own set of Java libraries, so I was wondering) |
| 18:45 | arkahn | should 'when' be avoided if side-effects are not being introduced |
| 18:46 | Fare | use and ? |
| 18:46 | arkahn | Fare: I'm sorry - I'm not sure what you mean |
| 18:47 | arkahn | Fare: use a pred? |
| 18:48 | raek | 'when' is useful whenever you would put nil in the false branch of an if |
| 18:48 | tomoj | ,(if nil 3) |
| 18:48 | clojurebot | nil |
| 18:48 | tomoj | guess it's just a better name than 'if' for this case |
| 18:48 | raek | hrm, yes |
| 18:49 | arkahn | ok ... so side effects are not required in a stylistic sense |
| 18:49 | tomoj | wait, huh? |
| 18:49 | tomoj | people use side-effects with when? |
| 18:49 | raek | (when pred do-a do-b do-c) |
| 18:49 | arkahn | I was reading that using 'do' suggests that "side effects follow" and 'when' is an if + do |
| 18:49 | technomancy | yes, that's why "when" has an implicit "do" |
| 18:50 | technomancy | arkahn: that's quite right. |
| 18:50 | tomoj | oh, weird, I never got that |
| 18:50 | arkahn | cool - thanks all |
| 18:50 | tomoj | I always just used it to replace an if with no else |
| 18:50 | arkahn | I read it's used then, too, but apparently only when you want to introduce side effects (?) |
| 18:51 | arkahn | not enforced by clojure, but programming style |
| 18:55 | chouser | no, 'when' is fine in pure code for "ifs" with no "elses" |
| 18:57 | arkahn | chouser: Programming Clojure (p. 48) suggests what technomancy said, but that's the only authoritative source I have to go off of |
| 19:00 | arkahn | chouser: 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:01 | arkahn | I feel like I'm learning basketball and all I've done so far is learn dribbling a basic passing o.0 |
| 19:08 | arkahn | fwiw, 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:09 | Chousuke | hm? |
| 19:09 | Chousuke | when is just a convenient form for an if that has no else-clause |
| 19:10 | Chousuke | the syntax for is is (if pred then else) whereas when is (when pred then-expr*) |
| 19:11 | Chousuke | it also conveys the intent better |
| 19:11 | arohner | arkahn: 'when' is also useful as a hint to the reader that there should be no else clause |
| 19:11 | arohner | as opposed to (if p true-clause) |
| 19:12 | arkahn | ok - thank you |
| 19:17 | tomoj | why does if seem like it would be uncommon? |
| 19:17 | tomoj | it's quite common |
| 19:19 | ataggart | perhaps he's asking because if isn't in the api? |
| 19:19 | arkahn | most 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:19 | arkahn | all this has been helpful to think over though |
| 19:28 | DuneMan | one 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:31 | DuneMan | neither am I. |
| 19:31 | DuneMan | but I do like how "when" reads. |
| 19:36 | maxhodak | no matter what i do amap always throws java.lang.IllegalArgumentException on me |
| 19:40 | defn | Could someone explain the whole Q thing? |
| 19:40 | defn | ,Q |
| 19:40 | clojurebot | <-nil-< |
| 19:40 | defn | ,`Q |
| 19:40 | clojurebot | sandbox/Q |
| 19:40 | defn | ,``Q |
| 19:40 | clojurebot | (quote sandbox/Q) |
| 19:41 | arkahn | it's shorthand for clojure.lang.PersistentQueue/EMPTY I think, but I've only seen it used with clojurebot and/or sexpbot |
| 19:42 | ataggart | (conj 5 Q) |
| 19:42 | ataggart | ,(conj 5 Q) |
| 19:42 | clojurebot | java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IPersistentCollection |
| 19:42 | ataggart | ,(conj Q 5) |
| 19:42 | clojurebot | <-(5)-< |
| 19:43 | ataggart | interesting |
| 19:43 | ataggart | ,(pop *1) |
| 19:43 | clojurebot | java.lang.IllegalStateException: Var clojure.core/*1 is unbound. |
| 19:44 | tomoj | what about the whole <-*-< thing? |
| 19:45 | tomoj | is that how PersistentQueues print now? |
| 19:45 | arkahn | that's bot specific because I haven't seen that at the repl when using those |
| 19:46 | arkahn | it makes me think they're there to show where elements enter and exit the queue |
| 19:49 | arkahn | I 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:52 | ninjudd | ,(class Q) |
| 19:52 | clojurebot | clojure.lang.PersistentQueue |
| 19:53 | tomoj | arkahn: I don't think the choice is between PersistentQueue and agents |
| 19:54 | tomoj | if you use a PersistentQueue, don't you need a reference type anyway? |
| 19:54 | arkahn | yes |
| 19:56 | ninjudd | that reminds me, i have a patch i need to submit to make PersistentQueue count O(1) |
| 19:56 | arkahn | I 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:56 | ninjudd | right now, if you call count, it iterates through the list portion of the queue to count it |
| 19:58 | ninjudd | arkahn: all persistent data structures are a way to share data |
| 20:00 | ninjudd | you still need a time construct to modify a persistent queue... a ref or an agent or an atom |
| 20:01 | ninjudd | if you want another thread to see the change |
| 20:02 | DuneMan | arkahn: SynchronousBlockingQueue can actually make more sense for that use case |
| 20:03 | DuneMan | but it depends on what you're doing |
| 20:03 | DuneMan | If you're just doing like... spin up a bunch of threads and process messages on them |
| 20:03 | DuneMan | then just use agents |
| 20:03 | DuneMan | 'cause that's what they are. |
| 20:03 | arkahn | I 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:04 | DuneMan | Atom + watchers |
| 20:04 | DuneMan | or a SynchronousBlockingQueue |
| 20:05 | DuneMan | depending on what behavior you need. |
| 20:05 | arkahn | For 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:05 | DuneMan | take a look at fill-queue |
| 20:05 | arkahn | ok |
| 20:06 | ninjudd | arkahn: 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:06 | ninjudd | the reference could be to a PersistentQueue |
| 20:07 | arkahn | ninjudd: 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:07 | ninjudd | ok :) |
| 20:07 | tomoj | are there any good examples of fill-queue out there? |
| 20:08 | tomoj | I believe I understand how it works, but that I don't really get it |
| 20:32 | mmarczyk | tomoj: clojure.contrib.lazy-seq uses it |
| 20:33 | tomoj | thanks |
| 20:34 | mmarczyk | aaaa, wait, wrong lib |
| 20:34 | mmarczyk | I meant c.c.lazy-xml |
| 20:34 | mmarczyk | in parse-seq |
| 20:35 | Raynes | Michael 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:35 | Raynes | This makes me a happy Rayne. |
| 20:35 | mmarczyk | Raynes: cool :-) |
| 20:54 | alexyk | given two maps with keys which are integers, what's the cutest way to get the merged deduped list of keys in sorted order? |
| 20:54 | alexyk | don't need values here, just the keys |
| 20:55 | alexyk | I guess adding them to sorted set? |
| 20:56 | alexyk | forgot, how do add things to a set?... |
| 20:56 | alexyk | .(sorted-set 1 2 3) |
| 20:56 | alexyk | ,(sorted-set 1 2 3) |
| 20:56 | clojurebot | #{1 2 3} |
| 20:57 | alexyk | now how do we add 4? |
| 20:58 | ninjudd | ,(keys (merge (sorted-map) {2 3 7 6} {19 2 1 3})) |
| 20:58 | clojurebot | (1 2 7 19) |
| 20:58 | alexyk | ninjudd: no merge before keys! |
| 20:59 | alexyk | maps are huge, think graphs :) |
| 20:59 | rdsr | Hi all, can I define a let within the bindings of for |
| 20:59 | rdsr | ? |
| 20:59 | mmarczyk | ,(reduce into [(sorted-set) (keys {2 3 7 6}) (keys {19 2 1 3})]) |
| 20:59 | clojurebot | #{1 2 7 19} |
| 21:00 | rdsr | something like this (for [i ... j ... :let n (* i j)] ... |
| 21:00 | mmarczyk | rdsr: :let [n (* i j)] |
| 21:01 | alexyk | mmarczyk: warmer, can we tuck both keys into a map to operate on a list of maps? |
| 21:01 | ninjudd | mmarczyk: nice |
| 21:01 | alexyk | i.e. say keys once :) |
| 21:01 | mmarczyk | sure |
| 21:01 | alexyk | ok :) |
| 21:01 | mmarczyk | ,(reduce into (cons (sorted-set) (map keys [{2 3 7 6} {19 2 1 3}]))) |
| 21:01 | clojurebot | #{1 2 7 19} |
| 21:01 | alexyk | yay! |
| 21:01 | mmarczyk | :-) |
| 21:02 | alexyk | how about we do (apply sorted-set (concat...)) instead? |
| 21:02 | alexyk | then the set will be sorted at creation time |
| 21:02 | mmarczyk | um, nope, try it |
| 21:03 | mmarczyk | also, the set *is* sorted at creation time |
| 21:03 | mmarczyk | of course it's also empty :-) |
| 21:03 | ninjudd | ,(apply sorted-set (mapcat keys [{2 3 7 6} {19 2 1 3}])) |
| 21:03 | clojurebot | #{1 2 7 19} |
| 21:03 | mmarczyk | ah yes, mapcat helps :-) |
| 21:04 | DuneMan | *enjoys watching these types of discussions* |
| 21:04 | MadWombat | Hello |
| 21:04 | mmarczyk | but anyway, it's the same thing |
| 21:04 | mmarczyk | with the sorted set being built incrementally by a Java loop |
| 21:04 | mmarczyk | who knows, maybe that's a bit faster :-) |
| 21:05 | alexyk | ,(apply sorted-set (apply concat (map keys [{2 3 7 6} {19 2 1 3}]))) |
| 21:05 | clojurebot | #{1 2 7 19} |
| 21:05 | mmarczyk | DuneMan: me too :-) |
| 21:05 | mmarczyk | alexyk: mapcat = (apply concat (map ...)) |
| 21:05 | alexyk | ah! |
| 21:05 | alexyk | mapcat should be clojure mascot |
| 21:06 | DuneMan | *pictures a really lame logo* |
| 21:06 | mmarczyk | ohhh, and you mentioned concat above |
| 21:06 | alexyk | and... the Oscar goes to ninjudd! |
| 21:06 | mmarczyk | sorry, missed that |
| 21:06 | DuneMan | aha, I'm in IRC, I can actually use /me, doh |
| 21:06 | ataggart | cdr shdr wdr |
| 21:07 | DuneMan | ugh |
| 21:07 | alexyk | who stole car/cdr from clojure? |
| 21:07 | DuneMan | An ex-coworker of mine made and sold a bunch of t-shirts with just "()" on them |
| 21:07 | alexyk | ,(doc car) |
| 21:07 | clojurebot | I don't understand. |
| 21:07 | DuneMan | I see the occasional nerd in the bay are wandering around with one |
| 21:07 | DuneMan | area* |
| 21:08 | ataggart | "my other car is a cdr." |
| 21:08 | mmarczyk | :-) |
| 21:08 | ataggart | someone's bumpersticker |
| 21:08 | DuneMan | *shakes head* |
| 21:09 | DuneMan | I almost got a custom license plate with SFINAE on it... but I decided only 4 people would get it |
| 21:11 | mmarczyk | is the *jure ban due to the Great or the Dear part? ;-) |
| 21:12 | alexyk | mmarczyk: meaning Great Dear Leader's reluctance to use *jure-suffixed names? |
| 21:12 | ataggart | there are only so many puns |
| 21:12 | ataggart | seajure |
| 21:12 | ataggart | I like the best |
| 21:13 | mmarczyk | alexyk: no, meaning his reluctance to allow people to use those names with their projects with current snapshots of lein :-P |
| 21:14 | alexyk | mmarczyk: that's the dear part, since it's endearing :) |
| 21:15 | mmarczyk | alexyk: isn't that "endangering", with who knows how many *jure partisans lurking around? |
| 21:16 | alexyk | mmarczyk: then it's Great since it imposes an iron will on an unruly and anarchical mob! |
| 21:16 | alexyk | with the unabashed bold display of stylistic preferences |
| 21:19 | mmarczyk | fine :-) |
| 21:20 | _brian2_ | noob question > I want to develop patches to a library, what do to my project file, etc? |
| 21:20 | ninjudd | lancepantz: maybe we should name our NativeClassLoader project classlojure just to spite him |
| 21:21 | ninjudd | or is classloadjure better? |
| 21:21 | mmarczyk | I'd say, go with loajure |
| 21:21 | mmarczyk | ;-) |
| 21:22 | ninjudd | classlojure is nice because you take the c from clojure and replace it with class |
| 21:22 | mmarczyk | true! |
| 21:27 | ninjudd | http://github.com/ninjudd/classlojure |
| 21:27 | mmarczyk | way to go! |
| 21:28 | mmarczyk | :-) |
| 21:28 | mmarczyk | nice Gist (NCL), by the way |
| 21:29 | ninjudd | mmarczyk: thanks. now we just need to figure out how to make it work without changing Clojure internals |
| 21:31 | mmarczyk | you think that's possible? (I really wouldn't know, my Java-fu is rather weak) |
| 21:33 | ninjudd | i think that *use-context-classloader* is supposed to allow you to use your own classloader |
| 21:33 | ninjudd | but it doesn't seem to work for import for whatever reason |
| 21:38 | hugod | ninjudd: *use-context-classloader* is true by default, you just need to set the thread context class loader to the one you want |
| 21:39 | ninjudd | hugod: yeah, but for some reason it doesn't work for import |
| 21:39 | ninjudd | here's my code that doesn't work: http://github.com/ninjudd/classlojure/blob/master/src/clj/classlojure.clj |
| 21:45 | MadWombat | can anyone point me in the right direction to load and call ant tasks from an XML file in clojure/java? |
| 21:45 | MadWombat | some sort of factory class perhaps? |
| 21:47 | hugod | ninjudd: you trying that AOT'd ? |
| 21:47 | ninjudd | hmm, no |
| 21:47 | ninjudd | i 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:56 | hugod | ninjudd: 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:57 | brweber2 | so I created a gateway drug to help people get into clojure |
| 21:57 | brweber2 | http://github.com/brweber2/clojure/tree/master/examples/ |
| 21:57 | brweber2 | mostly b/c I wanted to start messing around with the source code |
| 21:57 | brweber2 | it is NOT intended to be serious |
| 21:57 | brweber2 | but any feedback is appreciated |
| 21:57 | brweber2 | it is a full fork of clojure on github |
| 21:57 | brweber2 | but the changes are very minimal |
| 22:01 | brweber2 | rhickey How was day 1? |
| 22:04 | hugod | some clojure mojo : http://github.com/hugoduncan/clojure-mojo-example/blob/master/src/main/clojure/maven/clojure/example/plugin.clj |
| 22:14 | lancepantz | how 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:50 | joshua-choi | Perhaps 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:50 | joshua-choi | Perhaps one that uses transients. This function would be very useful to me. |
| 22:53 | hiredman | ,(doc fmap) |
| 22:53 | clojurebot | "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:55 | tomoj | awesome |
| 22:55 | joshua-choi | Eh...that's a multimethod. Thank you, though. |
| 23:06 | powr-toc | lancepantz: http://gist.github.com/399438 |
| 23:06 | lancepantz | thank you :) |
| 23:12 | joshua-choi | Is there a for-like macro that iterates specifically through nested maps? |
| 23:14 | powr-toc | joshua-choi: the closest I can think of is building something with tree-seq |
| 23:14 | joshua-choi | (map-for [x {:a {:a 1, :b 3}, :b {:a 2, :b 2}}, y x] (+ (count x) y)) |
| 23:14 | joshua-choi | Hmm |
| 23:15 | powr-toc | can you not just call seq on the maps? |
| 23:15 | powr-toc | and treat them as pairs?# |
| 23:16 | joshua-choi | powr-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:17 | powr-toc | yeah |
| 23:17 | joshua-choi | I'm surprised that this isn't much in demand yet |
| 23:18 | joshua-choi | I want things like this all the time |
| 23:18 | powr-toc | what do you want it for? |
| 23:19 | joshua-choi | I have a nested map, and I want to transform it into a similar nested map with modified inner vals |
| 23:20 | powr-toc | can you use merge-with? |
| 23:20 | joshua-choi | How would I do that? |
| 23:21 | joshua-choi | I don't think I can, no. |
| 23:22 | tomoj | can't you just take the fmap for maps and make it a function? |
| 23:23 | tomoj | huh, seems fmap doesn't even do what you want |
| 23:24 | powr-toc | joshua-choi: I'm struggling to see what your idea for map-for is doing... is the destructuring right? |
| 23:24 | joshua-choi | I believe the do-monad of the map-m monad does what I want, though it's not very well-supported |
| 23:25 | tomoj | and certainly not fast, I'd think? |
| 23:25 | joshua-choi | powr-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:26 | joshua-choi | Ideally, it'd use transients or something |
| 23:26 | joshua-choi | If I wrote my own, could I submit it to clojure-contrib? |
| 23:30 | joshua-choi | If monads are good at one thing, it's making it easier to write let/for-like macros. |
| 23:31 | tomoj | oh, so you'd use map-m just to generate the macroexpansion which would be fast code? |
| 23:33 | joshua-choi | tomoj: Yes, I would—except map-m doesn't yet exist in clojure.contrib.monads. |
| 23:34 | tomoj | I was wondering earlier whether protocols would help |
| 23:34 | joshua-choi | I'm glad Rich Hickey showed an interest in eventually integrating monads into clojure's main namespaces |
| 23:34 | powr-toc | he did? |
| 23:34 | joshua-choi | I think it was on the clojure-dev Google group. |
| 23:34 | tomoj | "Number of monads in Clojure 1.0: Zero. In 1.1: Zero. In 1.2: Zero. Monads are not idiomatic (via @stuarthalloway)" |
| 23:35 | tomoj | heh |
| 23:35 | joshua-choi | Yeah, I read that too. |
| 23:35 | joshua-choi | But anyways, it seems that there's currently no standard way to transform a map's vals easily, which is annoying |
| 23:35 | joshua-choi | Oh well |
| 23:35 | joshua-choi | (into {} (map ...)) |
| 23:35 | tomoj | I've run into that problem before as well |
| 23:35 | tomoj | and I think it's come up in here before |
| 23:36 | joshua-choi | I would think this would be a common thing to do with maps...:| |
| 23:36 | rdsr | hey 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:36 | rdsr | ? |
| 23:37 | powr-toc | http://www.innoq.com/blog/st/2010/04/clojure_performance_guarantees.html |
| 23:37 | sexpbot | "Clojure Performance Guarantees - Stefan Tilkov's Random Stuff" |
| 23:38 | rdsr | powr-toc: thanks |