#clojure logs

2011-12-29

04:02kral'morning
04:03CmdrDatsgood morning
04:05CmdrDatshey guys, i'm starting to use the whole (with-…) paradigm and have written a small (with-mail [config & body]) macro/function that binds *store* to the imap connection which you can then use in body...
04:06CmdrDatswhat bugs me though is that *store* is kindof invisible in local scope, you need to know more about the function than just analyzing the signature in order to use it
04:08CmdrDatsie - i have (with-mail config (print (take 1 (messages *store*))))
04:08CmdrDatsthoughts?
04:29hoeck1CmdrDats: as this is a typical 'close-resource-on-leaving-scope' situation, you could also use the builtin with-open macro: (with-open [store (get-connection)] ...code-using-store]) and make sure store has a .close method
04:30hoeck1CmdrDats: that would make it more readable by separating the 'close this resource' task and the 'bind resource to X' task
04:31CmdrDatsah, nice :)
04:31CmdrDatsdidn't realize the with-open worked like that, that's neat
04:33CmdrDatsluckily, this (get-connection) does have a .close - but what if the java object doesn't have .close (say it's .closeConnection or something stupid)?
04:34CmdrDatshoeck1: sorry - still trying to get used to prepending the name of the person i'm addressing in irc :P
04:34hoeck1you would have to write your own close (multi) method then
04:36hoeck1CmdrDats: my clojure skills are a bit rusty, I have to google for that first :)
04:36CmdrDatshoeck1: busy looking at http://clojuredocs.org/clojure_core/clojure.core/with-open
04:37CmdrDatshoeck1: can you multi-method the a dotted function like that? having a hard time imagining how
04:37CmdrDats(looking at the source of with-open
04:37CmdrDats)
04:39CmdrDatshoeck1: i suppose i get generate a little (proxy) that has a close method, but that doesn't seem very idiomatic clojure
04:40hoeck1yep, the multimethod won't work
04:41hoeck1CmdrDats: no, I think creating a proxy or using extend-type is the right way to go, especially when you interfacing with java classes
04:42hoeck1otherwise you probably would define your own type and implement the java.io.Closeable interface in the same way
04:43hoeck1or define your own interface or protocol that provides a close method
04:44CmdrDatshoeck1: awesome, didn't know the Closeable interface existed - i might use that :)
06:31wei_is there a version of "some" that returns the actual element, instead of (pred element) ?
06:46Raynes(first (filter odd? [2 2 2 1 4]))
06:46Raynes&(first (filter odd? [2 2 2 1 4]))
06:46lazybot⇒ 1
06:46Rayneswei_: ^
06:46Rayneswei_: This is no less efficient because filter returns a lazy sequence and you're only asking for the first element.
06:47wei_i see, i was wondering whether filter would go through the entire list
06:47RaynesNope.
06:47RaynesNo unnecessary computation is done.
06:48wei_&(first (drop-while odd? [2 2 2 1 4]))
06:48lazybot⇒ 2
06:48wei_&(first (drop-while #(not (odd? %)) [2 2 2 1 4]))
06:48lazybot⇒ 1
06:48Raynes&(even? 1)
06:48lazybot⇒ false
06:51dbushenkohi all!
07:26Blktgood morning everyone
08:17raekmidje-mode displays some messages like this: ^[[31mFAIL^[[m0
08:17raekanyone know how to fix that?
08:18raekapparently it tries to use terminal color escape codes in emacs buffers...
10:44TimMcraek: I think I remember something about those being added recently...
11:20kurtharrigeris it possible for leiningen to add extra class paths based on environment variables? :extra-classpath-dirs [(System/getenv "HBASE_HOME")] ?
11:33TimMckurtharriger: Don't tell technomancy I told you this, but you can add arbitrary code to project.clj files.
11:33TimMcso you could probably insert a variable.
11:34kurtharrigerhmm the above was never evaluated lein classpath | tr ":" "\n" contained (System/getenv "HBASE_HOME") instead of the value
11:34buduhi
11:34kurtharrigerthe hbase config folder needs to be in the classpath which works if I use the full path but the above did't
11:35kurtharrigerone workaround I have for now is just to create a symlink to the config directory
11:36budui was wondering about the best way to add a new map type
11:37budufor example using the Guava BiMap in the same way as an hash-map or sorted-map
11:37budufrom my understanding i would need to create a protocol overriding the map functions and dispatch from them
11:38buduis that correct or there's something i'm missing?
11:38TimMcbudu: Is that a persistent data structure?
11:38buduyup
11:38technomancy_kurtharriger: you can use unquote to add abritrary code, but it's kind of gross
11:39kurtharrigerok I'll try it
11:39kurtharriger :extra-classpath-dirs [~(str (System/getenv "HBASE_HOME") "/" "conf")]
11:39kurtharrigerperfect thanks!
11:40TimMc"Var clojure.core/unquote is unbound"
11:40technomancy_TimMc: inside defproject
11:40kurtharrigermaybe later I'll create add a :extra-classpath-env or something
11:41kurtharrigeralso does leiningen have any support for compiling languages other than java, namely groovy
11:41TimMctechnomancy_: I think it varies based on where in the defproject.
11:41technomancy_TimMc: as long as it's after the version it should be fine
11:42TimMctechnomancy_: Yeah, I discovered that (defproject adhoc ~(str "1.0." (rand-int 10) "-SNAPSHOT") ...) doesn't work.
11:42TimMcBut without the unquote it is fine!
11:42technomancy_kurtharriger: if there's an ant task for groovy compilation it should be easy to write one.
11:43technomancy_TimMc: oh weird. that's unintentional but kind of funny.
11:43kurtharrigeris it possible to implement languge additions as plugins or do plugins only allow addition of extra commands to cli
11:44TimMctechnomancy_: Now I'm imagining using Date there to version a project's releases. :-P
11:44technomancy_not sure what language additions means
11:44technomancy_kurtharriger: plugins can include defns etc if that's what you mean
11:44kurtharrigerlike :java
11:45TimMckurtharriger: You mean, custom field parsers for the project.clj?
11:45kurtharrigerif I add :groovy source dir to project have it compile all the groovy classes without having to go through ant to do it
11:45kurtharrigerno desire to write more groovy code just replace gradle with leiningen
11:45kurtharrigergradle is a POS
11:45kurtharrigerbut better than maven
11:46kurtharrigerin some cases
11:49technomancy_kurtharriger: what I mean is you could implement a wrapper for ant's groovy compilation using leiningen
11:50technomancy_and you could have it trigger on the compile task using a hook
11:50kurtharrigerah okay that sounds promising
11:50technomancy_look at how the lein-javac plugin is implemented I guess
11:50kurtharrigerI thought you meant write an ant.xml file and then could call that
11:50technomancy_nah, it's all programmatic
11:51kurtharrigersounds good then I'll try to do that this weekend if I have time then
11:57zawzeyClojureScript question. What's the proper way to create a Javascript associative map object?
11:57zawzeyI can only get it to work using (js* "{foo: 'bar', bar: 'foo'}")
11:58zawzeyI don't like this approach, but that's the only way to get interop with Javascript code it seems, for an object
12:09raekzawzey: I have barely used cljs myself, but I think there is a function called clj->js
12:09zawzeywell there's a js->clj function
12:09zawzeybut no clj->cs
12:10ibdknoxcorrect
12:10zawzeyanyway, there's a solution here: https://gist.github.com/1199718/107cc34620fa3a8284face3c3f7aa4439a565e45
12:11ibdknoxpinot has a simple map->js function
12:11zawzeyperhaps same as this: https://gist.github.com/1199718/fb9e16ac1ce261e0dac59db3b2b3c18f1c5f71cc
12:11zawzeythanks i'll check that out
12:13zawzeywell it's here: https://github.com/ibdknox/pinot/blob/master/src/pinot/util/js.cljs
12:42choffsteinHello all. Quick q: why does conj add to the front of a list and the back of a vector? Is it to try to maintain O(1)? I'm trying to figure out which will be faster to me -- conjing to a list and reversing, or conjing to a vector.
12:43shalesmrb_bk: have you tried bytebuffer?
12:44blcooleychoffstein: conjing to a vector should be faster
12:44choffsteinblocooley: Well, only if conjing to a vector is O(1), right?
12:45cgraychoffstein: if you are only adding one thing, then both are O(n)
12:45cgraychoffstein: (assuming you are starting with a list)
12:45zzachBrowser-based REPL from clojurescript is working OK with firefox, but is not connecting to Internet Explorer. Is it in principle possible to use it with IE?
12:45choffsteinHow can conjing to a list be O(n)? You're adding to the front? It should just be a cons...
12:46arohnerchoffstein: correct. They're both O(1), and yes, that's why it's at the front of the list and the back of the vector
12:46cgraychoffstein: you said conjing and then reversing
12:46choffsteinarohner: Thanks.
12:46cgrayI think technically, conjing to a vector is O(\log_{32} n)
12:47choffsteincgray: Right. I was just saying that if conjing a vector is O(n), then n O(n) operations will be slower than n O(1) operations followed by an O(n) operation
12:47cgraychoffstein: ahh, i see
12:48choffsteinWell … maybe the source will tell me?
12:49blcooleychoffstein: it's discussed in 5.2.4 of JoC
12:49blcooleychoffstein: "A small change, but the code is now a touch cleaner and a bit faster"
12:50blcooleychoffstein: that's a discussion of conjing to a vector versus conjing to a list and reversing
12:50choffsteinI'll check it out. Thanks.
12:54mrb_bkshales: i did play with it, yes
12:55mrb_bkshales: are you the author?
12:57choffsteinblcooley: That answered my questions. I would love to know the big-O notation … but I don't feel like digging through the code :)
13:00blcooleychoffstein: PersistentVector is here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java
13:00TimMc&(into () '(1 2 3 4 5))
13:00lazybot⇒ (5 4 3 2 1)
13:02blcooleychoffstein: it looks like it should be O(1) because it is setting an element in an array. There is the issue of making a copy of the array, but I think you'll find that Lists have the same overhead since it's for immutability.
13:02choffsteinyeah. Awesome.
13:03choffsteinThat is helpful. Thanks for poking around
13:03blcooleyyw
13:04cgrayblcooley: see line 460 or so
13:04cgrayif the tail is full, it creates a new node in a tree
13:10choffsteincgray: Hmm…seems strange to have vector be a tree. I'd expect a dynamic array that doubles in size everytime the end of the array gets hit. The only reason I could see using a tree is so that nth is O(logn) -- but a dynamic array would have nth being O(1) -- so that doesn't make much sense to me
13:10choffsteinThough, this Java code isn't very clear to me
13:10arohnerchoffstein: the vector is a tree, so that when you update the middle element, you only copy a constant number of items, rather than the whole tree
13:10shalesmrb_bk: sorry, was away for a bit. Yeah, I replied to your email on the lsit
13:10mrb_bkshales: cool!
13:11choffsteinAhhhh … right. Cloning.
13:11choffsteinForgot this was immutable data.
13:11choffsteinOkay, the tree makes WAY more sense now.
13:11mrb_bkshales: i especially like unpack-bits
13:11mrb_bkthink it would be cool to have in core
13:13shalesya maybe. I don't know if anyone other than me or you have used it =)
13:21mrb_bkshales: hehe word
13:21mrb_bkshales: have you used bytebuffer to lazily read from a binary file?
13:24shalesmrb_bk: no. I've only used it to pull apart and build network packets
13:25mrb_bkshales: ah cool
13:25mrb_bkshales: i was having a hard time getting it to work with files
13:26shaleswhat sort of trouble? I imagine you can read chunks of the file into a ByteBuffer and pull what you need from it with the library
13:26shalesI guess you'd have to be careful how much you read into the buffer if you don't know in advance where the boundaries between fields in the binary data are
13:28shalesmaybe a function that returns the number of bytes needed by one of pack/unpack's format string would be useful?
14:16kurtharrigeris it possible to reload java class files in clojure ie (import :reload '[com.some.java.package SomeClass])
14:18TimMckurtharriger: Looks like import doesn't take any keyword arguments.
14:18technomancyyou'd need a new classloader to do that
14:18kurtharrigeryeah, currently just killing and reloading swank when I recompile the groovy application
14:20kurtharrigerlooking to avoid gradle install; lein deps; lein swank... so I just pointed :extra-classpath-dir to my groovy app classes/main folder then I just need gradle compileGroovy and then restart swank
14:21sjl #haskell
14:23gf3technomancy: ping
14:23technomancygf3: what's up?
14:23gf3technomancy: when I install your clojure-swank as a standalone plugin, the generated script contains a hardcoded classpath
14:23gf3/home/phil/... or something
14:24technomancyhm; let me take a look
14:24gf3technomancy: http://cloud.gf3.ca/CwsE
14:24MenTaLguYhey guys
14:26MenTaLguYI'm wondering, is there a more idiomatic (or at least concise) way to do stuff like: (apply hash-map (map (fn [[key value]] [key (some-fn value)]) some-map))
14:26cgrayzipmap
14:26MenTaLguYbasically, take some map and transform the keys in it
14:26MenTaLguYhmm
14:27kurtharrigertechnomancy: I actually had an issue with the shell-wrapper when I tried it not adding the classpath to the resulting shell script so maybe its related
14:27technomancygf3: definitely a bug; can you open an issue?
14:28gf3technomancy: sure thing, thank you
14:28MenTaLguYcgray: so that would be: (zipmap (keys some-map) (map some-fn (values some-map))) ?
14:28cgrayMenTaLguY: or more precisely (zipmap (keys some-map) (map some-fn (vals some-map)))
14:28MenTaLguYah yeah, vals, not values
14:28MenTaLguYI guess that's a bit better
14:28MenTaLguYstill seems like there should be a more concise way to do it
14:29technomancyMenTaLguY: agreed; I'd love a map-keys and map-vals
14:30blergseems like it will always be a less efficient operation b/c of the need to recompute hashes / rebal trees / etc, depending on the underlying data structure
14:30blergmaybe that's why there's no ready made for it?
14:30pjstadigbut we're lisp hackers
14:30pjstadigwe know the value of everything and the cost of nothing
14:31blerg:) true dat
14:33gf3technomancy: https://github.com/technomancy/swank-clojure/issues/95
14:33gf3thanks again
14:34amalloy(into {} (for [[k v] m] [k (some-fn v)])) is another option, MenTaLguY
14:39technomancyprocessing? without org.clojars? really? =(
14:40amalloytechnomancy: was lein the first tool nudging clojure in the direction of "group name defaults to artifact name"?
14:41technomancyamalloy: it's not unheard of in java-land; particularly with projects that moved from ant to maven.
14:44pjstadigi think junit has a project-name-as-group-name
14:51TimMctechnomancy: What's the problem?
14:52technomancyTimMc: processing is a language and drawing toolkit; someone either published a random one-off fork of it on clojars masquerading as the original or is really bad at picking names and happened to collide.
14:52TimMcWhat are the semantics of using org.clojars.foo/*?
14:53TimMcDoes that just mean "this is my local fork"?
14:53TimMcs/local//
14:54technomancyright
14:54raekTimMc: yes. foo's personal fork.
14:55TimMcWhere org.clojars.foo is just some namespace that the user owns, yeah?
14:55TimMcSo org.timmc would be equivalent.
14:55amalloythat seems unnecessarily specific. you can have a personal fork with a different name, or use org.clojars.foo/libname as the canonical name because you disagree with the libname/libname pattern
14:56technomancyit's a matter of communicating to potential consumers
14:57pjstadigand presumably there's a way to manage transitive dependencies that you want to use org.clojars.foo/libname instead of what the real group is?
14:58technomancyno, unfortunately you need to use exclusions
14:58technomancythere's really no good existing solution for nonlinear versioning in dependencies
14:58technomancyin any language
15:08cemericktechnomancy: so, does easy s3 deployments from lein mean we can close the book on e.g. org.clojars.name/foo?
15:56TimMccemerick: Why would that be?
15:56blakesmithIs there an easier way to convert keywords to their string representation without the leading colon?
15:56blakesmith&(apply str (drop 1 (str :hello)))
15:56lazybot⇒ "hello"
15:57emezeske&(name :hello)
15:57lazybot⇒ "hello"
15:57TimMccemerick: There are plenty of things on clojars that aren't personal projects.
15:57blakesmithemezeske: Perfect, thanks!
15:57emezeskeblakesmith: NP
15:57TimMc$findfn :name "name"
15:57lazybot[clojure.core/name]
15:58cemerickTimMc: My understanding is that org.clojars.name groupIds should only be used for private forks of projects. Making it hard for others to find such artifacts is a good default, IMO.
15:59quizmewhy does the handler function of the ring tutorial need to be a var?
16:01cemerickquizme: it doesn't need to be, but providing a var allows changes you make at the REPL, etc. to be available without restarting the HTTP server.
16:02quizmecemerick i see thank you
16:03quizmecemerick: so it sort of makes it like a "global" across different threads(?)
16:03technomancycemerick: well the stuff I added was really only for private deploys
16:03technomancyyou've been able to do public s3 deploys since forever; it's just a matter of docs
16:04chouserwell, I finally pushed TractionSVG out there, for anyone interested: https://github.com/chouser/tractionsvg
16:04technomancycemerick: I think in most cases putting them on your own s3 bucket is better for clutter reduction, but I want to wait till I've solved the nasty chicken/egg problem before switching all lein's docs to recommend that approach.
16:05cemericktechnomancy: sure; I'm agitating. ;-)
16:05cemerickquizme: all vars are "global" across threads :-)
16:05cemerick(except for those created with `with-local-vars`)
16:06technomancyhush
16:07hiredmanchouser: neat
16:08technomancy,(alter-meta! #'with-local-vars update-in [:doc] (partial str "Warning: don't use this unless you know what you're doing.\n"))
16:08clojurebot{:macro true, :ns #<Namespace clojure.core>, :name with-local-vars, :arglists ([name-vals-vec & body]), :added "1.0", ...}
16:08technomancyholy crap; that worked
16:08technomancynot sure how I feel about that
16:09technomancyhiredman: might want to take a look at that. =)
16:10chouserhiredman: thanks. It certainly doesn't rate more than that yet.
16:11chouserall named vars
16:15choffsteinHey all. I've read that to speed up your clojure code, you should try to make as few "intermediate" objects as possible. In an iterative version of the code base (in Ruby), I iterate over data and mutate values in place, where computations rely on data computed in previous iterations. In clojure, I end up `mapping` over the data for the different computations I need, then combining them at the end. This seems to create a lot of
16:15choffsteinunecessary objects. If I really want to speed it up, should I just go transient and use a reduction style loop? I've already done as much type-hinting and profiling and algorithm restructuring as I think I can -- and the ruby code still seems to about about 1.5-2x faster.
16:16technomancychoffstein: transients will help if the slowness is caused by GC
16:16technomancyuntil you profile you're in the dark
16:17technomancythat said, if you're 2x slower than ruby it's likely to be something a bit more obvious
16:17technomancyare you letting the JIT warm up and excluding JVM boot time?
16:17choffsteinHmm. My profiling skills with JVisualVM are still beginnerish. Know if I can see how the GC is behaving
16:17choffsteinNot really letting the JIT "warm-up" per-se … just yes on excluding JVM boot time
16:19cmeierchouser: thumbs up for tractionsvg
16:20tmciverchouser: tractionsvg looks very cool
16:26choffsteinOh, wow -- I did a dotimes and let the JIT warm up. The clojure code sped-up by almost 4-5x. Yikes.
16:26choffsteinThe majority of the code is still taken up my invokeMatchingMethod though. Arg. As far as my code tells me, all the reflections are in other libraries...
16:28technomancyouch
16:29technomancychoffstein: did you get a chance to try out https://github.com/heroku/heroku-buildpack-clojure/tree/private-repo?
16:29choffsteinYeah! It's awesome!
16:29technomancyexcellent
16:29choffsteinI thought I had PMed you. My apologies if I didn't. You're a life-saver. Awesome solution to my problem
16:30technomancyno worries; my bouncer isn't 100% reliable, so PMs are sometimes lost.
16:30choffsteinI had a little clojure app up using redis, resque, background workers and mongodb in like … 6 hours. It was unbelievable.
16:30technomancyhow do you like resque?
16:31solussdtechnomancy: could you point me at current instructions on how to install swank-cljure/slime-clj/clojure-mode, etc with the emacs-starter-kit? I've had this set up on my personal machine forever, but can't seem to get things going at work-- running M-x package-install with the various packages fails or complains that <whatever> already exists. :/
16:32technomancysolussd: I think the swank-clojure readme has everything you need. you can do a manual install of clojure-mode if the package manager is giving you grief.
16:32TimMctechnomancy: hiredman has known about alter-meta! being allowed since forever. *shrug*
16:32solussdtechnomancy: oh, so I shouldn't install swank-clojure via elpa?
16:32TimMcI think that's why clojurebot restarts every 15 minutes.
16:33technomancysolussd: yeah, that is way out of date
16:33choffsteinWhat amazes me is that in running my huge program like … 50 tims, invokeMatchingMethod takes 99.99999% of the time with only 144 invocations.
16:33technomancysolussd: clojure-mode is the only thing required on the elisp side these days
16:34lypanovchoffstein: accumulative?
16:34choffsteinlypanov: Sorry, I don't understand the question
16:35lypanovchoffstein: just wondering if the profile output is inclusive or exclusive.
16:36choffsteinlypanov: inclusive or exclusive of what?
16:36mcrittendendo I have to install maven to get clojure contrib?
16:37lypanovchoffstein: time, i assume invokeMatchingMethod is the caller. if its inclusive then 99.999 makes sense.
16:37lypanovjust ignore me :)
16:37choffsteinlypanov: oh. Yeah, I think invokeMatchingMethod is the caller and it is inclusive.
16:38choffsteinIt measures "self time"
16:42AeroNotixanyone used clojure with minecraft?
16:43cemerickAeroNotix: I've seen blog posts where those words were in proximity. No idea if they were any good or interesting though.
16:43TimMcYeah, I built a JVM using redstone.
16:43AeroNotixTimMc: LOL
16:43AeroNotixTimMc: About as memory efficient as well?
16:45TimMcActually, I've never played the game.
16:48skelternetI think I'm doing it wrong.
16:49SomelauwWhat is the quickest way to just make use of all functions in clojure.string? Something like (import clojure.string)?
16:49TimMcSomelauw: (require '[clojure.string :as s])
16:50TimMcSomelauw: or (use '[clojure.string :only (foo bar etc)])
16:50quizmeSomelauw: (use 'clojure.string)
16:50TimMcquizme: Bad!
16:50TimMcOnly use use with only*
16:51TimMc* Except clojure.test and the namespace under test in your test files.
16:51hiredmana use like that is not the best idea
16:52hiredmanclojure.string may have some functions that are the same name as clojure.core
16:52hiredman(require '[clojure.string :as str]) or (:require [clojure.string :as str]) in your ns form
16:52skelternetShould I be using a protocol to bundle up various related functions , each of these bundles a particular implementation of a known set of abstract functions? Doesn't that sound like a protocol? or should I relax and toss a bunch of curried functions into a map. That seems ugly.
16:52SomelauwThanks, it works
16:54SomelauwI think directly using "use" is useful when testing it in a repl.
16:55TimMcOh yeah, the REPL is a fine place for it.
16:58skelternetI'm expecting to have to swap out the implementations based on user-specified configuration
16:59technomancyskelternet: if you use a protocol you'll be forced to dispatch on the first argument of every function. if that will result in an awkward API and you don't need crazy-fast dispatch, you probably shouldn't use protocols.
17:00technomancymultimethods are a bit slower but can dispatch on anything; doesn't even have to be an argument
17:00skelternetI will be concerned about performance later, after I measure it and discover I am concerned about it. For now, I'd like a clean API to speed development.
17:01technomancyvery few things in practice are bottlenecked on method dispatch (modulo reflection, which is easy to solve anyway)
17:01skelternetMy main concern is not wanting to change the client code.
17:04skelternetclojure's given me several options that satisfy that.
17:05skelternetI started down the protocol route since it seems like the most likely to satisfy separating the implementations of this API from the API and it's clients.
17:07skelternetit is familiar behind the scenes: Java interfaces. but more involved.
17:07hiredmanI have a macro somewhere, that lets you write something that sort of looks like a multimethod, that generates a static cond + a check to see if the static cond is still valid
17:08hiredmanand falls back to a multimethod if the static cond isn't valid
17:08hiredmanit is ugly
17:09mcrittendenTimMc: does the "only use 'use' with 'only' rule apply here: https://github.com/ibdknox/Noir-blog/blob/master/src/noir_blog/views/blog.clj#L2
17:17mdeboardAnyone have an idea off-hand where to find a quote rhickey made that I cannot recall about performance not mattering if your data wasn't reliable?
17:18emezeskeBoy I wish Clojars had a field for linking to the repo from which a jar was built...
17:18emezeskeI might need to work up a patch for that
17:18skelternetdata not reliable as in quality or not always available, as in waiting to come back from storage?
17:18scottjemezeske: :url in project.clj?
17:18pandeiromcrittenden: i think 'only use use with only' is only enforced in ClojureScript
17:18emezeskescottj: awesome!
17:19emezeskescottj: that just needs to be on the web UI somewhere
17:19scottjemezeske: it is displayed if that's what you mean
17:19scottjemezeske: but if it were in instructions or some way to make it more popular might be nice
17:20emezeskescottj: ah, I guess most projects must not fill it in then
17:20emezeskescottj: including mine X_X
17:20emezesketime to fix
17:21ordnungswidrigemezeske: one should crawl clojars and send warnings to the owners of projects without url.
17:21emezeskeordnungswidrig: I love that idea
17:21emezeskeAlso, what's up with people having their open-source projects depend on random jars that are not hosted anywhere? PAIN
17:22ordnungswidrigemezeske: drop from clojars ;-)
17:22scottjemezeske: getwoven?
17:22emezeske*the source code for which is not hosted anywhere
17:22emezeskescottj: what's that?
17:23technomancyemezeske: wouldn't hurt to have it filled out as a FIXME in the default project.clj emitted by lein
17:23technomancyeasy pull request; hint hint
17:23scottjemezeske: a team that sometimes does that
17:23emezeskescottj: ahh, gotcha
17:23emezesketechnomancy: :) adding to my list
17:26ordnungswidrigwhich hash functions does assoc/PersistentArrayMap use?
17:26ordnungswidrigobject/hashcode?
17:27scottjtechnomancy: do you prefer "FIXME: project url" or ""?
17:28scottjor write url
17:28TimMchttp://www.example.org/FIXME
17:28technomancyscottj: probably best to leave it commented out; something like ;; :url "http://FIXME&quot;
17:28amalloyno, link it somewhere really offensive so they're incentivized to fix it
17:28technomancyamalloy: early versions of hoe (a ruby gem generator) attributed all libraries to the author of hoe
17:29technomancybut he got sick of all the bug reports
17:29ordnungswidrigtechnomancy: hehe
17:30TimMchoist in his own petard
17:30scottjtechnomancy: pull sent
17:30TimMcs/in/with/ I guess
17:31technomancyscottj: excellent
17:31ordnungswidrigI once returned from holidays to notice 1e5 new emails in my inbox. Now I stay away from mail-sending logging handlers.
17:31scottjtechnomancy: I'd wanted this for a long time but figured you'd considered and rejected it :)
17:31technomancyemezeske: if you still want to get a patch in (which qualifies you for commit access as well as a sticker) you could backport scottj's commit to the 1.x branch =)
17:32scottjordnungswidrig: some dude once returned from holidays to find 3e6 of his emails posted on bittorrent
17:32scottjtechnomancy: I'll be collecting my sticker on seajure next week :)
17:32ordnungswidrigscottj: bittorrent ist the new imap.
17:33hiredmanordnungswidrig: on 1.4-SNAPSHOT it uses a custom hash function, which in most cases falls back to .hashCode
17:34lypanov(502s yay)
17:34emezesketechnomancy: I might get to it!
17:35technomancyscottj: uh oh... I may be out of stock.
17:35technomancybeen meaning to order a fresh batch with the high-res image
17:37ordnungswidrighiredman: I was just wondering because of this http://events.ccc.de/congress/2011/Fahrplan/events/4680.en.html
17:37scottjtechnomancy: no worries
17:38scottjtechnomancy: sticker 2.0 for new release
17:39hiredmanordnungswidrig: yeah, I don't imagine rich moving fast on that
17:40ordnungswidrighiredman: in a web context: easy to fix for request headers but hard to check request bodies that are parsed as json/xml and like that I suppose.
17:41hiredman*shrug*
17:42hiredmanthe report I saw mentioned web requests, but really any kind of transport would do
17:42hiredmanmost message queues get used to more or less pass around maps
17:42ordnungswidrigunix comes to help by limiting processing time. But the monolithic java servlet model is a burdon here.
17:43hiredmanuh
17:43ordnungswidriglimiting thread runtime in java, anyone?
17:43hiredmanreally?
17:43ordnungswidrigone cannot, right?
17:54ordnungswidrigscary: ,(let [l 10 s (apply str "bB" (repeat l "a"))] s (for [i (range l)] (let [s (apply str (concat (take i s) (drop i s)))] [s (.hashCode s)])))
18:00kd4joaI was wondering if anyone could help me with a problem I'm having trying to use the Lucene java library. It seems like an easy question, but I'm not finding the answer
18:01kd4joaI have an object that is a TokenStream. I have to call incrementToken() on it in order to get all the tokens from the string one at a time
18:01kd4joaeach time that is called I need to get the value of that token from a TermAttribute object using its term() method
18:02kd4joaquestion is how to call incrementToken() until it's false, gather up all the tokens and create a vector out of them
18:03kd4joaI tried doing it in a "while" and can get at the tokens inside the while, but it of course returns nil and I can't figure out how to collect the terms up.
18:03kd4joacan someone point me in the right direction?
18:03hiredman(repeatedly #(doto ts .incrementToken .getTermAttribute))
18:03amalloyhiredman: .getTermAttribute goes outside the doto, right?
18:03raekkd4joa: one basic way is to use loop and recur. keep the collection of tokens that you build up as one of the loop variables
18:04hiredmanamalloy: I have no idea
18:04hiredmanhttp://lucene.apache.org/java/3_0_3/api/all/org/apache/lucene/analysis/TokenStream.html
18:05hiredmankd4joa: your best solution is to write something like enumeration-seq which takes a tokenstream and turns it into a lazy seq
18:05amalloyheh. well, i don't either; his description is obviously not very clear. but i was thinking more like (map #(.getTermAttribute %) (take-while identity (repeatedly #(.incrementToken ts))))
18:06kd4joasorry. how can I help make it more cleaer
18:07raekkd4joa: when .incrementToken returns true, what do you need to call to get the token?
18:08kd4joa(.term termatt) will give me the token (termatt is a TermAttribute)
18:08kd4joahere's a working function that prints the token each time through the while: https://gist.github.com/1536626
18:10raekkd4joa: I would make a lazy sequence like this: https://gist.github.com/1536636
18:10clojurebotPardon?
18:11ordnungswidrigkd4joa: comment written
18:11ordnungswidrigkd4joa: simple fix using a atom a temp result holder.
18:12ordnungswidrigI don't feel too dirty bacause the java objects already are mutable as hell
18:12kd4joaheh, no kidding
18:12raekkd4joa: a non-lazy variant: https://gist.github.com/1536637
18:12kd4joathanks to both of you. both approaches look like they should work
18:13raekordnungswidrig: no need to use the concurrency primitives when you can use simple recursion in this case
18:13kd4joathanks. I had started looking at atoms (never used them before), but it seemed like there should be an easier way
18:13amalloy(take-while identity (repeatedly #(when (.incrementToken tokenstream) (.term termatt))))
18:15kd4joawhat makes repeatedly stop there? I thought it returned an infinite sequence
18:16amalloy(take-while ...)
18:17raekit would be neat to have a "unfold" ("unreduce?") in clojure.core
18:17kd4joahmm. I'll have to play with that a little to understand it
18:17amalloyraek: maybe. i implemented unfold, and it seems like i've never found a case where using it was simpler or easier than not using it
18:18kd4joathanks to all of you for the pointers. It'll take me a bit to understand each of the different approaches. So much to learn...
18:18hiredman(fn f [ts ta] (lazy-seq (when (.incrementToken ts) (cons (.term ta) (f ts ta)))))
18:20jhirnWhat's the quickest way to move a file from one path to another creating the directories if needed?
18:20TimMcquickest to type?
18:20TimMcrsync
18:21jhirn=), prefer to keep it java'ish for cross platform.
18:21hiredmanhttp://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/FileChannel.html#transferTo%28long,%20long,%20java.nio.channels.WritableByteChannel%29
18:21jhirnwas shelling out to mv,
18:21jhirnbut need to mkdir -p... then i figured there might be a move-file somewhere.
18:22hiredmanyou'll need to call .mkdirs on the target files parent directory yourself
18:22technomancy.mkdirs on j.i.File is mkdir -p
18:22technomancyoops; too slow
18:23hiredmanbut transferTo or transferFrom should be faster than anything else on the jvm
18:23jhirnAh, so I must creat files... I need mv -p like a mofo right now.
18:23hiredmancreate files?
18:23jhirnmoving from one place to another.
18:23jhirnfor a git utility i'm working on to make renames out of delete/new pairs.
18:24jhirnwas doing a simple , reset-> mv -> git mv but mv is failing due to directory not being there.
18:24jhirni supposed it's easy enough to shell out a mkdir -p
18:25jhirnthen that whole dot the right thing started conflicting with the right now thing....
18:33hiredmanchouser: it would be neat if analemma could be used to generate traction svgs
18:33hiredmanhttps://github.com/liebke/analemma
18:35solussdwhat's the best way to convert a record into a hash-map? currently I use (into {} (vec my-record))
18:38sandboxhello, is this a place to ask questions about clojure?
18:39amalloywell, that's one so far. i guess the answer must be yes
18:45sandboxsorry i was just wondering about namespaces. in particular how do i add functions to an already existing namespace, and is it good practice to do that in project
18:45sandboxwhen i don't intended to add that function to the library later
18:51technomancysandbox: yeah, definitely don't want to change namespaces you don't control
18:59sandboxokay that helps. what i'm still wondering is how to do what is done in clojure/core (defines the namespace) and clojure/core_deftype.clj (uses in-ns to add more to core). i'm getting a "unable to resolve symbol: defn" error when trying to add functions to another namespace. i'm guessing there is something wrong with my build settings but i'm not exactly sure what
18:59technomancythe stuff done by core_deftype.clj shouldn't ever be done in user code
19:00technomancyit gets a pass because it has to bootstrap a bunch of crazy stuff
19:05sandboxokay that makes that clear thanks
19:12flognikrsandbox: have you looked into Clojure's protocols as a mechanism for extending types?
19:17sandboxi wasn't dealing with any type but wanted to add a function to a namespace that wasn't mine because it seemed to make sense to put it in that particular namespace. i'm just building a simple web app, using noir, and in noir.response they've defined some functions for different types of responses. i just wanted to add a response that added some things to the header
19:21flognikrsandbox: ok, that helps me understand your use case better.
19:21sandboxi should have probably started with that information sorry if it was unclear
19:23flognikrsandbox: no problem at all
20:31fryguywhat do people prefer for REPL in vim? slimv or VimClojure?
20:32devni think most everyone i know uses vimclojure
20:52technomancyhttp://p.hagelb.org/slime-compile-presave.el.html
20:52technomancy^ so this hook will attempt to compile the current buffer when you save and refuse if it doesn't compile
20:52technomancyis this awesome? [y/n]
20:53Kowboyy
20:54Kowboynow I just wish I could get M-x clojure-jack-in working on NT Emacs so I can use it at work ;-P
20:54KowboyI use Ubuntu at home though (a proper emacs system), so I'm happy here ;-)
20:56KowboyIn general, what is the status of clojure contrib for 1.3? I see someone has moved clojure.contrib.http.agent into clojure.contrib.io, but it's not in any public repo yet.
20:57Kowboyor is there a better/alternative lib I should be using for HTTP requests?
20:57hiredmanclj-http
20:57technomancyand clojure.java.io
20:57hiredmanhttps://github.com/dakrone/clj-http
20:58technomancyerr--misread that
21:21augustlhi folks. Is leiningen the de facto way of managing clojure projects? I'm new to the jvm and java and compiled languages in general
21:21TimMcyep
21:22augustlTimMc: thanks :)
21:22TimMcaugustl: You may see references to Cake here and there, but it is being merged into Leiningen, sort of.
21:25augustlTimMc: ah, I see
21:26augustlLeiningen seems simple enough. Just created a project, unlike maven it didn't download the internet
21:27amalloylein uses maven, so you'll be getting some internet before long
21:27amalloybut clojure has very few (zero?) dependencies, so you just need the jars you're using yourself
21:28augustlah
21:29emezeskeHmm... I have a project that works fine when I run it with 'java ...' (specifying lib/ as my classpath, etc), but explodes in mysterious ways when run via 'lein run'.
21:29emezeskeAnyone have any tips on where to start on debugging such a problem?
21:30emezeske(I should add that to make the 'java ...' invocation work, I add "(apply -main *command-line-args*)" to my main source file)
21:42TimMcemezeske: What is one of the mysterious ways?
21:42TimMcMaybe there's some AOT difference.
21:43emezeskeTimMc: Exception in thread "main" java.lang.RuntimeException: java.lang.AssertionError: Assert failed: Can't recur here
21:43emezeskeThat's coming out of the clojurescript compiler
21:43TimMcAh, I've seen that!
21:44emezeskeYeah, I see some references to it on the noir lists
21:44emezeskeBut I don't see any solutions
21:44TimMcLet me chcek my logs...
21:44emezeskeThanks!
21:45pandeirodamn my swank is broken again
21:46TimMcemezeske: Ah yes, when I was hacking on try-cljs. For a while, the first evaluation would throw that assertion error, and all subsequent evals would succeed (until restart.)
21:47TimMcAnd now it doesn't do it. -.-
21:47emezeskeYeah, it's throwing that error when compiling core.cljs
21:48emezeskeAfter it's compiled, I think the js output is cached and used again (hence no error on try 2)
21:48pandeiro"error in process filter: symbol's function definition is invalid: slime-output-buffer"
21:48emezeskeFor me, it never fails when I run via "java ...", and always fails under "lein run"
21:49emezeskeI'm guessing it's some kind of weird class loading thing
21:49pandeiroweird part is i get the success message (Take this REPL brother etc), but no *slime-repl* buffer
21:49TimMcemezeske: Well, throw in a memoized (try compile (catch ...)). :-P
21:50emezeskeHah! :)
21:50emezeskeI'd actually consider doing that, but for me it fails 100% from lein run
21:50emezeskeEven the second time..
21:52TimMcemezeske: So, if you (do (try (compile-stuff) (catch ...)) (compile-stuff)) it fails on the second one too?
21:52emezeskeTimMc: I think so, checking right now to be certain
21:53emezeskeTimMc: yep, that fails too
21:54TimMcFascinating.
21:54emezeskewith the same error
21:55emezeskeThe thing that's really throwing me off is that things fail in the same way if I create an uberjar and run that
21:55emezeskeI'd think that would run things very closely the same way as when I run "java ..."
21:56DerGuteMoritzhello everyone, how can I use one of the eval bots in here? I'd like to get feedback on something
21:57TimMcemezeske: I can't reconcile that with what I was seeing, but I bet it's an AOT-ish thingy.
21:57emezeskeTimMc: Yeah, that sounds probable. Thanks for your input!
21:58emezeskeYeah... I don't either. I moved as much stuff as possible out of my (:gen-class) namespace to hopefully avoid problems :P
21:58TimMcIt's infectious though, right?
21:58emezeskeAh, I did not know that
21:58TimMcI don't either.
21:59TimMcI just *think* it.
21:59emezeskehaha
21:59tmciverDerGuteMoritz: comma as first character followed by valid Clojure:
21:59tmciver,(+ 2 2)
21:59clojurebot4
22:00DerGuteMoritztmciver: ah, thank you
22:00DerGuteMoritzso there:
22:00DerGuteMoritz,(symbol? (symbol "123"))
22:00clojurebottrue
22:00DerGuteMoritz,(symbol? (read-string (pr-str (symbol "123"))))
22:00clojurebotfalse
22:00DerGuteMoritzis this a read/write inconsistency or am I missing something?
22:02tmciverDerGuteMoritz: looks like pr-str is just producing "123", which is not a symbol?
22:02DerGuteMoritztmciver: that's right
22:03TimMcDerGuteMoritz: Sort of. That round-trip is only valid for literal expressions, I believe.
22:03TimMcSince '123 is 123...
22:04DerGuteMoritzseems like there is no external representation for symbols which consist of digits only
22:04TimMcCorrect. That's because symbols are supposed to name things.
22:05TimMcand names are restricted to a certain set of characters.
22:05DerGuteMoritzsymbols containing spaces are even worse
22:05DerGuteMoritzok then the symbol function should reject such strings
22:05amalloy"should" is a strong word
22:05TimMcThere's a forward-compatibility problem there.
22:06DerGuteMoritz"must" is even stronger :-)
22:06amalloythe expectation is that (pr-str (read-string x)) results in x - if your input to pr-str can never be a valid result from read-string, it's not reasonable to expect read-string to be able to read it back
22:07TimMcHmm, that's right -- there are two round-trips possible.
22:07amalloy(read-string (pr-str x)) resulting in x is a much more difficult task
22:07amalloyand all over the language that fails. ##(pr-str (java.util.Date.)) sure can't be read back in
22:07lazybot⇒ "#<Date Thu Dec 29 19:08:49 PST 2011>"
22:08DerGuteMoritzamalloy: that's right, but the reader will error on that one
22:09DerGuteMoritzhmmm
22:09amalloyso? the requirement (and here i'm inventing requirements, these aren't in the API docs afaik) is that (pr-str (read-string x)) "works". if you try to do something else, behavior is undefined. sometimes exception, sometimes unexpected output, sometimes explosions
22:09DerGuteMoritzagreed
22:09amalloyif clojure had to babysit and hand-hold every time you called the symbol function, or the keyword function, or the...things would slow down
22:10tmciverread-string is typically used to read a string of valid Clojure to be passed to eval, yes?
22:10DerGuteMoritztmciver: it just reads a datum from a string, you can do with it whatever you want
22:12DerGuteMoritzamalloy: it just seemed inconsistent to me but I agree that since you can't read in a symbol consisting of numbers or spaces it doesn't have to be possible to write them out, too
22:12TimMcDerGuteMoritz: It used to bug me a bit that nil can't be a symbol: ##(map class '[nil true foo])
22:12lazybot⇒ (nil java.lang.Boolean clojure.lang.Symbol)
22:12DerGuteMoritzhmmm indeed
22:13DerGuteMoritz,(name 'nil)
22:13clojurebot#<NullPointerException java.lang.NullPointerException>
22:13DerGuteMoritz:-/
22:13TimMcThat's not true in Scheme, where #t and #f are the boolean literals.
22:13DerGuteMoritz,(name (symbol "nil"))
22:13clojurebot"nil"
22:13DerGuteMoritzsomething seems off there
22:14DerGuteMoritzTimMc: yeah, I'm coming from Scheme which is why I'm kind of used to these kinds of edge cases being specified :-)
22:14DerGuteMoritzamalloy: what is your take on the nil issue?
22:15amalloyit's kinda weird
22:15DerGuteMoritzlooks like an implementation detail shining through
22:16amalloymeh. what is (true false)? is it a list of two symbols, which happen to refer to booleans, or is it a list of booleans?
22:17DerGuteMoritzamalloy: depends on the quoting
22:17DerGuteMoritzah, same issue here:
22:17DerGuteMoritz,(name 'true)
22:17tmciverright, how's the reader to know if you meain your symbol nil or the value nil?
22:17clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.Named>
22:17TimMcDerGuteMoritz: Not implementation, it's a philosophical diff.
22:17DerGuteMoritztmciver: well, how does it know in this case: (list 'list)
22:18amalloyuhhh, because list is not a language primitive with a special type
22:18TimMcDerGuteMoritz: You're never going to name something "nil", "true", or "false". Symbols are for naming things.
22:18amalloyit's an ordinary symbol, naming a function defined in clojure.core
22:18DerGuteMoritzTimMc: special cases ...
22:18TimMcYeha, I know.
22:19TimMcIt took me a while to be OK with it.
22:19tmciverDerGuteMoritz: flierting with disaster
22:19DerGuteMoritzamalloy: yes, and when quoted it is just that symbol
22:19DerGuteMoritztmciver: hm?
22:20amalloyDerGuteMoritz: so what's your point? list is a symbol, true is a boolean. they behave differently unquoted, and they behave differently quoted
22:20tmciverDerGuteMoritz: why would you ever need to name your symbols nil, true or false? Sounds like a problem waiting to happen.
22:20amalloythey look "similar" to our eyes because they're made up of letters
22:20DerGuteMoritzwhy does 'true resolve to the boolean true value but 'list not resolve to the list function?
22:20amalloybut 4 behaves just the same as true, in all of these cases
22:21TimMctmciver: My only concern is automatic code generation, but we have gensym to take care of this stuff.
22:21DerGuteMoritztmciver: it's a question of consistency rather
22:21amalloyDerGuteMoritz: when you quote a literal, you get that literal back
22:21TimMcDerGuteMoritz: Compare all this with (4) vs. '(4) vs. [4] vs. '[4].
22:21amalloy&['4 'true 'nil 'list]
22:21lazybot⇒ [4 true nil list]
22:21DerGuteMoritzit's a matter of special cases
22:21amalloyDerGuteMoritz: you can say that all you want
22:22amalloythe "special case" is that you want every sequence of letters to be a symbol, and some of them aren't
22:22amalloysad, perhaps, but true, and no further inconsistencies arise once you get past that
22:22DerGuteMoritzsure, it's just a matter of getting used to and avoiding the edges
22:25technomancythere was a ticket open back in the google code days for symbol and keyword to enforce readability
22:25DerGuteMoritztechnomancy: interesting, do you know how it was resolved?
22:26technomancyI patched it, and the patch was ignored
22:26technomancywhich started a long tradition
22:27DerGuteMoritzof people creating the same patch over and over again? :-)
22:27pandeirotechnomancy: did swank-clojure 1.3.2 also place a swank folder in .emacs.d/ with the compiled slime files?
22:27technomancypandeiro: I think that was new in 1.3.3
22:29amalloyof people ignoring technomancy's patches, i assume
22:30kenthI'm on the macro chapter in JoC, what does ~@ do?
22:30DerGuteMoritzperhaps technomancy didn't fax in the paperwork
22:30amalloy&(let [x [1 2 3] y [4 5 6]] `(~@x ~y))
22:30lazybot⇒ (1 2 3 [4 5 6])
22:31DerGuteMoritzkenth: if you know scheme: it's the same as unquote-splicing
22:31tensorpudding~@ splices a list
22:31clojurebotIt's greek to me.
22:31tensorpuddingwell, a collection
22:33DerGuteMoritzhm, can somebody explain this:
22:33DerGuteMoritz,['foo]
22:33clojurebot[foo]
22:33DerGuteMoritz`[foo]
22:33DerGuteMoritz,`[foo]
22:33clojurebot[sandbox/foo]
22:33DerGuteMoritzwhy is the symbol resolved with `? is it because ` is meant to be used for syntax only?
22:34DerGuteMoritzs,resolved,qualified,
22:35ldhi've got a map (data structure) which i process with map (function), which produces a lazy seq of MapEntry. how can i turn that back into a map?
22:35DerGuteMoritzif so, is there a syntactic way to splice a list or vector of symbols outside of macros then?
22:35technomancyldh: (into {} (map f x))
22:35ldhtechnomancy: ah, thanks
22:36DerGuteMoritz(a list of unqualified symbols, obviously)
22:37technomancyDerGuteMoritz: syntax-quote can be used outside macros
22:37DerGuteMoritztechnomancy: yeah but it qualifies symbols
22:37DerGuteMoritz,`(foo ~'foo)
22:37clojurebot(sandbox/foo foo)
22:37technomancyoh right; not paying attention here
22:38DerGuteMoritzno problemo
22:38tensorpuddingit's just a reader macro
22:38DerGuteMoritzyes
22:38DerGuteMoritzbut apparently it can't be used for a list of unqualified symbols
22:39DerGuteMoritzaha, perhaps thus hiccup's choice of keywords rather than symbols
22:39DerGuteMoritzI wondered about that the other day
22:43kenthwhy are there two quoting forms?
22:44DerGuteMoritzkenth: the ` form allows "unquoting", i.e. inside the quoted form you can switch back to evaluation
22:45DerGuteMoritzkenth: Conrad Barski has made a nice illustration of that: http://lisperati.com/backquote.jpg (except in clojure, unquoting is done using ~)
22:50kenthso ' does not allow unquoting?
22:50DerGuteMoritzthat's right
22:55amalloyhaving ` qualify symbols is also hugely helpful in avoiding unintentional symbol capture in macros
22:56amalloybut it's pretty rare you want to splice together a list *and* include literal symbols in it. if you just want to splice stuff together, you can write `(~@x ~y), which is the same as (concat x [y])
22:58DerGuteMoritzhm, indeed:
22:58DerGuteMoritz,(let [x 'foo] `(~x))
22:58clojurebot(foo)
22:59DerGuteMoritzI assumed that literal symbols behave the same in this situation
23:00DerGuteMoritzerr wait
23:00jhirnIs it wrong that I get the urge to write code instead of tests with Clojure? It feels illicit.
23:02DerGuteMoritzamalloy: the use case I have in mind is more like constructing a relatively complicated nested list structure with few unquotes, e.g. something like `(html (head (title ~title)) (body (h1 ~title) ~@body)
23:02DerGuteMoritz)
23:04amalloyyeah, hence keywords. clojure doesn't encourage the use of symbols as data when that data doesn't represent code you plan to execute, i think
23:04DerGuteMoritzyep
23:04DerGuteMoritzthus my enlightenment regarding hiccup above :-)
23:06DerGuteMoritzalas, something like ~@body in my example above is not possible with hiccup
23:06DerGuteMoritzbut not terribly missing either
23:06amalloysure it is
23:06amalloyit's not clear to me what you're saying is not possible, but i'm confident it's possible
23:07DerGuteMoritzamalloy: splicing into a vector literal
23:08DerGuteMoritzyou need to use concat, as you said earlier
23:08amalloy&(let [x [1 2 3]] `[foo ~@x])
23:08lazybot⇒ [clojure.core/foo 1 2 3]
23:08DerGuteMoritzyeah then you have to take care not to have symbols in there :-)
23:08amalloymore importantly, in hiccup you don't have to splice at all. it ignores lists, so [:foo (list 1 2 3)] is the same as [:foo 1 2 3]
23:09DerGuteMoritzthat's good
23:09DerGuteMoritzok thanks for the feedback guys
23:09DerGuteMoritzgotta get some sleep now, hard to keep the eyes open
23:09DerGuteMoritzgood night!
23:15sandy1986Hi, can anyone explain me how form validation in enlive works?
23:23TimMcsandy1986: I was not aware enlive had anything to do with that.
23:26sandy1986Mhh ... yeah
23:26sandy1986maybe I must use sandbar
23:28emezeske,*clojure-version*
23:28clojurebot{:major 1, :minor 3, :incremental 0, :qualifier nil}
23:28emezeske&*clojure-version*
23:28lazybot⇒ {:major 1, :minor 3, :incremental 0, :qualifier nil}
23:42mbacwhat's the most standard clojure csv parsing library?
23:48ldhhow does one compare lists in clojure? (compare '(1 2) '(3 4)) throws an exception
23:51ldhnm, = does it :-|