2012-05-31
| 00:00 | amalloy | (even though it claims to). and you installed 0.3.0, which is the lein2 plugin, not the lein1 plugin |
| 00:01 | coventry | Just a misunderstanding, will give it a go. Thanks. |
| 00:04 | coventry | Ah, so that's why adding the plugin to ./lein/project.clj didn't work. |
| 00:32 | michaelr525 | morning! |
| 03:01 | tomoj | devn: hey, do you still have the link to that gist about core.logic? |
| 03:02 | tomoj | my laptop conveniently locked up completely right as I was going to click on it, thinking "whoa" |
| 03:02 | tomoj | and google custom search seems not to have picked it up yet |
| 03:03 | tomoj | oh |
| 03:03 | tomoj | datomic not core.logic |
| 03:03 | tomoj | found it |
| 03:21 | muhoo | where is it? |
| 03:35 | muhoo | oic, i had to do this before i finally understood it: (->> [185 13235209671M 25939708511M 1654794401M 12429901063M 131081 65539] (mapcat #(cons "\n" (next (map {\0 \ , \1 \#} (Long/toBinaryString %))))) (apply str) symbol) |
| 03:35 | muhoo | it's a bitmap, clever. |
| 04:35 | TEttinger | hmm |
| 04:35 | TEttinger | I'm trying to make a dead-simple Conway's Game of Life in the console |
| 04:36 | ordnungswidrig | TEttinger: that is a good excercise |
| 04:36 | TEttinger | and I can't figure out how to keep the app going, continually generating new boards |
| 04:36 | TEttinger | it is something to do with Thread/sleep |
| 04:36 | ordnungswidrig | should it repeateldy print the state in the repl? |
| 04:37 | TEttinger | I just need to know a way to evaluate some function, sleep, eval, sleep, etc. |
| 04:37 | TEttinger | well it could use a repl? |
| 04:37 | TEttinger | i was just using lein run |
| 04:37 | TEttinger | i used the repl for the development part |
| 04:37 | ordnungswidrig | k |
| 04:38 | ordnungswidrig | can you show your problem at a pastebin? |
| 04:39 | clgv | TEttinger: you just need an infinite loop that prints one iteration step. |
| 04:40 | clgv | maybe you should specify in advance how many steps you want to see ;) |
| 04:40 | clgv | TEttinger: e.g.: (dotimes [_ 100] (my-iteration-code)) |
| 04:41 | PeregrinePDX | (take 10 (repeatedly game-of-life-function)) |
| 04:41 | PeregrinePDX | Would get you 10 iterations. |
| 04:42 | TEttinger | thanks |
| 04:43 | ordnungswidrig | for a pure implementation you can do like this: |
| 04:43 | TEttinger | I was struggling with ideone having weird syntax highlighting, and that made me think there was a problem with my code |
| 04:43 | TEttinger | http://pastie.org/4000414 |
| 04:44 | ordnungswidrig | (->> step-fn (repeat num-iters) (reduce #(%2 %1) seed)) |
| 04:45 | TEttinger | ->> does what now? |
| 04:46 | ordnungswidrig | (->> 5 (+ 1 2 3) (print "result" )) will expand to (print "result" (+ 1 2 3 5)) thus is "inserts" the result as the _last_ argument to the next expression |
| 04:46 | TEttinger | PeregrinePDX, yeah the code i based it off of (mislabeled in there, part of -main is the original code) |
| 04:46 | ordnungswidrig | but it was overly complicated because iterate will be easier |
| 04:46 | TEttinger | yeah the code originally used iterate |
| 04:47 | ordnungswidrig | so (nth (iterate step seed) num-iters) will be easier |
| 04:47 | TEttinger | I'm sorry, what? |
| 04:48 | TEttinger | what is that solving? |
| 04:48 | ordnungswidrig | this will to the same as the code I showed above using reduce |
| 04:48 | clgv | probably `take` is better since you want to see the progress of the game, right? |
| 04:48 | TEttinger | yeah |
| 04:48 | TEttinger | but I need to pause with Thread.sleep between printing the steps |
| 04:49 | TEttinger | ideally it would keep going until the user Ctrl-D or Ctrl-C 's it |
| 04:49 | PeregrinePDX | So remove the take x portion. |
| 04:49 | ordnungswidrig | PeregrinePDX: there is no printing |
| 04:50 | TEttinger | yeah, but how would I sleep |
| 04:50 | clgv | (Thread/sleep 1000) |
| 04:51 | TEttinger | steps it needs to do: run first generation, print, sleep, run second generation, print, sleep... |
| 04:51 | clgv | &(do (println "1") (flush) (Thread/sleep) (println "2") (flush)) |
| 04:51 | lazybot | java.lang.NoSuchFieldException: sleep |
| 04:51 | TEttinger | &(do (println "1") (flush) (Thread/sleep 10) (println "2") (flush)) |
| 04:51 | lazybot | ⇒ 1 2 nil |
| 04:51 | clgv | ah lol^^ |
| 04:52 | TEttinger | so how would i handle function calls mixed into taking an element from a lazy sequence |
| 04:52 | clgv | TEttinger: (doseq [board (iterate ...)] (println board) (Thread/sleep 1000)) |
| 04:53 | TEttinger | oh! doseq! I always forget about the do??? functions |
| 04:53 | TEttinger | thanks clgv, will try |
| 04:53 | clgv | you want to have side effects, you should use a `do*` ;) |
| 04:59 | TEttinger | http://pastie.org/4000482 for those who want to try, it needs an 80-char-wide terminal |
| 05:45 | amalloy | TEttinger: have you looked at http://www.4clojure.com/problem/94? |
| 06:21 | opened | I'm going to start reading sicp. Any comments on the book, from the clojure perspective? |
| 06:22 | clgv | amalloy: that one is underspecified for the "edge cases" ;) |
| 06:25 | ejackson | anybody know the equivalent for $(this) is cljs ? |
| 06:26 | ejackson | (using jayq, that is) |
| 06:26 | clgv | ejackson: maybe an implizit 'this symbol? |
| 06:27 | clgv | *implicit |
| 06:27 | ejackson | yeah, I fooled about with ($ "this") and ($ :this) etc |
| 06:28 | ejackson | (js* "this") yields DOM objects in callback, but is a bit wild |
| 06:31 | clgv | ejackson: did you examine the js it is compiled to? |
| 06:31 | ejackson | eep, no I didn't, good call, thanks ! |
| 06:34 | ejackson | lol its 20k lines |
| 06:34 | ejackson | hence all the fuss about minifiers :) |
| 06:37 | ejackson | FTR, this works: ($ (js* "this")) in callbacks to get a jquery on that thingie doing the calling |
| 06:37 | kilon | never liked any of the common lisp / scheme books i read |
| 06:37 | ejackson | a bit wild though |
| 06:37 | kilon | confused me a lot |
| 06:37 | kilon | fortunately clojure documentation is way better |
| 06:38 | kilon | i find this very helpful |
| 06:38 | kilon | http://clojuredocs.org/quickref/Clojure%20Core |
| 06:38 | clgv | ejackson: if you are interested you could trace back through jayq where ($ :this) fails. would be worth a patch I guess. |
| 06:39 | clgv | kilon: this is also pretty good: http://clojure.org/cheatsheet - I have the pdf printed on the desk ;) |
| 06:40 | kilon | clgv: indeed this is extremely helpful |
| 06:41 | kilon | thanks , missed that one |
| 06:41 | kilon | i am suprised that such a new language has such good documentation |
| 06:45 | ejackson | clgv: I'll raise it, but I'm sure there's a reason its not there already :) |
| 06:45 | ejackson | Raynes: you're a contributor - you still about ? |
| 06:46 | clgv | ejackson: which reason would that be? |
| 06:46 | ejackson | something like "yes it works in your instance, but look at this other case where it blows up" |
| 06:46 | ejackson | i don't know enough about the JS world to say |
| 06:48 | clgv | then I would start with the premis that this one might have slipped attention so far since cljs and jayq are both pretty young ;) |
| 06:49 | ejackson | alrighty, I'll raise an issue and see who slaps me up first :) |
| 07:13 | clgv | Instead of having global parameters for the run of an algorithm, which are accessed where needed, one could compile the functions of the algorithm when just before the run and inject the parameters as constants into the code of the functions. One could write a special defn-macro for this. Has anyone tried that yet? |
| 07:15 | ejackson | sortof like inlining data |
| 07:17 | clgv | ejackson: and functions. I'd describe it more as templates for functions |
| 07:17 | ejackson | what's the win ? |
| 07:17 | clgv | The functions would get cleaner since I dont have to pass the Parameter-Container along and access it to query the parameter values |
| 07:19 | ejackson | you can't have the data as argument 0 and partial it in ? |
| 07:19 | clgv | jvm could inline functions (that are given as parameter as well) |
| 07:19 | clgv | ejackson: it's distributed through the whole algorithm |
| 07:19 | ejackson | yeah, I have similar stuff but I like it there :) |
| 07:20 | ejackson | so I can see its bony ass |
| 07:20 | clgv | I dont like it - I would like more clarity and save the additional parameter access times |
| 07:21 | clgv | I have a single point where I could compile the whole thing |
| 07:22 | clgv | maybe it could even be dual: if no parameters are bound it compiles normal functions that take the parameter-container |
| 07:23 | ejackson | i've grown to be frightened of such magics |
| 07:24 | clgv | it needs to be thouroughly tested. thats true. but it can't really cause much pain since it'll explode if no params are bound ;) |
| 07:26 | clgv | a pity that the word "template" is so strictly bound to html if you search for "clojure function templates" |
| 07:27 | clgv | hmmm there is clojure.template but thats not sufficient |
| 07:27 | clgv | and not really near the vision I have |
| 07:30 | michaelr525 | can i create a non-caching lazy seq using loop recur? I would like to "run over" the rows of a big table, proccesing one at a time. |
| 07:35 | Chousuke | michaelr525: just use a lazy seq and doseq |
| 07:37 | michaelr525 | Chousuke: isn't there a potential stack overflow? |
| 07:37 | Chousuke | no? |
| 07:37 | clojurebot | no is tufflax: there was a question somewhere in there, the answer |
| 07:37 | michaelr525 | Chousuke: i mean, lazy-seq implies recursive function call which implies stack overflow, no? |
| 07:38 | Chousuke | nope |
| 07:38 | Chousuke | laziness prevents the stack growth |
| 07:39 | michaelr525 | are you sure? i will eventually force the whole seq |
| 07:40 | michaelr525 | say 2M items, means 2M recursions no? |
| 07:40 | Chousuke | ths recursive call is done when an element is realised, at which point the previous call will have returned |
| 07:40 | sjl | michaelr525: as long as you don't hold onto a pointer to the head of that seq, the elements will get garbage collected as you move past them |
| 07:40 | michaelr525 | great! :) |
| 07:40 | Chousuke | that is a separate issue |
| 07:41 | clgv | kilon: slow. see solaris ;) |
| 07:41 | sjl | yeah, there's not really any recursion because by the time you actually call the function a second time you're out of the first call |
| 07:41 | kilon | clgv: i dont mean entirely, linux kerner will do |
| 07:42 | kilon | keep around things in C for speed, is perfectly fine by me |
| 07:43 | clgv | kilon: isnt solaris a unix with only a java desktop? |
| 07:43 | kilon | it is ? sorry i am not that familiar with it |
| 07:43 | kilon | never used it |
| 07:43 | clgv | I had a demo cd back in 2004 or so ;) |
| 07:44 | scottj | kilon: I don't think clojure dictates much of how a user environment would be. you could imagine the concurrency and database-backed filesystem of BeOS (but with datomic), the interactiveness of smalltalk VM/Symbolics Genera/emacs, but maybe you'd just end up with unity running the speed of libreoffice. |
| 07:45 | kilon | one thing i learned , is making a coder life easier, immediately affects the user |
| 07:47 | kilon | look how much python boosted the development of linux |
| 07:48 | kilon | pupy linux uses both genie (python clone that runs much faster, with static types) and Vala (C# clone) |
| 07:49 | kilon | cant say either have any noticable slow downs |
| 07:49 | kilon | and python is way way slower than clojure |
| 07:49 | michaelr525 | (defn rows [start-at limit] |
| 07:49 | michaelr525 | (lazy-cat (get-rows limit start-at) (rows limit (+ start-at limit)))) |
| 07:50 | michaelr525 | does this look ok ^^^ |
| 07:51 | michaelr525 | i mean, it doesn't hold onto it's head, does it? ;) |
| 08:00 | michaelr525 | wow |
| 08:00 | michaelr525 | it works |
| 08:00 | michaelr525 | so cool.. |
| 08:02 | michaelr525 | err |
| 08:02 | michaelr525 | how to stop? |
| 08:02 | michaelr525 | hehe |
| 08:04 | kilon | reboot always works :D |
| 08:05 | michaelr525 | maybe take-while |
| 08:09 | michaelr525 | if lazy seq doesn't recurse, why do we need loop recur? |
| 08:11 | ejackson | for data not dealing with seqs :) |
| 08:12 | michaelr525 | such as.. |
| 08:14 | ejackson | a numeric function: such as say an integration |
| 08:14 | michaelr525 | (defn rows [limit start-at] |
| 08:14 | michaelr525 | (lazy-cat (get-rows limit start-at) |
| 08:14 | michaelr525 | (rows limit (+ start-at limit)))) |
| 08:14 | michaelr525 | why take 1 from the above triggers infinite realization? |
| 08:16 | bobry | how can I tell cljsbuild to include a js library in the output file? |
| 08:16 | ejackson | bobry: i dunno, i tend to put it into the HTML template |
| 08:17 | ejackson | michaelr525: depends on get-rows i guess |
| 08:17 | bobry | yup, that'll surely work :) |
| 08:17 | bobry | I thought it has :externs option, but I can't find it in the docs |
| 08:17 | ejackson | luke vanderhart's articel goes into this, 1 sec |
| 08:18 | ejackson | here: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html |
| 08:19 | michaelr525 | ejackson: err how does it depend on get-rows? the whole thing seems very lazy to me |
| 08:19 | ejackson | well, I dunno what get-rows is/does, it might realise the whole thing |
| 08:20 | bobry | ejackson: thanks! that's exactly what I needed :) |
| 08:20 | michaelr525 | ejackson: it returns a vector of maps (rows from database) |
| 08:21 | ejackson | hmm, dunno. |
| 08:22 | michaelr525 | oh, maybe the repl does automatically? |
| 08:24 | ejackson | chunking perhaps |
| 08:24 | michaelr525 | ah |
| 08:24 | michaelr525 | yeah, it could be |
| 08:24 | michaelr525 | damn chunking |
| 08:26 | ejackson | ah |
| 08:27 | michaelr525 | not chunking i think, i replaced get rows with the following and it works as expected now: (defn get-rows [row-limit start-at] [1 2 3]) |
| 08:31 | michaelr525 | ejackson: it happens when get-rows returns an empty seq |
| 08:32 | michaelr525 | ejackson: how do you explain that? |
| 08:34 | ejackson | dunno |
| 08:34 | ejackson | :) |
| 08:35 | michaelr525 | &(lazy-cat [1 2 3] [0]) |
| 08:35 | lazybot | ⇒ (1 2 3 0) |
| 08:36 | michaelr525 | &(lazy-cat [1 2 3] []) |
| 08:36 | lazybot | ⇒ (1 2 3) |
| 08:36 | michaelr525 | &(lazy-cat [] []) |
| 08:36 | lazybot | ⇒ () |
| 08:36 | michaelr525 | &(defn get-rows [] nil) |
| 08:36 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 08:36 | clojurebot | Roger. |
| 08:39 | michaelr525 | &(let [f1 (fn [] nil) f2 (fn [] (lazy-cat (f1) (f2)))] (take 1 (f2))) |
| 08:39 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: f2 in this context |
| 09:01 | Chiron_ | Hi, (defn fun [id & {:keys [name phones]}] (println name) (println phones)) phones is a varargs . it could be one value or a lot of values . should I destructure it somehow also? |
| 09:11 | mfex | Chiron_: phones can't be both a keyword argument and a varargs. You should pass it a collection if you more than one value for phones |
| 09:23 | rguillebert | hi |
| 09:24 | rguillebert | is there something equivalent to the haskell "where" clause in clojure ? |
| 09:27 | jedmtnman | rguillebert: cond, maybe? |
| 09:27 | jedmtnman | ,(doc cond) |
| 09:28 | clojurebot | "([& clauses]); Takes a set of test/expr pairs. It evaluates each test one at a time. If a test returns logical true, cond evaluates and returns the value of the corresponding expr and doesn't evaluate any of the other tests or exprs. (cond) returns nil." |
| 09:28 | jedmtnman | or |
| 09:28 | jedmtnman | ,(loop) |
| 09:28 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (0) passed to: core$loop> |
| 09:28 | jedmtnman | ,(doc loop) |
| 09:28 | clojurebot | "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein. Acts as a recur target." |
| 09:29 | mfex | rguillebert: use (let or (letfn. for both of these the declarations come for their usage, in haskell the declarations in the 'where' are after their usage |
| 09:39 | rguillebert | mfex, yes I think that'll do it |
| 09:39 | rguillebert | thanks |
| 10:25 | glitch99 | this is kind of a goofy question - don't know if anyone is in the room - what is the typical clojure/lisp coding style - lots of _ like C? lots of camel case like java and C++? hungarian? |
| 10:25 | babilen | glitch99: typically-like-this |
| 10:25 | glitch99 | lowercase and dash? |
| 10:26 | babilen | glitch99: Yes. See http://clojure.github.com/clojure/ for a list of functions in the standard library |
| 10:26 | bsteuber | yes except java casing for java interop |
| 10:26 | di-csuehs | that is an interesting question...I don't recall seeing a style guide. |
| 10:27 | glitch99 | awesome :-) thanks everyone! |
| 10:27 | babilen | di-csuehs, glitch99: http://dev.clojure.org/display/design/Library+Coding+Standards |
| 10:27 | Vinzent | bsteuber, actually it's not only java interop - any type names should be CamelCased |
| 10:29 | babilen | ... as should names of protocols (i.a.) |
| 10:34 | twhume | So… I'm trying to load Java classes from an array of bytes (being a serialised class) in Clojure. I also need to be able to unload classes, which I think means getting the class loader which loads them garbage-collected. There may be an easier way of doing this than the one I'm trying, which is to gen-class a subclass of ClassLoader and use that. I'm having trouble with gen-class though: I can generate a class OK but it always seems to |
| 10:34 | twhume | subclass Object, and not respond to dot-notation method calls. |
| 10:34 | twhume | https://gist.github.com/2843627 has the code - (-dummy cg) works just fine, (.dummy cg) doesn't... |
| 10:35 | twhume | Any ideas? |
| 10:41 | llasram | twhume: Clojure >=1.3 includes a class-loader which may already do what you need. It's used by deftype but gen-class wasn't switched over. https://github.com/clojure/clojure/blob/eccde24c7fb63679f00c64b3c70c03956f0ce2c3/src/jvm/clojure/lang/DynamicClassLoader.java |
| 10:42 | llasram | It's wired in to how Clojure loads classes, with some helpers available on clojure.lang.RT |
| 10:43 | llasram | Here's as example I wrote, extending gen-class to use DynamicClassLoader: https://github.com/llasram/shady/blob/master/src/shady/gen_class.clj |
| 10:43 | gfredericks | what's the latest strategy for cljs testing? |
| 10:44 | twhume | Thanks. I'm quite a Clojure noob, mind if I have a look at that and probably get back to you with more questions? |
| 10:44 | llasram | np |
| 10:47 | wastrel | hi |
| 10:50 | TimMc | dnolen: Ever seen anything like this with core.match? https://www.refheap.com/paste/2937 |
| 10:51 | TimMc | dnolen: Basically, a match clause is intermittently returning nil, even though it is guaranteed a match. |
| 10:55 | SurlyFrog | Hi all, I'm coming to Clojure without any significant Java experience (a decade or so C, Common Lisp, Python, and a few others). I'm wondering if the JVM handles "swapping" or caching large data structures to disk. For example, if you are growing a large data structure in memory, and it gets too large, will the JVM automagically cache portions of it to disk, or will you get out-of-memory exceptions? |
| 10:56 | clgv | SurlyFrog: no. If you hit the -Xmx limit the JVM will die with an exception |
| 10:56 | SurlyFrog | clgv: okay, thanks... |
| 10:57 | SurlyFrog | clgv: is -Xmx a command line option to the JVM? |
| 10:57 | clgv | yes |
| 10:57 | SurlyFrog | thanks |
| 10:58 | cemerick | well, the thread of execution that hits the allocation limit will throw that exception…which can be caught and recovered from. OutOfMemoryErrors don't actually terminate the JVM process. |
| 10:58 | clgv | hm right. never tried to catch one yet ;) |
| 10:59 | SurlyFrog | cemerick: okay. |
| 11:00 | cemerick | ,(try (byte-array Integer/MAX_VALUE) (catch OutOfMemoryError e "you're safe!")) |
| 11:00 | clojurebot | cemerick: Huh? |
| 11:00 | cemerick | wha? |
| 11:00 | cemerick | &(try (byte-array Integer/MAX_VALUE) (catch OutOfMemoryError e "you're safe!")) |
| 11:00 | lazybot | java.lang.SecurityException: You tripped the alarm! catch is bad! |
| 11:00 | cemerick | oh hell |
| 11:00 | cemerick | anyway, it works outside of a sandboxed environment |
| 11:00 | twhume | llasram: OK, thanks for your help. I now have a class being loaded OK; any idea how I would force it to be unloaded (so that I can load a new class in under the same name)? |
| 11:05 | llasram | twhume: My understanding is that you don't explicitly "unload" the class. You load it again w/ a different class loader, which gets a new Class instance representing the new class version |
| 11:05 | llasram | These classes are never resolved through normal JVM class resolution, but instead always go through Clojure namespace lookup mechanisms |
| 11:06 | twhume | OK, but the class loader in this case is a locally scoped variable inside the load-class function. If I were to pass a new instance of the class loader into that method each time, do you think that would do it? |
| 11:06 | twhume | (I'm guessing that the class loader won't be GCed until classes it's loaded are...) |
| 11:15 | clgv | twhume: a class has a reference to it's classloader |
| 11:16 | twhume | clgv: yup. So the loaded and the class have to go. I can sometimes force them out by doing ns-unmap followed by a GC, but it doesn't seem reliable. I think I'll do something else to work around this… it's quite important for my application. |
| 11:17 | clgv | twhume: what is your big picture? |
| 11:17 | twhume | As in, what's the app? |
| 11:17 | clgv | so to say |
| 11:18 | twhume | A bit wacky; I'm writing a "superoptimiser" for Java byte code - essentially, doing an exhaustive search for optimal programs across all possibilities. So I'm generating many classes, loading them, testing each one, testing if it works, and (usually) discarding it. |
| 11:19 | gfrederi` | is there a CLJS equivalent to (extend-type Object ...)? |
| 11:19 | gfrederi` | (i.e., something that covers all the JS types) |
| 11:20 | clgv | twhume: oha, ok. |
| 11:22 | matthavener | twhume: have you seen the minikanren presentation on bliptv ? |
| 11:22 | dnolen | gfredericks: extend-type default |
| 11:23 | twhume | matthavener: nope |
| 11:23 | matthavener | those minikanren guys write a program that generates arbitrary programs that result in the number 6 |
| 11:23 | matthavener | might be interesting to you |
| 11:23 | twhume | This one? http://blip.tv/clojure/dan-friedman-and-william-byrd-minikanren-5936333 |
| 11:23 | matthavener | yes, near the end |
| 11:24 | twhume | Thanks very much - I'll give it a look. There have been superoptimisers for specific hardware (SPARC, RS6000, 68000), but none for the JVM... |
| 11:26 | gfredericks | dnolen: cool thx |
| 11:28 | TimMc | dnolen: Did you see the core.match weirdness I posted? |
| 11:28 | TimMc | I can't get a minimal test case since it's nondeterministic... |
| 11:28 | dnolen | TimMc: no, there's a lot of core.match weirdness, matching what kind of type? |
| 11:29 | TimMc | keywords |
| 11:30 | dnolen | TimMc: link or gist? |
| 11:30 | TimMc | dnolen: https://www.refheap.com/paste/2937 but it doesn't fail reliably (or in isolation?) |
| 11:31 | dnolen | TimMc: what is the weirdness the error? |
| 11:32 | Chiron_ | hi! what is wrong with this http://pastie.org/4002330 |
| 11:32 | Chiron_ | CompilerException java.lang.RuntimeException: Unable to resolve symbol: server in this context |
| 11:33 | dnolen | TimMc: hmm, yeah not sure what's going on and don't have the bandwidth to pursue. Feel free to open a ticket with more details - patch even better of course. |
| 11:35 | clgv | Chiron_: the content of your doseq: (1) the ~ (2) there is one pair of parenthesis which is too much |
| 11:35 | jcromartie | hooray for -webkit-overflow-scrolling: touch; |
| 11:37 | TimMc | dnolen: OK, we'll probably just drop it for now. Macro-expansion of the match clause looks fine -- I can't see how it would fail. If we get anything reproducible I'll open a ticket. |
| 11:37 | ezyang | Hello folks. I was wondering if there were any implementations of STM-ized mutable data structures. |
| 11:38 | ezyang | Or if this is even a good idea at all. |
| 11:38 | dnolen | TimMc: thanks much! Yeah I do not recommmend relying on core.match until it hits beta status. |
| 11:38 | dnolen | ezyang: probably not a good idea I'd think. |
| 11:39 | ezyang | dnolen: How many references would the structure have to use before it became a bad idea? |
| 11:42 | ezyang | Certainly, it wouldn't be "more than one", since the whole point about STM is to deal with multiple references properly. |
| 11:43 | S11001001 | ezyang: when it comes to collections, there are only three numbers: 0, 1, and many. |
| 11:43 | dnolen | ezyang: do you just mean allowing mutable data structures to participate in STM? isn't that what a most STM research has been trying to do all along? (is not an STM expert) |
| 11:43 | S11001001 | yes, and it's slow as hell |
| 11:44 | S11001001 | ezyang: so the correct answer is it's fine, as long as your data structure has either 0 or 1 element(s) |
| 11:45 | S11001001 | do more stuff immutably; STM gets a lot less interesting then |
| 11:47 | ezyang | S11001001: OK. The difference is something like 'one STM var per index on data store' to 'one STM var per element stored' |
| 11:47 | ezyang | I wonder if there is a middle ground. |
| 12:04 | goodieboy | I'm using an agent w/send-off for async http requests. Under what circumstances will my agent "fail", and how to do I completely avoid failure from happening? Use a top-level try/catch in my agent function? |
| 12:06 | nDuff | goodieboy: an unhandled exception, and yes... though "completely" is a little strong; there _are_ uncatchable exceptions in the JVM. |
| 12:06 | nDuff | goodieboy: ...the proper Right Thing is to check for failure when you're going to interact with the agent, and deal with it then. |
| 12:07 | goodieboy | nDuff: ahh, right before I attempt to call send-off? |
| 12:09 | nDuff | That's what I generally do. That said, there _is_ a race condition there, so it's probably not the best pattern. |
| 12:12 | nDuff | goodieboy: ...catching the exception from trying to do a send to a failed agent, and handling it there, would be the safer thing. |
| 12:13 | nDuff | goodieboy: ...that said, if you aren't checking the value the agent holds anyhow, there's a decent chance that you're doing something for which a different concurrency mechanism would be more appropriate. |
| 12:13 | nDuff | s/doing something/doing is something/ |
| 12:18 | goodieboy | nDuff: yes, you're right. I don't care about the value of the agent. Should I be doing something else? |
| 12:21 | nDuff | goodieboy: ...to quote Joy of Clojure: "In cases where you just need a bunch of worker threads banging away on some work, or you have a specific long-running thread polling or blocking on events, or any other situation where it doesn't seem useful that the Agent maintain a value [...] there's every reasot to consider using a Java Thread directly, or a Java executor" |
| 12:22 | nDuff | goodieboy: (if you have your own copy -- this discussion is in 11.3.5, pages 254-255) |
| 12:23 | goodieboy | nDuff: ahh ok, thanks |
| 12:23 | nDuff | ...except the book doesn't contain that typo :) |
| 12:23 | nDuff | s/reasot/reason/ |
| 12:25 | S11001001 | is the pool used for sends accessible? |
| 12:26 | duck1123 | if you're using the new version of lamina, it has some nice helper functions for managing tasks on thread pools |
| 12:26 | nDuff | S11001001: the executors are public static on clojure.lang.Agent, so it's _possible_ to access them |
| 12:26 | nDuff | S11001001: whether it's _wise_... |
| 12:29 | technoma` | planning on cutting a lein release today |
| 12:29 | technoma` | anything else that should be considered for it? |
| 12:30 | technoma` | this one is going out mostly in order to fix a bug in the repl and add support for encrypted credentials |
| 12:31 | clgv | lein2 or lein1.7.x? |
| 12:31 | technoma` | 2.0.0-preview5 |
| 13:02 | pbuckley | Anyone know how I can use C-x-e (emacs slime) in a function that relies on args or values from destructuring without having to temporarily def those args/bindings? |
| 13:03 | pbuckley | like how do I test the inner fn "some-fn" in (defn build? [some-arg] (some-fn some-arg)) without having to temporarily do (def some-arg "foo")? |
| 13:04 | pbuckley | by "test" I mean C-x-e |
| 13:17 | lpetit | hello |
| 13:19 | tmciver | pbuckley: I don't believe you can. C-x C-e just 'evaluates' code, it does not call the fn. |
| 13:19 | locojay | hi anything similar to python os.path.join (to make sure between unix and win paths...) |
| 13:19 | tmciver | pbuckley: To test your inner fn you'd just have to rely on test for the outer fn, or break out the inner fn. |
| 13:19 | joegallo | pbuckley: you could C-c C-e instead, and then type (build? "whatever-arg-you-want") |
| 13:20 | joegallo | or (some-fn whatever-arg), for that matter |
| 13:20 | raek | locojay: yes. (clojure.java.io/file "foo" "bar" "baz") |
| 13:20 | locojay | thnks |
| 13:20 | raek | that produces a File object (which represents a path) |
| 13:20 | lpetit | Shameless plug: Counterclockwise (the Clojure Eclipse Plugin) now has decent leiningen 2 support in its (quite stable) beta version. With the ability to create new projects via a wizard wrapping lein new new (so you also get templates for free) |
| 13:24 | lpetit | For those interested, more info here: https://groups.google.com/d/topic/clojuredev-users/UhfnjBvIips/discussion |
| 13:25 | Bronsa | cool lpetit |
| 13:30 | gfrederi` | why would naive-recursive-fib be 20 times slower in clojure than java? |
| 13:31 | amalloy | gfrederi`: best explanation: you're doing something wrong? i certainly can't guess without seeing any code |
| 13:31 | gfrederi` | amalloy: okay I'll pull it together |
| 13:31 | amalloy | eg, boxing is going to cost you a little, but not 20x |
| 13:31 | pbuckley | tmciver, joegallo, thanks, looks like I just have to break out the inner fn |
| 13:33 | gfrederi` | amalloy: refheap.com/paste/2944 |
| 13:34 | gfrederi` | amalloy: I guess the clojure could be changed to case? |
| 13:35 | amalloy | cemerick: OOM errors can trash your JVM pretty badly though, unless every thread knows how to deal with them at any time (pretty unlikely). thread 1 allocates almost-all the memory, then thread 2 gets an OOM and dies, then thread 1 gets an OOM, recovers, and throws out its excess crap |
| 13:36 | cemerick | amalloy: fair point |
| 13:38 | technoma` | is it or is it not idiotic that exceeding your thread limit throws an out of memory exception? |
| 13:38 | amalloy | technoma`: the JVM just can't remember all the dang threads you want |
| 13:39 | amalloy | gfrederi`: and that's 20x faster in java? even on clojure 1.2 i wouldn't expect that big a difference |
| 13:40 | amalloy | you could try hinting with ^int, on x and on the parameter vector (to hint the return type) |
| 13:41 | gfrederi` | amalloy: I'll verify the runtimes in just a sec |
| 13:42 | gfrederi` | amalloy: running (time (fib 40)) in clojure prints ~7 seconds |
| 13:42 | amalloy | oh cool, case actually has code in it to special-case "all the test clauses are for ints, don't bother hashing anything" |
| 13:43 | gfrederi` | `time java ...` runs in 0.75 sec INCLUDING jvm startup time |
| 13:43 | gfrederi` | amalloy: switching to case cuts it down to ~6.5 sec |
| 13:43 | jcromartie | gfrederi`: are you counting the Clojure startup time? |
| 13:43 | gfrederi` | jcromartie: nope, running the time macro from a repl |
| 13:44 | jcromartie | ah ok |
| 13:44 | amalloy | &(-> (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])) (nth 40)) ;; just checking the number |
| 13:44 | lazybot | ⇒ 102334155 |
| 13:44 | kmicu | &(time (-> (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])) (nth 40))) |
| 13:44 | lazybot | java.lang.ClassNotFoundException: clojure.core |
| 13:45 | gfrederi` | kmicu: obviously that will be much faster |
| 13:45 | Raynes | Man, I sure wish I knew what caused that. |
| 13:45 | Raynes | $login |
| 13:46 | lazybot | You've been logged in. |
| 13:46 | Raynes | $reload |
| 13:46 | lazybot | Reloaded successfully. |
| 13:46 | Raynes | $`foo |
| 13:46 | Raynes | &`foo |
| 13:46 | lazybot | java.lang.ClassNotFoundException: clojure.core |
| 13:46 | amalloy | gfrederi`: adding ^long hints speeds it up 10x |
| 13:48 | bordatoue | hello |
| 13:48 | bordatoue | is it safe to use double as a key in hashmap |
| 13:49 | S11001001 | bordatoue: what's safe? |
| 13:49 | kmicu | in cljs repl it takes 3ms in my clj repl 8 ms :) |
| 13:49 | S11001001 | &({1.0 42} 1) |
| 13:49 | lazybot | ⇒ nil |
| 13:51 | gfrederi` | amalloy: oh we tried with Long; yeah primitives are much better |
| 13:52 | Bronsa | yes |
| 13:52 | gfrederi` | &(let [x 1.7e90] ({x 12} x)) |
| 13:52 | lazybot | ⇒ 12 |
| 13:52 | bordatoue | S11001001: safe in the sense, will there be key misses |
| 13:52 | bordatoue | when computing hash |
| 13:52 | gfrederi` | bordatoue: only if your doubles aren't quite equal |
| 13:52 | gfrederi` | bordatoue: can you use ratios instead of doubles? |
| 13:54 | bordatoue | i can try |
| 13:55 | gfrederi` | ratios are much less scary |
| 13:55 | bordatoue | but is it recommended to use double as key in hashmap, what is the function used to create hashcode |
| 13:55 | gfrederi` | amalloy: with case and primitive typehints it is only 3 times slower |
| 13:56 | gfrederi` | maybe for var lookup? |
| 13:58 | technoma` | bordatoue: if you're performing lookup on a map from Clojure functions the numbers will hash correctly. if you're using Java methods to get at them then the required broken Java semantics will apply. |
| 13:58 | bordatoue | technoma`: thanks, |
| 13:58 | bordatoue | technoma`: Could you please tell me how java would result in incorrect result when using double |
| 13:59 | bordatoue | technoma`: Basically i just want to know how different it will be |
| 13:59 | technoma` | I don't really know the details; I just know Java requires you to confirm to incorrect semantics if you claim to support certain interfaces. |
| 13:59 | bordatoue | technoma`: You could point me to some resource I can read , it would be great |
| 13:59 | technoma` | I think you can have both (Long. 1) and (Integer. 1) as separate keys or something? |
| 14:00 | technoma` | no idea how doubles play into that |
| 14:00 | gfrederi` | oddly type-hinting the parameter vector slowed it down significantly |
| 14:00 | gfrederi` | and eleminating the var lookup doesn't help either |
| 14:01 | amalloy | technomancy: that got fixed in 1.4 though |
| 14:01 | amalloy | maps now use equiv instead of equals for key uniqueness |
| 14:01 | technoma` | amalloy: I thought the clojure functions were fixed in 1.3 but the java methods were still broken due to the requirements of the java interfaces? |
| 14:02 | amalloy | the clojure functions certainly weren't fixed in 1.3 - that was when the breakage became obvious, because longs became the default box |
| 14:03 | amalloy | whether the java methods are broken, i don't know about |
| 14:03 | technoma` | oh, I'm talking about Integer/Long equivalence; primitives are another can of worms |
| 14:04 | bordatoue | Can anyone suggest a method to check if using double is safe as key in java hashmap |
| 14:04 | amalloy | as am i |
| 14:05 | amalloy | i think |
| 14:05 | amalloy | bordatoue: step 1 has got to be "decide what you mean by that question" |
| 14:06 | amalloy | ,*clojure-version* |
| 14:06 | clojurebot | {:interim true, :major 1, :minor 4, :incremental 0, :qualifier "master"} |
| 14:06 | amalloy | &*clojure-version* |
| 14:06 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 14:06 | amalloy | i hate you both |
| 14:06 | hiredman | you want 1.5? |
| 14:06 | bordatoue | amalloy: when i say safe, it means something would work consistently |
| 14:07 | amalloy | hiredman: 1.3 |
| 14:07 | hiredman | pffft |
| 14:07 | hiredman | 1.3 is bad and no one should use it |
| 14:07 | amalloy | i agree! |
| 14:07 | amalloy | technomancy claimed something worked in 1.3, and i was hoping to prove him wrong |
| 14:10 | S11001001 | bordatoue: it isn't nondeterministic, you will definitely either get a key match or a key mismatch for any two values |
| 14:11 | bordatoue | S11001001: could there be a key miss |
| 14:12 | S11001001 | bordatoue: well you'd want key misses, wouldn't you, otherwise what's the point of a map? |
| 14:13 | S11001001 | ok, I'll put it this way |
| 14:13 | bordatoue | S11001001: due to floating point precision can there be key misses |
| 14:14 | S11001001 | you can't deal with precision and have = |
| 14:14 | S11001001 | let me formalize |
| 14:14 | S11001001 | forall a b c in values where c is not nil. (= a b) implies ({a c} b) => c and (not= a b) implies ({a c} b) => nil. |
| 14:17 | bordatoue | S11001001: thanks |
| 14:17 | bordatoue | I will do some research on it |
| 14:39 | locojay | anyone using congomongo . when doing an update! call i keep on getting <#WriteResult N/A> on stdout. anyway i can prevent the output |
| 14:43 | amalloy | locojay: stop calling println on the result of the update? there's really no other reason it would print |
| 14:44 | gtrak` | hmm, is swank supposed to be able to M-. to a protocol def? |
| 14:45 | technoma` | I don't think so |
| 14:58 | technoma` | emezeske: this is weird; someone is claiming authorship of lein-cljsbuild in the comments: http://technomancy.us/158 |
| 14:58 | technoma` | is that a spam-bot copying your content from another source? |
| 14:59 | emezeske | technoma`: that it is. I did write that comment, months ago, on some other blog |
| 14:59 | emezeske | crazy! |
| 15:00 | technoma` | did you misspell "plugin" in your comment as well? =) |
| 15:00 | technoma` | weird that there's no URL associated with the post |
| 15:00 | emezeske | I hope I didn't :( |
| 15:00 | TimMc | Nope. |
| 15:01 | kilon | that make no sense, what would be the benefit for a spam bot ? |
| 15:01 | TimMc | It is probably doing that as a probe. Some spambots will use unique strings so they can do a web search later to find out if their comment was approved. |
| 15:01 | locojay | amalloy: i don't have any print at all https://gist.github.com/2845411 line 5 does the output |
| 15:01 | technoma` | kilon: possibly testing the anti-spam defenses? |
| 15:01 | amalloy | emezeske: no hits for "leiningen plguin" anywhere on the web |
| 15:01 | technoma` | yeah |
| 15:01 | technoma` | emezeske is cleared =) |
| 15:01 | kilon | ah i see |
| 15:01 | TimMc | The original: http://ubercode.de/blog/settling-down-with-clojurescript |
| 15:01 | TimMc | The bot stripped out all tags, too. |
| 15:01 | technoma` | damn; better wipe that comment before the bot finds it |
| 15:02 | amalloy | locojay: (update! ...) returns a WriteResult, so if you're just printing the result of that (say, in the repl)... |
| 15:02 | technoma` | clever bugger; the content *almost* makes sense |
| 15:02 | locojay | runing via lein run and main |
| 15:02 | kilon | companies with too much free time in their hands |
| 15:02 | kilon | no wonder why global economy goes to hell |
| 15:02 | technoma` | in fact if it had been on my most recent post and I didn't already know emezeske then I wouldn't have suspected a thing |
| 15:03 | raek | I vagely recall that "lein run" prints the result of the -main function for some reason |
| 15:03 | emezeske | technoma`: That is a clever way to keep your comment from being deleted |
| 15:03 | technoma` | hm; that explains the nonsense alphanumerics in the URL field too |
| 15:03 | technoma` | it's a token for checking up on later |
| 15:03 | TimMc | indeed |
| 15:03 | TimMc | technoma`: Alter the token, cause havoc? |
| 15:04 | technoma` | TimMc: mwahaha |
| 15:04 | technoma` | I've heard of people writing tarpits that have slowly-increasing latencies to gum up the bots |
| 15:04 | solussd_ | I'm getting a compiler error "can't recur here" from clojurescript- I've narrowed it down to this: https://www.refheap.com/paste/4fc7bf16e4b09302d009a309 could anyone tell me why I can't recursively call that function? |
| 15:05 | hiredman | there is no recur in that function |
| 15:06 | hiredman | solussd_: what makes you think it is that function? |
| 15:06 | hiredman | (my guess it is your code calling that function) |
| 15:06 | solussd_ | hiredman: b/c taking it out makes the compiler error go away. :) |
| 15:06 | solussd_ | in fact, removing the (map?) condition stops the error |
| 15:06 | emezeske | solussd_: are you up to date with your compiler version? |
| 15:07 | hiredman | doseq may be broken in clojure script |
| 15:07 | emezeske | solussd_: I know I've encountered that before, but I can't remember where :( |
| 15:07 | emezeske | doseq works just fine |
| 15:08 | emezeske | Oh, I think maybe cond is not supported in older clojurescript versions (?) |
| 15:08 | solussd_ | emezeske: it compiles w/o the map? condition though |
| 15:08 | dnolen | emezeske: cond has been there since the beginning far as I know. |
| 15:08 | solussd_ | it's definitely the recursive call that is making it blow up |
| 15:08 | emezeske | dnolen: Okay, color me crazy then |
| 15:08 | solussd_ | i'm using the version of clojurescript pulled in by noir-cljs: [org.clojure/clojurescript "0.0-1236"] |
| 15:09 | amalloy | emezeske: early versions didn't have case |
| 15:09 | emezeske | amalloy: Thank you for preserving my sanity, "case" is definitely what I was thinking of |
| 15:09 | dnolen | solussd_: create a minimal reproducible case, open a ticket |
| 15:10 | solussd_ | dnolen: k. |
| 15:19 | piranha | hi, if I have a question regarding clojurescript one and lein, should I ask it here, go to #clojurescript or to #leiningen? :) |
| 15:20 | kilon | you can ask it here too |
| 15:21 | piranha | sure. I'm trying to get cljs one up and running, but then (probably because I have lein2) none of the examples work |
| 15:21 | piranha | for example, they say run "lein repl" and then "(go)" |
| 15:22 | piranha | function go is not defined in my repl |
| 15:22 | piranha | dev-server is not defined as well |
| 15:22 | piranha | and I'm a bit lost already what to do :\ |
| 15:23 | technoma` | have you tried lein-cljsbuild? |
| 15:23 | piranha | hm, nope |
| 15:23 | dnolen | piranha: CLJS one has seen much activity lately, it's pretty out of date as far CLJS far as I know. |
| 15:23 | amalloy | seancorfield: i'm digging through congomongo to remove the remaining reflection warnings. there are a number of cases like (.method ^GridFS f arg), where arg can be one of several types |
| 15:23 | dnolen | has not seen |
| 15:23 | amalloy | i have a macro in useful, multi-hinted-let, that can easily expand to something like (condp instance? arg File (.method ^GridFS f ^File arg), InputStream (.method ^GridFS f ^InputStream arg) ...). would you prefer that i (a) add a dependency on useful in project.clj, (b) copy/paste the macro into congomongo, or (c) just do it by hand every time? |
| 15:24 | dnolen | piranha: best to start with lein-cljsbuild at this point |
| 15:24 | technoma` | piranha: yeah, lein-cljsbuild seems a lot more usable |
| 15:24 | piranha | dnolen: ah, so it's better to skip it and just do... |
| 15:24 | piranha | ok, I see, thanks :) |
| 15:33 | antares_ | seancorfield, amalloy: Monger uses helper protocols to coerce things like arg in this example (where possible) |
| 15:34 | antares_ | other clojurewerkz.org projects do the same, it works pretty well (although there are cases where something like multi-hinted-let would still be necessary) |
| 15:35 | amalloy | antares_: so does congomongo in other cases, but for example GridFS/createFile accepts either a byte[] or a File or an InputStream, and there's no zero-overhead way to coerce those into a single thing |
| 15:36 | antares_ | amalloy: yeah, I am not saying helper protocols are zero overhead. But it is OK for most needs (less overhead than reflective calls). Here's what monger uses, FYI: https://github.com/michaelklishin/monger/blob/master/src/monger/gridfs.clj |
| 15:39 | amalloy | antares_: the other thing i'm doing is removing all the unnecessary typehints from congomongo - looks like monger could use some of the same treatment :) |
| 15:39 | antares_ | amalloy: yeah. Monger was my 2nd clojure library, it has a lot of things I'd like to clean up. Pull requests are welcome :) |
| 15:46 | clojure-newcomer | hi guys, I'm trying to do multi method dispatch on a key… I found a working example that dispatches on the value of a key ':name', but my data has arbitrary keys… http://pastebin.com/wpjaBKWU |
| 15:46 | clojure-newcomer | I've made a failed attempt below the working example |
| 15:49 | dnolen | clojure-newcomer: make key return the relevant value for a particular map. |
| 15:50 | dnolen | clojure-newcomer: if you're looking for the general case, not possible with multimethods - would require predicate dispatch. |
| 15:50 | clojure-newcomer | dnolen: I think you are saying I need to change my data structure because its not possible to do what I am trying to do ? |
| 15:51 | dnolen | clojure-newcomer: changing your data structure won't help you. |
| 15:51 | dnolen | clojure-newcomer: it sounds like you want different methods to run if a key is present |
| 15:52 | clojure-newcomer | dnolen: yes I think so, so a certain function called if a key ':id' is found, different function for ':blurb' etc etc |
| 15:52 | dnolen | clojure-newcomer: not possible with multimethods |
| 15:52 | clojure-newcomer | dnolen: nuts, thanks for saving me time anyhow :-) |
| 15:53 | clojure-newcomer | dnolen: I think I can flip it on its head and work with the value anyhow, thx for the help |
| 15:53 | ezyang | Can someone help me out: I can't find where Clojure's jvm code keeps track of nested transactions. |
| 15:54 | ezyang | runInTransaction seems to always attempt to commit the transaction at the end. |
| 15:54 | ezyang | What am I missing? |
| 15:55 | TimMc | Are you sure they nest? |
| 15:55 | TimMc | Maybe dosync always joins any open transaction. |
| 15:55 | ezyang | there are claims on the Internet that they do. But I might be wrong :-) |
| 15:55 | hiredman | they nest |
| 15:56 | hiredman | ezyang: have a look at clojure.core/sync |
| 15:57 | ezyang | That just calls LockingTransaction.runInTransaction |
| 15:57 | ezyang | I'm staring at that code right now. |
| 15:57 | hiredman | right, which looks for a locking transaction where? |
| 15:58 | ezyang | So, it checks if there is a current transaction. But then regardless of whether or not there was a running transaction, it invokes t.run(fn) |
| 15:58 | ezyang | I think that's wrong. I also think that this will have the wrong semantics if a retry is necessary. |
| 15:59 | hiredman | why do you think it is wrong? |
| 15:59 | hiredman | a transaction joins the current transaction if there is one already running |
| 16:00 | ezyang | Yes, that is correct. |
| 16:00 | ezyang | The problem is what happens when the inner transaction finishes. |
| 16:00 | hiredman | what about it? |
| 16:00 | ezyang | If you straightline the code, you get something like: |
| 16:01 | ezyang | transaction.set(t = new LockingTransaction()); ... /* no set */; fn.call; t.run(fn2); .... t.run(fn1) |
| 16:02 | hiredman | that is not correct |
| 16:02 | ezyang | Unless I'm super misunderstanding what t.run does, I think it finalizes the transaction |
| 16:02 | ezyang | I think that's what the code is doing. |
| 16:02 | hiredman | do you have code that demos the problem? |
| 16:02 | ezyang | No. It'd probably be a very fiddly race to cause too. |
| 16:03 | ezyang | oh, actually, no, this should be pretty simple. |
| 16:03 | ezyang | just a sec. |
| 16:03 | hiredman | you cannot "straighline" the code, it is nested |
| 16:03 | ezyang | hiredman: What I mean by "straightline" is saying what a hypothetical execution would step through. |
| 16:04 | hiredman | that is incorrect in that sense too |
| 16:04 | ezyang | OK, help me understand why this doesn't happen. |
| 16:04 | hiredman | fn1 would start executing before fn2 and finish executing after fn2 finishes |
| 16:04 | hiredman | (where fn2 is a nested transaction) |
| 16:04 | ezyang | No, that's not right. |
| 16:04 | hiredman | it is right |
| 16:05 | ezyang | fn.call is responsible for calling the function. |
| 16:05 | hiredman | fn2 code is run from inside fn1 |
| 16:05 | ezyang | Yes, I inlined that in my example. |
| 16:06 | hiredman | (sync nil (X (sync nil Y))) turns in to (.../runTransaction (fn [] (X (../runTransaction (fn [] Y))))) |
| 16:06 | ezyang | Yes. |
| 16:07 | hiredman | so the outermost fn is fn1, and the inner most is fn2 |
| 16:07 | ezyang | So when you enter the inner runTransaction, you run fun2's code, and then run t.run(fun2) |
| 16:07 | hiredman | right |
| 16:07 | hiredman | which happens while fn1 is running |
| 16:07 | ezyang | I think running t.run(fun2) finishes up the transaction. |
| 16:07 | ezyang | and then when fn1 finishes running, it runs t.run(fun1) |
| 16:08 | devijvers | greetings, can anybody tell me how attribute selectors work in enlive? |
| 16:08 | hiredman | ezyang: no |
| 16:08 | hiredman | they are nested, t.run(fn2) cannot happen unless t.run(fn1) is running |
| 16:09 | ezyang | OK, let me state my assumptions. |
| 16:09 | ezyang | 1) fn.call() in runInTransaction is responsible for running the code inside fn |
| 16:10 | ezyang | 2) If fn contains a runInTransaction, when fn is finished running, all of the lines in runInTransaction will have run. |
| 16:11 | ezyang | 3) In our example, we first runInTransaction on fn1. fn.call() causes fn1 to be executed, and doesn't return until fn1 is done executing. |
| 16:12 | hiredman | it depends for some cases the fn.call line is never reached |
| 16:12 | hiredman | in the facse of the outmost transaction the fn is run inside the call to t.run(fn) not fn.call() |
| 16:12 | hiredman | because info will be null |
| 16:12 | ezyang | OK, that is true. |
| 16:13 | ezyang | 3') In our example, we first runInTransaction on fn1. t.run(fn1) causes fn1 to be executed, and that f.call() doesn't return until fn1 is done executing. |
| 16:13 | ezyang | combining (3') and (2), because fn1 contains a runInTransaction, when /that/ f.call() line returns, all the lines in runInTransaction on fn2 have finished executing. |
| 16:14 | hiredman | correct |
| 16:14 | ezyang | OK. |
| 16:14 | hiredman | so what happens for fn2 is it goes right to t.run(fn2) |
| 16:14 | ezyang | 4) A line of that runInTransaction is t.run(fn2) |
| 16:14 | ezyang | aha! return is short circuiting. |
| 16:14 | ezyang | Ok, we're good. |
| 16:14 | hiredman | *eyeroll* |
| 16:15 | ezyang | Sorry, this is why I came and asked :-) |
| 16:18 | devijvers | hey, can anybody help me with attribute selectors in enlive? |
| 16:18 | amalloy | ~anyone |
| 16:18 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 16:19 | devijvers | I want to write this selector: select[name=somename] |
| 16:20 | ystael | What is the most idiomatic way to filter a seq by a predicate which may have side effects so is required to be evaluated exactly once for each seq element? (I don't care _when_ the predicate is evaluated, only that it is at most once each) |
| 16:20 | ystael | s/at most/exactly/ |
| 16:21 | bobry | emezeske: is it possible to pass --define to closure compiler? |
| 16:21 | emezeske | bobry: Nope. |
| 16:21 | bobry | ouch <_< |
| 16:21 | bobry | why? |
| 16:21 | clojurebot | bobry: because you can't handle the truth! |
| 16:22 | bobry | turns out the only way to override 'goog.LOCALE' is pass --define goog.LOCALE=... |
| 16:22 | emezeske | bobry: Well, for one, it's not called from the command line, so passing command line arguments doesn't really make sense |
| 16:22 | TimMc | Sure it does. |
| 16:23 | emezeske | bobry: And nobody's created a nice way to set all of the google closure options in the clojurescript compiler |
| 16:23 | mstump | I'm getting an exception which doesn't make sense. I'm passing a string to a Java constructor, and I keep getting "java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Comparable" which doesn't make sense because String implements Comparable. Any ideas? |
| 16:23 | TimMc | mstump: Look at the [L |
| 16:23 | kmicu | bobry: you have fix for that http://dev.clojure.org/jira/browse/CLJS-77 |
| 16:23 | TimMc | That means you have an array of something. |
| 16:23 | emezeske | bobry: I'd love to have all of the google closure options exposed, they're just not. There's about a billion of them. |
| 16:23 | hiredman | mstump: you are not calling the constructor you think are calling |
| 16:23 | TimMc | mstump: I'll hazard a guess that you're running into varargs. |
| 16:24 | mstump | That constructor does take a vargs Comparable |
| 16:24 | mstump | what should I be doing? |
| 16:24 | bobry | I see.. and thanks kmicu ;) |
| 16:24 | TimMc | Passing in an array. |
| 16:24 | TimMc | Varargs is a lie. |
| 16:25 | TimMc | &(class (into-array ["foo"])) might do it |
| 16:25 | lazybot | ⇒ [Ljava.lang.String; |
| 16:26 | devijvers | how do I write this selector in enlive? select[name=somename]? |
| 16:27 | locojay | if i do map #(some funciton) on a lazy seq nothing happens do i have to use a doall ? |
| 16:28 | emezeske | bobry: This is where the google closure options get set. Very basic at the moment. 'Twould be awesome for this to be configurable, maybe via a callback that sets the options: https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/closure.clj#L76 |
| 16:28 | devijvers | locojay: yes |
| 16:29 | devijvers | locojay: if you use map as a replacement of a loop you're better off with for |
| 16:30 | dnolen | emezeske: bobry: patches welcome |
| 16:30 | mstump | That was it. Thank you! That was a horrible fcking exception. I want my morning back. Someone should be violently penetrated with a cactus. |
| 16:31 | locojay | devijvers : thanks. i was planning to use pmap and and upload function to my db to upload in parrallel so i m not sure if for is better |
| 16:32 | bobry | dnolen: great! btw, is there a reason, cljs doesn't accept pull requests? |
| 16:32 | dnolen | bobry: because that's not approved Clojure process. |
| 16:33 | emezeske | dnolen: I wish I had more time to allocate to the cljs compiler... Maybe someday soon. :) |
| 16:33 | bobry | oh, where can I read more about the process? |
| 16:33 | dnolen | bobry: on the Confluence pages. |
| 16:33 | bobry | emezeske: I like the callback idea, can you submit a patch? :) |
| 16:34 | emezeske | bobry: Unfortunately, my time to interest ratio in that particular feature is rather low :( |
| 16:34 | kmicu | dnolen: i can write a patch, but my idiomatic clojure sucks for now :] and jonase/kibit it's not so good to fix that :P and seriously what is wrong with this http://dev.clojure.org/jira/browse/CLJS-77 |
| 16:34 | bobry | except for patch formatting :) |
| 16:36 | devijvers | locojay: can't think of a better solution than pmap |
| 16:36 | devijvers | how do I write this selector in enlive? select[name=somename]? |
| 16:37 | bobry | kmicu: I think this needs a more generic solution, the patch in CLJS-77 only covers --define |
| 16:37 | locojay | devijvers: not at the moment as i m a total novice |
| 16:37 | dnolen | bobry: kmicu: patch looks ok and applies - just confirmation from someone that it works for them. |
| 16:39 | dnolen | bobry: would welcome a more generic patch. |
| 16:41 | bobry | dnolen: sure, should I create a separate issue? |
| 16:44 | dnolen | bobry: feel free, have you sent in your CA? |
| 16:44 | TimMc | devijvers: Doesn't the Enlive wiki have an example of that? |
| 16:46 | devijvers | TimMc: thx!! found it on the wiki: these selectors requre double brackets, now it works |
| 16:47 | bobry | dnolen: nope, not yet, can you merge the patch from CLJS-77, while the CA flies all the way from Russia? :) |
| 16:48 | dnolen | bobry: if you can confirm that it actually works |
| 16:48 | bobry | okay, let me check then |
| 16:53 | devth | anyone know if clojure.contrib.cond ever got a replacement? looking for a cond-let |
| 16:58 | devth | if there's not a replacement for an old contrib, what's the correct way of making one? |
| 17:00 | kmicu | devth: http://dev.clojure.org/display/design/Moving+Projects+Into+Contrib |
| 17:01 | devth | kmicu: thanks, but doesn't that only apply to 1.2 and below? |
| 17:02 | devth | also, i'm not the original author. i just want an old contrib to use in my project. |
| 17:03 | S11001001 | (<<- (if-let [x whatever] x) (if-let [y whatever] y) otherwise) |
| 17:03 | S11001001 | trivial expansion target, combined with flipped ->> |
| 17:06 | coventry` | What's the status of clojure in clojure? Is there a public repository for it? |
| 17:06 | dnolen | coventry`: ClojureScript is effectively C-in-C |
| 17:07 | technomancy | coventry`: there hasn't been much movement on replacing the Java in Clojure with Clojure |
| 17:08 | coventry` | I read that the project was blocking on an inefficiency in Clojure's object creation (http://blog.n01se.net/blog-n01se-net-p-41.html) Is that still the case? |
| 17:09 | dnolen | coventry`: that is very old, the mechanisms for building on host types are already in place. |
| 17:11 | coventry` | Thanks. So the recent work on speeding up operations on native ClojureScript object operations (the benchmark graphs which were posted here recently), is that at the clojure-in-clojure level, or is that hand-tuned js? |
| 17:12 | dnolen | conventry`: barring some 7 lines of interop, nothing in ClojureScript written in JS. |
| 17:13 | dnolen | conventry`: the compiler is tuned to emit optimal JS |
| 17:13 | hiredman | dnolen: once the clojure datastructures are replaced with onces written in clojure ported from clojurescript implementations then I will buy that |
| 17:13 | coventry` | Thanks for the info. |
| 17:13 | clojurebot | We live to serve. |
| 17:14 | coventry` | You too, clojurebot. :-) |
| 17:14 | dnolen | hiredman: if you want to wait for that, *shrug* |
| 17:15 | hiredman | dnolen: until then clojurescript is just "clojurescript in clojure" |
| 17:15 | hiredman | clojurescript isn't selfhosting |
| 17:15 | hiredman | neither is clojure |
| 17:18 | dnolen | hiredman: more *shrug* :) |
| 17:20 | technomancy | I'll believe it when I see (ns clojure.var) |
| 17:20 | hiredman | dnolen: so why keep saying "clojurescript is effectively clojure-in-clojure"? |
| 17:20 | hiredman | clojurescript is not clojure so it cannot be substituted as either instance of clojure in that expression |
| 17:21 | SurlyFrog | Can someone double check me. If a function is reading an atom, and during the course of the function, it is swapped out by another thread that changes the atom, the first function does not re-read the atom. Correct? |
| 17:21 | hiredman | and even if it could, you can't do it for both because clojurescript is written in clojure |
| 17:21 | dnolen | hiredman: because most of the language constructs are written in itself? is Clojure all the lame limitations imposed by the JVM? I think not. |
| 17:21 | brehaut | SurlyFrog: yes |
| 17:21 | hiredman | technomancy: (ns clojure.lang) (deftype Var [...]) |
| 17:22 | SurlyFrog | brehaut: thanks :-) |
| 17:22 | S11001001 | SurlyFrog: read via deref, right |
| 17:22 | dnolen | hiredman: and of course vice versa (limitations) for CLJS |
| 17:22 | technomancy | hiredman: yeah yeah--backwards compatibility; who needs it =) |
| 17:22 | hiredman | dnolen: clojure is specificly targeted at the jvm, clojurescript is specificly target at js |
| 17:22 | hiredman | they are not the same thing |
| 17:23 | hiredman | http://clojure.org/jvm_hosted |
| 17:23 | dnolen | hiredman: is Clojure a language or an implementation? |
| 17:23 | hiredman | *sigh* |
| 17:24 | dnolen | hiredman: do any of the things in Compiler.java that's not portable make any difference to the language? |
| 17:24 | hiredman | do you really want be to start quoting rhickey on the subject to you? |
| 17:24 | hiredman | he went through this entire thing with clojure on the clr |
| 17:24 | dnolen | hiredman: uh, what quote? |
| 17:25 | hiredman | dnolen: lemme grep then |
| 17:25 | pipeline | clojure on the clr could be a cool thing but it wouldn't be clojure anymore |
| 17:25 | dnolen | pipeline: ClojureCLR exists |
| 17:26 | clojure-newcomer | hey guys… I'm using clj-time to try to get a DB field like '1065691975' converted into a decent format… trouble is I am getting 'No instant converter found for type: java.lang.Integer' |
| 17:26 | clojure-newcomer | can I convert this Integer to a Long in clojure ? |
| 17:27 | clojure-newcomer | I had thought to use 'from-long' |
| 17:27 | brehaut | ,(class (long (Integer. 1))) |
| 17:27 | clojurebot | java.lang.Long |
| 17:27 | miceiken | First time with clojure here, how can I comment a larger segment of code |
| 17:27 | brehaut | but i dont think thast actually answering the question |
| 17:27 | miceiken | instead of ;; each line |
| 17:28 | clojure-newcomer | brehaut: thanks! |
| 17:28 | TimMc | miceiken: There's no true multiline comment. |
| 17:28 | TimMc | miceiken: However, #_ will make the reader ignore the next (valid!) form, and (comment ...) is a macro that will replace multiple valid forms with nil. |
| 17:28 | @rhickey | http://vote.jax-awards.com/ |
| 17:29 | TimMc | lol @ Jenkins |
| 17:30 | kmicu | where is thinkrelevance? :) |
| 17:31 | TimMc | This Restructure thing is such a Java-ish thing. |
| 17:31 | sjl | Is it possible to use swank-clojure (the lein plugin thing) with Clojure 1.4? Even if I require clojure 1.4 in my project's project.clj 'lein swank' always seems to produce a 1.3 repl |
| 17:31 | S11001001 | ,(+ #_#_3 7 11) |
| 17:31 | clojurebot | 11 |
| 17:32 | vijaykiran | sjl: which version of lein are you using ? |
| 17:32 | sjl | vijaykiran: 2.0.0-preview4 |
| 17:33 | kmicu | hiredman: :dnolen 10:43-12.xx http://blip.tv/clojure/rich-hickey-unveils-clojurescript-5399498, so David was right |
| 17:33 | vijaykiran | sjl: lein repl is also giving 1.3 ? |
| 17:33 | sjl | vijaykiran: yeah |
| 17:34 | vijaykiran | sjl: I just created a sample project with 1.4/lein2-prev-3 |
| 17:35 | vijaykiran | sjl: seems to work fine *clojure-version* is 1.4 |
| 17:35 | hiredman | kmicu: uh, "the compiler itself is written in clojure" |
| 17:35 | sjl | what/where is *clojure-version* defined? |
| 17:35 | vijaykiran | sjl: may be the deps you have in the project bringing different clojure version ? |
| 17:35 | bobry | dnolen: nope, the patch doesn't work |
| 17:35 | vijaykiran | sjl: type it directly into repl |
| 17:36 | jhulten | My googlefoo is failiing. How do I call a clojure function dynamically? for instance (let [name "action"] (execute (str "do-" name) arg) => (do-action arg) |
| 17:36 | dnolen | bobry: thanks for verifying. |
| 17:37 | hiredman | kmicu: "when you write macros for clojurescript, you write them in clojure" etc etc etc |
| 17:37 | bobry | kmicu: are you the author of the patch for CLJS-77? |
| 17:37 | sjl | oh cute, clojure.math.combinatorics and clojure.math.numeric-tower both required 1.3.0, so it silently ignored my 1.4.0 requirement in project.clj |
| 17:37 | technomancy | ugh; version ranges |
| 17:38 | technomancy | any project that uses version ranges needs to have hell of bugs filed against it |
| 17:38 | vijaykiran | sjl: ^^ :) |
| 17:38 | amalloy | alternatively, a plague of locusts |
| 17:38 | sjl | I still want a language that enforces semantic versioning at the language level somehow |
| 17:39 | amalloy | sjl: that's probably harder than the halting problem, just fyi |
| 17:39 | technomancy | you could always take the go approach: never introduce a backwards-incompatible change ever |
| 17:39 | sjl | yeah, the "don't break your users' code" approach is a fairly solid one |
| 17:39 | technomancy | also more difficult than the halting problem though |
| 17:40 | hiredman | *shrug* you mean the people who get to use your code for free? |
| 17:40 | hiredman | you should go out of your way to keep their code running? |
| 17:40 | sjl | hiredman: yes, because they're humans and wasting their lives is a dick move |
| 17:40 | `rand`-AFK | jhulten: use (symbol) |
| 17:41 | sjl | at least put a "don't use this project if you care about your sanity" warning label if you're going to break things a lot -- that's totally fine |
| 17:41 | hiredman | sjl: wasting yours working around their faulty assumptions is better? |
| 17:41 | emezeske | sjl: Nobody is forcing users to upgrade to a newer version of the language |
| 17:41 | sjl | emezeske: yeah I'm sure all the new libraries will continue to release security fixes compatible with old versions forever |
| 17:41 | sjl | hiredman: yes, it's called being a nice person |
| 17:41 | emezeske | sjl: They can always keep using the old version. If they want all the cool features or security fixes from a new version, they can choose whether it's worth making things work against breaking changes |
| 17:41 | nDuff | sjl: eh? The clojure version you require in your project.clj should override what your dependencies specify |
| 17:42 | sjl | nDuff: that's what I thought, but it doesn't |
| 17:42 | kmicu | bobry: nope, I only have used some solution based on that diff in ClojureScript One |
| 17:42 | sjl | emezeske: alternatively, library authors can grow up and care about backwards compatibility and everyone wins |
| 17:42 | amalloy | nDuff: not if version ranges are involved. thus, the locusts/bugs |
| 17:42 | nDuff | sjl: I'm really _very_ sure that, under normal circumstances, it does. I have dependencies which specify 1.2.0, and I very certainly get 1.4.0 |
| 17:42 | emezeske | sjl: Are you the author of an open source library? |
| 17:43 | nDuff | sjl: ...it'd be interesting to look at the project.clj or pom.xml files for the relevant bits of tooling. |
| 17:43 | sjl | emezeske: yeah, a whole bunch, which I use Semantic versioning for |
| 17:43 | amalloy | if your dependency specified [1.2.0] instead of 1.2.0, then you would not get 1.4.0 no matter what your project.clj says, nDuff |
| 17:43 | emezeske | sjl: Then you know how much work it is. I also try hard for backwards compat. |
| 17:43 | emezeske | sjl: But sometimes that weight can build up and drag you down |
| 17:43 | sjl | emezeske: it's really not that much work to write a few wrapper functions to preserve backwards compatibility |
| 17:43 | nDuff | amalloy: *nod*, which is why I noted that it'd be interesting to actually look at the relevant files. |
| 17:43 | emezeske | sjl: I beg to differ. |
| 17:44 | hiredman | backwards compatibility is just another trade off |
| 17:44 | emezeske | hiredman: Exactly |
| 17:44 | emezeske | hiredman: Time spent on backwards compat is not spent on cool new stuff |
| 17:44 | nDuff | sjl: It depends. As I understand it, rhickey tries hard to stay backwards compatible, but only with behaviors he explicitly documented; anything which happens to fall out of the current implementation but isn't documented is liable to change at any time w/o notice. |
| 17:44 | emezeske | hiredman: Both are desirable, and it's a balancing act like everything else. |
| 17:45 | hiredman | the dick move is pretending you haven't made a trade off |
| 17:45 | sjl | nDuff: 1.4 doesn't seem to bad, 1.3 was a mess |
| 17:45 | technomancy | someone should write a lein plugin that tells you which of your dependencies have version ranges and opens your browser to the bug report page for those libraries |
| 17:45 | nDuff | technomancy++ |
| 17:45 | hiredman | technomancy: people should use their version ranged deps via polycosm! |
| 17:45 | sjl | technomancy: if library specifies a range, will lein deps :tree show you the range or just a single number? |
| 17:45 | Chousuke | in Clojure's case, I think all backwards-incompatible changes have been good so far. |
| 17:46 | technomancy | sjl: just the number; it's collapsed down |
| 17:46 | sjl | technomancy: ah okay |
| 17:46 | technomancy | you could determine it's a conflicting range by looking at top-level :deps in project.clj and comparing though |
| 17:46 | nDuff | (don't even remember what it was about anymore) |
| 17:46 | sjl | technomancy: numeric-tower and combinatorics don't seem to use project.clj -- they have pom.xml files |
| 17:47 | sjl | so I don't know where the range would be specified |
| 17:47 | technomancy | that's contrib for you =( |
| 17:47 | amalloy | Chousuke: 1.3 contained a big batch of bad incompatible changes. 1.4 reverted or otherwise addressed most of them |
| 17:47 | technomancy | it should be under <dependencies> -> <version> |
| 17:47 | hiredman | nDuff: http://www.leancrew.com/all-this/2012/04/where-modules-go-to-die/ |
| 17:47 | sjl | technomancy: https://github.com/clojure/math.numeric-tower/blob/master/pom.xml |
| 17:48 | technomancy | hiredman: I just read the ruby equivalent to that post this morning |
| 17:48 | hiredman | it is a universal |
| 17:48 | brehaut | sneaking the name munging change into 1.2.1 was a pain |
| 17:48 | technomancy | sjl: bleh; maven is being object-oriented here and inheriting from another pom =\ |
| 17:49 | sjl | but yeah, working on projects like Mercurial (which is wire-compatible to versions something like ~5 years old) made me realize that A) Backwards compatibility matters. and B) It's not that hard once you actually commit to it. |
| 17:49 | hiredman | project object model oriented programming |
| 17:49 | sjl | technomancy: ah |
| 17:49 | S11001001 | wire protocols aren't apis |
| 17:49 | sjl | technomancy: so how can I use both numeric-tower and clojure 1.4? |
| 17:49 | glitch99 | anybody know a trick for a memset of clojure - like 10 copies of the same element in a list? |
| 17:49 | sjl | S11001001: It's Mercurial's API, along with the CLI |
| 17:49 | hiredman | ,(doc repeat) |
| 17:49 | technomancy | sjl: you could add an :exclusions entry to your numeric-tower dependency |
| 17:50 | clojurebot | "([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs." |
| 17:50 | glitch99 | hiredman: sweet! thanks! |
| 17:50 | sjl | technomancy: hmm, never seen that -- are there docs on it somewhere? |
| 17:50 | S11001001 | implication doesn't imply equivalence |
| 17:50 | glitch99 | clojurebot: also thanks! |
| 17:50 | clojurebot | I'm no man, and she's no lady! |
| 17:50 | technomancy | sure; `lein help sample` | grep :exclusions |
| 17:50 | sjl | S11001001: okay, replace "API" with "the part of your thing that real humans other than you are going to use" |
| 17:51 | technomancy | hm; well the grep doesn't really work since it cuts off a wrapped line but you get the idea |
| 17:51 | S11001001 | right, even more of those things are different |
| 17:51 | technomancy | sjl: anyway, there's a time to commit to stability and a time to be experimental and explorative. |
| 17:51 | amalloy | technomancy: grep -C? |
| 17:51 | technomancy | amalloy: yeah, that |
| 17:52 | technomancy | if I had to commit to stability on something like slamhound it would never get written |
| 17:52 | sjl | technomancy: right, and the time is either "version 1.0" or "lots of real people use this now and will have to waste time if you break it" |
| 17:52 | sjl | technomancy: you did the right thing with lein 2.0 -- I just wish more people did the same. |
| 17:52 | technomancy | the problem isn't that people break things, it's that they don't communicate expectations well |
| 17:53 | sjl | sure, putting "Don't use this if you care about your time" is fair warning. You're right -- people don't do that either. |
| 17:53 | hiredman | the problem is people use a software package and expect the next version to work the same way |
| 17:54 | hiredman | which is why tools like maven are good, because you can lock a specific version and just use it |
| 17:54 | sjl | Yes. Why would a version that had *more* work put into it now be broken? Isn't it supposed to be *better* after more work? |
| 17:54 | hiredman | and not worry about "oh, I depended on this bug that got fixed, in what was a patch version, so I thought it was ok to upgrade" |
| 17:55 | technomancy | sjl: it's silly to think "better" is one-dimensional |
| 17:55 | sjl | technomancy: Partially, but it's important to remember that the only person who actually cares how pretty the internals are is you (plus other implementers) |
| 17:56 | sjl | People using the library care way more about "it's not broken" than "it's elegant inside". |
| 17:56 | technomancy | code that's easier to reason about has fewer bugs |
| 17:56 | sjl | Sure, except it's broken and now I need to fix things before I move on. |
| 17:57 | technomancy | it's complicated |
| 17:57 | technomancy | sometimes it's worth it in an immature codebase |
| 17:57 | sjl | It's really not that hard to either 1) Provide little wrappers to stay backwards compatible or 2) Increment the major version and make it obvious that people are going to need to sit down and figure out how to deal. |
| 17:58 | hiredman | even in a mature codebase |
| 17:58 | sjl | yes! |
| 17:58 | hiredman | "this is slow and in efficient, it will now be fast, any stick in the mud who hates change is welcome to continue to use the old version" |
| 17:59 | hiredman | etc |
| 17:59 | sjl | Sure, if you don't care about the time and frustration of other human beings that's a valid approach. |
| 17:59 | technomancy | often you're not free to use old code though; upgrades are contagious |
| 17:59 | antoineB | hello, can i talk clojure-script in this channel? |
| 18:00 | Raynes | We'd prefer English, but sure. |
| 18:00 | Raynes | ;) |
| 18:00 | sjl | technomancy: exactly -- "use the old version" tends to be a valid option for a couple of months or so |
| 18:00 | technomancy | unless you use that fancy new polycosmosish thing I hear is pretty hot these days =) |
| 18:00 | borkdude | Esperanto is also accepted |
| 18:00 | hiredman | it is pretty sweet |
| 18:00 | hiredman | :) |
| 18:01 | borkdude | or maybe emacs people like Ido more (http://en.wikipedia.org/wiki/Ido) |
| 18:01 | hiredman | it lets you be more free wheeling with your versions, you can stick with an old version and still move to newer versions of it's dependencies for your own code |
| 18:02 | technomancy | hiredman: curious why you didn't just use plain old classloaders thouh |
| 18:02 | technomancy | though |
| 18:02 | technomancy | do jboss models get you basically the same thing? |
| 18:02 | sjl | technomancy: okay this is weird |
| 18:03 | sjl | technomancy: http://paste.stevelosh.com/4fc7e98b58d2e20007000000?clojure |
| 18:03 | hiredman | technomancy: they get you more than classloaders, e.g. if you have two things that depend on clojure-1.2 they can share a clojure 1.2 runtime |
| 18:03 | sjl | technomancy: that results in http://paste.stevelosh.com/4fc7e99c58d2e20007000001 -- no clojure 1.3.0, which looks right |
| 18:03 | technomancy | hiredman: can't you do that by nesting your classloaders the right way though? |
| 18:03 | technomancy | hiredman: I guess you aren't responsible for the tricky calculations on how to do that? |
| 18:03 | hiredman | technomancy: right |
| 18:03 | sjl | technomancy: but if I remove the exclusion from metrics-clojure, clojure 1.3.0 reappears under combinatorics in lein deps :tree |
| 18:03 | technomancy | hiredman: cool |
| 18:03 | sjl | how could that be? |
| 18:04 | hiredman | the plan for jboss modules seems to be that they will be compatible with whatever comes out of project jigsaw too |
| 18:04 | nDuff | technomancy: ...at least with the OSGi classloader-based model, I have trouble with thread-locals being left around by "unloaded" Clojure plugins, linked to their classloaders, which can't be unloaded in turn until everything they instantiated is gone. Not saying that there aren't approaches to track down and fix leftover thread-locals -- I think Tomcat makes the attempt on app unload -- but it's not always easy. |
| 18:05 | hiredman | nDuff: yeah that kind of thing is still an issue |
| 18:05 | hiredman | polycosm doesn't attempt to provide a way to unload modules |
| 18:05 | technomancy | sjl: I think when multiple dependencies bring in a given dep there's not really one right answer for questions like that. |
| 18:06 | sjl | technomancy: okay, I lied -- it's just metrics-clojure bringing in clojure 1.3. But why does :tree put it under combinatorics? |
| 18:06 | hiredman | if X brings in A and B, and A and B depend on C, should A and B be visble to each other? |
| 18:07 | sjl | technomancy: and should I not be specifying a version of clojure in the metrics-clojure library anyway? Just tell people which one they need? |
| 18:07 | hiredman | it short of depends on what you mean by visible, and given clojure's implementation it is actually pretty tricky to avoid |
| 18:07 | technomancy | sjl: as long as you don't specify a range you're fine |
| 18:07 | hiredman | but dealing with that kind of stuff is what a module system does |
| 18:08 | sjl | seems strange that specifying a range (more flexibility) actually makes things less flexible... |
| 18:09 | technomancy | sjl: yeah, I didn't realize how horrible the implementation was for a long time and unfortunately encouraged their use for a wihle |
| 18:09 | technomancy | while |
| 18:09 | amalloy | you can specify open-ended ranges like [1.3.0,], or some syntax like that |
| 18:10 | technomancy | amalloy: which is horrible for different reasons =) |
| 18:10 | amalloy | when i did that, people made fun of me "lol how can you know it will work with 1.6.3?" |
| 18:10 | TimMc | [1.3.0,1.3.9999999] is safer |
| 18:10 | technomancy | you can say it'll work with 1.3.0 up to but not including 2.0.0 |
| 18:10 | amalloy | technomancy: sure you can |
| 18:10 | TimMc | it still doesn't protect you from alpha releases |
| 18:10 | technomancy | to which aether will be like "what's that? you want 2.0.0-SNAPSHOT? OK, here ya go!" |
| 18:10 | technomancy | ಠ_ಠ |
| 18:11 | amalloy | and then if it happens to work with 2.0.0 anyway, people will still be annoyed |
| 18:11 | technomancy | amalloy: yeah, exactly why I don't recommend the 9999999999 approach |
| 18:11 | technomancy | semantic versioning doesn't mean major version bumps must be completely incompatible |
| 18:12 | sjl | "Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced to the public API." |
| 18:13 | TimMc | technomancy: Unless you version your variable names too. :-P |
| 18:13 | amalloy | sjl: uhhhh, are you trying to disagree with technomancy? because he just stated that the converse is untrue |
| 18:13 | antoineB | i am trying to use the browser repl with a server (file:///myfile.....) and it doesn't works |
| 18:14 | sjl | amalloy: the other part is that there's no other place in that spec that says anything about incrementing major version numbers |
| 18:14 | TimMc | amalloy: Not even that. |
| 18:14 | TimMc | "Completely" is the operative (and fun) word. |
| 18:14 | sjl | Well sure, they could happen to have only broken parts of the code you never use, that's true. |
| 18:15 | amalloy | sjl: so what? "x MUST be done if y" does not mean "x MUST NOT be done if not-y" |
| 18:15 | sjl | But in the semver.org description of it, the ONLY time the major version is incremented is when you break something |
| 18:15 | pjstadig | if P, then Q does not imply if Q, then P |
| 18:15 | sjl | amalloy: yeah, but that's the only rule applying to major versions in the spec |
| 18:15 | amalloy | sjl: uh huh |
| 18:16 | pjstadig | in fact it is fallacious to draw that conclusion |
| 18:16 | amalloy | which is my point |
| 18:16 | amalloy | and pjstadig's |
| 18:16 | technomancy | the more careful you are about bumping on every incompatible change the more likely it is that a bump will result from a change that doesn't affect some people |
| 18:16 | TimMc | sjl: It's not part of the spec, even though it might be a good idea. |
| 18:16 | sjl | Sure, you could also say "well he doesn't say NOT to increment the major version number when you eat Indian food for lunch that day!" |
| 18:16 | pjstadig | sjl: sounds good to me |
| 18:16 | amalloy | *shrug* and if i chose to increment the major version number once a year on my birthday, i would not be in violation of the spec |
| 18:17 | amalloy | as long as i also bumped it whenever i broke something |
| 18:17 | sjl | amalloy: you are technically correct |
| 18:17 | sjl | the best kind |
| 18:17 | pjstadig | if the sun comes up, then the rooster crows, therefore if the rooster crows, then the sun will come up |
| 18:17 | pjstadig | but of course roosters don't make the sun come up |
| 18:17 | amalloy | sjl: the only kind. if the spec doesn't forbid something, then doing it can't cause you to be non-compliant. that's what a spec MEANS |
| 18:18 | sjl | amalloy: I guess I'm assuming some level of common sense here, |
| 18:18 | TimMc | pjstadig: Well, we've never tested that by taping all the roosters' beaks shut... |
| 18:18 | amalloy | TimMc, chicken-harasser incognito |
| 18:19 | arohner | is there a way to examine an agent's queue? |
| 18:19 | TimMc | sjl: I get annoyed at "needless" major version bumps, but I'd not say they're counter-spec. |
| 18:19 | arohner | and has anyone else ever wanted an agent's queue to be a sorted set? i.e. ignore duplicate calls? |
| 18:19 | TimMc | sjl: It certainly violates the Principle of Least Astonishment. |
| 18:19 | hiredman | arohner: perhaps you should put a set in your agent |
| 18:20 | pjstadig | TimMc: you do something major, so you bump the major version...doesn't astonish me |
| 18:20 | arohner | hiredman: I'm kind of hacking it. I don't really care about the value of the agent, I just want to serialize some I/O |
| 18:20 | pjstadig | "something major" is not necessarily equal to "something breaking" |
| 18:20 | sjl | TimMc: They might not violate the spec in the pedantic nerd version of it, but they do in the normal-human, spirit-of-the-thing version. |
| 18:20 | hiredman | arohner: :( |
| 18:20 | sjl | pjstadig: in semantic versioning yes, it is |
| 18:20 | TimMc | pjstadig: If it only adds stuff, it's a minor version bump. |
| 18:21 | hiredman | arohner: then just put a sorted set in a ref |
| 18:21 | sjl | pjstadig: http://semver.org/ is the spec we're talking about |
| 18:21 | TimMc | semver doesn't track cool, it tracks compatibility. |
| 18:21 | hiredman | run a loop in a future to read it and the io |
| 18:21 | technomancy | uh oh; pjstadig is violating semver |
| 18:21 | technomancy | ~guards |
| 18:21 | clojurebot | SEIZE HIM! |
| 18:21 | arohner | hiredman: yeah, but I want the fn to be called when I call it, but if another call to f is already in the queue, throw it on the floor |
| 18:22 | sjl | The benefit to using it is that I can say "Foo works with version 1.4 or higher, but not anything starting with a 2 because that broke something" |
| 18:22 | sjl | That way I don't need to manually inspect each new version of the library unless the major version changed |
| 18:22 | hiredman | arohner: well that isn't an agent anyway, right? agents are asynchronous |
| 18:22 | borkdude | so emacs 24 is not compatible with 23? |
| 18:22 | sjl | borkdude: if they used semver, that would be the case, but I don't think they do |
| 18:23 | arohner | hiredman: I want async and serialized, I just want the queue to be a sorted set |
| 18:23 | amalloy | arohner: so put a ref around a set. or a queue, and have your alter function check to see if it should actually add anything |
| 18:23 | hiredman | arohner: right, but you don't want a reference, you don't care about the value |
| 18:23 | technomancy | borkdude: the answer, as always, is "it's complicated" =) |
| 18:23 | technomancy | some things are compatible and some aren't. |
| 18:23 | hiredman | so you don't want an agent |
| 18:23 | sjl | borkdude: and anyway isn't the "24" in "emacs 24" short for "emacs 1.24" and it's just that no one ever writes the "1." any more? |
| 18:23 | sjl | I thought I read that somewhere |
| 18:23 | sjl | Could be wrong though -- I use Vim. |
| 18:23 | hiredman | so, stick a sorted set in a ref, have a thread read from the ref in a loop |
| 18:23 | hiredman | done |
| 18:24 | borkdude | slj with java that is the case, with emacs I doubt it, but could be |
| 18:24 | technomancy | borkdude: no, he's right |
| 18:24 | TimMc | It doesn't always make sense to follow semver. |
| 18:24 | borkdude | technomancy ah, ok |
| 18:24 | TimMc | Apps like Firefox and Emacs... nothing really links against the UI. |
| 18:24 | TimMc | Now, their internal components, sure. |
| 18:24 | sjl | Yeah, standalone GUI apps don't really make sense, definitely. |
| 18:25 | clojure-newcomer | hey guys, I've got dates stored as '1065706498' (int(11) in MySQL), I'm trying to get them out with clojure.java.jdbc and they are all coming up as 1970 or thereabouts….. how do I extract them correctly ? oh, I'm using clj-time |
| 18:25 | sjl | CLI ones do though -- the CLI becomes the public-facing API as soon as someone writes a bash script. |
| 18:25 | borkdude | technomancy where can I find that? |
| 18:26 | pjstadig | meh |
| 18:27 | pjstadig | that's enough bikeshedding for me for today |
| 18:27 | technomancy | borkdude: wikipedia says "Versions 2 to 12 never existed. Earlier versions of GNU Emacs had been numbered "1.x.x", but sometime after version 1.12 the decision was made to drop the "1", as it was thought the major number would never change." |
| 18:27 | technomancy | so I guess that's a little different from 24 technically still being 1.24 |
| 18:27 | pjstadig | hehe |
| 18:28 | jjido | clojure-newcomer: maybe times 1000? This timestamp is in 2003 using Unix epoch |
| 18:28 | pjstadig | "these are not the major numbers you are looking for" |
| 18:28 | pipeline | emacs also stopped development for a really, really long time |
| 18:29 | pipeline | all "interesting" things happened inside of xemacs or another fork first for a really l ong time |
| 18:29 | pipeline | emacs 22 came out in '07 and development has been really rapid since then |
| 18:29 | clojure-newcomer | jjido: could you tell me a little more about this, sorry |
| 18:29 | TimMc | Java will never go 2.0. Python is pretty much stuck at 2.x. |
| 18:29 | hiredman | java went 2.0 |
| 18:29 | hiredman | and is now at 7 |
| 18:29 | technomancy | pipeline: I think it still came in under the XP->vista gap though =) |
| 18:30 | S11001001 | TimMc: I'm a 3k believer :) |
| 18:30 | pjstadig | clojure-newcomer: that doesn't seem like a clojure issue. ask the person who created the database and inserted the data what the numbers mean |
| 18:30 | TimMc | hiredman: Eh, Java 7 is the marketing name, but it is Java v1.7. |
| 18:30 | gfrederi` | you'd think there weren't any major numbers above 5 |
| 18:30 | hiredman | TimMc: 1.7 is the jvm version |
| 18:30 | S11001001 | wasn't it java 2 v1.2, java 2 v1.3? |
| 18:30 | pipeline | technomancy: yes, technically, but versions 18 through 21, particularly 18, 19, 20, were so similar that you might as well compare them to service packs |
| 18:30 | pjstadig | clojure-newcomer: java dates can be constructed with number of millis since epoch, you may need to do some work to convert the fields to millis |
| 18:31 | gfrederi` | versions could be like points in pinball -- you add 500 at the slightest provocation |
| 18:31 | TimMc | hiredman: Mmm, interesting... I'll have to think about that. |
| 18:31 | TimMc | gfrederi`: Well, Firefox already went full retard with versions. |
| 18:31 | clojure-newcomer | thanks guys |
| 18:31 | pjstadig | clojure-newcomer: i think what jjido suspects is that they are actually the number of seconds since epoch, which means you'd have to multiply my 1000 |
| 18:31 | clojure-newcomer | I'll have a look |
| 18:31 | pjstadig | *by |
| 18:31 | jjido | clojure-newcomer: it is a JDBC issue, find how it interprets timestamp from your db. |
| 18:31 | gfrederi` | TimMc: the only thing retarded is all opinions except my own |
| 18:31 | ethanis | hey guys, I'm trying to setup testing in a clojure project and use leiningen to run the tests |
| 18:32 | pjstadig | but he said they are int(11) fields, not date fields |
| 18:32 | pjstadig | so my guess is JDBC brings them out as integers |
| 18:32 | ethanis | but whenever I call "lein test", the output is: "Exception in thread "main" java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate sherbondy/test/point_api__init.class or sherbondy/test/point_api.clj on classpath" |
| 18:32 | hiredman | jjido: most likely since he says "I am using clj-time" he is turning the ints in to dates badly |
| 18:32 | clojure-newcomer | pjstadig: yes int(11) |
| 18:32 | ethanis | is there some sort of classpath voodoo I need to do to set things up properly? |
| 18:32 | TimMc | ethanis: Did you name the file with an underscore or a hyphen? |
| 18:32 | ethanis | hyphen |
| 18:33 | clojure-newcomer | hiredman: same problem if I construct from java.util.Date with Long in constructor |
| 18:33 | TimMc | ethanis: There's your problem. |
| 18:33 | ethanis | woohoo |
| 18:34 | technomancy | welcome to the JVM where the filenames are made up and the points don't matter |
| 18:35 | brehaut | lol |
| 18:35 | brehaut | i liked the original british JVM better than the US remake |
| 18:36 | hiredman | the british jvm is for toffs |
| 18:36 | technomancy | but there was that one episode where Stephen Fry made a cameo |
| 18:37 | technomancy | as the G1 garbage collector |
| 18:37 | technomancy | wait, are toffs good or bad? |
| 18:38 | brehaut | clearly they are good |
| 18:38 | brehaut | otherwise hiredman wouldnt be making any sense |
| 18:39 | pjstadig | http://en.wikipedia.org/wiki/Toff |
| 18:39 | pjstadig | derogatory |
| 18:39 | pjstadig | and mildly so |
| 18:42 | zomg | Hi, I wonder if there are any common gotchas or such in Clojure for people not familiar with it? |
| 18:42 | technomancy | zomg: contains?, isa?, and partition don't do what you think they do. |
| 18:42 | zomg | I'm converting some Java code into Clojure, and while I've managed to make the code compile, it doesn't work the same way as the Java code does |
| 18:42 | zomg | So just wondering if there's anything that could easily trick you before I go through the code again for the 5th time to find out if I did some stupid mistake somewhere |
| 18:42 | zomg | =) |
| 18:42 | technomancy | also don't use protocols, defrecord, or deftype until you have a few months of experience |
| 18:43 | zomg | Yeah I don't even know what those are... =) |
| 18:43 | technomancy | even better! =) |
| 18:43 | technomancy | don't mix laziness and side effects |
| 18:43 | technomancy | we need like a ten commandments for newbies |
| 18:43 | hiredman | zomg: that is generally a bad idea, clojure code for the same task is often very different from the java code |
| 18:44 | zomg | hiredman: Yeah I'm not doing one to one code of course :) |
| 18:44 | gfrederi` | technomancy: that was impressive |
| 18:44 | zomg | but more like rewriting it to do the same job |
| 18:44 | technomancy | gfrederi`: I, uh... spend a lot of time on IRC. |
| 18:44 | gfrederi` | ~gotcha |
| 18:44 | clojurebot | Cool story bro. |
| 18:44 | zomg | I've done some Haskell before so I'm not *completely* lost ;) |
| 18:44 | zomg | But only passingly familiar with any lisp like languages |
| 18:44 | gfrederi` | clojurebot: gotcha is contains?, isa?, and partition don't do what you think they do. |
| 18:44 | clojurebot | Roger. |
| 18:44 | gfrederi` | ~gotcha |
| 18:44 | clojurebot | gotcha is contains |
| 18:44 | technomancy | don't write any macros in your first three months |
| 18:44 | gfrederi` | crap |
| 18:45 | gfrederi` | technomancy: please make your language sound as much like new-parent advice as possible |
| 18:45 | technomancy | haha |
| 18:45 | borkdude | also, only use def/defn on top level expressions |
| 18:45 | zomg | "do not drop the baby" |
| 18:45 | pjstadig | don't expect any sleep for at least 2 months |
| 18:46 | arohner | hiredman: FYI, you can get at the agent's queue with wallhack field, but the items in the queue aren't amenable to being put in a set, because each fn gets a new (binding-conveyor-fn) wrapped, which kills equality |
| 18:46 | zomg | Oh regarding defn, is there a difference between using 'do' in it or not? :P As in, (defn foo [] (one) (two)) vs (defn foo [] (do (one) (two))) |
| 18:46 | gfrederi` | zomg: no diff |
| 18:46 | zomg | I noticed the docs for certain things like when and when-not say they have an implicit do, but I wasn't really able to find out anything concrete |
| 18:46 | technomancy | zomg: sounds like you're asking the right questions at least. =) |
| 18:46 | pjstadig | uh oh |
| 18:47 | pjstadig | let's not open up that can of worms |
| 18:47 | gfrederi` | pjstadig: there's a diff? |
| 18:47 | pjstadig | when vs. if can be very contentious |
| 18:47 | gfrederi` | oh nm |
| 18:47 | gfrederi` | well there is technically one difference |
| 18:48 | pjstadig | zomg: i think the answer is that defns have an implicit do as well, so the do is unnecessary |
| 18:48 | zomg | Ah I see |
| 18:48 | gfrederi` | (fn [] {:pre [false]} :x) is definitely not the same as (fn [] (do {:pre [false]} :x)) |
| 18:48 | gfrederi` | but you wouldn't do that anyways |
| 18:48 | hiredman | arohner: also it is just a bad idea, as everyone (all 2 of us) that have responded to you have said |
| 18:49 | hiredman | the semantics you want are not the semantics of agents, so stop trying to use them |
| 18:49 | zomg | Well, thanks for the pointers. I guess I'm going over my code once more to find that mistake I did =) |
| 19:03 | ethanis | hmm, how can I preserve my shell's environment variables when using lein repl/test? |
| 19:04 | ethanis | as in, I have defs which rely on System/getenv calls |
| 19:04 | ethanis | or is there a better way of going about this? profiles? |
| 19:04 | technomancy | the environment should be preserved |
| 19:04 | technomancy | (just ask Captain Planet) |
| 19:04 | technomancy | sorry |
| 19:04 | ethanis | haha |
| 19:06 | ethanis | even the temporary environment created by a call of source? |
| 19:06 | ethanis | here's my setup: |
| 19:06 | ethanis | I have a local .env file containing various API keys |
| 19:07 | ethanis | to test, I figured I could call source .env |
| 19:07 | technomancy | ethanis: try export $(cat .env) |
| 19:07 | ethanis | alright! |
| 19:07 | technomancy | ethanis: curious, is this for heroku? |
| 19:07 | ethanis | yep |
| 19:08 | technomancy | cool; have fun =) |
| 19:09 | ethanis | great, it works! thanks technomancy. |
| 19:48 | devn | i wonder... does it make sense to port pprint to clojurescript? |
| 19:51 | devn | klauern: howdy |
| 19:52 | antoineB | i just start to do a simple "hello world" in clojure-script |
| 19:53 | antoineB | it give me 19000 lines |
| 19:53 | brehaut | have you used advanced compilation? |
| 19:53 | antoineB | no |
| 19:53 | amalloy | good thing the computer writes them for you, eh? |
| 19:53 | brehaut | that would be why then |
| 19:56 | devn | antoineB: {:optimizations :advanced, :pretty-print :false} |
| 20:00 | antoineB | 5400 lines, it is probably more than my application will need |
| 20:01 | devn | antoineB: perhaps |
| 20:02 | devn | antoineB: not everyone needs jquery or clojurescript |
| 20:03 | antoineB | i try to build a schema maker with the svg element |
| 20:06 | antoineB | in 708 lines i do "simple direct link", "box wiith text", "context menu", "serialization/deSerialzation" |
| 20:11 | devn | antoineB: why do you think it is 700 lines? |
| 20:12 | antoineB | until no it is 700lines |
| 20:12 | devn | sorry. why do you think it is 5400 lines? |
| 20:12 | antoineB | i just count them |
| 20:13 | devn | antoineB: yes. but why do you think it is 5400 lines? |
| 20:13 | TimMc | I wonder what jquery weighs in at these days. |
| 20:13 | antoineB | i make a simple hello world compile then with advance but with pretty print and give me a js file |
| 20:14 | brehaut | 9404 lines |
| 20:14 | brehaut | TimMc: ^ |
| 20:14 | devn | antoineB: i understand. think about why the output is that big. do you know why? |
| 20:14 | antoineB | realy? |
| 20:15 | antoineB | devn: unfortly not |
| 20:15 | devn | antoineB: http://lukevanderhart.com/2011/09/30/using-javascript-and-clojurescript.html |
| 20:15 | TimMc | brehaut: Huh. That's the uncompressed, right? |
| 20:15 | brehaut | TimMc: yes |
| 20:15 | brehaut | antoineB: if you wrote hello.c compiled it and statically linked it with libc would you be surprised if it was large? |
| 20:16 | brehaut | TimMc: compressed im pretty sure its only one line |
| 20:18 | TimMc | heh |
| 20:18 | devn | haha i was thinking the same thing |
| 20:22 | fil512 | how do i add something to the front of a vector? |
| 20:22 | antoineB | devn: i think the code is the goog stuff |
| 20:23 | technomancy | fil512: depends, do you care the tiniest bit about performance? |
| 20:23 | fil512 | not so much... |
| 20:23 | antoineB | brehaut: no, but the libc embrace also the browser stuff |
| 20:23 | brehaut | err |
| 20:24 | devn | fil512: why do you want to add to the front of a vector? what do you want to accomplish? |
| 20:24 | fil512 | the reason I want to stick it at the start is to make it easy to use update-in, e.g. (update-in :foo 0 :bar 0 |
| 20:24 | technomancy | fil512: ok, in that case you can do something goofy like (vec (cons x myvec)) |
| 20:24 | hiredman | into! |
| 20:24 | technomancy | oh yeah |
| 20:25 | fil512 | I'd love it if I could go (update-in :foo $ :bar $) or sth to mean "last" |
| 20:25 | technomancy | ,(into [:head] [:middle :tail]) |
| 20:25 | clojurebot | [:head :middle :tail] |
| 20:25 | fil512 | nice! |
| 20:25 | TimMc | Huh, cute. |
| 20:25 | fil512 | thanks! |
| 20:26 | TimMc | Hmm. update-in would make a nice protocol. |
| 20:27 | devn | cute indeed |
| 20:27 | TimMc | Each layer could decide how much of the key list to consume. |
| 20:28 | TimMc | For instance, a 3rd-order tensor would consume 3 integer keys. |
| 20:33 | brehaut | ,(for [:let [a [1 2]] b a] (inc b)) |
| 20:33 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Can't pop empty vector> |
| 20:33 | brehaut | ,*clojure-version* |
| 20:33 | clojurebot | {:interim true, :major 1, :minor 4, :incremental 0, :qualifier "master"} |
| 20:35 | antoineB | good night |
| 20:37 | TimMc | brehaut: Same in 1.3.0. What's up? |
| 20:38 | brehaut | just curious |
| 20:39 | brehaut | its also the same in 1.2; i just wondered if it had been fixed on a new version |
| 20:39 | hiredman | what for really needs is :do |
| 20:39 | TimMc | brehaut: Fixed, as in... better error message? |
| 20:40 | brehaut | well, let you have a :let at the start of a for |
| 20:40 | technomancy | hiredman: :let [_ (horrible-side-effects)] |
| 20:40 | technomancy | oops, beat me to it |
| 20:41 | hiredman | well, duh |
| 20:41 | hiredman | I would just prefer :do to having to do that |
| 20:41 | saml | hey, how can I watch a directory tree for modification? |
| 20:41 | saml | something like inotify on linux |
| 20:41 | technomancy | saml: you need java 7 to do it portably IIRC |
| 20:41 | TimMc | That's a common question these days. |
| 20:42 | saml | cool i just downloaded jdk |
| 20:42 | saml | 7 |
| 20:42 | technomancy | hiredman: that comes dangerously close to endorsing side effects in laziness |
| 20:42 | technomancy | ugly things should be ugly |
| 20:43 | lazybot | java.lang.RuntimeException: EOF while reading |
| 20:46 | hiredman | technomancy: sometimes you gotta log |
| 20:46 | hiredman | :do in doseq would be nice too |
| 20:52 | TimMc | Explain to me again the use-case for a :let at the beginning of a for form? |
| 20:53 | hiredman | you have a for inside a let, and you want to pull it up a level |
| 21:13 | _KY_ | I did a "lein clean" before "lein uberjar" but I still get "java.language.NoClassDefFoundError", how to fix that? |
| 21:20 | hiredman | I don't see how people expect to get anything done when they go around throwing out all the information that comes with an exception |
| 21:20 | _KY_ | This is the error log: |
| 21:20 | _KY_ | https://www.refheap.com/paste/2950 |
| 21:22 | hiredman | what does the ns form for genifer.core look like? |
| 21:25 | _KY_ | 1 sec... |
| 21:25 | _KY_ | (Ands genifer.core |
| 21:25 | _KY_ | (:require [genifer.forward_chaining :as forward]) |
| 21:25 | _KY_ | (:require [genifer.backward_chaining :as backward]) |
| 21:25 | _KY_ | (:require [genifer.core :as core]) |
| 21:25 | _KY_ | (:require [clojure.main]) |
| 21:25 | _KY_ | (:require [clojure.string :as string :only [split triml]]) |
| 21:25 | _KY_ | (:gen-class) |
| 21:26 | brehaut | _KY_: http://refheap.com etc |
| 21:26 | _KY_ | First line should be (ns |
| 21:26 | hiredman | those underscores should be hyphens |
| 21:26 | hiredman | you only need a single :require |
| 21:26 | xeqi | why does genifer.core :require itself? |
| 21:26 | _KY_ | But it used to work... |
| 21:27 | hiredman | that's not right either |
| 21:27 | hiredman | _KY_: no it didn't |
| 21:27 | _KY_ | The file name is with the underscore |
| 21:27 | hiredman | sure |
| 21:27 | hiredman | the file name has an underscore |
| 21:27 | hiredman | the namespace name should have a hyphen |
| 21:28 | hiredman | _KY_: you tricked yourself in to thinking it worked somehow |
| 21:28 | hiredman | but it did not |
| 21:28 | _KY_ | Namespace is just genifer.core |
| 21:29 | _KY_ | The file is exactly "forward_chaining.clj" |
| 21:29 | hiredman | sure |
| 21:29 | _KY_ | You mean I change it to hyphen in the file name? |
| 21:29 | hiredman | no |
| 21:29 | hiredman | the file name stays the same |
| 21:29 | _KY_ | Alright |
| 21:29 | hiredman | but the namespace for the namespace backed by that file should have a hyphen |
| 21:30 | hiredman | clojure trys to make things simpler by giving the .clj file name the same file name as the generated class, and java doesn't allow '-' in classnames |
| 21:31 | hiredman | but in clojure the convention is to use '-' in symbols to separate words |
| 21:31 | hiredman | namespaces are named by a symbol |
| 21:31 | hiredman | so the namespace genifer.forward-chaining lives in the file genifer/forward_chaining.clj |
| 21:32 | hiredman | and this is why most people just avoid hyphens or dashes when it comes to namespaces |
| 21:33 | joegallo | here's something totally bizarre |
| 21:33 | hiredman | _KY_: so there are a number of problems with that ns form, the one that is stopping your code from loading is most likely the namespace requiring itself |
| 21:33 | joegallo | oops, wrong channel -- you tricked me hiredman! |
| 21:33 | hiredman | hah, now people in #clojure know you can talk |
| 21:34 | _KY_ | Do you mean clojure automatically changes my namespace to forward-chaining? |
| 21:35 | _KY_ | But I declared the namespace in that file to be genifer.forward_chaining |
| 21:35 | hiredman | don't do that |
| 21:35 | hiredman | it should be genifer.forward-chaining |
| 21:35 | brehaut | underscores in clojure space names is non-idiomatic style, even when it works |
| 21:36 | brehaut | not to mention plain ugly |
| 21:37 | _KY_ | So I keep the file names, and change the space names? |
| 21:37 | _KY_ | Is that allowed? |
| 21:37 | ethanis | hey guys, has there been any talk of tweaking the load-lib function in clojure.core so that the :only option accepts an individual symbol in addition to a seq of symbols? |
| 21:37 | _KY_ | I thought it's required that file name = namespace name |
| 21:38 | ethanis | I'm new to clojure, and I keep getting tripped up and accidentally typing (:use some-package :only bla) when I only want to use one function |
| 21:38 | ethanis | I guess this would make the use function inconsistent |
| 21:39 | ethanis | but it seems like a pragmatic tweak |
| 21:39 | ethanis | thoughts? |
| 21:39 | hiredman | ethanis: use :require not :use |
| 21:39 | _KY_ | I have been using :only blah without [] and it seems to work |
| 21:39 | ethanis | ah, so it's just poor form to do :use if I only want a single function? |
| 21:42 | tmciver | ethanis: not because you only want one function; use is discouraged - use require. |
| 21:42 | ethanis | _KY_: what version of clojure are you using? (use '[clojure.string :only lower-case]) definitely does not work for me. |
| 21:42 | ethanis | ah, use is just generally discouraged because require is more explicit? |
| 21:43 | _KY_ | 1.3.0 |
| 21:43 | gtrak | I find 'use' obfuscating |
| 21:43 | ethanis | sure, I understand why |
| 21:43 | _KY_ | I use :require in ns |
| 21:44 | brehaut | use is also unnecessary with :refer in 1.4+'s require |
| 21:44 | brehaut | though still useful at a repl |
| 21:44 | hiredman | _KY_: have you read the docstring on require? |
| 21:44 | hiredman | (you may find that there is no :only option, so clojure is silently ignoring you) |
| 21:46 | _KY_ | Oh really |
| 21:46 | saml | hey, if anyone is using La Clojure, how would I import lein project to that IDE? |
| 21:46 | gtrak | where's an example of the :refer feature? |
| 21:48 | ethanis | don't actually do this |
| 21:48 | brehaut | ,(do (require '[clojure.set :as set :refer [difference]]) (difference (set/union #{:a} #{:b}) #{:b})) |
| 21:48 | clojurebot | #{:a} |
| 21:48 | ethanis | but an example |
| 21:48 | ethanis | oh, never mind |
| 21:48 | brehaut | gtrak: ^ |
| 21:49 | gtrak | ah, neat |
| 21:49 | ethanis | even so |
| 21:50 | gtrak | ,(difference #{:a} #{:a :b}) |
| 21:50 | clojurebot | #{} |
| 21:50 | ethanis | it'd be nice to be able to type (require '[clojure.set :as set :refer difference]) |
| 21:50 | ethanis | but you could make the case |
| 21:50 | hiredman | denied |
| 21:50 | brehaut | clojure.set/difference cares about ordering |
| 21:50 | ethanis | that it'd just be more typing later the moment you decide to refer another function |
| 21:50 | gtrak | ,(difference #{:a :b} #{:a}) |
| 21:50 | clojurebot | #{:b} |
| 21:51 | brehaut | gtrak: theres a math word for that and i cant remember waht it is |
| 21:51 | brehaut | transitive? |
| 21:51 | brehaut | associative? |
| 21:51 | brehaut | one of those |
| 21:51 | gtrak | associative |
| 21:51 | brehaut | thanks |
| 21:52 | aperiodic | well, if it cares about ordering, then it's *not* associative |
| 21:52 | gtrak | right |
| 21:53 | metellus | I think you mean commutative |
| 21:53 | brehaut | this is why im no good at math |
| 21:53 | ethanis | alright folks, thanks for the style tips re: use of require |
| 21:54 | ethanis | night |
| 21:54 | aperiodic | "ordering" in the (a (b c)) vs ((a b) c) sense |
| 21:54 | aperiodic | not the (a b) vs (b a) sense |
| 21:54 | gfrederi` | What's purple and commutes? |
| 21:54 | aperiodic | an abelian grape! |
| 21:54 | gfrederi` | AAAAHAHAHAHAHHAA |
| 21:55 | gfrederi` | o/ |
| 21:55 | aperiodic | \o |
| 21:55 | gfrederi` | my work here is done |
| 21:55 | _KY_ | ,(docs ns) |
| 21:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: docs in this context, compiling:(NO_SOURCE_PATH:0)> |
| 21:55 | aperiodic | i'm partial to the "what's purple and takes the train to work?" version, myself |
| 21:55 | _KY_ | ,(doc ns) |
| 21:55 | clojurebot | "([name docstring? attr-map? references*]); Sets *ns* to the namespace named by name (unevaluated), creating it if needed. references can be zero or more of: (:refer-clojure ...) (:require ...) (:use ...) (:import ...) (:load ...) (:gen-class) with the syntax of refer-clojure/require/use/import/load/gen-class respectively, except the arguments are unevaluated and need not be quoted. (:gen-class ..... |
| 22:05 | _KY_ | I don't know why but I changed my deps and now lein won't work |
| 22:05 | _KY_ | It's always noClassFound for this and that file |
| 22:06 | _KY_ | The namespace, require etc used to work |
| 22:15 | TimMc | Hey, Light Table hit 300 kilobucks! |
| 22:26 | abp | TimMc: Thanks, reminded me that i meant to pledge too.. |
| 22:26 | TimMc | :-D |
| 22:27 | xhh | abp: you got 19 hours left ;) |
| 22:29 | abp | xhh: I know, but then I surely would miss the deadline. Where waiting the last months, despite knowing i will pledge eventually . |
| 22:43 | _KY_ | Oh I found out... I was opening 2 sessions of lein at the same time =) |
| 22:43 | _KY_ | Almost drove me nuts |
| 23:03 | irc2samus | hi guys, if I were to capture SIGINT in order to do cleanup I should use the Java way that is registering a shutdown hook like it's said here: http://stackoverflow.com/questions/2541475/capture-sigint-in-java right? or is there a Clojure-specific way that is preferable? |
| 23:03 | technomancy | irc2samus: shutdown hook is best |
| 23:04 | irc2samus | great thanks! |
| 23:40 | zomg | Neat, managed to whip together a desktop streaming application even though I had never used clojure before :D |
| 23:40 | zomg | Using xuggler with ogg theora encoder and html5 video as the "target" where you can view the desktop stream |
| 23:41 | zomg | on my local box only about 1-2 seconds of latency so not bad I think =) |
| 23:41 | zomg | prob worse over a network tho |
| 23:42 | irc2samus | so guys, do I need gen-class for the shutdown hook thread? or is there a more "direct" way to define the function to run there |
| 23:45 | Lajla | Chousuke, mun rakkaus, oletko täällä? |
| 23:48 | irc2samus | hmm there's a "proxy" thingy that seems to do it |
| 23:51 | abp | irc2samus: http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ have a look at that chart and deceide |
| 23:55 | technomancy | irc2samus: you don't need anything fancy to create a thread, just pass it a function |
| 23:55 | technomancy | (.start (Thread. #(do :some 'stuff))) |
| 23:56 | technomancy | well, don't start it in this case I guess |
| 23:58 | irc2samus | lots of options :) the proxy thing worked, copied it from here: http://java.dzone.com/articles/clojuretest-introduction |