2011-03-03
| 00:31 | ossareh | technomancy: have you any thoughts / experiences about how hard / easy it would be to get a git revision value in a hooke? |
| 00:41 | ossareh | hm, seems jgit can be wrapped reasonably easily. |
| 00:41 | technomancy | ossareh: those seem pretty orthogonal to me |
| 00:41 | ossareh | well... I want to be able to load a version number into my output html and I figured git version would be the most helpful |
| 00:42 | ossareh | zz my english is sucking right now :/ |
| 00:42 | ossareh | i guess my question was more like - have you done this / know of a project doing this. |
| 00:44 | technomancy | the pom.xml that comes with every lein-generated jar has git revision info in it |
| 00:45 | ossareh | OK - that is good. So accessing that from the runtime is just a case of read/parse the pom.xml? |
| 00:48 | technomancy | yeah, should work with clojure.java.io/resource |
| 00:49 | tomoj | mine doesn't appear to have git revision info |
| 00:50 | tomoj | maybe I misunderstood |
| 00:51 | ossareh | technomancy: ah, and there is the magic - I've realised that through my learning curve with clojure I learn about a new set of language features every 6 weeks or so - I then spend 6 weeks crow baring them into a solution that is usually already handled somewhere in the stdlibs... |
| 01:03 | technomancy | tomoj: lein pom has no git info? |
| 01:04 | tomoj | `lein pom && grep git pom.xml` gives only " https://github.com/technomancy/leiningen -->" |
| 01:05 | technomancy | it's actually able to read files straight out of .git/; you don't even need git installed to do it |
| 01:05 | technomancy | crazy |
| 01:05 | technomancy | tomoj: is the project OSS? |
| 01:05 | tomoj | oh, is it only supposed to work when the project root is the git root? |
| 01:05 | tomoj | naturally, I suppose |
| 01:05 | technomancy | yeah, I guess it might not work for a project that's nested |
| 01:05 | tomoj | nope |
| 01:06 | tomoj | I tried to argue for multiple repos but wound up with one mega-repo into which all my various projects go :( |
| 01:06 | technomancy | ah, bummer |
| 01:07 | tomoj | of course in this case it doesn't matter anyway, I'm not publishing the pom and would want to strip any git information that did make it in.. |
| 03:28 | bairespace_ | ,(defn <- [& args] (reduce #(%1 %2) args)) |
| 03:28 | clojurebot | DENIED |
| 03:29 | bairespace_ | ,(+ 2 2 2 2) |
| 03:29 | clojurebot | 8 |
| 03:40 | bairespace_ | ,(source core/->) |
| 03:40 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 03:41 | bairespace_ | ,(doc ->) |
| 03:42 | clojurebot | "([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts ... |
| 03:47 | bairespace_ | ,[0 1 2 #{3 4 5}] (-> {:a {:b 3}} :a :b) |
| 03:47 | clojurebot | [0 1 2 #{3 4 5}] |
| 03:53 | bairespace_ | ,(([0 1 2 #{3 4 5}] (-> {:a {:b 3}} :a :b) 4) |
| 03:53 | clojurebot | EOF while reading |
| 03:55 | bairespace_ | ,([0 1 2 #{3 4 5}] (-> {:a {:b 3}} :a :b)) |
| 03:55 | clojurebot | #{3 4 5} |
| 04:03 | bairespace_ | ,[] |
| 04:04 | clojurebot | [] |
| 04:04 | bairespace_ | ,{} |
| 04:04 | clojurebot | {} |
| 04:04 | bairespace_ | ,#{} |
| 04:04 | clojurebot | #{} |
| 07:08 | clgv | &(macroexpand-1 '(when-let [bla blubb] haha hoho)) |
| 07:08 | sexpbot | ⟹ (clojure.core/let [temp__3589__auto__ blubb] (clojure.core/when temp__3589__auto__ (clojure.core/let [bla temp__3589__auto__] haha hoho))) |
| 07:09 | clgv | why are there two let expressions involved? wouldn't one be sufficient? |
| 07:42 | raek | &(macroexpand-1 '(when-let [[foo bar] blubb] haha hoho)) |
| 07:42 | sexpbot | ⟹ (clojure.core/let [temp__3589__auto__ blubb] (clojure.core/when temp__3589__auto__ (clojure.core/let [[foo bar] temp__3589__auto__] haha hoho))) |
| 07:44 | raek | clgv: I think it is done this way make sure that the expression is only evaluated once, even when combined with desctructuring |
| 07:44 | clgv | raek: thx. hoeck already gave me a similar hint :) |
| 07:57 | fogus` | Whoa! Clojure's juxt is FP's []! That is all |
| 07:58 | __name__ | FP? |
| 07:59 | __name__ | $source juxt |
| 07:59 | sexpbot | juxt is http://is.gd/8fgyhN |
| 08:01 | fogus` | http://en.wikipedia.org/wiki/FP_(programming_language) |
| 08:14 | clgv | what's that supposed to mean? java.lang.IllegalArgumentException: recur arg for primitive local: sum must be matching primitive |
| 08:15 | clgv | I get it in this line: (loop [complist (second group-complist), cdf (transient []), sum (double 0.0)] |
| 08:17 | raek | clgv: what does the recur form lool like? |
| 08:17 | mduerksen | clgv: is the third argument in in your recur form a double? |
| 08:18 | clgv | it should be. it is like: new-sum (+ sum (f x)) and new-sum is in the recur |
| 08:19 | AWizzArd | http://www.classnamer.com/ |
| 08:20 | clgv | AWizzArd: "SecureGirlfriendStream" roflmao. |
| 08:24 | mduerksen | clgv: if (f x) doesn't return a double, then + won't return a double as well afaik |
| 08:25 | clgv | mduerksen: ok, but (f x) is a method specified in a protocol. can I type hint its return type? |
| 08:25 | mduerksen | i'm not sure about that. i guess it also depends on the clojure version |
| 08:25 | clgv | 1.2 |
| 08:26 | clgv | well otherwise I surround it with (double ...) |
| 08:26 | mduerksen | you could find out with (class (f x)) |
| 08:27 | clgv | I know that it should return a double since I wrote it myself |
| 08:27 | clgv | but I don't know how to tell the compiler that this protocol method will return a double |
| 08:27 | raek | hrm, I thought this primitive stuff was new for 1.3... |
| 08:28 | clgv | raek: not everything |
| 08:30 | Chousuke | functions can't return primitives in 1.2 IIRC :/ |
| 08:31 | clgv | but there is the fibonacci example that is said to be valid in 1.2 |
| 08:31 | Chousuke | http://dev.clojure.org/display/doc/Enhanced+Primitive+Support this describes 1.3 |
| 08:32 | clgv | oh ok. damn :( |
| 08:32 | clgv | hmm I thought I read something related to 1.2 in a blog entry on ^:static |
| 08:32 | clgv | is ^:static also 1.3? |
| 08:34 | cemerick | IIRC, ^:static became a no-op with the recent var changes |
| 08:34 | cemerick | a no-op and unnecessary, that is |
| 08:40 | clgv | ok. probably (double ...) will work then |
| 09:00 | clgv | &(doc empty?) |
| 09:00 | sexpbot | ⟹ "([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))" |
| 09:01 | clgv | &(empty? nil) |
| 09:01 | sexpbot | ⟹ true |
| 10:36 | flatt | should I be using eval here: (defn [x] (eval (doto (SomeClass.) (.doStuff x))))? can I (or should I) pull it off with defmacro instead? |
| 10:38 | raek | flatt: you very rarely need to use eval. |
| 10:38 | raek | flatt: why not (defn [x] (doto (SomeClass.) (.doStuff x))) |
| 10:38 | flatt | oh, wait, that was over-simplified. |
| 10:40 | flatt | (defn [& args] (eval `(doto (SomeClass.) ~(list '.doStuff ~args)))) |
| 10:40 | Chousuke | flatt: why would you do that with a function? |
| 10:40 | Chousuke | one big problem with eval is that it can't access locals |
| 10:41 | Chousuke | so all you can pass to your function are symbols that name globals. |
| 10:41 | Chousuke | or literals |
| 10:41 | raek | flatt: ah, so you want something like apply, but for methods? |
| 10:41 | flatt | oh, then then eval doesn't help there. |
| 10:42 | flatt | imagine variable number of forms in the body of doto, depending on what args are supplied |
| 10:44 | bennylu | how to use ns-publics? (ns-publics 'some-ns) |
| 10:44 | bennylu | => #<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.IObj> |
| 10:44 | bennylu | i want to retrive all the functions in the namespace with a certin type .. |
| 10:44 | raek | ,(ns-publics 'clojure.core) |
| 10:44 | clojurebot | {sorted-map #'clojure.core/sorted-map, read-line #'clojure.core/read-line, re-pattern #'clojure.core/re-pattern, keyword? #'clojure.core/keyword?, val #'clojure.core/val, chunked-seq? #'clojure.core/... |
| 10:46 | bennylu | , (ns-publics 'clojure.xml) |
| 10:46 | clojurebot | {content-handler #'clojure.xml/content-handler, *stack* #'clojure.xml/*stack*, attrs #'clojure.xml/attrs, element #'clojure.xml/element, tag #'clojure.xml/tag, startparse-sax #'clojure.xml/startparse... |
| 10:46 | raek | bennylu: it looks like the exception is from the code that uses the value of your (ns-publics 'some-ns) call |
| 10:48 | raek | flatt: it is certainly possible to do that with a macro, but dependending on what you know about the methods (e.g. arity) you could possibly implement it as an ordinary function (which is preferred if possible) |
| 10:48 | bennylu | i am calling it directly from the repl.. |
| 10:49 | flatt | raek: I see, thanks. |
| 10:51 | TimMc | bennylu: Are you bennylut? |
| 10:51 | raek | bennylu: what does the stack trace look like? |
| 10:52 | raek | bennylu: also, does this happen for all namespaces? for instance, does (ns-publics 'clojure.core) work for you? |
| 11:03 | perkinsc | ,(clojure-version) |
| 11:03 | clojurebot | "1.2.0" |
| 11:09 | sattvik | flatt: If you know the number of arities you will be working with, you can do something like: |
| 11:09 | sattvik | ,(let [invoker (fn ([a] (. Integer valueOf a)) ([a b] (. Integer valueOf a b)))] (apply invoker ["100" 2])) |
| 11:09 | clojurebot | 4 |
| 11:09 | pyr | hi |
| 11:10 | sattvik | The only other non-macro approach I can think of is using Java's reflection APIs. |
| 11:10 | pyr | it's not clear to me if there's a way to kill agents forcibly |
| 11:10 | pyr | i'm using agents with await-for |
| 11:10 | pyr | if an agent returns false from await-for |
| 11:11 | pyr | do I need to kill it or will the thread be available for a new agent ? |
| 11:11 | TimMc | $findfn [1 2 3] 3 4 [1 2 4] |
| 11:11 | sexpbot | [] |
| 11:12 | chouser | pyr: I don't think there's any good way to forcibly kill an agent. |
| 11:13 | pyr | ok |
| 11:15 | clgv | where do I get clojure-contrib 1.3.0 alpha 4? |
| 11:49 | gtrak | how do you guys do a find-usages? |
| 11:53 | sattvik | find-usages? |
| 11:54 | gtrak | yea |
| 11:55 | TimMc | Like, all references to a var in a project? |
| 11:55 | TimMc | I generally grep. -.- |
| 11:56 | gtrak | I guess that's pretty simple :-) |
| 11:57 | dakrone | b |
| 11:58 | amalloy | gtrak: slime has a feature like that, but i don't know if the clojure swank server supports it |
| 11:58 | gtrak | ah |
| 11:58 | amalloy | heh, indeed. "Wrong type argument: listp, :not-implemented" |
| 11:59 | amalloy | if it did work, though, it would be C-c C-w C-r |
| 11:59 | amalloy | for "who references" |
| 12:00 | bennylu | TimMc, yes i am bennylut |
| 12:00 | gtrak | amalloy, i can confirm "error in process filter: who-references is not implemente yet on clojure" |
| 12:00 | TimMc | bennylu: OK, so you were confused some days back about why ^foo didn't give you the metadata on foo. It turns out this was a change from CLojure 1.1. to 1.2. |
| 12:01 | TimMc | I was reading Programming Clojure and ran into the same problem. |
| 12:01 | bennylu | raek, i just checked and to clojure.core and it not throwing exception.. |
| 12:01 | sattvik | gtrak: If you wanted to do it within clojure, you could probably abuse the source macro. |
| 12:02 | bennylu | TimMc, Thanks! i was reading the book programming clojure and there it was explained that that sould work, i guess that it changed after the book came of |
| 12:02 | amalloy | $source -> |
| 12:03 | sexpbot | -> is http://is.gd/yfj1XP |
| 12:03 | __name__ | good morning |
| 12:04 | gtrak | anyone ever had lein marg throw an exception that it can't find the project.clj? |
| 12:05 | amalloy | TimMc: the findfn you were looking for a bit ago is probably replace |
| 12:05 | amalloy | &(replace {3 4} [1 2 3]) |
| 12:05 | sexpbot | ⟹ [1 2 4] |
| 12:06 | TimMc | Oh, right! |
| 12:06 | TimMc | And replace has the wrong semantics for me. |
| 12:06 | TimMc | behavior, rather |
| 12:07 | amalloy | oh? |
| 12:08 | TimMc | I need identical? instead of =. |
| 12:10 | TimMc | I ended up writing replace-1: https://gist.github.com/853113 |
| 12:10 | amalloy | TimMc: you could use an identity map |
| 12:11 | TimMc | What's this now? |
| 12:11 | amalloy | http://download.oracle.com/javase/1.4.2/docs/api/java/util/IdentityHashMap.html in java - i think there's something similar in clojure |
| 12:12 | TimMc | Oh yeah, I just came across that the other day. |
| 12:15 | TimMc | Haha, it works! |
| 12:16 | TimMc | (replace (IdentityHashMap. {d0 d1}) [3 4 d0 5]) |
| 12:16 | amalloy | TimMc: or (into (sorted-map-by identical?) mymap) |
| 12:17 | amalloy | except rewritten so that it actually works :P |
| 12:25 | TimMc | That's even longer. |
| 12:25 | naeu | is there anyone about that can help me understand how I may avoid inserting a race condition by using the STM and refs? |
| 12:25 | TimMc | naeu: Do you just want to make sure that a read-update-write is consistent? |
| 12:26 | naeu | TimMc: I'm not sure what you mean. In my head I want to make sure that if while I read a given ref, it can't be updated elsewhere |
| 12:27 | naeu | perhaps I just want basic locking |
| 12:27 | naeu | but that doesn't feel right |
| 12:27 | TimMc | You don't want locking. Nobody does, even if they think they do. |
| 12:27 | naeu | :-) |
| 12:27 | naeu | so I have a ref of keywords |
| 12:28 | naeu | and I want one thread to be able to look at that ref, and if a particular keyword doesn't exist in there, to register a fn to be called when it does |
| 12:28 | TimMc | A ref of a collection of keywords? |
| 12:28 | naeu | and on another thread I want to be able to update the ref and add a keyword to the collection |
| 12:29 | naeu | and call all the registered fns associated with that keyword |
| 12:29 | naeu | yup, I'm just currently using a vector |
| 12:29 | TimMc | You might find a set more appropriate than a vector, depending on your app. |
| 12:30 | naeu | TimMc: oh sure |
| 12:30 | sattvik | Does ensure solve your problem? |
| 12:30 | TimMc | But anyway, there are a couple of ways to do this, and I'm still learning about concurrency in Clojure. |
| 12:31 | TimMc | naeu: You're familiar with dosync, yes? |
| 12:31 | naeu | TimMc: by familiarity, I've used it |
| 12:31 | naeu | and I understand that it stops modification from multiple places by re-running |
| 12:31 | TimMc | So you know that inside a dosync you have a consistent view of the world. |
| 12:31 | naeu | sattvik: so you just call (ensure my-ref) in the dosync? |
| 12:32 | naeu | TimMc: sure, but is that just a consistent view of the refs you modify or also the refs you deref? |
| 12:33 | TimMc | All of them. |
| 12:33 | naeu | TimMc: perhaps not, it doesn't explain the existence of ensure |
| 12:33 | naeu | sattvik: I think that this is exactly what I need |
| 12:34 | naeu | TimMc: I believe that in a dosync the state of a ref you deref may change during the rest of the execution of the transaction |
| 12:35 | naeu | without requiring the transaction to re-run |
| 12:35 | sattvik | naeu: Your welcome. |
| 12:35 | naeu | whereas a ref you modify may not change elsewhere during the rest of the execution of the transaction |
| 12:35 | naeu | sattvik: is what I'm saying making any sense? |
| 12:35 | naeu | I might be totally wrong :-) |
| 12:35 | TimMc | huh |
| 12:36 | sattvik | From http://clojure.org/refs : No changes will have been made by any other transactions to any Refs that have been ref-set/altered/ensured by this transaction |
| 12:37 | amalloy | yes, that's what ensure is for |
| 12:37 | chouser | naeu: I don't think that's right. Once you're in a transaction, every deref of a ref will return the same value. |
| 12:37 | naeu | chouser: yeah, but it will return the first value |
| 12:38 | naeu | even if the ref has been modified elsewhere since the first deref |
| 12:38 | naeu | at least that's what I understand |
| 12:38 | chouser | oh, maybe I misunderstood you |
| 12:38 | joshua__ | Alright, I'm confused. I have two programs running congomongo. If I use one of the programs to upload items via the swank repl it does fine. If I use it to upload items via normal running it fails, despite the upload being accomplished through the same method calls. The other program doesn't have this problem. What am I not understanding? |
| 12:38 | naeu | so it provides a consistent view in the transaction |
| 12:38 | naeu | but not necessarily across transactions |
| 12:39 | naeu | whereas if you change the ref, the transaction will ensure a consistent view across transactions |
| 12:39 | naeu | by forcing other transactions to repeat if necessary |
| 12:40 | naeu | which brings me to my next question - how do I have a side-effect fn get executed immediately*after* a transaction has completed |
| 12:41 | naeu | obviously I can't put it in the transaction |
| 12:41 | naeu | do i use an agent for that? |
| 12:41 | Chousuke | dunno about immediately, but agent sends are queued until the transaction finishes |
| 12:43 | naeu | cool, i think a combo of dosync, ensure and agents will do what I want |
| 12:43 | sattvik | naeu: I may be misunderstanding your question, but can't you just call the function after the transaction? (do (dosync ...) (my-fn ...))? |
| 12:46 | sattvik | Or you can even use the result of a transaction as an argument to a function. |
| 12:46 | naeu | sattvik: I'm not sure I can as the arg to my-fn will be the dereffed ref |
| 12:47 | naeu | sattvik: that might work |
| 12:47 | amalloy | sattvik: https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/registry.clj#L96 is an example of doing this |
| 12:47 | sattvik | ,(conj [1 2] (dosync 3)) |
| 12:47 | clojurebot | [1 2 3] |
| 12:47 | amalloy | er |
| 12:47 | amalloy | naeu: ^ was for you |
| 12:51 | mattmitchell | is there a way to extract values from a hash in a ordered way? |
| 12:54 | naeu | amalloy: so that works because bot is altered within the transaction |
| 12:54 | naeu | but if there was no alter on bot, then @bot might be different at time t+1 on another thread than the value of @bot at time t within the transaction |
| 12:57 | amalloy | naeu: https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/ping.clj#L10-17 maybe? captures the return value of the dosync. still uses alter so maybe this doesn't address your concern but i guess i don't understand your concern :P |
| 12:57 | naeu | amalloy: I probably don't understand my concern either! |
| 12:58 | naeu | but i think capturing the result of a dosync will be enough |
| 12:59 | TimMc | naeu: "All reads of Refs will see a consistent snapshot of the 'Ref world' as of the starting point of the transaction (its 'read point'). The transaction will see any changes it has made. This is called the in-transaction-value." |
| 12:59 | TimMc | http://clojure.org/refs |
| 12:59 | amalloy | mattmitchell: you can use a sorted-map |
| 13:00 | amalloy | otherwise, no, hashes are not ordered |
| 13:00 | mattmitchell | amalloy: ok excellent thanks! |
| 13:00 | naeu | TimMc: so reads don't affect a transaction then? |
| 13:00 | naeu | TimMc: I don't grok this snippet " The transaction will see any changes it has made." |
| 13:01 | amalloy | &(let [x (ref 0)] (dosync (println @x) (alter x inc) (println @x))) |
| 13:01 | sexpbot | ⟹ 0 1 nil |
| 13:01 | naeu | I'm assuming it means the transaction will see any changes to the ref within it, but care of changes outside of it if the ref is only read |
| 13:01 | TimMc | If I (dosync @foo (ref-set foo ...) @foo) the two reads will be different. |
| 13:01 | TimMc | amalloy: Holy shit you're fast. |
| 13:01 | naeu | TimMc: sure, but that's setting the ref from within the same transaction |
| 13:02 | naeu | TimMc: but if you did a ref-set in a different transaction on a different thread, @foo would always be the same |
| 13:03 | amalloy | naeu: that's the point. it's a transaction. you don't want to see changes others have made: if you did, it would be unrestrained global mutability, no? |
| 13:03 | naeu | exactly, but I want to retry my transaction if others have made changes to the ref I'm reading |
| 13:03 | TimMc | amalloy: Then what does ensure do? |
| 13:03 | naeu | which is why I believe I need ensure |
| 13:03 | naeu | which does exactly that |
| 13:04 | amalloy | right |
| 13:04 | amalloy | i belive you do too. we could both be wrong, but it seems like you'll find out faster if you just try |
| 13:04 | naeu | the docs say it's similar (but more efficient) to doing (ref-set myref @my-ref) |
| 13:05 | naeu | the problem is that it's not so easy to try out things that might have a race condition |
| 13:05 | raek | ensure is for when you want to ensure that a ref that you don't need to read or write from stays unmodified during the transaction |
| 13:06 | TimMc | raek: Ah! It is a way of pulling other refs into the transaction? |
| 13:06 | naeu | thanks everyone for your help, it's much appreciated |
| 13:07 | mattmitchell | amalloy: is there a way to take a hash-map, and convert it into a sorted-map? |
| 13:07 | raek | I think it's like saying "this ref must be unchanged during the transaction" |
| 13:07 | amalloy | mattmitchell: yes, but if you aren't building a sorted map to begin with it will be slow and you might as well just do (sort (keys m)) |
| 13:08 | naeu | raek: that's my understanding too |
| 13:08 | devn | re-reading WhyFP is a good idea |
| 13:08 | mattmitchell | amalloy: ok makes sense. thanks. |
| 13:08 | devn | it's like re-reading the agile manifesto, it should be done every now and then |
| 13:08 | bennylu | hi, a little quiestion about managing clojure project - |
| 13:08 | devn | bennylu: go ahead |
| 13:09 | amalloy | &(let [m {"test" 1 "egr" 2 "wer`1" 3}] (print m) (print (into (sorted-map) m))) |
| 13:09 | sexpbot | ⟹ {test 1, egr 2, wer`1 3}{egr 2, test 1, wer`1 3}nil |
| 13:09 | amalloy | mattmitchell: ^ |
| 13:09 | bennylu | if i have a reletivly big project do you split it to several namespaces in a hirarchy similar to java? |
| 13:10 | devn | bennylu: yes and no |
| 13:11 | devn | bennylu: im trying to think of how to expand on that... heh |
| 13:11 | devn | clojure is not java so the hierarchies look a bit different |
| 13:12 | bennylu | i try - but it look like namespaces are "larger" in scope than classes and so there is too few name spaces and too much code in each ... |
| 13:13 | devn | bennylu: My opinion is that what you want to do is Separation of Concerns, and modularize where appropriate |
| 13:13 | bennylu | im finding myself scrolling reletivly large text in order to find the function that i want to modify / read |
| 13:13 | devn | ive found that it is helpful to write one gigantic file where everything lives in the same namespace |
| 13:13 | devn | and then split it out from there |
| 13:13 | devn | but i havent done anything that's like 800k lines of code |
| 13:13 | devn | so perhaps that would not work for you |
| 13:14 | devn | bennylu: clojure.core, the source, is mostly in one place |
| 13:14 | devn | over-namespacing can be equally annoying |
| 13:15 | bennylu | i not talking about 800k too :) but even on 900 lines of code it gets preety heavy to find stuff.. |
| 13:15 | bennylu | yes, i know what you means .. i guess i just have to learn to use the find function more :) |
| 13:16 | amalloy | bennylu: are you using slime/swank? |
| 13:16 | devn | bennylu: i mean, this is not so much a clojure problem as it is how you decide to separate the modules |
| 13:16 | devn | "modules" |
| 13:16 | TimMc | ,[(identical? 3 3) (identical? 300 300)] |
| 13:16 | clojurebot | [true false] |
| 13:16 | TimMc | Is this an instance of interning in Integer? |
| 13:16 | TimMc | or rather, in the compiler's handling of int literal? |
| 13:16 | amalloy | TimMc: yes |
| 13:16 | amalloy | the first 32 ints (or 256?) are interned |
| 13:16 | bennylu | i started with it but i hear about counterclockwise and give it a shot - its preety good .. |
| 13:17 | bennylu | so i now use cw |
| 13:17 | amalloy | bennylu: well, find ccw's "find" feature, then :P |
| 13:17 | TimMc | WHOA |
| 13:17 | amalloy | instead of looking around by hand |
| 13:17 | devn | CCW is pretty awesome if you want to stay in IDE land. learning a little bit of slime isn't a bad idea, though. it's awesome. |
| 13:17 | mattmitchell | amalloy: cool thanks again :) |
| 13:17 | bennylu | lol :) |
| 13:17 | devn | lpetit is a champ. |
| 13:17 | bennylu | lpetit? |
| 13:17 | TimMc | I just got the last screenful of text within a couple seconds. latency weirdness |
| 13:17 | devn | bennylu: he did most of CCW |
| 13:18 | amalloy | &(identical? 1 (inc 0)) |
| 13:18 | sexpbot | ⟹ true |
| 13:18 | devn | he put a ton of thought into the structural editing |
| 13:18 | bennylu | he did relly good job |
| 13:18 | devn | yeah it's pretty great |
| 13:19 | amalloy | funny how from where i'm sitting, your latency issues are indistinguishable from illegal drugs |
| 13:19 | devn | im an emacs guy until the day i die, but CCW is fantastic |
| 13:19 | bennylu | i tried enclojure to but it was awfull - crashing all the time and slow... |
| 13:19 | devn | amalloy: who me? |
| 13:19 | amalloy | no, tim |
| 13:19 | devn | ah |
| 13:19 | amalloy | his sudden WHOA just reminded me of stoners |
| 13:19 | devn | :) |
| 13:19 | devn | WHOA DUDE THIS FUNCTION IS LIKE, WHOA |
| 13:20 | TimMc | amalloy: Same here, actually. |
| 13:20 | TimMc | IT'S LIKE EACH SEXPR IS ITS OWN UNIVERSE |
| 13:21 | devn | hahaha |
| 13:21 | amalloy | *chuckle* |
| 13:21 | devn | that sounds like something id say after a beer or two |
| 13:21 | devn | im not proud of that |
| 13:21 | devn | it's just true |
| 13:23 | devn | this is your chance to make fun of me |
| 13:24 | pyr | (str :foo) yields ":foo" |
| 13:24 | amalloy | &(name :foo) |
| 13:24 | sexpbot | ⟹ "foo" |
| 13:24 | amalloy | i think stoner TimMc makes an excellent observation about the ramifications of immutability |
| 13:24 | devn | amalloy: say more |
| 13:24 | pyr | amalloy: :) |
| 13:24 | pyr | amalloy: thx! |
| 13:25 | cemerick | devn: it's going to keep getting better. I'm hoping to take a day for it next week. |
| 13:25 | devn | cemerick: yeah i didn't mean to assign all of CCW's development only to lpetit |
| 13:25 | devn | thanks for your work as well. :) |
| 13:25 | cemerick | oh, wasn't trying to grab credit |
| 13:26 | cemerick | He's absolutely the driving force -- I only pitch in here and there. :-) |
| 13:26 | devn | cemerick: nono i wasn't trying to suggest you were im just interested in giving it where it's due |
| 13:26 | cemerick | :-) |
| 13:26 | devn | :) |
| 13:26 | cemerick | devn: how's things, BTW |
| 13:27 | devn | great, started a clojure meetup in Madison, WI -- have our 2nd meeting next monday, still pretty small but im slowly making the rounds to local meetup groups and attracting some interest |
| 13:27 | devn | i've slowly convinced a few ruby guys to pair program with me on some clojure |
| 13:27 | devn | they scoffed and hemmed and hawed at first, but i think i beat them into submission by showing them ruby came out of dylan, scheme, and the CLOS :) |
| 13:30 | devn | cemerick: how about you? |
| 13:30 | cemerick | devn: sorry, pulled in different directions :-) |
| 13:31 | cemerick | absurdly busy |
| 13:31 | cemerick | usually in a good way, sometimes not |
| 13:31 | cemerick | it's been an odd year so far |
| 13:31 | devn | :) sine waves or square waves? |
| 13:31 | cemerick | Been working on a bunch of Clojure open source stuff in the past couple of weeks, which is a nice change of pace |
| 13:31 | cemerick | square, definitely :-/ |
| 13:32 | devn | yeah, that can be exhilirating though! when people walk in the door, hit the whiteboard and the room explodes with action that's a great feeling |
| 13:33 | devn | cemerick: going to make it to the next conj? |
| 13:33 | cemerick | devn: can't imagine not :-) |
| 13:34 | devn | :) good to hear it |
| 13:34 | devn | cemerick: what open source projects have you been cracking at? (btw if you're busy feel free to table this discussion -- i had a doctor's appointment today so I'm slacking a bit) |
| 13:36 | cemerick | devn: there's https://github.com/cemerick/bandalore, some nREPL fixes, and a refurbishing of a simpledb client library based on Rich's original implementation. |
| 13:36 | devn | cemerick: wanna give me an elevator pitch? :) |
| 13:37 | cemerick | on simpledb? |
| 13:37 | devn | *nod* |
| 13:37 | devn | also, i didn't know rich wrote a simpledb implementation |
| 13:38 | cemerick | devn: it's a zero-admin couchdb with "proper" indexes and ad-hoc query capabilities |
| 13:39 | cemerick | hosted by a known-good vendor, etc |
| 13:39 | cemerick | right next to the EC2 instances I'm using already, etc |
| 13:39 | cemerick | Essentially, I'm going all-in on AWS. |
| 13:39 | devn | yeah absolutely -- ive been pretty much doing everything on S3 and EC2 lately along with a bit of heroku here and there |
| 13:39 | cemerick | Thus the SQS client impl. |
| 13:40 | devn | Redis is really cool. Play with that at all? |
| 13:40 | cemerick | No, never looked at it. |
| 13:41 | cemerick | I've been trying to simplify everything as much as possible of late -- and anything with a whiff of administration overhead is getting tossed overboard. |
| 13:41 | devn | Redis in a lot of ways reminds me of the clojure STM -- do you can wrap multiple commands in a pipeline etc |
| 13:41 | cemerick | devn: FYI, the most recent maintained fork of Rich's SDB client is here: https://github.com/bapehbe/sdb |
| 13:41 | devn | O(1) for pretty much everything except on lists, and so on |
| 13:42 | cemerick | I'm mostly rebuilding it though: https://docs.google.com/document/d/1K5p2RRVtvYxBNLEJuWGNf1iZak2ri8cI73joWu9K1W0/edit?hl=en&authkey=CMDR_6AF |
| 13:42 | devn | cemerick: im definitely going to look into that |
| 13:42 | devn | we've been using mongo quite a bit lately |
| 13:42 | devn | (where appropriate of course) |
| 13:42 | cemerick | it sounds like redis has a lot going for it, especially since they managed to work out larger-than-memory datasets |
| 13:43 | cemerick | That was the limitation that kept me away initially |
| 13:43 | devn | cemerick: the coolest part of redis that i have yet to toy with is the pub/sub system |
| 13:43 | devn | http://redis.io/commands#pubsub |
| 13:46 | devn | it gives you what is essentially a broadcast server to transmit messages over channels to many subscribers in real time |
| 13:47 | devn | lots of cool ideas come to mind |
| 13:50 | edw``` | Are there Clojure-native string->number procedures? I wind up doing #(Integer. %) a lot, which is rather tedious. |
| 13:50 | cemerick | edw```: if you're certain the string only contains a number literal, use read-string |
| 13:50 | edw | That sort of seems like using an atomic bomb when a firecracker is called for. How efficient is that? |
| 13:50 | edw | In practive, I have STRING-TO-INT and STRING-TO-FLOAT defined in a million files, which is what makes me think having a built-in would be wise. (I do a lot of reading from text files and URLs.) |
| 13:54 | cemerick | ah, so an ad-hoc mq |
| 14:07 | devn | cemerick: yeah good way of thinking about it |
| 14:07 | devn | cemerick: i think about using it for things like...you have data being funneled from one big EC2 instance to many smaller instances that handle specific subsets of the total dataset |
| 14:08 | devn | this is probably a cliche by now, but also, if you wanted to do a Twitter clone, that's your ticket |
| 14:09 | devn | redis 2.3 is i believe going to introduce a more complete distributed system, it will be interesting to see how pub/sub works in that context |
| 14:09 | Nanarpuss | Anyone work with slime? I'm getting an error everytime I hit return on the REPL... It says "Error in process filter: Wrong number of arguments: nil, 1" |
| 14:10 | devn | Nanarpuss: ah yeah i was getting that... i think it's your version of SLIME |
| 14:10 | devn | are you running slime from source? |
| 14:10 | Nanarpuss | yeah |
| 14:10 | devn | yeah, use the ELPA package |
| 14:10 | mattmitchell | i'm using the contrib.sql lib and attempting to insert a date to mysql. How does it handle dates? Just as strings? Do I have to format the value myself? |
| 14:10 | Nanarpuss | I've tried ELPA too |
| 14:10 | devn | that will get rid of it |
| 14:10 | devn | Nanarpuss: hm, weird. that fixed it for me |
| 14:11 | Nanarpuss | so ELPA slime and swank-clojure worked for you? |
| 14:11 | devn | Nanarpuss: are you sure you don't have slime loading from source still? |
| 14:11 | devn | Nanarpuss: yes. with 1.3.0-SNAPSHOT |
| 14:11 | Nanarpuss | ohh I'm on 1.2 |
| 14:11 | Nanarpuss | let me try 1.3 and see what happens |
| 14:11 | devn | Nanarpuss: im not sure how much of a difference it makes, but that's my setup and it seems to be working |
| 14:12 | raek | I don't think the clojure version should make any difference here |
| 14:12 | devn | raek: is 1.3.0-SNAPSHOT just for clojure 1.2 then? and swank-clojure is just 1.2? |
| 14:12 | devn | err and swank-clojure 1.2 is just for 1.1.0? |
| 14:13 | technomancy | any version of swank-clojure should work with all clojure versions |
| 14:13 | raek | ah, thought you were refering to clojure versions... |
| 14:13 | technomancy | modulo a few times where I apply patches I get without thinking them through =( |
| 14:13 | devn | technomancy: i saw your post on the Wrong number of arguments: nil, 1 i think |
| 14:13 | devn | IIRC you suggested to just use the ELPA packages, and so I did, and then never received the error again |
| 14:13 | technomancy | the slime version is what you have to watch out for |
| 14:14 | devn | i was compiling from source |
| 14:14 | devn | technomancy: why no marmalade in the starter-kit, btw? |
| 14:14 | technomancy | I wish that were simpler, but I don't really have the patience to work it out with the CL guys. |
| 14:14 | technomancy | devn: no reason; just haven't gotten around to it |
| 14:15 | technomancy | tarball packages are slightly more complicated; I guess that's the excuse |
| 14:15 | devn | *nod* -- ill submit a pull req. |
| 14:16 | TimMc | What is a use-case of ensure? |
| 14:17 | TimMc | That is, why protect a ref from modification if you never read or write it in that transaction? |
| 14:19 | devn | TimMc: ive seen several opinions on that |
| 14:20 | devn | what ive concluded is that it's a read with an annotation |
| 14:20 | devn | it increases parallelism w/r/t a dummy read/write like ref-set |
| 14:20 | TimMc | Surely there's no behavioral difference within one transaction between @foo and (ensure foo)? |
| 14:21 | devn | i think it basically means that you're going to be changing foo later and so others should stay away from it |
| 14:21 | devn | maybe to ease contention? |
| 14:21 | Nanarpuss | hmm still no luck |
| 14:21 | Nanarpuss | just tried 1.3 |
| 14:22 | TimMc | devn: Like a way to say early on in a long transaction, "back off, I'll be using this"? |
| 14:22 | devn | TimMc: i THINK so |
| 14:22 | devn | it increases isolation |
| 14:22 | bennylu | what is the difference between into and concat?? (besides the order of the result) |
| 14:23 | TimMc | I don't see any usage inside the clojure source. |
| 14:23 | amalloy | bennylu: concat is lazy |
| 14:23 | bennylu | amalloy, thanks! |
| 14:23 | amalloy | &(take 1 (into () (range))) |
| 14:23 | devn | TimMc: i think it is ref-set's half-brother |
| 14:23 | amalloy | &(take 1 (concat () (range))) |
| 14:23 | sexpbot | ⟹ (0) |
| 14:23 | raek | bennylu: into is conj'ing on some element to any data structure, concat concatenates two sequences |
| 14:23 | sexpbot | Execution Timed Out! |
| 14:24 | TimMc | bennylu: I believe into gives you back a collection of the type you asked for. |
| 14:24 | devn | TimMc: i think i found an answer for you |
| 14:24 | amalloy | TimMc: into is just (partial reduce conj), more or less |
| 14:25 | amalloy | &((partial reduce conj) [1 2] (range 5)) |
| 14:25 | sexpbot | ⟹ [1 2 0 1 2 3 4] |
| 14:25 | amalloy | &(into [1 2] (range 5)) |
| 14:25 | sexpbot | ⟹ [1 2 0 1 2 3 4] |
| 14:25 | raek | ,[(into [1 2] [3 4]) (into (list 1 2) [3 4]) (concat [1 2] [3 4]) (concat (list 1 2) [3 4]] |
| 14:25 | clojurebot | Unmatched delimiter: ] |
| 14:25 | raek | ,[(into [1 2] [3 4]) (into (list 1 2) [3 4]) (concat [1 2] [3 4]) (concat (list 1 2) [3 4])] |
| 14:25 | clojurebot | [[1 2 3 4] (4 3 1 2) (1 2 3 4) (1 2 3 4)] |
| 14:25 | devn | TimMc: The scenario you describe cannot happen in Clojure's STM. Clojure's STM uses MVCC and provides snapshot isolation to transactions - a transaction will never see inconsistent state. Being MVCC-based, it is subject to write skew, and provides an ensure construct that allows one to tag dependent reads, with more concurrency than the dummy writes usually used to address write skew. Livelock is a theoretical scenario, but it is not a non-blocking ... |
| 14:25 | devn | ... design, thus mitigating churn. Actual livelock is avoided via retry limits and timeouts. There is, as you mention, as-yet-unrealized potential for configurable contention resolution policy. |
| 14:26 | devn | -rich hickey, 2009 |
| 14:27 | TimMc | I don't know what livelock is (though I could guess) and I don't know what write skew is. |
| 14:27 | TimMc | So... ensure is probably there if you need super concurrency performance. |
| 14:27 | TimMc | ...but is never strictly necessary from a results point of view. |
| 14:27 | devn | TimMc: there's a lot of literature out there, but most of it is specific to an implementation |
| 14:29 | devn | TimMc: i wish i could be of more help, but i can't really give you anything more than i already have without speculation |
| 14:29 | TimMc | As long as I don't need to know about ensure, I'll probably hold off on trying to figure it out. :-) |
| 14:30 | devn | TimMc: yeah I'm hunting for some code that uses it, but then you need to be sure that they're not just using it for the sake of using it |
| 14:30 | TimMc | It's not present in contrib either, I think. |
| 14:31 | devn | TimMc: http://www.cs.rochester.edu/research/synchronization/rstm/primer.shtml |
| 14:31 | devn | that's interesting and somewhat relevant to this discussion |
| 14:31 | TimMc | (I've only beenlooking on the .clj side of things.) |
| 14:31 | devn | TimMc: http://www.cs.rochester.edu/research/synchronization/rstm/libraries.shtml |
| 14:31 | devn | that's good as well |
| 14:33 | gfrlog | ,(format #"this won't work %s cuz it's a regex" "oh well") |
| 14:33 | clojurebot | java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to java.lang.String |
| 14:33 | gfrlog | so is there any function for regexly escaping a string? |
| 14:33 | gfrlog | and did I state that question in an understandable way? |
| 14:33 | devn | IIRC there is |
| 14:34 | gfrlog | I just looked on java.util.regex.Pattern and don't see anything |
| 14:34 | TimMc | $findfn "." "\\." |
| 14:34 | sexpbot | [] |
| 14:34 | gfrlog | TimMc: brilliant, if unsucessful |
| 14:35 | devn | i used to have a thingamajig that let me build up a regex from strings |
| 14:35 | brehaut | (str #".") |
| 14:35 | brehaut | ,(str #".") |
| 14:35 | gfrlog | ,(str #".") |
| 14:35 | clojurebot | "." |
| 14:35 | clojurebot | "." |
| 14:35 | TimMc | ooh |
| 14:35 | TimMc | ,(java.util.regex.Pattern/quote ".") |
| 14:35 | clojurebot | "\\Q.\\E" |
| 14:35 | gfrlog | wtf is \Q and \E? |
| 14:35 | TimMc | Oh, uh, I guess that works too. |
| 14:36 | jweiss | quote, end quote? |
| 14:36 | gfrlog | man I looked right at that function in the javadocs and didn't see it cause it wasn't called "escape" |
| 14:36 | TimMc | ,"\\" |
| 14:36 | clojurebot | "\\" |
| 14:36 | gfrlog | ,(java.util.regex.Pattern/quote "\\E") |
| 14:36 | clojurebot | "\\Q\\E\\\\E\\Q\\E" |
| 14:36 | gfrlog | holy cow |
| 14:37 | TimMc | haha |
| 14:37 | gfrlog | man testing to make sure that does what I think it does sounds like a headache |
| 14:37 | TimMc | ,(java.util.regex.Pattern/quote "\\$") |
| 14:37 | clojurebot | "\\Q\\$\\E" |
| 14:37 | devn | this seems like the wrong way to go about doing this... |
| 14:38 | gfrlog | devn: it sounds perfect, what could be wrong with it? |
| 14:38 | TimMc | ,(java.util.regex.Pattern/quote "$") |
| 14:38 | clojurebot | "\\Q$\\E" |
| 14:38 | gfrlog | ,(re-pattern (java.util.regex.Pattern/quote "\\E")) |
| 14:38 | clojurebot | #"\Q\E\\E\Q\E" |
| 14:38 | devn | maybe i misunderstand your original problem, but you wanted to call format on a regex |
| 14:38 | devn | i dont see how this solves your problem |
| 14:38 | TimMc | OK, so it doesn't attempt to quote its own sentinals via nesting or anything. |
| 14:38 | gfrlog | devn: no, I actually just needed an escape |
| 14:38 | gfrlog | ,(re-pattern (java.util.regex.Pattern/quote "\\E\\Q\\E")) |
| 14:39 | clojurebot | #"\Q\E\\E\Q\Q\E\\E\Q\E" |
| 14:39 | gfrlog | how the heck does that work? |
| 14:39 | devn | lol |
| 14:39 | gfrlog | devn: I can do format manually with (str) |
| 14:39 | gfrlog | devn: then pass to re-pattern |
| 14:39 | devn | okay now we're on the same page gfrlog |
| 14:39 | gfrlog | I'm seriously dumbfounded by the escaping strategy here |
| 14:40 | devn | that's what my suggests was |
| 14:40 | devn | suggestion* |
| 14:40 | gfrlog | I'm sure it works but I'm not sure why |
| 14:40 | TimMc | After a \Q, go into raw mode until \E. |
| 14:41 | TimMc | ,(java.util.regex.Pattern/quote "\\") |
| 14:41 | clojurebot | "\\Q\\\\E" |
| 14:41 | Null-A | ,```foo |
| 14:41 | clojurebot | (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote sandbox/foo)))) |
| 14:41 | TimMc | See, that string is \Q\\E, but the \\ isn't an escape. |
| 14:42 | TimMc | For a literal \E, drop out of raw mode, emit an escaped \E (\\E) and then go back into raw mode. |
| 14:42 | TimMc | It's a bit silly that it puts empty raw clauses in when the beginning or end of a string is \E |
| 14:43 | devn | "patches welcome" ;) |
| 14:43 | gfrlog | TimMc: okay, I think that makes sense |
| 14:43 | gfrlog | thanks |
| 14:43 | smnirven | got a question about clojure.contrib.sql with-query-results |
| 14:43 | gfrlog | smnirven: ask that question |
| 14:44 | smnirven | im trying to write a query by datetime, so I'm building a prepared statement - its not clear what I have to pass in |
| 14:44 | smnirven | here's my code: |
| 14:44 | smnirven | (sql/with-connection db/conn |
| 14:44 | smnirven | (sql/with-query-results rs [(str "select * FROM users WHERE updated_at >= ?" [start-dt-str])] |
| 14:44 | smnirven | (doseq [res rs] |
| 14:44 | smnirven | (prn res))))) |
| 14:45 | gfrlog | you're right. that is not clear. Have you tried anything? |
| 14:45 | smnirven | yeah, tried running that code - got this error |
| 14:45 | gfrlog | I know with sql you can use some kind of time literal in single-quotes. Maybe c.c.sql will take a string? |
| 14:45 | smnirven | java.sql.SQLException: No value specified for parameter 1 (NO_SOURCE_FILE:0) |
| 14:46 | gfrlog | smnirven: I don't think you want the argument to be in a vector |
| 14:46 | gfrlog | i.e., use start-dt-str instead of [start-dt |
| 14:46 | smnirven | yeah, in that code, start-dt-str is a string |
| 14:46 | gfrlog | -str] |
| 14:46 | smnirven | just get rid of the vector |
| 14:46 | gfrlog | right |
| 14:46 | smnirven | cool, i'll try that quick |
| 14:46 | TimMc | smnirven: Is start-dt supposed to be inside (str ...)? |
| 14:46 | gfrlog | the error message still looks weird, but maybe that's why anydow |
| 14:46 | gfrlog | anyhow* |
| 14:47 | smnirven | nope, it gets passed into a function as a string |
| 14:47 | TimMc | smnirven: ##(str "f" 5) |
| 14:47 | sexpbot | ⟹ "f5" |
| 14:47 | TimMc | Do you want concatenation? |
| 14:47 | gfrlog | maybe you forgot to include the (:fix-bugs) clause within the namespace declaration |
| 14:47 | gfrlog | TimMc: I think he was just using the c.c.sql api wrong |
| 14:48 | smnirven | here's a more direct example: |
| 14:48 | smnirven | (sql/with-query-results rs [(str "select * FROM raw_leads WHERE sdb_updated_at >= ?" "2011-03-03 12:00:00")] |
| 14:49 | TimMc | smnirven: Right, you don't want the date inside str. |
| 14:49 | smnirven | ohh i think i see what i did |
| 14:49 | smnirven | yeah |
| 14:49 | smnirven | oy - thanks |
| 14:49 | TimMc | Just kill str, actually. |
| 14:49 | TimMc | np |
| 14:50 | smnirven | excellent |
| 14:50 | smnirven | that worked |
| 14:50 | smnirven | ty |
| 14:51 | gfrlog | oh weird I didn't even see he did that in the original code |
| 15:49 | chouser | is this old news here? http://doc.akka.io/stm-java |
| 15:49 | mattmitchell | i have a lazy seq. i'd like to use map, to transform all of the values. i seriously, can't figure out how to do this, but i'm thinking doall might help me out here? |
| 15:50 | chouser | mattmitchell: why do you want to force the lazy seq instead of letting it remain lazy? |
| 15:51 | mattmitchell | hmm, let me try something |
| 15:51 | mattmitchell | chouser: is it possible to use map on a lazy seq? |
| 15:52 | chouser | mattmitchell: absolutely. and map returns a lazy seq in turn. |
| 15:52 | mattmitchell | chouser: interesting. ok. |
| 15:55 | TimMc | Wait wait wait... http://lambda-the-ultimate.org/node/3700#comment-52647 indicates that transactions do not provide consistency, if I'm understanding write skew correctly. |
| 15:59 | chouser | within the transaction, you always see a consistent state. |
| 16:00 | TimMc | That's isolation, I think. |
| 16:00 | chouser | As I understand it, most relational databases that claim ACID are also subject to write skew unless you do dummy writes. |
| 16:01 | TimMc | ...which is what ensure is a replacement for. |
| 16:01 | chouser | right |
| 16:02 | chouser | in practice, it's an unusual bit of code that is susceptible to write skew, but of course it's worth knowing about so that you can use ensure when needed. |
| 16:02 | amalloy | mattmitchell: ##(take 10 (map inc (range))) |
| 16:02 | sexpbot | ⟹ (1 2 3 4 5 6 7 8 9 10) |
| 16:02 | TimMc | chouser: How do I know if I need it? |
| 16:03 | TimMc | Rather, do you know of an example of Clojure code that is susceptible? |
| 16:12 | TimMc | OK, so it looks like I need to ensure any refs whose state I only read but whose final value must be consistent with refs I am writing. |
| 16:12 | chouser | that's a better description than I was in the middle of writing. :-) |
| 16:14 | TimMc | OK, I'll put this on the clojuredocs site. |
| 16:16 | TimMc | Look good? http://clojuredocs.org/clojure_core/clojure.core/ensure |
| 16:17 | TimMc | devn: ^ found out about ensure |
| 16:18 | TimMc | And now if you'll excuse me, I'm off to make sure all my dosyncs are safe from write skew. |
| 16:29 | TimMc | Here's a question: If inside a writing dosync I call a bunch of methods that read from various global refs, how am I supposed to know what I might need to ensure? |
| 16:31 | TimMc | amalloy: How does that help? |
| 16:32 | amalloy | TimMc: it doesn't really |
| 16:32 | TimMc | heh |
| 16:32 | chouser | TimMc: you really want to keep your transactions as small and contained as possible |
| 16:32 | amalloy | but i find it easier to think about having a single mutable object enclosing the N things i might need to change |
| 16:33 | amalloy | if i had lots and lots of threads hammering on it at once that might be bad for performance, but this way i don't have to worry about other reds |
| 16:33 | amalloy | refs |
| 16:35 | mattmitchell | trying to get contrib.sql do-prepared to work with a collection of records. Anyone know if this actually works with a collection? |
| 16:36 | TimMc | My app is a Swing graphics program where everything runs off the event loop, so it is essentially a single-threaded program. I don't *really* need to worry about concurrency. But the moment I add another thread, it'll matter. |
| 16:38 | TimMc | chouser: When the user drags something on the canvas, I have to use a snapshot of the current view rotation, translation, and scale along with the program's tool mode and the list of objects on the canvas. I do some computation, and then I need to update the objects on the canvas and maybe the tool state. |
| 16:39 | TimMc | I do try to keep the transactions small and contained, but in this case one atomic unit of work involves about 3 different refs of maps, minimum. |
| 16:40 | amalloy | TimMc: wtf, no it doesn't. minimum, it involves one atom enclusing three maps :P |
| 16:41 | TimMc | amalloy: If I merge all my global state into one reference, my program can no longer make use of concurrency when I add threads for animation, etc. |
| 16:43 | amalloy | animation threads can just get a @snapshot and not worry if it's a little out of date, no? |
| 16:43 | amalloy | i mean, i'm not asserting that your app would be better with atoms |
| 16:43 | amalloy | but to claim that it is impossible with atoms is patently false |
| 16:46 | TimMc | I suppose that animation just needs a snapshot, yeah. It wouldn't be writing anything back to references. |
| 16:46 | TimMc | amalloy: Only one transaction could run on the atom at a time, right? |
| 16:47 | amalloy | yes |
| 16:47 | amalloy | or at any rate only one could succeed |
| 16:47 | TimMc | right |
| 16:48 | TimMc | I guess I'll stop complaining until I actually need concurrency. :-P |
| 17:10 | solar_sea | When I try to start "lein repl" in a new project, I'm getting this - http://pastebin.com/sxJdqYNk What host / port does lein's repl command require ? |
| 17:11 | solar_sea | http://pastebin.com/9zmSKe4R - nothing weird in netstat either |
| 17:12 | dmiles_afk | does clojure's "," syntax preclude it from ever being read by the lispreader? |
| 17:13 | technomancy | solar_sea: it uses localhost and a random port above 1024, but you can override it with LEIN_REPL_HOST LEIN_REPL_PORT |
| 17:13 | technomancy | solar_sea: is it repeatable? |
| 17:13 | solar_sea | yes, everytime |
| 17:14 | dmiles_afk | i suppose a reader macro of #J could make the lisp reader tollerate clojure's "," |
| 17:14 | dmiles_afk | "," is alwaswy whitespace right? |
| 17:15 | hiredman | yes |
| 17:15 | technomancy | solar_sea: can you open a ticket with copious details so I can check it later? |
| 17:15 | solar_sea | sure, where's the tracker for it ? |
| 17:15 | dmiles_afk | teh [ and ] might i guess get tricky |
| 17:16 | technomancy | solar_sea: http://github.com/technomancy/leiningen/issues |
| 17:16 | TimMc | dmiles_afk: And {} |
| 17:20 | NielsE | hi, I have created a new clojure project in eclipse but it does not recognise things from contrib like 'sqrt' and 'primes', but clojure-contrib is in the classpath under libraries in eclipse, how come? |
| 17:21 | TimMc | chouser: I would *really* like to see some mention of write skew on the clojure.org/refs page. Should I bug Rich about that? |
| 17:22 | TimMc | NielsE: Have you used :require or :use in your namespace declaration to pull in contrib? |
| 17:23 | NielsE | TimMc: somehow I was not aware that I had to use or include the contrib library explicitely, I'll look into it, thanks :) |
| 17:24 | raek | technomancy: what does it mean for a project to be installed in leiningen? (I'm thinking about two-param "lein install") |
| 17:24 | technomancy | raek: it places shell scripts in ~/.lein/bin |
| 17:24 | raek | also, I just discovered "lein repl" outside a project and the swank-clojure shell wrapper. this will aid my introductory talk on clojure very much. :) |
| 17:24 | technomancy | raek: I think swank is the only thing that uses it so far |
| 17:25 | technomancy | but I want more people to try it out; clojure's command-line story right now sucks =\ |
| 17:25 | technomancy | cools! |
| 17:27 | solar_sea | technomancy, I found it, it turned out that my "lo" iface somehow was down |
| 17:27 | TimMc | NielsE: (:require [clojure.contrib.math :as math]) in your (ns ...) will let you do math/sqrt |
| 17:27 | solar_sea | there's nothing wrong with lein :) |
| 17:27 | technomancy | solar_sea: whoa; I didn't even know you could do that. =) |
| 17:28 | solar_sea | me neither ... I guess the wicd network manager that I use for wifi settings is to blame, I'll dig it up further some day :) |
| 17:28 | TimMc | solar_sea: How did you discover that? |
| 17:29 | solar_sea | netstat showed nothing wrong. LEIN_REPL_PORT/HOST didn't work either. Then I disabled ipv6, again to no avail. And I glanced again that "lo" was actually missing from ifconfig's output. |
| 17:30 | TimMc | Entirely missing? I would not have noticed that ever. |
| 17:46 | TimMc | Is the rational for class-per-fn that this allows selective code reloading? |
| 17:54 | mattmitchell | if i have a function, that accepts a series of optional arguments, how can i pass in a list of args without knowing the length? |
| 17:55 | brehaut | (apply + [1 2 3 4 5]) |
| 17:55 | brehaut | ,(apply + [1 2 3 4 5]) |
| 17:55 | clojurebot | 15 |
| 17:55 | mattmitchell | brehaut: ok cool. so the function i'm actually working with is clojure.contrib.sql do-prepared |
| 17:55 | mattmitchell | brehaut: i have a collection of row values |
| 17:56 | mattmitchell | looks something like this: (sql/with-connection db/conn |
| 17:56 | mattmitchell | (sql/do-prepared insert values)) |
| 17:56 | brehaut | (apply clojure.contrib.sql/do-prepared foo bar seq-of-values) |
| 17:56 | mattmitchell | brehaut: ahh ok :) |
| 18:01 | mattmitchell | brehaut: thank you |
| 18:02 | brehaut | no worries |
| 18:02 | raek | TimMc: what would be the alternative to class-pre-fn? you need to have separate classes for separate functions if one function should behave differently from another when called with the same method |
| 18:05 | TimMc | Oh right, there are different methods for different arities. |
| 18:06 | amalloy | TimMc: i don't think that's relevant |
| 18:06 | amalloy | the point is that functions have to have a general "call me" button, which has to be wrapped up in a method for java |
| 18:06 | amalloy | if function a is to behave differently from function b, they must be different classes implementing IFn |
| 18:06 | TimMc | And they all have to be instances of different classes, right. |
| 18:45 | amalloy | TimMc: plus, have you ever thought about how closures are implemented? it's a neat trick |
| 18:45 | TimMc | Hmm, fair point/ |
| 19:10 | bennylu | what the equivalance of substring in clojure? |
| 19:11 | bennylu | anyone? |
| 19:12 | clojurebot | Please do not ask if anyone uses, knows, is good with, can help you with <some program or library>. Instead, ask your real question and someone will answer if they can help. |
| 19:12 | Apage43 | ,(.susbtring "doghouse" 3) |
| 19:12 | clojurebot | java.lang.IllegalArgumentException: No matching method found: susbtring for class java.lang.String |
| 19:12 | bennylu | getit! thanks.. |
| 19:12 | Apage43 | yeah, that should work outside the bot xD |
| 19:14 | amalloy | subs |
| 19:14 | amalloy | which i think is in clojure.string |
| 19:14 | amalloy | &(use 'clojure.string) |
| 19:14 | sexpbot | ⟹ nil |
| 19:14 | amalloy | &(subs "test" 1) |
| 19:14 | sexpbot | java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox6385 |
| 19:15 | amalloy | &(use 'clojure.string) |
| 19:15 | sexpbot | java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox6385 |
| 19:15 | amalloy | lol wtf |
| 19:15 | amalloy | oh i guess it's in core anyway |
| 19:15 | amalloy | &(subs "test" 1) |
| 19:15 | sexpbot | ⟹ "est" |
| 19:15 | amalloy | bennylu: ^ |
| 19:16 | bennylu | amalloy, Thanks! |
| 19:34 | bennylu | what the convention for constants in clojure? (for example - in jave its uppercase splitted by '_') |
| 19:35 | technomancy | bennylu: lowercase dash-separated |
| 19:37 | bennylu | technomancy, but this is the convention for normal variables - because clojure dont have a final/constant keyword i wanted to show the readers of my code that some variable is constant - i guess i will have to add somthing like c-varname |
| 19:38 | Apage43 | bennylu: shouldn't the preponderance of your variables in clojure be constant.. |
| 19:39 | Apage43 | if you |
| 19:39 | technomancy | you can tell when things are mutable by the presence of deref/atom/agent/ref |
| 19:39 | Apage43 | if you're going around re'def'ing things that's probably wrong |
| 19:40 | bennylu | Apage43, i guess you right.. :) |
| 19:40 | bennylu | i still thinking in java :) |
| 19:43 | pdk | bennylu it's a given that they're constant |
| 19:43 | amalloy | how do i specify a "source dependency" with cake/lein? it looks like with maven you add a <classifier> element |
| 19:43 | pdk | they're all immutable :p |
| 19:43 | pdk | if you're naming a global symbol though |
| 19:43 | pdk | the convetion is *like-this* |
| 19:43 | amalloy | pdk: that's overgeneralizing |
| 19:44 | amalloy | you define global symbols all the time; only the ones that you intend to be rebound are usually given *earmuffs* |
| 19:44 | pdk | barring java objs/reference types |
| 19:44 | amalloy | ooo i see there's a :classifier entry in the dependency thingy |
| 19:44 | bennylu | pdk, amalloy, thanks |
| 19:50 | TimMc | amalloy: I was using the convention of all my global refs (there are about 5) have, uh, earmuffs. |
| 19:50 | amalloy | well, altering global refs is similar to rebinding |
| 19:51 | amalloy | except more evil :P |
| 20:00 | technomancy | amalloy: what are you using source dependencies for? |
| 20:00 | amalloy | technomancy: i'm not really. i just wanted an easy way to get the source for a project |
| 20:01 | technomancy | I could see the use for a plugin that could pull in source and build a TAGS file if I had the misfortune to need such a thing. |
| 20:02 | technomancy | seems saner to inspect the <scm> element of the pom though |
| 20:16 | pdk | hm |
| 20:16 | pdk | i'll ask again, for folks who preordered joy of clojure through amazon do you know if you still get early access that way |
| 20:58 | TimMc | What is the M in MEAP? |
| 20:58 | TimMc | (speaking of EAP) |
| 21:00 | brehaut | Manning (the publisher) |
| 21:00 | brehaut | (i think) |
| 21:02 | TimMc | Hah, OK. |
| 21:24 | amalloy | indeed |
| 21:30 | devn | so erm, any idea on a good regex to capture sexps from strings? |
| 21:32 | brehaut | devn, do you want to just find them? or actually get sexps back? |
| 21:32 | devn | im typing in this line right now and then i do this (foo (bar (baz 4) "16") \c) |
| 21:33 | devn | i want to capture (foo (bar (baz 4) "16") \c) |
| 21:33 | Despite_ | ooo, fun! |
| 21:33 | brehaut | devn: theres not really a good solution to that with regexp |
| 21:33 | devn | i figure this is a solved problem but, hm... |
| 21:33 | amalloy | devn: if you use regexes to do this you are asking for pain, and also are probably a satan worshipper, no offense |
| 21:33 | Despite_ | you'll need perl for this! |
| 21:33 | devn | amalloy: well, how do you suggest i do it? |
| 21:33 | brehaut | for instance (is this) one or (two sexp) ? |
| 21:34 | amalloy | &(read-string "(foo (bar (baz 4) \"16\") \c)") |
| 21:34 | sexpbot | java.lang.Exception: Unsupported escape character: \c |
| 21:34 | brehaut | fnparse |
| 21:34 | amalloy | &(read-string "(foo (bar (baz 4) \"16\") \\c)") |
| 21:34 | sexpbot | ⟹ (foo (bar (baz 4) "16") \c) |
| 21:34 | devn | https://gist.github.com/854070 |
| 21:34 | devn | that works right now, and it's fast |
| 21:34 | devn | but im sick of that code. it's disgusting. |
| 21:35 | Despite_ | wow |
| 21:35 | brehaut | devn: you really are outside of the bounds of regular grammars, and need to write areal parser |
| 21:35 | amalloy | devn: please comment on why read-string is no good? |
| 21:36 | devn | &(read-string "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \c)") |
| 21:36 | sexpbot | java.lang.Exception: Unsupported escape character: \c |
| 21:36 | devn | &(read-string "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \\c)") |
| 21:36 | sexpbot | ⟹ hello |
| 21:36 | amalloy | &(with-in-string "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \\c)" (take-while identity (repeatedly read))) |
| 21:36 | sexpbot | java.lang.Exception: Unable to resolve symbol: with-in-string in this context |
| 21:37 | amalloy | &(with-in-str "hello i am in the #clojure irc channel (foo (bar (baz 4) \"16\") \\c)" (take-while identity (repeatedly read))) |
| 21:37 | sexpbot | Execution Timed Out! |
| 21:37 | amalloy | well, something like that anyway |
| 21:37 | amalloy | you probably need a try/catch for eof |
| 21:38 | devn | it doesn't need to be perfect and like...understand that \c is ok. it basically just needs to match an equal number of parens on both sides |
| 21:38 | devn | (((()))) is valid, for instance |
| 21:39 | amalloy | devn: the "regular" in regular expressions means that it has to be context-free, ie not tracking nested parens |
| 21:39 | devn | (1(j(4(d)))), same deal |
| 21:39 | brehaut | devn are you familiar with http://en.wikipedia.org/wiki/Pumping_lemma_for_regular_languages ? |
| 21:40 | devn | brehaut: no, reading now |
| 21:40 | devn | amalloy: *nod*, fair enough |
| 21:40 | amalloy | these days regular expressions have some non-regular extensions that *do* allow you to do stuff like this, but there are so many reasons not to, especially when you have a whole dang compiler at your disposal |
| 21:40 | TimMc | devn: TL;DR: You at least need a stack. |
| 21:40 | amalloy | heh |
| 21:40 | devn | lol |
| 21:40 | devn | pumping lemma sounds like a math porn movie |
| 21:41 | TimMc | hawt |
| 21:41 | amalloy | TimMc: how much will it cost me to have you follow me around with tldr explanations of my verbose rubbish? |
| 21:41 | TimMc | :-P |
| 21:43 | devn | lol |
| 21:44 | Despite_ | perl -MText::Balanced :) |
| 21:44 | brehaut | devn the 'best' you can use regexps for here is tokenisation such as ##(re-seq #"(\"(\\.|[^\"])*\")|[()]|[^()\"]*" "abc ( 1 2 ( c d \"ber\" ) ) ) asdf") |
| 21:44 | sexpbot | ⟹ (["abc " nil nil] ["(" nil nil] [" 1 2 " nil nil] ["(" nil nil] [" c d " nil nil] ["\"ber\"" "\"ber\"" "r"] [" " nil nil] [")" nil nil] [" " nil nil] [")" nil nil] [" " nil nil] [")" nil nil] [" asdf" nil nil] ["" nil nil]) |
| 21:44 | brehaut | please excuse the evil |
| 21:44 | devn | holy evil |
| 21:44 | devn | that's almost worst than what i have now :D |
| 21:44 | brehaut | haha |
| 21:44 | devn | (but i appreciate the suggestion (and yes this should match too)) |
| 21:44 | brehaut | its also bound to be broken |
| 21:45 | devn | i mean, here's the scenario so you have some context |
| 21:45 | devn | because maybe this changes things... |
| 21:46 | devn | im rewriting something i was messing with around a year ago that read-lines from the #clojure logs, pulls out s-exps and try to run them in a sandbox |
| 21:46 | devn | if they run, the expression as a string is the key, and their value is the result as a string |
| 21:46 | devn | that happens in a try catch so i dont really care if its faulty, liberal with parens, etc. |
| 21:47 | devn | i just want something that is good enough |
| 21:49 | amalloy | &1 |
| 21:49 | sexpbot | ⟹ 1 |
| 21:49 | brehaut | $findfn [1 2 3] ([1 2 3] [2 3] [3] []) |
| 21:49 | sexpbot | java.security.PrivilegedActionException: java.lang.IllegalArgumentException: Wrong number of args (3) passed to: PersistentVector (NO_SOURCE_FILE:0) |
| 21:50 | amalloy | devn: that's a sexp you won't get right :P |
| 21:55 | brehaut | devn: (defn tails [s] (when (seq s) (lazy-seq (cons s (tails (rest s)))))) (defn horror [s] (keep #(try (read-string (str %)) (catch Exception e e)) (tails s))) |
| 21:56 | brehaut | its missing an apply before str |
| 21:57 | brehaut | (defn horror [s] (keep #(try (read-string (apply str %)) (catch Exception e nil)) (tails s))) |
| 21:57 | brehaut | much better (for a given value of better) |
| 21:57 | brehaut | that'll find all the legit clojure expressions in a string |
| 21:57 | brehaut | including a bunch of stuff you dont want (eg, anything that looks like a symbol) |
| 21:58 | amalloy | brehaut: given input " 1" you'll generate a zillion instances of the expression "1" |
| 21:58 | brehaut | amalloy: he said it had to be approximate ;) |
| 21:58 | amalloy | also isn't tails just (partial reductions rest)? |
| 21:59 | amalloy | er not quite |
| 21:59 | brehaut | i know theres a good way to do it |
| 21:59 | brehaut | but its late friday here and my brain is tired |
| 21:59 | amalloy | brehaut: late friday already? |
| 21:59 | amalloy | it's barely late thursday here |
| 21:59 | brehaut | new zealand, its the future |
| 21:59 | brehaut | by late i mean late in te work day; about 4pm |
| 22:00 | amalloy | i guess i was reading late as 11pm |
| 22:00 | brehaut | (defn horror [s] (set (keep #(try (read-string (apply str %)) (catch Exception e nil)) (tails s)))) |
| 22:00 | brehaut | hows that :P |
| 22:00 | amalloy | (defn tails [s] (take-while identity (iterate #(subs % 1) s))) |
| 22:00 | amalloy | brehaut: my hero! |
| 22:01 | brehaut | hah brilliant :) |
| 22:01 | amalloy | i use take-while/identity/iterate so often i need to give it a function |
| 22:01 | amalloy | name proposals? |
| 22:01 | chouser | TimMc: point 8 refers to the usage of ensure. You wish it used the words "write skew" in particular? |
| 22:03 | brehaut | amalloy: its a "take-" something for sure |
| 22:03 | brehaut | perhaps even just take-iterations ? |
| 22:03 | amalloy | i have trim-seq for take-while identity |
| 22:03 | amalloy | hm, sensible |
| 22:03 | amalloy | or just iterations |
| 22:04 | brehaut | yeah that could work |
| 22:05 | amalloy | brehaut: putting that into my new little portably utils library now |
| 22:06 | brehaut | awesome :) |
| 22:07 | brehaut | amalloy: i see you have on-thread; why not join the lazier world and just use future :P |
| 22:08 | amalloy | well yes |
| 22:08 | amalloy | brehaut: i have that there because i grabbed everything from sexpbot.utils, and apparently Raynes has a reason to want different error semantics |
| 22:08 | amalloy | mebbe i'll junk it |
| 22:11 | brehaut | also, (def make-str (transform-if keyword? name str)) instead of keyword you probably want (partial instance? clojure.lang.Named) |
| 22:12 | amalloy | brehaut: good point. that too was extracted from another application |
| 22:12 | amalloy | as you can see my util package is pretty new so it's rough around the edges |
| 22:12 | brehaut | yeah for sure |
| 22:12 | brehaut | no point creating a utilities package whole cloth |
| 22:12 | amalloy | heh |
| 22:13 | amalloy | i'll wait until i can use it to replace contrib, then release it |
| 22:13 | brehaut | haha |
| 22:20 | brehaut | later |
| 22:46 | dnolen | does calling seq on a lazy-seq force evaluation of the first item? |
| 22:46 | dnolen | to determine if it's non-empty? |
| 22:48 | dnolen | ah |
| 22:48 | dnolen | it seems like it does. |
| 22:49 | amalloy | dnolen: yes |
| 22:50 | amalloy | next is basically (comp seq rest) |
| 22:50 | amalloy | er, no it's not. but whatever |
| 23:26 | amac | the docstring for future-cancel is hilarious |
| 23:28 | tomoj | I never read it that way before :) |
| 23:29 | amac | :) |
| 23:31 | spewn_ | ,(doc future-cancel) |
| 23:31 | clojurebot | "([f]); Cancels the future, if possible." |
| 23:31 | spewn_ | hah |
| 23:34 | amalloy | heh |
| 23:34 | amalloy | hopefully it always fails |
| 23:35 | amalloy | arguably it doesn't matter though. some kind of variation on the quantum bogosort |
| 23:39 | amalloy | man, the wikipedia article on quantum bogosort is terrible. if anyone is wondering why i would make such a stupid reference, see http://www.mathnews.uwaterloo.ca/Issues/mn11103/QuantumBogoSort.php |
| 23:45 | amac | Man, I hope some parallel asshole doesn't destroy our universe simply because his list was unsorted. |
| 23:46 | amac | I like this universe, it contains all my stuff. |
| 23:47 | dnolen | is it possible to get the name of a fn like (fn foo []) ? |
| 23:48 | technomancy | dnolen: there's an open ticket for putting stuff like that in metadata |
| 23:48 | technomancy | (no patch, just an unhelpful "this should have metadata") |
| 23:48 | dnolen | technomancy: heh, thx. |
| 23:49 | amalloy | dnolen: you can kinda-sorta do it with ##(class (fn foo[])) |
| 23:49 | sexpbot | ⟹ sandbox11264$eval13423$foo__13424 |
| 23:49 | dnolen | ,(println (fn foo[])) |
| 23:49 | clojurebot | #<sandbox$eval2577$foo__2578 sandbox$eval2577$foo__2578@1a707a0> |
| 23:50 | dnolen | I just need it for debugging really. would prefer to not get the mangled version. |
| 23:50 | amalloy | dnolen: regexes for the win? |