2011-12-29
| 04:02 | kral | 'morning |
| 04:03 | CmdrDats | good morning |
| 04:05 | CmdrDats | hey 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:06 | CmdrDats | what 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:08 | CmdrDats | ie - i have (with-mail config (print (take 1 (messages *store*)))) |
| 04:08 | CmdrDats | thoughts? |
| 04:29 | hoeck1 | CmdrDats: 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:30 | hoeck1 | CmdrDats: that would make it more readable by separating the 'close this resource' task and the 'bind resource to X' task |
| 04:31 | CmdrDats | ah, nice :) |
| 04:31 | CmdrDats | didn't realize the with-open worked like that, that's neat |
| 04:33 | CmdrDats | luckily, 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:34 | CmdrDats | hoeck1: sorry - still trying to get used to prepending the name of the person i'm addressing in irc :P |
| 04:34 | hoeck1 | you would have to write your own close (multi) method then |
| 04:36 | hoeck1 | CmdrDats: my clojure skills are a bit rusty, I have to google for that first :) |
| 04:36 | CmdrDats | hoeck1: busy looking at http://clojuredocs.org/clojure_core/clojure.core/with-open |
| 04:37 | CmdrDats | hoeck1: can you multi-method the a dotted function like that? having a hard time imagining how |
| 04:37 | CmdrDats | (looking at the source of with-open |
| 04:37 | CmdrDats | ) |
| 04:39 | CmdrDats | hoeck1: i suppose i get generate a little (proxy) that has a close method, but that doesn't seem very idiomatic clojure |
| 04:40 | hoeck1 | yep, the multimethod won't work |
| 04:41 | hoeck1 | CmdrDats: no, I think creating a proxy or using extend-type is the right way to go, especially when you interfacing with java classes |
| 04:42 | hoeck1 | otherwise you probably would define your own type and implement the java.io.Closeable interface in the same way |
| 04:43 | hoeck1 | or define your own interface or protocol that provides a close method |
| 04:44 | CmdrDats | hoeck1: awesome, didn't know the Closeable interface existed - i might use that :) |
| 06:31 | wei_ | is there a version of "some" that returns the actual element, instead of (pred element) ? |
| 06:46 | Raynes | (first (filter odd? [2 2 2 1 4])) |
| 06:46 | Raynes | &(first (filter odd? [2 2 2 1 4])) |
| 06:46 | lazybot | ⇒ 1 |
| 06:46 | Raynes | wei_: ^ |
| 06:46 | Raynes | wei_: This is no less efficient because filter returns a lazy sequence and you're only asking for the first element. |
| 06:47 | wei_ | i see, i was wondering whether filter would go through the entire list |
| 06:47 | Raynes | Nope. |
| 06:47 | Raynes | No unnecessary computation is done. |
| 06:48 | wei_ | &(first (drop-while odd? [2 2 2 1 4])) |
| 06:48 | lazybot | ⇒ 2 |
| 06:48 | wei_ | &(first (drop-while #(not (odd? %)) [2 2 2 1 4])) |
| 06:48 | lazybot | ⇒ 1 |
| 06:48 | Raynes | &(even? 1) |
| 06:48 | lazybot | ⇒ false |
| 06:51 | dbushenko | hi all! |
| 07:26 | Blkt | good morning everyone |
| 08:17 | raek | midje-mode displays some messages like this: ^[[31mFAIL^[[m0 |
| 08:17 | raek | anyone know how to fix that? |
| 08:18 | raek | apparently it tries to use terminal color escape codes in emacs buffers... |
| 10:44 | TimMc | raek: I think I remember something about those being added recently... |
| 11:20 | kurtharriger | is it possible for leiningen to add extra class paths based on environment variables? :extra-classpath-dirs [(System/getenv "HBASE_HOME")] ? |
| 11:33 | TimMc | kurtharriger: Don't tell technomancy I told you this, but you can add arbitrary code to project.clj files. |
| 11:33 | TimMc | so you could probably insert a variable. |
| 11:34 | kurtharriger | hmm the above was never evaluated lein classpath | tr ":" "\n" contained (System/getenv "HBASE_HOME") instead of the value |
| 11:34 | budu | hi |
| 11:34 | kurtharriger | the hbase config folder needs to be in the classpath which works if I use the full path but the above did't |
| 11:35 | kurtharriger | one workaround I have for now is just to create a symlink to the config directory |
| 11:36 | budu | i was wondering about the best way to add a new map type |
| 11:37 | budu | for example using the Guava BiMap in the same way as an hash-map or sorted-map |
| 11:37 | budu | from my understanding i would need to create a protocol overriding the map functions and dispatch from them |
| 11:38 | budu | is that correct or there's something i'm missing? |
| 11:38 | TimMc | budu: Is that a persistent data structure? |
| 11:38 | budu | yup |
| 11:38 | technomancy_ | kurtharriger: you can use unquote to add abritrary code, but it's kind of gross |
| 11:39 | kurtharriger | ok I'll try it |
| 11:39 | kurtharriger | :extra-classpath-dirs [~(str (System/getenv "HBASE_HOME") "/" "conf")] |
| 11:39 | kurtharriger | perfect thanks! |
| 11:40 | TimMc | "Var clojure.core/unquote is unbound" |
| 11:40 | technomancy_ | TimMc: inside defproject |
| 11:40 | kurtharriger | maybe later I'll create add a :extra-classpath-env or something |
| 11:41 | kurtharriger | also does leiningen have any support for compiling languages other than java, namely groovy |
| 11:41 | TimMc | technomancy_: I think it varies based on where in the defproject. |
| 11:41 | technomancy_ | TimMc: as long as it's after the version it should be fine |
| 11:42 | TimMc | technomancy_: Yeah, I discovered that (defproject adhoc ~(str "1.0." (rand-int 10) "-SNAPSHOT") ...) doesn't work. |
| 11:42 | TimMc | But without the unquote it is fine! |
| 11:42 | technomancy_ | kurtharriger: if there's an ant task for groovy compilation it should be easy to write one. |
| 11:43 | technomancy_ | TimMc: oh weird. that's unintentional but kind of funny. |
| 11:43 | kurtharriger | is it possible to implement languge additions as plugins or do plugins only allow addition of extra commands to cli |
| 11:44 | TimMc | technomancy_: Now I'm imagining using Date there to version a project's releases. :-P |
| 11:44 | technomancy_ | not sure what language additions means |
| 11:44 | technomancy_ | kurtharriger: plugins can include defns etc if that's what you mean |
| 11:44 | kurtharriger | like :java |
| 11:45 | TimMc | kurtharriger: You mean, custom field parsers for the project.clj? |
| 11:45 | kurtharriger | if I add :groovy source dir to project have it compile all the groovy classes without having to go through ant to do it |
| 11:45 | kurtharriger | no desire to write more groovy code just replace gradle with leiningen |
| 11:45 | kurtharriger | gradle is a POS |
| 11:45 | kurtharriger | but better than maven |
| 11:46 | kurtharriger | in some cases |
| 11:49 | technomancy_ | kurtharriger: what I mean is you could implement a wrapper for ant's groovy compilation using leiningen |
| 11:50 | technomancy_ | and you could have it trigger on the compile task using a hook |
| 11:50 | kurtharriger | ah okay that sounds promising |
| 11:50 | technomancy_ | look at how the lein-javac plugin is implemented I guess |
| 11:50 | kurtharriger | I thought you meant write an ant.xml file and then could call that |
| 11:50 | technomancy_ | nah, it's all programmatic |
| 11:51 | kurtharriger | sounds good then I'll try to do that this weekend if I have time then |
| 11:57 | zawzey | ClojureScript question. What's the proper way to create a Javascript associative map object? |
| 11:57 | zawzey | I can only get it to work using (js* "{foo: 'bar', bar: 'foo'}") |
| 11:58 | zawzey | I don't like this approach, but that's the only way to get interop with Javascript code it seems, for an object |
| 12:09 | raek | zawzey: I have barely used cljs myself, but I think there is a function called clj->js |
| 12:09 | zawzey | well there's a js->clj function |
| 12:09 | zawzey | but no clj->cs |
| 12:10 | ibdknox | correct |
| 12:10 | zawzey | anyway, there's a solution here: https://gist.github.com/1199718/107cc34620fa3a8284face3c3f7aa4439a565e45 |
| 12:11 | ibdknox | pinot has a simple map->js function |
| 12:11 | zawzey | perhaps same as this: https://gist.github.com/1199718/fb9e16ac1ce261e0dac59db3b2b3c18f1c5f71cc |
| 12:11 | zawzey | thanks i'll check that out |
| 12:13 | zawzey | well it's here: https://github.com/ibdknox/pinot/blob/master/src/pinot/util/js.cljs |
| 12:42 | choffstein | Hello 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:43 | shales | mrb_bk: have you tried bytebuffer? |
| 12:44 | blcooley | choffstein: conjing to a vector should be faster |
| 12:44 | choffstein | blocooley: Well, only if conjing to a vector is O(1), right? |
| 12:45 | cgray | choffstein: if you are only adding one thing, then both are O(n) |
| 12:45 | cgray | choffstein: (assuming you are starting with a list) |
| 12:45 | zzach | Browser-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:45 | choffstein | How can conjing to a list be O(n)? You're adding to the front? It should just be a cons... |
| 12:46 | arohner | choffstein: 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:46 | cgray | choffstein: you said conjing and then reversing |
| 12:46 | choffstein | arohner: Thanks. |
| 12:46 | cgray | I think technically, conjing to a vector is O(\log_{32} n) |
| 12:47 | choffstein | cgray: 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:47 | cgray | choffstein: ahh, i see |
| 12:48 | choffstein | Well … maybe the source will tell me? |
| 12:49 | blcooley | choffstein: it's discussed in 5.2.4 of JoC |
| 12:49 | blcooley | choffstein: "A small change, but the code is now a touch cleaner and a bit faster" |
| 12:50 | blcooley | choffstein: that's a discussion of conjing to a vector versus conjing to a list and reversing |
| 12:50 | choffstein | I'll check it out. Thanks. |
| 12:54 | mrb_bk | shales: i did play with it, yes |
| 12:55 | mrb_bk | shales: are you the author? |
| 12:57 | choffstein | blcooley: That answered my questions. I would love to know the big-O notation … but I don't feel like digging through the code :) |
| 13:00 | blcooley | choffstein: PersistentVector is here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java |
| 13:00 | TimMc | &(into () '(1 2 3 4 5)) |
| 13:00 | lazybot | ⇒ (5 4 3 2 1) |
| 13:02 | blcooley | choffstein: 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:02 | choffstein | yeah. Awesome. |
| 13:03 | choffstein | That is helpful. Thanks for poking around |
| 13:03 | blcooley | yw |
| 13:04 | cgray | blcooley: see line 460 or so |
| 13:04 | cgray | if the tail is full, it creates a new node in a tree |
| 13:10 | choffstein | cgray: 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:10 | choffstein | Though, this Java code isn't very clear to me |
| 13:10 | arohner | choffstein: 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:10 | shales | mrb_bk: sorry, was away for a bit. Yeah, I replied to your email on the lsit |
| 13:10 | mrb_bk | shales: cool! |
| 13:11 | choffstein | Ahhhh … right. Cloning. |
| 13:11 | choffstein | Forgot this was immutable data. |
| 13:11 | choffstein | Okay, the tree makes WAY more sense now. |
| 13:11 | mrb_bk | shales: i especially like unpack-bits |
| 13:11 | mrb_bk | think it would be cool to have in core |
| 13:13 | shales | ya maybe. I don't know if anyone other than me or you have used it =) |
| 13:21 | mrb_bk | shales: hehe word |
| 13:21 | mrb_bk | shales: have you used bytebuffer to lazily read from a binary file? |
| 13:24 | shales | mrb_bk: no. I've only used it to pull apart and build network packets |
| 13:25 | mrb_bk | shales: ah cool |
| 13:25 | mrb_bk | shales: i was having a hard time getting it to work with files |
| 13:26 | shales | what 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:26 | shales | I 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:28 | shales | maybe a function that returns the number of bytes needed by one of pack/unpack's format string would be useful? |
| 14:16 | kurtharriger | is it possible to reload java class files in clojure ie (import :reload '[com.some.java.package SomeClass]) |
| 14:18 | TimMc | kurtharriger: Looks like import doesn't take any keyword arguments. |
| 14:18 | technomancy | you'd need a new classloader to do that |
| 14:18 | kurtharriger | yeah, currently just killing and reloading swank when I recompile the groovy application |
| 14:20 | kurtharriger | looking 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:21 | sjl | #haskell |
| 14:23 | gf3 | technomancy: ping |
| 14:23 | technomancy | gf3: what's up? |
| 14:23 | gf3 | technomancy: when I install your clojure-swank as a standalone plugin, the generated script contains a hardcoded classpath |
| 14:23 | gf3 | /home/phil/... or something |
| 14:24 | technomancy | hm; let me take a look |
| 14:24 | gf3 | technomancy: http://cloud.gf3.ca/CwsE |
| 14:24 | MenTaLguY | hey guys |
| 14:26 | MenTaLguY | I'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:26 | cgray | zipmap |
| 14:26 | MenTaLguY | basically, take some map and transform the keys in it |
| 14:26 | MenTaLguY | hmm |
| 14:27 | kurtharriger | technomancy: 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:27 | technomancy | gf3: definitely a bug; can you open an issue? |
| 14:28 | gf3 | technomancy: sure thing, thank you |
| 14:28 | MenTaLguY | cgray: so that would be: (zipmap (keys some-map) (map some-fn (values some-map))) ? |
| 14:28 | cgray | MenTaLguY: or more precisely (zipmap (keys some-map) (map some-fn (vals some-map))) |
| 14:28 | MenTaLguY | ah yeah, vals, not values |
| 14:28 | MenTaLguY | I guess that's a bit better |
| 14:28 | MenTaLguY | still seems like there should be a more concise way to do it |
| 14:29 | technomancy | MenTaLguY: agreed; I'd love a map-keys and map-vals |
| 14:30 | blerg | seems 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:30 | blerg | maybe that's why there's no ready made for it? |
| 14:30 | pjstadig | but we're lisp hackers |
| 14:30 | pjstadig | we know the value of everything and the cost of nothing |
| 14:31 | blerg | :) true dat |
| 14:33 | gf3 | technomancy: https://github.com/technomancy/swank-clojure/issues/95 |
| 14:33 | gf3 | thanks again |
| 14:34 | amalloy | (into {} (for [[k v] m] [k (some-fn v)])) is another option, MenTaLguY |
| 14:39 | technomancy | processing? without org.clojars? really? =( |
| 14:40 | amalloy | technomancy: was lein the first tool nudging clojure in the direction of "group name defaults to artifact name"? |
| 14:41 | technomancy | amalloy: it's not unheard of in java-land; particularly with projects that moved from ant to maven. |
| 14:44 | pjstadig | i think junit has a project-name-as-group-name |
| 14:51 | TimMc | technomancy: What's the problem? |
| 14:52 | technomancy | TimMc: 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:52 | TimMc | What are the semantics of using org.clojars.foo/*? |
| 14:53 | TimMc | Does that just mean "this is my local fork"? |
| 14:53 | TimMc | s/local// |
| 14:54 | technomancy | right |
| 14:54 | raek | TimMc: yes. foo's personal fork. |
| 14:55 | TimMc | Where org.clojars.foo is just some namespace that the user owns, yeah? |
| 14:55 | TimMc | So org.timmc would be equivalent. |
| 14:55 | amalloy | that 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:56 | technomancy | it's a matter of communicating to potential consumers |
| 14:57 | pjstadig | and 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:58 | technomancy | no, unfortunately you need to use exclusions |
| 14:58 | technomancy | there's really no good existing solution for nonlinear versioning in dependencies |
| 14:58 | technomancy | in any language |
| 15:08 | cemerick | technomancy: so, does easy s3 deployments from lein mean we can close the book on e.g. org.clojars.name/foo? |
| 15:56 | TimMc | cemerick: Why would that be? |
| 15:56 | blakesmith | Is there an easier way to convert keywords to their string representation without the leading colon? |
| 15:56 | blakesmith | &(apply str (drop 1 (str :hello))) |
| 15:56 | lazybot | ⇒ "hello" |
| 15:57 | emezeske | &(name :hello) |
| 15:57 | lazybot | ⇒ "hello" |
| 15:57 | TimMc | cemerick: There are plenty of things on clojars that aren't personal projects. |
| 15:57 | blakesmith | emezeske: Perfect, thanks! |
| 15:57 | emezeske | blakesmith: NP |
| 15:57 | TimMc | $findfn :name "name" |
| 15:57 | lazybot | [clojure.core/name] |
| 15:58 | cemerick | TimMc: 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:59 | quizme | why does the handler function of the ring tutorial need to be a var? |
| 16:01 | cemerick | quizme: 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:02 | quizme | cemerick i see thank you |
| 16:03 | quizme | cemerick: so it sort of makes it like a "global" across different threads(?) |
| 16:03 | technomancy | cemerick: well the stuff I added was really only for private deploys |
| 16:03 | technomancy | you've been able to do public s3 deploys since forever; it's just a matter of docs |
| 16:04 | chouser | well, I finally pushed TractionSVG out there, for anyone interested: https://github.com/chouser/tractionsvg |
| 16:04 | technomancy | cemerick: 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:05 | cemerick | technomancy: sure; I'm agitating. ;-) |
| 16:05 | cemerick | quizme: all vars are "global" across threads :-) |
| 16:05 | cemerick | (except for those created with `with-local-vars`) |
| 16:06 | technomancy | hush |
| 16:07 | hiredman | chouser: neat |
| 16:08 | technomancy | ,(alter-meta! #'with-local-vars update-in [:doc] (partial str "Warning: don't use this unless you know what you're doing.\n")) |
| 16:08 | clojurebot | {:macro true, :ns #<Namespace clojure.core>, :name with-local-vars, :arglists ([name-vals-vec & body]), :added "1.0", ...} |
| 16:08 | technomancy | holy crap; that worked |
| 16:08 | technomancy | not sure how I feel about that |
| 16:09 | technomancy | hiredman: might want to take a look at that. =) |
| 16:10 | chouser | hiredman: thanks. It certainly doesn't rate more than that yet. |
| 16:11 | chouser | all named vars |
| 16:15 | choffstein | Hey 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:15 | choffstein | unecessary 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:16 | technomancy | choffstein: transients will help if the slowness is caused by GC |
| 16:16 | technomancy | until you profile you're in the dark |
| 16:17 | technomancy | that said, if you're 2x slower than ruby it's likely to be something a bit more obvious |
| 16:17 | technomancy | are you letting the JIT warm up and excluding JVM boot time? |
| 16:17 | choffstein | Hmm. My profiling skills with JVisualVM are still beginnerish. Know if I can see how the GC is behaving |
| 16:17 | choffstein | Not really letting the JIT "warm-up" per-se … just yes on excluding JVM boot time |
| 16:19 | cmeier | chouser: thumbs up for tractionsvg |
| 16:20 | tmciver | chouser: tractionsvg looks very cool |
| 16:26 | choffstein | Oh, wow -- I did a dotimes and let the JIT warm up. The clojure code sped-up by almost 4-5x. Yikes. |
| 16:26 | choffstein | The 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:28 | technomancy | ouch |
| 16:29 | technomancy | choffstein: did you get a chance to try out https://github.com/heroku/heroku-buildpack-clojure/tree/private-repo? |
| 16:29 | choffstein | Yeah! It's awesome! |
| 16:29 | technomancy | excellent |
| 16:29 | choffstein | I thought I had PMed you. My apologies if I didn't. You're a life-saver. Awesome solution to my problem |
| 16:30 | technomancy | no worries; my bouncer isn't 100% reliable, so PMs are sometimes lost. |
| 16:30 | choffstein | I had a little clojure app up using redis, resque, background workers and mongodb in like … 6 hours. It was unbelievable. |
| 16:30 | technomancy | how do you like resque? |
| 16:31 | solussd | technomancy: 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:32 | technomancy | solussd: 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:32 | TimMc | technomancy: hiredman has known about alter-meta! being allowed since forever. *shrug* |
| 16:32 | solussd | technomancy: oh, so I shouldn't install swank-clojure via elpa? |
| 16:32 | TimMc | I think that's why clojurebot restarts every 15 minutes. |
| 16:33 | technomancy | solussd: yeah, that is way out of date |
| 16:33 | choffstein | What amazes me is that in running my huge program like … 50 tims, invokeMatchingMethod takes 99.99999% of the time with only 144 invocations. |
| 16:33 | technomancy | solussd: clojure-mode is the only thing required on the elisp side these days |
| 16:34 | lypanov | choffstein: accumulative? |
| 16:34 | choffstein | lypanov: Sorry, I don't understand the question |
| 16:35 | lypanov | choffstein: just wondering if the profile output is inclusive or exclusive. |
| 16:36 | choffstein | lypanov: inclusive or exclusive of what? |
| 16:36 | mcrittenden | do I have to install maven to get clojure contrib? |
| 16:37 | lypanov | choffstein: time, i assume invokeMatchingMethod is the caller. if its inclusive then 99.999 makes sense. |
| 16:37 | lypanov | just ignore me :) |
| 16:37 | choffstein | lypanov: oh. Yeah, I think invokeMatchingMethod is the caller and it is inclusive. |
| 16:38 | choffstein | It measures "self time" |
| 16:42 | AeroNotix | anyone used clojure with minecraft? |
| 16:43 | cemerick | AeroNotix: I've seen blog posts where those words were in proximity. No idea if they were any good or interesting though. |
| 16:43 | TimMc | Yeah, I built a JVM using redstone. |
| 16:43 | AeroNotix | TimMc: LOL |
| 16:43 | AeroNotix | TimMc: About as memory efficient as well? |
| 16:45 | TimMc | Actually, I've never played the game. |
| 16:48 | skelternet | I think I'm doing it wrong. |
| 16:49 | Somelauw | What is the quickest way to just make use of all functions in clojure.string? Something like (import clojure.string)? |
| 16:49 | TimMc | Somelauw: (require '[clojure.string :as s]) |
| 16:50 | TimMc | Somelauw: or (use '[clojure.string :only (foo bar etc)]) |
| 16:50 | quizme | Somelauw: (use 'clojure.string) |
| 16:50 | TimMc | quizme: Bad! |
| 16:50 | TimMc | Only use use with only* |
| 16:51 | TimMc | * Except clojure.test and the namespace under test in your test files. |
| 16:51 | hiredman | a use like that is not the best idea |
| 16:52 | hiredman | clojure.string may have some functions that are the same name as clojure.core |
| 16:52 | hiredman | (require '[clojure.string :as str]) or (:require [clojure.string :as str]) in your ns form |
| 16:52 | skelternet | Should 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:52 | Somelauw | Thanks, it works |
| 16:54 | Somelauw | I think directly using "use" is useful when testing it in a repl. |
| 16:55 | TimMc | Oh yeah, the REPL is a fine place for it. |
| 16:58 | skelternet | I'm expecting to have to swap out the implementations based on user-specified configuration |
| 16:59 | technomancy | skelternet: 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:00 | technomancy | multimethods are a bit slower but can dispatch on anything; doesn't even have to be an argument |
| 17:00 | skelternet | I 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:01 | technomancy | very few things in practice are bottlenecked on method dispatch (modulo reflection, which is easy to solve anyway) |
| 17:01 | skelternet | My main concern is not wanting to change the client code. |
| 17:04 | skelternet | clojure's given me several options that satisfy that. |
| 17:05 | skelternet | I 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:07 | skelternet | it is familiar behind the scenes: Java interfaces. but more involved. |
| 17:07 | hiredman | I 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:08 | hiredman | and falls back to a multimethod if the static cond isn't valid |
| 17:08 | hiredman | it is ugly |
| 17:09 | mcrittenden | TimMc: 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:17 | mdeboard | Anyone 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:18 | emezeske | Boy I wish Clojars had a field for linking to the repo from which a jar was built... |
| 17:18 | emezeske | I might need to work up a patch for that |
| 17:18 | skelternet | data not reliable as in quality or not always available, as in waiting to come back from storage? |
| 17:18 | scottj | emezeske: :url in project.clj? |
| 17:18 | pandeiro | mcrittenden: i think 'only use use with only' is only enforced in ClojureScript |
| 17:18 | emezeske | scottj: awesome! |
| 17:19 | emezeske | scottj: that just needs to be on the web UI somewhere |
| 17:19 | scottj | emezeske: it is displayed if that's what you mean |
| 17:19 | scottj | emezeske: but if it were in instructions or some way to make it more popular might be nice |
| 17:20 | emezeske | scottj: ah, I guess most projects must not fill it in then |
| 17:20 | emezeske | scottj: including mine X_X |
| 17:20 | emezeske | time to fix |
| 17:21 | ordnungswidrig | emezeske: one should crawl clojars and send warnings to the owners of projects without url. |
| 17:21 | emezeske | ordnungswidrig: I love that idea |
| 17:21 | emezeske | Also, what's up with people having their open-source projects depend on random jars that are not hosted anywhere? PAIN |
| 17:22 | ordnungswidrig | emezeske: drop from clojars ;-) |
| 17:22 | scottj | emezeske: getwoven? |
| 17:22 | emezeske | *the source code for which is not hosted anywhere |
| 17:22 | emezeske | scottj: what's that? |
| 17:23 | technomancy | emezeske: wouldn't hurt to have it filled out as a FIXME in the default project.clj emitted by lein |
| 17:23 | technomancy | easy pull request; hint hint |
| 17:23 | scottj | emezeske: a team that sometimes does that |
| 17:23 | emezeske | scottj: ahh, gotcha |
| 17:23 | emezeske | technomancy: :) adding to my list |
| 17:26 | ordnungswidrig | which hash functions does assoc/PersistentArrayMap use? |
| 17:26 | ordnungswidrig | object/hashcode? |
| 17:27 | scottj | technomancy: do you prefer "FIXME: project url" or ""? |
| 17:28 | scottj | or write url |
| 17:28 | TimMc | http://www.example.org/FIXME |
| 17:28 | technomancy | scottj: probably best to leave it commented out; something like ;; :url "http://FIXME" |
| 17:28 | amalloy | no, link it somewhere really offensive so they're incentivized to fix it |
| 17:28 | technomancy | amalloy: early versions of hoe (a ruby gem generator) attributed all libraries to the author of hoe |
| 17:29 | technomancy | but he got sick of all the bug reports |
| 17:29 | ordnungswidrig | technomancy: hehe |
| 17:30 | TimMc | hoist in his own petard |
| 17:30 | scottj | technomancy: pull sent |
| 17:30 | TimMc | s/in/with/ I guess |
| 17:31 | technomancy | scottj: excellent |
| 17:31 | ordnungswidrig | I once returned from holidays to notice 1e5 new emails in my inbox. Now I stay away from mail-sending logging handlers. |
| 17:31 | scottj | technomancy: I'd wanted this for a long time but figured you'd considered and rejected it :) |
| 17:31 | technomancy | emezeske: 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:32 | scottj | ordnungswidrig: some dude once returned from holidays to find 3e6 of his emails posted on bittorrent |
| 17:32 | scottj | technomancy: I'll be collecting my sticker on seajure next week :) |
| 17:32 | ordnungswidrig | scottj: bittorrent ist the new imap. |
| 17:33 | hiredman | ordnungswidrig: on 1.4-SNAPSHOT it uses a custom hash function, which in most cases falls back to .hashCode |
| 17:34 | lypanov | (502s yay) |
| 17:34 | emezeske | technomancy: I might get to it! |
| 17:35 | technomancy | scottj: uh oh... I may be out of stock. |
| 17:35 | technomancy | been meaning to order a fresh batch with the high-res image |
| 17:37 | ordnungswidrig | hiredman: I was just wondering because of this http://events.ccc.de/congress/2011/Fahrplan/events/4680.en.html |
| 17:37 | scottj | technomancy: no worries |
| 17:38 | scottj | technomancy: sticker 2.0 for new release |
| 17:39 | hiredman | ordnungswidrig: yeah, I don't imagine rich moving fast on that |
| 17:40 | ordnungswidrig | hiredman: 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:41 | hiredman | *shrug* |
| 17:42 | hiredman | the report I saw mentioned web requests, but really any kind of transport would do |
| 17:42 | hiredman | most message queues get used to more or less pass around maps |
| 17:42 | ordnungswidrig | unix comes to help by limiting processing time. But the monolithic java servlet model is a burdon here. |
| 17:43 | hiredman | uh |
| 17:43 | ordnungswidrig | limiting thread runtime in java, anyone? |
| 17:43 | hiredman | really? |
| 17:43 | ordnungswidrig | one cannot, right? |
| 17:54 | ordnungswidrig | scary: ,(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:00 | kd4joa | I 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:01 | kd4joa | I 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:01 | kd4joa | each time that is called I need to get the value of that token from a TermAttribute object using its term() method |
| 18:02 | kd4joa | question is how to call incrementToken() until it's false, gather up all the tokens and create a vector out of them |
| 18:03 | kd4joa | I 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:03 | kd4joa | can someone point me in the right direction? |
| 18:03 | hiredman | (repeatedly #(doto ts .incrementToken .getTermAttribute)) |
| 18:03 | amalloy | hiredman: .getTermAttribute goes outside the doto, right? |
| 18:03 | raek | kd4joa: 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:04 | hiredman | amalloy: I have no idea |
| 18:04 | hiredman | http://lucene.apache.org/java/3_0_3/api/all/org/apache/lucene/analysis/TokenStream.html |
| 18:05 | hiredman | kd4joa: your best solution is to write something like enumeration-seq which takes a tokenstream and turns it into a lazy seq |
| 18:05 | amalloy | heh. 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:06 | kd4joa | sorry. how can I help make it more cleaer |
| 18:07 | raek | kd4joa: when .incrementToken returns true, what do you need to call to get the token? |
| 18:08 | kd4joa | (.term termatt) will give me the token (termatt is a TermAttribute) |
| 18:08 | kd4joa | here's a working function that prints the token each time through the while: https://gist.github.com/1536626 |
| 18:10 | raek | kd4joa: I would make a lazy sequence like this: https://gist.github.com/1536636 |
| 18:10 | clojurebot | Pardon? |
| 18:11 | ordnungswidrig | kd4joa: comment written |
| 18:11 | ordnungswidrig | kd4joa: simple fix using a atom a temp result holder. |
| 18:12 | ordnungswidrig | I don't feel too dirty bacause the java objects already are mutable as hell |
| 18:12 | kd4joa | heh, no kidding |
| 18:12 | raek | kd4joa: a non-lazy variant: https://gist.github.com/1536637 |
| 18:12 | kd4joa | thanks to both of you. both approaches look like they should work |
| 18:13 | raek | ordnungswidrig: no need to use the concurrency primitives when you can use simple recursion in this case |
| 18:13 | kd4joa | thanks. I had started looking at atoms (never used them before), but it seemed like there should be an easier way |
| 18:13 | amalloy | (take-while identity (repeatedly #(when (.incrementToken tokenstream) (.term termatt)))) |
| 18:15 | kd4joa | what makes repeatedly stop there? I thought it returned an infinite sequence |
| 18:16 | amalloy | (take-while ...) |
| 18:17 | raek | it would be neat to have a "unfold" ("unreduce?") in clojure.core |
| 18:17 | kd4joa | hmm. I'll have to play with that a little to understand it |
| 18:17 | amalloy | raek: 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:18 | kd4joa | thanks 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:18 | hiredman | (fn f [ts ta] (lazy-seq (when (.incrementToken ts) (cons (.term ta) (f ts ta))))) |
| 18:20 | jhirn | What's the quickest way to move a file from one path to another creating the directories if needed? |
| 18:20 | TimMc | quickest to type? |
| 18:20 | TimMc | rsync |
| 18:21 | jhirn | =), prefer to keep it java'ish for cross platform. |
| 18:21 | hiredman | http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/FileChannel.html#transferTo%28long,%20long,%20java.nio.channels.WritableByteChannel%29 |
| 18:21 | jhirn | was shelling out to mv, |
| 18:21 | jhirn | but need to mkdir -p... then i figured there might be a move-file somewhere. |
| 18:22 | hiredman | you'll need to call .mkdirs on the target files parent directory yourself |
| 18:22 | technomancy | .mkdirs on j.i.File is mkdir -p |
| 18:22 | technomancy | oops; too slow |
| 18:23 | hiredman | but transferTo or transferFrom should be faster than anything else on the jvm |
| 18:23 | jhirn | Ah, so I must creat files... I need mv -p like a mofo right now. |
| 18:23 | hiredman | create files? |
| 18:23 | jhirn | moving from one place to another. |
| 18:23 | jhirn | for a git utility i'm working on to make renames out of delete/new pairs. |
| 18:24 | jhirn | was doing a simple , reset-> mv -> git mv but mv is failing due to directory not being there. |
| 18:24 | jhirn | i supposed it's easy enough to shell out a mkdir -p |
| 18:25 | jhirn | then that whole dot the right thing started conflicting with the right now thing.... |
| 18:33 | hiredman | chouser: it would be neat if analemma could be used to generate traction svgs |
| 18:33 | hiredman | https://github.com/liebke/analemma |
| 18:35 | solussd | what's the best way to convert a record into a hash-map? currently I use (into {} (vec my-record)) |
| 18:38 | sandbox | hello, is this a place to ask questions about clojure? |
| 18:39 | amalloy | well, that's one so far. i guess the answer must be yes |
| 18:45 | sandbox | sorry 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:45 | sandbox | when i don't intended to add that function to the library later |
| 18:51 | technomancy | sandbox: yeah, definitely don't want to change namespaces you don't control |
| 18:59 | sandbox | okay 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:59 | technomancy | the stuff done by core_deftype.clj shouldn't ever be done in user code |
| 19:00 | technomancy | it gets a pass because it has to bootstrap a bunch of crazy stuff |
| 19:05 | sandbox | okay that makes that clear thanks |
| 19:12 | flognikr | sandbox: have you looked into Clojure's protocols as a mechanism for extending types? |
| 19:17 | sandbox | i 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:21 | flognikr | sandbox: ok, that helps me understand your use case better. |
| 19:21 | sandbox | i should have probably started with that information sorry if it was unclear |
| 19:23 | flognikr | sandbox: no problem at all |
| 20:31 | fryguy | what do people prefer for REPL in vim? slimv or VimClojure? |
| 20:32 | devn | i think most everyone i know uses vimclojure |
| 20:52 | technomancy | http://p.hagelb.org/slime-compile-presave.el.html |
| 20:52 | technomancy | ^ so this hook will attempt to compile the current buffer when you save and refuse if it doesn't compile |
| 20:52 | technomancy | is this awesome? [y/n] |
| 20:53 | Kowboy | y |
| 20:54 | Kowboy | now I just wish I could get M-x clojure-jack-in working on NT Emacs so I can use it at work ;-P |
| 20:54 | Kowboy | I use Ubuntu at home though (a proper emacs system), so I'm happy here ;-) |
| 20:56 | Kowboy | In 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:57 | Kowboy | or is there a better/alternative lib I should be using for HTTP requests? |
| 20:57 | hiredman | clj-http |
| 20:57 | technomancy | and clojure.java.io |
| 20:57 | hiredman | https://github.com/dakrone/clj-http |
| 20:58 | technomancy | err--misread that |
| 21:21 | augustl | hi 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:21 | TimMc | yep |
| 21:22 | augustl | TimMc: thanks :) |
| 21:22 | TimMc | augustl: You may see references to Cake here and there, but it is being merged into Leiningen, sort of. |
| 21:25 | augustl | TimMc: ah, I see |
| 21:26 | augustl | Leiningen seems simple enough. Just created a project, unlike maven it didn't download the internet |
| 21:27 | amalloy | lein uses maven, so you'll be getting some internet before long |
| 21:27 | amalloy | but clojure has very few (zero?) dependencies, so you just need the jars you're using yourself |
| 21:28 | augustl | ah |
| 21:29 | emezeske | Hmm... 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:29 | emezeske | Anyone have any tips on where to start on debugging such a problem? |
| 21:30 | emezeske | (I should add that to make the 'java ...' invocation work, I add "(apply -main *command-line-args*)" to my main source file) |
| 21:42 | TimMc | emezeske: What is one of the mysterious ways? |
| 21:42 | TimMc | Maybe there's some AOT difference. |
| 21:43 | emezeske | TimMc: Exception in thread "main" java.lang.RuntimeException: java.lang.AssertionError: Assert failed: Can't recur here |
| 21:43 | emezeske | That's coming out of the clojurescript compiler |
| 21:43 | TimMc | Ah, I've seen that! |
| 21:44 | emezeske | Yeah, I see some references to it on the noir lists |
| 21:44 | emezeske | But I don't see any solutions |
| 21:44 | TimMc | Let me chcek my logs... |
| 21:44 | emezeske | Thanks! |
| 21:45 | pandeiro | damn my swank is broken again |
| 21:46 | TimMc | emezeske: 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:47 | TimMc | And now it doesn't do it. -.- |
| 21:47 | emezeske | Yeah, it's throwing that error when compiling core.cljs |
| 21:48 | emezeske | After it's compiled, I think the js output is cached and used again (hence no error on try 2) |
| 21:48 | pandeiro | "error in process filter: symbol's function definition is invalid: slime-output-buffer" |
| 21:48 | emezeske | For me, it never fails when I run via "java ...", and always fails under "lein run" |
| 21:49 | emezeske | I'm guessing it's some kind of weird class loading thing |
| 21:49 | pandeiro | weird part is i get the success message (Take this REPL brother etc), but no *slime-repl* buffer |
| 21:49 | TimMc | emezeske: Well, throw in a memoized (try compile (catch ...)). :-P |
| 21:50 | emezeske | Hah! :) |
| 21:50 | emezeske | I'd actually consider doing that, but for me it fails 100% from lein run |
| 21:50 | emezeske | Even the second time.. |
| 21:52 | TimMc | emezeske: So, if you (do (try (compile-stuff) (catch ...)) (compile-stuff)) it fails on the second one too? |
| 21:52 | emezeske | TimMc: I think so, checking right now to be certain |
| 21:53 | emezeske | TimMc: yep, that fails too |
| 21:54 | TimMc | Fascinating. |
| 21:54 | emezeske | with the same error |
| 21:55 | emezeske | The thing that's really throwing me off is that things fail in the same way if I create an uberjar and run that |
| 21:55 | emezeske | I'd think that would run things very closely the same way as when I run "java ..." |
| 21:56 | DerGuteMoritz | hello everyone, how can I use one of the eval bots in here? I'd like to get feedback on something |
| 21:57 | TimMc | emezeske: I can't reconcile that with what I was seeing, but I bet it's an AOT-ish thingy. |
| 21:57 | emezeske | TimMc: Yeah, that sounds probable. Thanks for your input! |
| 21:58 | emezeske | Yeah... I don't either. I moved as much stuff as possible out of my (:gen-class) namespace to hopefully avoid problems :P |
| 21:58 | TimMc | It's infectious though, right? |
| 21:58 | emezeske | Ah, I did not know that |
| 21:58 | TimMc | I don't either. |
| 21:59 | TimMc | I just *think* it. |
| 21:59 | emezeske | haha |
| 21:59 | tmciver | DerGuteMoritz: comma as first character followed by valid Clojure: |
| 21:59 | tmciver | ,(+ 2 2) |
| 21:59 | clojurebot | 4 |
| 22:00 | DerGuteMoritz | tmciver: ah, thank you |
| 22:00 | DerGuteMoritz | so there: |
| 22:00 | DerGuteMoritz | ,(symbol? (symbol "123")) |
| 22:00 | clojurebot | true |
| 22:00 | DerGuteMoritz | ,(symbol? (read-string (pr-str (symbol "123")))) |
| 22:00 | clojurebot | false |
| 22:00 | DerGuteMoritz | is this a read/write inconsistency or am I missing something? |
| 22:02 | tmciver | DerGuteMoritz: looks like pr-str is just producing "123", which is not a symbol? |
| 22:02 | DerGuteMoritz | tmciver: that's right |
| 22:03 | TimMc | DerGuteMoritz: Sort of. That round-trip is only valid for literal expressions, I believe. |
| 22:03 | TimMc | Since '123 is 123... |
| 22:04 | DerGuteMoritz | seems like there is no external representation for symbols which consist of digits only |
| 22:04 | TimMc | Correct. That's because symbols are supposed to name things. |
| 22:05 | TimMc | and names are restricted to a certain set of characters. |
| 22:05 | DerGuteMoritz | symbols containing spaces are even worse |
| 22:05 | DerGuteMoritz | ok then the symbol function should reject such strings |
| 22:05 | amalloy | "should" is a strong word |
| 22:05 | TimMc | There's a forward-compatibility problem there. |
| 22:06 | DerGuteMoritz | "must" is even stronger :-) |
| 22:06 | amalloy | the 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:07 | TimMc | Hmm, that's right -- there are two round-trips possible. |
| 22:07 | amalloy | (read-string (pr-str x)) resulting in x is a much more difficult task |
| 22:07 | amalloy | and all over the language that fails. ##(pr-str (java.util.Date.)) sure can't be read back in |
| 22:07 | lazybot | ⇒ "#<Date Thu Dec 29 19:08:49 PST 2011>" |
| 22:08 | DerGuteMoritz | amalloy: that's right, but the reader will error on that one |
| 22:09 | DerGuteMoritz | hmmm |
| 22:09 | amalloy | so? 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:09 | DerGuteMoritz | agreed |
| 22:09 | amalloy | if 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:10 | tmciver | read-string is typically used to read a string of valid Clojure to be passed to eval, yes? |
| 22:10 | DerGuteMoritz | tmciver: it just reads a datum from a string, you can do with it whatever you want |
| 22:12 | DerGuteMoritz | amalloy: 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:12 | TimMc | DerGuteMoritz: It used to bug me a bit that nil can't be a symbol: ##(map class '[nil true foo]) |
| 22:12 | lazybot | ⇒ (nil java.lang.Boolean clojure.lang.Symbol) |
| 22:12 | DerGuteMoritz | hmmm indeed |
| 22:13 | DerGuteMoritz | ,(name 'nil) |
| 22:13 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 22:13 | DerGuteMoritz | :-/ |
| 22:13 | TimMc | That's not true in Scheme, where #t and #f are the boolean literals. |
| 22:13 | DerGuteMoritz | ,(name (symbol "nil")) |
| 22:13 | clojurebot | "nil" |
| 22:13 | DerGuteMoritz | something seems off there |
| 22:14 | DerGuteMoritz | TimMc: yeah, I'm coming from Scheme which is why I'm kind of used to these kinds of edge cases being specified :-) |
| 22:14 | DerGuteMoritz | amalloy: what is your take on the nil issue? |
| 22:15 | amalloy | it's kinda weird |
| 22:15 | DerGuteMoritz | looks like an implementation detail shining through |
| 22:16 | amalloy | meh. 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:17 | DerGuteMoritz | amalloy: depends on the quoting |
| 22:17 | DerGuteMoritz | ah, same issue here: |
| 22:17 | DerGuteMoritz | ,(name 'true) |
| 22:17 | tmciver | right, how's the reader to know if you meain your symbol nil or the value nil? |
| 22:17 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.Named> |
| 22:17 | TimMc | DerGuteMoritz: Not implementation, it's a philosophical diff. |
| 22:17 | DerGuteMoritz | tmciver: well, how does it know in this case: (list 'list) |
| 22:18 | amalloy | uhhh, because list is not a language primitive with a special type |
| 22:18 | TimMc | DerGuteMoritz: You're never going to name something "nil", "true", or "false". Symbols are for naming things. |
| 22:18 | amalloy | it's an ordinary symbol, naming a function defined in clojure.core |
| 22:18 | DerGuteMoritz | TimMc: special cases ... |
| 22:18 | TimMc | Yeha, I know. |
| 22:19 | TimMc | It took me a while to be OK with it. |
| 22:19 | tmciver | DerGuteMoritz: flierting with disaster |
| 22:19 | DerGuteMoritz | amalloy: yes, and when quoted it is just that symbol |
| 22:19 | DerGuteMoritz | tmciver: hm? |
| 22:20 | amalloy | DerGuteMoritz: so what's your point? list is a symbol, true is a boolean. they behave differently unquoted, and they behave differently quoted |
| 22:20 | tmciver | DerGuteMoritz: why would you ever need to name your symbols nil, true or false? Sounds like a problem waiting to happen. |
| 22:20 | amalloy | they look "similar" to our eyes because they're made up of letters |
| 22:20 | DerGuteMoritz | why does 'true resolve to the boolean true value but 'list not resolve to the list function? |
| 22:20 | amalloy | but 4 behaves just the same as true, in all of these cases |
| 22:21 | TimMc | tmciver: My only concern is automatic code generation, but we have gensym to take care of this stuff. |
| 22:21 | DerGuteMoritz | tmciver: it's a question of consistency rather |
| 22:21 | amalloy | DerGuteMoritz: when you quote a literal, you get that literal back |
| 22:21 | TimMc | DerGuteMoritz: Compare all this with (4) vs. '(4) vs. [4] vs. '[4]. |
| 22:21 | amalloy | &['4 'true 'nil 'list] |
| 22:21 | lazybot | ⇒ [4 true nil list] |
| 22:21 | DerGuteMoritz | it's a matter of special cases |
| 22:21 | amalloy | DerGuteMoritz: you can say that all you want |
| 22:22 | amalloy | the "special case" is that you want every sequence of letters to be a symbol, and some of them aren't |
| 22:22 | amalloy | sad, perhaps, but true, and no further inconsistencies arise once you get past that |
| 22:22 | DerGuteMoritz | sure, it's just a matter of getting used to and avoiding the edges |
| 22:25 | technomancy | there was a ticket open back in the google code days for symbol and keyword to enforce readability |
| 22:25 | DerGuteMoritz | technomancy: interesting, do you know how it was resolved? |
| 22:26 | technomancy | I patched it, and the patch was ignored |
| 22:26 | technomancy | which started a long tradition |
| 22:27 | DerGuteMoritz | of people creating the same patch over and over again? :-) |
| 22:27 | pandeiro | technomancy: did swank-clojure 1.3.2 also place a swank folder in .emacs.d/ with the compiled slime files? |
| 22:27 | technomancy | pandeiro: I think that was new in 1.3.3 |
| 22:29 | amalloy | of people ignoring technomancy's patches, i assume |
| 22:30 | kenth | I'm on the macro chapter in JoC, what does ~@ do? |
| 22:30 | DerGuteMoritz | perhaps technomancy didn't fax in the paperwork |
| 22:30 | amalloy | &(let [x [1 2 3] y [4 5 6]] `(~@x ~y)) |
| 22:30 | lazybot | ⇒ (1 2 3 [4 5 6]) |
| 22:31 | DerGuteMoritz | kenth: if you know scheme: it's the same as unquote-splicing |
| 22:31 | tensorpudding | ~@ splices a list |
| 22:31 | clojurebot | It's greek to me. |
| 22:31 | tensorpudding | well, a collection |
| 22:33 | DerGuteMoritz | hm, can somebody explain this: |
| 22:33 | DerGuteMoritz | ,['foo] |
| 22:33 | clojurebot | [foo] |
| 22:33 | DerGuteMoritz | `[foo] |
| 22:33 | DerGuteMoritz | ,`[foo] |
| 22:33 | clojurebot | [sandbox/foo] |
| 22:33 | DerGuteMoritz | why is the symbol resolved with `? is it because ` is meant to be used for syntax only? |
| 22:34 | DerGuteMoritz | s,resolved,qualified, |
| 22:35 | ldh | i'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:35 | DerGuteMoritz | if so, is there a syntactic way to splice a list or vector of symbols outside of macros then? |
| 22:35 | technomancy | ldh: (into {} (map f x)) |
| 22:35 | ldh | technomancy: ah, thanks |
| 22:36 | DerGuteMoritz | (a list of unqualified symbols, obviously) |
| 22:37 | technomancy | DerGuteMoritz: syntax-quote can be used outside macros |
| 22:37 | DerGuteMoritz | technomancy: yeah but it qualifies symbols |
| 22:37 | DerGuteMoritz | ,`(foo ~'foo) |
| 22:37 | clojurebot | (sandbox/foo foo) |
| 22:37 | technomancy | oh right; not paying attention here |
| 22:38 | DerGuteMoritz | no problemo |
| 22:38 | tensorpudding | it's just a reader macro |
| 22:38 | DerGuteMoritz | yes |
| 22:38 | DerGuteMoritz | but apparently it can't be used for a list of unqualified symbols |
| 22:39 | DerGuteMoritz | aha, perhaps thus hiccup's choice of keywords rather than symbols |
| 22:39 | DerGuteMoritz | I wondered about that the other day |
| 22:43 | kenth | why are there two quoting forms? |
| 22:44 | DerGuteMoritz | kenth: the ` form allows "unquoting", i.e. inside the quoted form you can switch back to evaluation |
| 22:45 | DerGuteMoritz | kenth: Conrad Barski has made a nice illustration of that: http://lisperati.com/backquote.jpg (except in clojure, unquoting is done using ~) |
| 22:50 | kenth | so ' does not allow unquoting? |
| 22:50 | DerGuteMoritz | that's right |
| 22:55 | amalloy | having ` qualify symbols is also hugely helpful in avoiding unintentional symbol capture in macros |
| 22:56 | amalloy | but 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:58 | DerGuteMoritz | hm, indeed: |
| 22:58 | DerGuteMoritz | ,(let [x 'foo] `(~x)) |
| 22:58 | clojurebot | (foo) |
| 22:59 | DerGuteMoritz | I assumed that literal symbols behave the same in this situation |
| 23:00 | DerGuteMoritz | err wait |
| 23:00 | jhirn | Is it wrong that I get the urge to write code instead of tests with Clojure? It feels illicit. |
| 23:02 | DerGuteMoritz | amalloy: 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:02 | DerGuteMoritz | ) |
| 23:04 | amalloy | yeah, 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:04 | DerGuteMoritz | yep |
| 23:04 | DerGuteMoritz | thus my enlightenment regarding hiccup above :-) |
| 23:06 | DerGuteMoritz | alas, something like ~@body in my example above is not possible with hiccup |
| 23:06 | DerGuteMoritz | but not terribly missing either |
| 23:06 | amalloy | sure it is |
| 23:06 | amalloy | it's not clear to me what you're saying is not possible, but i'm confident it's possible |
| 23:07 | DerGuteMoritz | amalloy: splicing into a vector literal |
| 23:08 | DerGuteMoritz | you need to use concat, as you said earlier |
| 23:08 | amalloy | &(let [x [1 2 3]] `[foo ~@x]) |
| 23:08 | lazybot | ⇒ [clojure.core/foo 1 2 3] |
| 23:08 | DerGuteMoritz | yeah then you have to take care not to have symbols in there :-) |
| 23:08 | amalloy | more 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:09 | DerGuteMoritz | that's good |
| 23:09 | DerGuteMoritz | ok thanks for the feedback guys |
| 23:09 | DerGuteMoritz | gotta get some sleep now, hard to keep the eyes open |
| 23:09 | DerGuteMoritz | good night! |
| 23:15 | sandy1986 | Hi, can anyone explain me how form validation in enlive works? |
| 23:23 | TimMc | sandy1986: I was not aware enlive had anything to do with that. |
| 23:26 | sandy1986 | Mhh ... yeah |
| 23:26 | sandy1986 | maybe I must use sandbar |
| 23:28 | emezeske | ,*clojure-version* |
| 23:28 | clojurebot | {:major 1, :minor 3, :incremental 0, :qualifier nil} |
| 23:28 | emezeske | &*clojure-version* |
| 23:28 | lazybot | ⇒ {:major 1, :minor 3, :incremental 0, :qualifier nil} |
| 23:42 | mbac | what's the most standard clojure csv parsing library? |
| 23:48 | ldh | how does one compare lists in clojure? (compare '(1 2) '(3 4)) throws an exception |
| 23:51 | ldh | nm, = does it :-| |