2013-12-19
| 00:03 | noprompt | bitemyapp: we'll probably have to move our pairing session to sunday if that's cool. |
| 00:04 | noprompt | bitemyapp: i have to attend holiday "events" tomorrow and potentially friday. |
| 00:29 | deadghost_ | hmm how I can recover from an exception? |
| 00:30 | deadghost_ | (clojure.java.io/reader "http://deadgho.st/this-page-does-not-exist") |
| 00:31 | deadghost_ | gives a file not found exception |
| 00:31 | deadghost_ | I want to tell it to continue the program |
| 00:32 | deadghost_ | or in the case of 503 try a few more times then continue |
| 00:33 | TEttinger | ##(doc try) |
| 00:33 | lazybot | ⇒ "Special: try; catch-clause => (catch classname name expr*)\n finally-clause => (finally expr*)\n\n Catches and handles Java exceptions." |
| 00:34 | seancorfield | deadghost_: perhaps use clj-http instead so you have more control over how HTTP status is handled? |
| 00:55 | blur3d | does anyone know of an idiomatic way to define an expression once and allow it to be bi-directional (eg. 1 day = 24 hours and 24 hours = 1 day) |
| 00:56 | blur3d | would something like core.logic be suitable? |
| 00:56 | bitemyapp | noprompt: this weekend works. |
| 00:59 | noprompt | bitemyapp: fantastic. |
| 01:02 | echo-area | blur3d: Will java.util.concurrent.TimeUnit be suitable for you? |
| 01:02 | echo-area | Oh, that is only an example |
| 01:02 | blur3d | I'm looking to use it in a much broader sense |
| 01:03 | blur3d | something like this |
| 01:03 | blur3d | http://www.algebrahelp.com/calculators/equation/calc.do?equation=a%3D2b&solvf=b |
| 01:04 | blur3d | I'm fairly sure i have seen an example in clojure somewhere... likely in one of the books I've read, but its hard to find |
| 01:04 | blur3d | basically i want to be able to define something once, and flag it is reversible - and then it automatically adds both variations |
| 01:05 | TEttinger | blur3d, sounds like a use for macros? |
| 01:05 | TEttinger | like def-rev |
| 01:06 | blur3d | yeah, the macro can be used to define both of them... but i need a way to start with a=2b and get b=0.5a |
| 01:06 | echo-area | I saw similar things in SICP which introduced a constraint propagation system. Not sure if it exists for Clojure though |
| 01:07 | blur3d | maybe was I remember was a reverse stack function in C. |
| 01:08 | blur3d | Im hoping to find something I can use generically... so if it knows you can get AUD/USD, then it knows you can get USD/AUD |
| 01:10 | echo-area | blur3d: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-22.html#%_sec_3.3.5 Maybe implementing something like this is a last resort |
| 01:13 | blur3d | I know the problem is similar to unit conversion, thus you can define a base unit as 1 and then the other units as a factor of the base - and for that you can use multi-dimensional analysis |
| 01:19 | blur3d | anyway, ill keep looking out. Thanks @echo-area TEttinger |
| 01:20 | TEttinger | np |
| 01:21 | TEttinger | speaking of heavy metal in boss fights, Giygas part one has nes-style music, then transitions to http://youtu.be/9gbG_gzgyJI?t=2m6s |
| 01:22 | TEttinger | gah wrong chan |
| 01:39 | blur3d | I've found something that I might be able to work off - https://github.com/francoisdevlin/Full-Disclojure/blob/master/src/episode_012/episode_012.clj |
| 01:40 | blur3d | it has a video covering it also http://vimeo.com/9666573 |
| 02:10 | chenglou | clojure newb here, why does the let statement take a vector for binding and not a map |
| 02:14 | blur3d | chenglou: http://stackoverflow.com/questions/3859765/why-does-let-require-a-vector |
| 02:15 | chenglou | blur3d: ah thanks. Isn't that slightly expensive though |
| 02:15 | chenglou | I've read that the implementation is a 32-way tree |
| 02:16 | chenglou | but I guess usually they dont exceed a certain number of items |
| 02:16 | blur3d | I really haven't looked into it |
| 02:16 | chenglou | kk thanks |
| 02:17 | TEttinger | chenglou, I think the trees are used for sorted sequences IIRC |
| 02:17 | chenglou | TEttinger: I read it's the vector's underlying implementation |
| 02:17 | TEttinger | to the src! |
| 02:18 | blur3d | chenglou: IIRC hash-maps are internally vectors, so I would presume they are more performant then hash-maps |
| 02:18 | TEttinger | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/PersistentVector.java |
| 02:19 | chenglou | TEttinger: yep |
| 02:19 | chenglou | blur3d: didn't know that, thanks |
| 02:20 | TEttinger | it appears to be a linked list up to or after 32 items, I cannot make sense of this |
| 02:20 | chenglou | TEttinger: 32-way tree |
| 02:20 | chenglou | TEttinger: http://hypirion.com/musings/understanding-persistent-vector-pt-1 |
| 02:20 | chenglou | got it |
| 02:21 | chenglou | btw loving clojure right now, it makes so much sense =) |
| 02:24 | TEttinger | yeah, that kind of data structure seems to be pretty useful in general. I know Judy Arrays (a kind of less-memory-intensive associative array designed to reduce cache misses, but 20K lines of code) internally use a 32 or larger way tree |
| 02:24 | TEttinger | err trie |
| 02:26 | chenglou | first time I hear about judy arrays |
| 02:27 | chenglou | that thing looks awesome and has no performance downside...? |
| 02:27 | seriously_random | how to rewrite "(condition? (= blah bleh) (cons '() (recursive-fn (+ 1 n) a-seq))" so that function in the end doesn't give back a list with useless '()? |
| 02:28 | noidi_ | seriously_random, maybe a list comprehension would work better than explicit recursion and consing: http://clojuredocs.org/clojure_core/clojure.core/for |
| 02:28 | noidi_ | seriously_random, the first example on that page demonstrates the use of `:when` to filter out elements |
| 02:29 | seriously_random | noidi_, it's got to be recursive |
| 02:30 | noidi_ | why? |
| 02:30 | clojurebot | http://clojure.org/rationale |
| 02:31 | noidi_ | http://blog.fogus.me/2011/03/09/recursion-is-a-low-level-operation/ |
| 02:31 | seriously_random | noidi_, because it's mooc :) |
| 02:32 | seriously_random | also, recursions are kinda cool |
| 02:46 | rurumate | How to pass command line arguments (like input path) to a cascalog job jar? |
| 02:48 | rurumate | nvm I found it in the cascalog-impatient wiki |
| 03:28 | blur3d | is there a version of deref that evals the function if it is not a delay, or derefs it? something like |
| 03:28 | blur3d | (defn do-deref [r] |
| 03:28 | blur3d | (if (delay? r) |
| 03:28 | blur3d | @r |
| 03:28 | blur3d | (r))) |
| 03:50 | noidi_ | blur3d, AFAIK, you can implement IDeref if you want to create your own derefable objects https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/IDeref.java |
| 03:51 | TEttinger | blur3d, that function looks perfectly reasonable. I should probably learn more about delays |
| 03:51 | noidi_ | ,(let [x (reify clojure.lang.IDeref (deref [this] "lol"))] @x) |
| 03:51 | clojurebot | "lol" |
| 03:53 | noprompt | just wrote a wrapper around BreakIterator. bleh. |
| 03:54 | noprompt | first cut: https://www.refheap.com/22037 |
| 03:54 | noprompt | bleh |
| 03:59 | noprompt | i'm probably never going to use it. |
| 04:02 | blur3d | noidi_ TEttinger:kk, cheers |
| 04:07 | dyreshark | can anyone recommend a solid, idiomatic clojure codebase to read? |
| 04:09 | vijaykiran | dyreshark: https://github.com/Datomic/codeq perhaps ? |
| 04:09 | TEttinger | dyreshark, I can't say much about how idiomatic it is, but lazybot is certainly fun to work with, and it uses a lot of clojure features (from the written-early parts of the language) |
| 04:11 | dyreshark | vijaykiran: TEttinger: cool, i'll look into them. thanks :) |
| 04:12 | sm0ke | any one tried vertx adapater for ring? |
| 04:13 | sm0ke | clojure seems to be lagging behind in http://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=db |
| 04:13 | sm0ke | round 8 web framework benchmarks |
| 04:14 | sm0ke | also is there a grizzly ring adapter? |
| 04:25 | TheBusby | Any creative ways to produce a sorted-map which has random order? (just need to shuffle it once) |
| 04:30 | sm0ke | TheBusby: what do you mean by sorted-map with random orders? |
| 04:32 | clgv | TheBusby: sorted-map and random order sound pretty much mutually exclusive ;) |
| 04:32 | TheBusby | is sorted-map the only mechanism to create a map in one specific order? |
| 04:32 | TEttinger | sorted-map-by ? |
| 04:32 | TEttinger | ,(doc sorted-map-by) |
| 04:32 | clojurebot | "([comparator & keyvals]); keyval => key val Returns a new sorted map with supplied mappings, using the supplied comparator. If any keys are equal, they are handled as if by repeated uses of assoc." |
| 04:33 | TheBusby | (sorted-map-by get-rand-boolean-value ...) ? |
| 04:34 | clgv | TheBusby: that might not work if you desire a uniform random distribution |
| 04:34 | TheBusby | that was my first though, then shuffle and array-map? |
| 04:34 | clgv | TheBusby: you could create a random permutation and use that for sorting |
| 04:37 | TheBusby | clgv: so shuffle the map, then turn it into an array-map to preserve the random ordering? |
| 04:37 | clgv | TheBusby: ##(let [m {:a 1 :b 2 :c 3 :d 4}, order (zipmap (keys m) (shuffle (range (count m))))] (into (sorted-map-by order) m)) |
| 04:37 | lazybot | java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to java.util.Comparator |
| 04:38 | clgv | ah damn comparator instead of attribute^^ |
| 04:39 | TheBusby | ,(apply array-map (flatten (shuffle (seq {1 1 2 2 3 3})))) |
| 04:39 | clojurebot | {2 2, 3 3, 1 1} |
| 04:39 | clgv | ,(let [m {:a 1 :b 2 :c 3 :d 4}, order (zipmap (keys m) (shuffle (range (count m))))] (into (sorted-map-by #(< (order (key %1)) (order (key %2)))) m)) |
| 04:39 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry> |
| 04:39 | clgv | TheBusby: no. do not rely on the order of the arraymap since it is automatically converted to a persistenhashmap when growing beyond a certain size |
| 04:40 | TheBusby | clgv: excellent point, but hopefully I wont encounter that issue as I'm immediately converting the array-map to EDN, JSON, or XML |
| 04:41 | taruti | What is the right way to "pr" a byte-array so that it can be read back? |
| 04:41 | clgv | TheBusby: well, then just try. why do you need it to be ordered randomly then? |
| 04:41 | TEttinger | TheBusby, have you seen the lib Ordered? |
| 04:42 | TEttinger | https://github.com/flatland/ordered |
| 04:42 | TheBusby | clgv: hopefully to keep developers from depending on the order of fields. :) |
| 04:42 | TheBusby | TEttinger: no, looking now! |
| 04:42 | clgv | TheBusby: o_O |
| 04:42 | TEttinger | they might use some trick that you would find useful |
| 04:43 | TheBusby | TEttinger: would the advantage of order-map over array-map be the issue of assoc/dissoc that clgv mentioned? |
| 04:43 | TEttinger | ordered's maps are basically the same as Java's TreeMap s, just persistent? |
| 04:44 | TEttinger | no, http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashMap.html |
| 04:45 | TEttinger | I don't know why it needs to be random though |
| 04:46 | TheBusby | yeah... Just trying to make the dev API simulate all the different possible types of responses to break developer code before they release it. |
| 04:46 | TEttinger | if you just want to rearrange the order of fields to discourage wrong assumptions, ##(sorted-map-by (fn [l r] (- (rand-int 1000) 500)) :a 1 :b 2 :c 3) would work |
| 04:46 | lazybot | ⇒ {:a 1, :b 2, :c 3} |
| 04:46 | TheBusby | changing field orders, JSON/XML encoding tricks, etc |
| 04:46 | TEttinger | pfft |
| 04:46 | TEttinger | ##(sorted-map-by (fn [l r] (- (rand-int 1000) 500)) :a 1 :b 2 :c 3) |
| 04:46 | lazybot | ⇒ {:b 2, :a 1, :c 3} |
| 04:46 | TEttinger | there we go |
| 04:47 | TheBusby | TEttinger: as clgv was good to point out though, that doesn't ensure an even distribution |
| 04:47 | TEttinger | but I don't think you need one |
| 04:47 | dav | did the algebraic data types code get lost when the contribs got split into several packages? (https://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/types.clj) |
| 04:48 | clgv | TheBusby: I think your motivation for the whole taks is quite bizarre |
| 04:48 | clgv | $contrib |
| 04:48 | TEttinger | ~contrib |
| 04:48 | clojurebot | Monolithic clojure.contrib has been split up in favor of smaller, actually-maintained libs. Transition notes here: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go |
| 04:48 | TheBusby | clgv: I found developers "grep'ing out" data from a JSON response already... |
| 04:48 | clgv | TheBusby: why is it your task to forbid that? |
| 04:49 | TheBusby | clgv: if we make changes in the future, it'll break their code |
| 04:49 | TheBusby | clgv: in a perfect world, they'd be responible for their own poorly implemented code; and yet 800 pound gorilla's... |
| 04:49 | clgv | TheBusby: but only because they use it wrongly. is it really your task to ensure they are doing it right? |
| 04:50 | clgv | if you start there you'll end up doing a lot of strange things to ensure they are using the service right |
| 04:51 | TheBusby | I used to feel the exact same way, now I'm willing to do a little effort if it'll head-off potential problems |
| 04:53 | TEttinger | you know... you could just reverse it at random |
| 04:54 | TheBusby | TEttinger: yep, that works too ;) |
| 04:54 | clgv | TheBusby: well just go with the array-map approach if you serialize it directly without modifications |
| 04:55 | TEttinger | ##((rand-nth [identity reverse]) sorted-map :a 1 :b 2 :c 3)) |
| 04:55 | lazybot | clojure.lang.ArityException: Wrong number of args (7) passed to: core$reverse |
| 04:55 | TheBusby | okay, thanks for the heads up about distribution and the pointer to ordered-map! ;) |
| 04:55 | TEttinger | ##((rand-nth [identity reverse]) (sorted-map :a 1 :b 2 :c 3)) |
| 04:55 | lazybot | ⇒ {:a 1, :b 2, :c 3} |
| 04:57 | TEttinger | err no ##((rand-nth [reverse]) (sorted-map :a 1 :b 2 :c 3)) |
| 04:57 | lazybot | ⇒ ([:c 3] [:b 2] [:a 1]) |
| 04:58 | TEttinger | apparently reverse and rseq will both return a seq not a sorted-map |
| 05:00 | sm0ke | i have (defn ring-handler [] (handler/site #'myroutes)) in my code which i add to project.clj :ring {:handler myns/ring-handler} |
| 05:00 | sm0ke | but i seem to be getting clojure.lang.ArityException |
| 05:00 | sm0ke | for every route i try |
| 05:01 | sm0ke | wtf is this |
| 05:02 | TEttinger | arity exceptions are just you passed the wrong number of args to some fn |
| 05:02 | TEttinger | does it give a line number? |
| 05:02 | broquaint | sm0ke: I think you want def rather than defn there. |
| 05:03 | sm0ke | broquaint: just tried that to no use |
| 05:03 | TEttinger | and of course you'd take out the [] for def |
| 05:04 | clgv | gists with code and stacktraces for the win ;) |
| 05:04 | sm0ke | TEttinger: hehe :P |
| 05:05 | sm0ke | forgot to take out the [] |
| 05:07 | sm0ke | where do i specify these options? https://github.com/weavejester/lein-ring#web-server-options |
| 05:08 | mercwithamouth | anyone here have any medium sized projects that use enfocus? |
| 05:08 | clgv | mercwithamouth: better ask your question directly^^ |
| 05:08 | bvdeenen | hi all, I'm looking for a way to limit the number of digits of a float that's shown in the repl. Any tips ? |
| 05:08 | sm0ke | fuck i never knew lein ring server is so awesome for development! |
| 05:08 | sm0ke | it has hot swap |
| 05:09 | mercwithamouth | clgv: no question...i just wanted to look over someones project to see how they structure their code =P |
| 05:09 | clgv | bvdeenen: you probably have to overide print-method for floats |
| 05:09 | TEttinger | there's a way, let me check |
| 05:09 | clgv | bvdeenen: or if you explicitely output them you can use `format` |
| 05:09 | mercwithamouth | sm0ke: hah i didn't know it allowed hot swapping either. c00l beanz |
| 05:10 | bvdeenen | no,no, it's just for during development of a function |
| 05:10 | bvdeenen | I know about format |
| 05:11 | TEttinger | there's http://clojuredocs.org/clojure_core/clojure.core/with-precision |
| 05:11 | TEttinger | but that's for BigDecimals |
| 05:12 | bvdeenen | yeah, I found that already. I am developing some math functions that return float sequences, and my screen just fills up like mad |
| 05:12 | TEttinger | floats shouldn't be very long, hm? |
| 05:13 | bvdeenen | So it would be nice if I could just limit the number of digits the repl shows. I guess I'll go have a look at overloading core/print-method |
| 05:13 | bvdeenen | Well each float is about 15 characters, and my function returns a vector of 50 :-) |
| 05:13 | bvdeenen | Oh worse, 50 vectors of 3 floats |
| 05:14 | bvdeenen | Anyway, I'll check on print-method, thanks for thinking along.... |
| 05:14 | TEttinger | http://clojuredocs.org/clojure_core/clojure.core/*print-length* ? |
| 05:14 | TEttinger | that's what clojurebot uses |
| 05:14 | TEttinger | ,(repeat 7) |
| 05:14 | clojurebot | (7 7 7 7 7 ...) |
| 05:15 | bvdeenen | yep that works, it helps. |
| 05:17 | bvdeenen | I'll see if I can add this to clojure.core/print-method, maybe even suggest it as a patch, with a *print-round* global |
| 05:17 | clgv | bvdeenen: you can just set *print-length* and *print-level* in your REPL |
| 05:18 | clgv | bvdeenen: print-method would be only for using format to limit the decimal places shown |
| 05:19 | bvdeenen | Yep, I'm using *print-length* now, that helps, but I still like the idea of having a global rounding constant for floats in the repl |
| 05:19 | clgv | bvdeenen: that's the approach I meant (defmethod print-method Float [v ^java.io.Writer w] (.write w (format "%.3f" v))) |
| 05:19 | clgv | similar for Double |
| 05:20 | bvdeenen | Cool! thanks for the tip |
| 05:20 | clgv | bvdeenen: you could also use a dynamic variable for the number of decimal places there |
| 05:21 | bvdeenen | He dude, you just created my patch! Just add it to clojure.core please, and everone is happy... :-) |
| 05:21 | clgv | bvdeenen: no certainly not. since this influences text serialization ;) |
| 05:22 | bvdeenen | oh :-( |
| 05:22 | clgv | pr-str and such use print-method as well |
| 05:24 | bvdeenen | That's too cool, it works, ok now I'll try to figure out how it works, because I'm new to clojure |
| 05:25 | seriously_random | is there tuple assignment like in python? |
| 05:25 | clgv | seriously_random: Clojure has destructuring if that is what you mean |
| 05:26 | dav | Is there no decent algebraic data type library for clojure? |
| 05:26 | clgv | ,(let [[a b c] (range)] [c a b]) |
| 05:26 | clojurebot | [2 0 1] |
| 05:27 | clgv | dav: what do you want to do? |
| 05:28 | dav | clgv: pattern matching on algebraic data types |
| 05:29 | dav | clgv: as done here: https://code.google.com/p/clojure-contrib/source/browse/trunk/src/clojure/contrib/types/examples.clj?spec=svn596&r=596 |
| 05:29 | dav | clgv: except clojure-contrib was disbanded and it seems to me that this code is gone |
| 05:29 | clgv | dav: there is core.match for pattern matching |
| 05:29 | dav | clgv: it seems to pattern match values.. that's not very interesting |
| 05:30 | dav | clgv: I'd want to pattern match type constructors |
| 05:31 | dav | I guess I can probably reproduce the functionality with map matching |
| 05:45 | broquaint | There's a subtlety here I'm not appreciating and could do with some enlightenment - https://gist.github.com/broquaint/8037288 |
| 05:53 | broquaint | Oh I think it's the REPL not knowing how to stringify it. |
| 05:54 | seriously_random | how to write the following for loop in clojure: http://pastebin.com/1WcjHa90 |
| 05:55 | sm0ke | broquaint: thats weird there is a default toString for EVERY Object in java which prints the object reference |
| 05:57 | sm0ke | broquaint: working with java apis which do not have Builder patterns is ugly in clojure |
| 05:58 | sm0ke | as a sidenote |
| 06:04 | broquaint | Duly noted, sm0ke :) |
| 06:09 | daGrevis | did I do this koan correctly? "One function can beget another" |
| 06:09 | daGrevis | (= 9 (((fn [] #(+ %1 %2))) 4 5)) |
| 06:09 | daGrevis | yodas? |
| 06:20 | clgv | daGrevis: what is filled in? otherwise I'd say (= 9 (+4 5)) is simpler ;) |
| 06:21 | daGrevis | clgv, it would be simpler, but I would count is as cheating |
| 06:22 | clgv | daGrevis: why? |
| 06:22 | daGrevis | beacuse u r just ignoring 4 5 that are passed to the function as arguments |
| 06:22 | daGrevis | elegant cheating :P |
| 06:22 | clgv | daGrevis: I dont know what the exakt exercise is. no + does not ignore 4 5 ;) |
| 06:22 | daGrevis | clgv, can you show me full example of your code? |
| 06:23 | clgv | as said above, I have no clue what part of the expression is fixed and where exactly you need to fill in something |
| 06:23 | uday | Hi, We are using core.match for pattern matching. And we want to match a set instead of a vector or sequence like this [([1 2 3 4] :set)]. Can you someone suggest us how we can implement our own matchers like this? |
| 06:24 | clgv | uday: in case you get no answer very soon, try to ask dnolen in several hours |
| 06:26 | daGrevis | clgv, https://github.com/functional-koans/clojure-koans/blob/master/src/koans/06_functions.clj#L26 |
| 06:26 | daGrevis | you need to fill ___ |
| 06:26 | uday | clgv: Sure. Thanks |
| 06:26 | daGrevis | you could just fill it with 9 and it will pass |
| 06:26 | clgv | daGrevis: ok then I'd use (= 9 (((fn [] +)) 4 5)) |
| 06:27 | clgv | daGrevis: no you couldnt |
| 06:27 | daGrevis | :/ |
| 06:27 | clgv | ,(= 9 (((fn [] 9)) 4 5)) |
| 06:27 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 06:27 | clgv | see ;) |
| 06:27 | clgv | ,(= 9 (((fn [] +)) 4 5)) |
| 06:27 | clojurebot | true |
| 06:28 | daGrevis | clojurebot, ye, cool |
| 06:28 | clojurebot | I don't understand. |
| 06:28 | daGrevis | whoops |
| 06:28 | daGrevis | i got to ask, why 9 doesn't work? |
| 06:29 | daGrevis | , (= 9 (((fn [] 9)) 4 5)) |
| 06:29 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 06:29 | clgv | because 9 ist not a function but it called as one |
| 06:29 | clgv | ,(= 9 (((fn [] (constantly 9))) 4 5)) |
| 06:29 | clojurebot | true |
| 06:29 | daGrevis | clgv, is + a function? |
| 06:29 | clgv | ;) |
| 06:29 | clgv | yes |
| 06:29 | daGrevis | , (= 9 (((fn [] '9)) 4 5)) |
| 06:29 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 06:29 | clgv | + is a symbol which is resolved to the function that adds numbers ;) |
| 06:29 | daGrevis | for something sake ;D |
| 06:30 | clgv | daGrevis: using (constantly 9) works in that case since it creates a function that always returns 9 |
| 06:30 | daGrevis | clgv, why doesn't '9 work? |
| 06:30 | clgv | daGrevis: it is no function |
| 06:30 | clgv | ,(type '9) |
| 06:30 | clojurebot | java.lang.Long |
| 06:31 | daGrevis | i thought ' had a special meaning |
| 06:31 | clgv | daGrevis: yeah, it is a shortcut for (quote ...) |
| 06:31 | daGrevis | , (= 9 (((fn [] '9)) 4 5)) |
| 06:31 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 06:31 | daGrevis | whoops |
| 06:31 | clgv | but that does not create functions ;) |
| 06:31 | daGrevis | ok, til and gotta learn a lot more |
| 06:31 | daGrevis | thanks :) |
| 06:33 | clgv | daGrevis: you got a book or know about clojure-doc.org? |
| 06:33 | daGrevis | clgv, currently im walking throught the koan |
| 06:34 | daGrevis | i have some knowledge in programming ;) |
| 06:34 | daGrevis | python, a bit of haskell |
| 06:34 | daGrevis | gotta get book! \o/ |
| 06:34 | clgv | daGrevis: reading about the concepts of the language will speed up your progress ;) |
| 06:35 | daGrevis | clgv, any suggestions? |
| 06:35 | daGrevis | i mean, for book |
| 06:35 | clgv | daGrevis: "Clojure Programming" is quite recent. I read a few chapters of it which were well written |
| 07:08 | casperc | s |
| 07:23 | seriously_random | from index 1 to 2 in '(1 2 3 4 5) => (2 3) - how? |
| 07:25 | daGrevis | clgv, thanks for book suggestion ;) |
| 07:26 | clgv | seriously_random: ##(->> (range 1 6) (drop 1) (take 2) |
| 07:27 | clgv | ups |
| 07:27 | clgv | ,(->> (range 1 6) (drop 1) (take 2)) |
| 07:27 | clojurebot | (2 3) |
| 07:44 | seriously_random | I don't want to sound intrusive, but could someone show something like this: http://pastebin.com/1WcjHa90 is done in clojure |
| 07:47 | seriously_random | I guess I could use destructure, "let [[a b c] '(1 2 3)]". But that will only work if sequence is fixed size |
| 07:48 | jballanc | seriously_random: in your pastebin you say "hashset", but sets are inherantly unordered |
| 07:48 | jballanc | did you mean a seq or vec? |
| 07:49 | seriously_random | hashset is original input, I guess I convert it to sequence first |
| 07:49 | seriously_random | skipping words, not a good sign :) |
| 07:50 | jballanc | so, yeah, you could make it a seq |
| 07:50 | jballanc | '(seq #{1 2 3 4}) |
| 07:50 | jballanc | whoops |
| 07:50 | jballanc | ,(seq #{1 2 3 4}) |
| 07:50 | clojurebot | (1 2 3 4) |
| 07:50 | clgv | seriously_random: since it is swapping back and forth there is no clear functional result. is it only supposed to do the printing side effect? |
| 07:50 | jballanc | but if you want to swap, you probably want a vec |
| 07:51 | seriously_random | would vec simplify the task? |
| 07:51 | clgv | seriously_random: what is the task? printing the original sequences with the 3 swaps? |
| 07:52 | seriously_random | clgv, 1234, 2134, 3214, etc (swapping with index 0) |
| 07:54 | clgv | ,(let [v [1 2 3 4]] (dotimes [i 3] (let [i (inc i)] (println (assoc v 0 (v i) i (v 0)))))) |
| 07:54 | clojurebot | [2 1 3 4]\n[3 2 1 4]\n[4 2 3 1]\n |
| 07:54 | jballanc | heh...I would've used a for comprehension |
| 07:55 | jballanc | saves a form |
| 07:55 | seriously_random | why can't it be something simple, like a, b = b, a in python? |
| 07:55 | jballanc | because vectors (and seqs and hashes and sets) in Clojure are immutable |
| 07:55 | clgv | seriously_random: persistent data structures, that's why |
| 07:56 | clgv | this is you a,b = b,a => (assoc v 0 (v i) i (v 0))) |
| 07:57 | clgv | you could write a separate swap function if it's worth it |
| 07:58 | jballanc | actually, since you're only printing the vectors there's not even any need to really do the assoc |
| 08:00 | clgv | jballanc: well it is the simplest. traversing the vetor needs more code ;) |
| 08:00 | clgv | and closer to the semantic in the pseudocode |
| 08:04 | jballanc | eh, I guess... |
| 08:05 | jballanc | the pseudocode doesn't really fit with a functional design, though |
| 08:05 | seriously_random | here is the actual "pseudocode": http://helloacm.com/a-recursive-full-permutation-in-python/ |
| 08:11 | clgv | jballanc: thats right. but we could approximate it with `dotimes` in idiomatic clojure ;) |
| 08:12 | jballanc | you can do a lot of ugly stuff in clojure :) |
| 08:12 | clgv | seriously_random: well there is at least one existing implementation for a lazy sequence of all permutations of a given length... |
| 08:13 | clgv | it was in the old contrib libs |
| 08:13 | jballanc | seriously_random: the article you linked, though, is doing something different than your pastebin |
| 08:14 | jballanc | you were just permuting two positions, but the article you link is doing a full permutation |
| 08:14 | jballanc | that should actually be much easier/clearer to do (recursively, as the article suggests) in clojure |
| 08:17 | seriously_random | jballanc, I was aware of not doing a full perm. set. It was more like a practice before the real deal. |
| 08:17 | jballanc | well, in this particular case, I think you've made the problem harder by not tackling the whole thing at once |
| 08:18 | jballanc | with clojure (and functional programming in general) it's much better to sit and think about the whole problem than to try and piecemeal it together |
| 08:19 | seriously_random | or you could argue that starting from something will lead to some kind of understanding of what it is that you are doing |
| 08:20 | jballanc | yeah, but because of clojure's immutable data structures you're going to have a much harder time implementing the half-solution |
| 08:25 | clgv | jballanc: I think building solutions to problems bottom-up is pretty normal in Clojure due to the testing abilities in the REPL. but you need to think about howto structure the implementation it the needed functions |
| 08:32 | seriously_random | jballanc, http://pastebin.com/wpLWgzF5 - doesn't seem to do the same thing |
| 08:34 | seriously_random | one mistake is at dotimes (range) |
| 08:34 | clgv | seriously_random: yeah the mistake is that you wanted side-effect only code before and now you want a return value ;) |
| 08:36 | mdrogalis | Morning. |
| 08:47 | seriously_random | clgv, know anything about for and how println behaves? http://pastebin.com/x0fCMMT2 |
| 08:49 | stuartsierra | clojurebot: for? |
| 08:49 | clojurebot | for is a loop...in Java |
| 08:56 | seriously_random | how to avoid deep nesting? http://pastebin.com/5cP2VQ7i |
| 08:57 | xsyn | I all |
| 08:57 | xsyn | I'm busy playing with incanter |
| 08:58 | xsyn | and I want to do an intersaection on the two lazy-seqs I've got |
| 08:58 | xsyn | but I can't convert them into sets |
| 08:58 | xsyn | how do I find the values that each lazy-seq has easily |
| 09:03 | silasdavis | any recommendations for load testing in clojure? |
| 09:05 | fredyr | xsyn: do you need to keep dups, or why not convert to set? |
| 09:05 | xsyn | just worked that out |
| 09:05 | xsyn | thanks |
| 09:05 | xsyn | (set (doall (lazy-seq)) |
| 09:13 | clgv | xsyn: just (set your-lazy-seq) should work as well |
| 09:14 | jonasen | Bronsa: ping |
| 09:14 | jonasen | Bronsa: https://github.com/clojure/tools.analyzer/blob/master/src/main/clojure/clojure/tools/analyzer/utils.clj#L85 |
| 09:15 | jonasen | Bronsa: that call to 'var?' makes tools.analyzer much less platform agnostic. Is it necessary? |
| 09:21 | Bronsa | jonasen: I know, that's something I need to fix before the first release |
| 09:23 | jonasen | Bronsa: ok, it's not a real big problem, the ast is returned as ':op :maybe-class' and I can write my own resolve-var pass |
| 09:25 | Bronsa | jonasen: FWIW resolve-var will be a dynamic var like create-var. I don't think there's any other option to support arbitrary representation in the ns map |
| 09:28 | jonasen | Bronsa: yes, that's probably true. There are a few other places in analyzer.utils where you're using 'var?'. Not sure if that's a problem |
| 09:30 | Bronsa | jonasen: no, I don't think those other places will be a problem |
| 09:58 | sw1nn | hiredman: Hi, I set up an instance of clojurebot for #ldnclj, but I just noticed that there's some code to invite the clojurebot from here into that channel. Is that something that might be possible? |
| 10:11 | romain_p_ | Hi everyone, could somebody tell me what is wrong with http://pastebin.com/PkR7P6Rk |
| 10:12 | romain_p_ | Specifically, I get an error "<! used not in go block" |
| 10:12 | clojurebot | Excuse me? |
| 10:14 | fredyr | are there any clojurescript alternatives similar to Backbone models? |
| 10:17 | jjl`_ | what things have metadata attached by default? |
| 10:18 | tbaldrid_ | romain_p_: not sure, did you :require <! from cljs.core.async? |
| 10:18 | tbaldrid_ | and are you importing macros from cljs.core.async.macros? |
| 10:18 | `cbp | vars have metadata by default i guess? |
| 10:18 | `cbp | this sounds like some interview question |
| 10:19 | jjl`_ | heh, i actually do have a use for this information |
| 10:20 | `cbp | things that start with def put metadata on the vars, at the very least things like ns, line, file, etc |
| 10:20 | pepijndevos | hiring people in usefull |
| 10:21 | jjl`_ | `cbp: that's what i thought, but i've just defined a function with defn in a lein repl and (meta myfn) returns nil |
| 10:21 | `cbp | (meta #'myfn) |
| 10:21 | `cbp | on the var not the function |
| 10:21 | jjl`_ | aha |
| 10:22 | romain_p_ | tbaldridge: I am using (require [cljs.core.async :refer [<! >! chan go]) |
| 10:23 | tbaldridge | romain_p_: remove the go symbol and do this for go instead: |
| 10:23 | tbaldridge | (:require-macros [cljs.core.async.macros :refer [go]]) |
| 10:23 | romain_p_ | tbaldridge: OK, thanks! |
| 10:23 | tbaldridge | romain_p_: in CLJS you have to pull in macros via reqire-macros. |
| 10:23 | romain_p_ | I was confused about that one |
| 10:23 | tbaldridge | *require-macros |
| 10:24 | romain_p_ | tbaldridge: although it would be nice if the compiler complained, but I guess it cannot be done in such a dynamic language |
| 10:25 | pepijndevos | is there a reason for that other than noone bothered reimplementing the macro system? |
| 10:29 | stuartsierra | It's more complicated than that. |
| 10:31 | stuartsierra | The Clojure compiler is partially implemented in Clojure. Macros are part of that. |
| 10:31 | stuartsierra | The ClojureScript compiler is also implemented in Clojure. |
| 10:31 | stuartsierra | Macros are a compiler feature that also require the full language runtime. |
| 10:32 | stuartsierra | In ClojureScript, the language runtime (JavaScript) and the compiler (Clojure / JVM) are separate. |
| 10:33 | tbaldridge | My only complaint is that go doesn't exist inside cljs.core.async. So I would expect CLJS to at least warn about that. |
| 10:34 | stuartsierra | I think there's a CLJS compiler option for warnings like that. |
| 11:08 | dnolen | tbaldridge: romain_p_: there is new sugar now, if you give your macro file the same name as the CLJS file barring extension, :include-macros true works |
| 11:08 | dnolen | also (:require [foo.bar :as bar :refer-macros [woz]]) |
| 11:11 | lpetit | cemerick: hello |
| 11:11 | cemerick | lpetit: hi! :-) |
| 11:12 | lpetit | What's up ? |
| 11:12 | cemerick | lpetit: not much / a lot, depending. :-) |
| 11:12 | lpetit | he |
| 11:30 | zerokarmaleft | I'm getting a weird var resolution error, despite it clearly being interned => https://gist.github.com/zerokarmaleft/8042030 |
| 11:37 | andyf | only on that symbol? |
| 11:40 | zerokarmaleft | andyf: afaict, yes |
| 11:40 | andyf | And repeatably with a new JVM? |
| 11:42 | zerokarmaleft | andyf: my bad, get-all-bids and delete-bid also fail to resolve, get-bid resolves but is unbound |
| 11:43 | zerokarmaleft | andyf: yea, just tried with a fresh repl |
| 11:44 | andyf | no errors when loading the namespace? |
| 11:45 | zerokarmaleft | namespace loads fine |
| 11:46 | rukor | zerokarmaleft: out of curiosity, do you justify your namespace declarations by hand or some Emacs magic. |
| 11:47 | zerokarmaleft | rukor: a little of column A and a little of column B, but that's mostly enabled by M-x align-regexp |
| 11:50 | zerokarmaleft | I wonder if this is some cider/nrepl funkiness |
| 11:51 | andyf | worth trying outside on a plain terminal REPL to check, if that isn't too much trouble. |
| 11:51 | rukor | Zerokarmaleft: i see, thanks. I also see some docstrings justified. Any ideas on how to achieve that? |
| 11:53 | zerokarmaleft | rukor: that's part of clojure-mode, I believe...clojure-fill-docstring |
| 11:57 | rukor | Aha, thanks. Perfect. Ive always disliked the default fill mode for docstrings. Thanks |
| 11:57 | zerokarmaleft | andyf: same thing |
| 11:57 | zerokarmaleft | rukor: np |
| 11:58 | andyf | zerokarmaleft: I wish I had something more useful to suggest, but I'm not coming up with anything. |
| 11:58 | zerokarmaleft | it's bizarre |
| 11:58 | zerokarmaleft | eval'ing directly in the repl creates a working binding |
| 11:59 | andyf | does defentity define any other symbols with the substring "bids", like "get-bids", as part of its effect? |
| 11:59 | zerokarmaleft | hmm, good question...checking korma docs |
| 12:02 | hiredman | zerokarmaleft: that form-init bit in a temp file name is something lein does when first launching a project repl, getting it at the repl like that is very weird, what does your project.clj look like? |
| 12:02 | zerokarmaleft | andyf: looks like it just creates a map and binds "bids" to it |
| 12:03 | hiredman | zerokarmaleft: what repl are you using? |
| 12:04 | zerokarmaleft | hiredman: https://github.com/codesy/patronage/blob/master/project.clj |
| 12:05 | zerokarmaleft | hiredman: cider/nrepl |
| 12:08 | hiredman | zerokarmaleft: what happens if you remove the init-ns stuff and try to compile the file in a fresh repl? |
| 12:09 | zerokarmaleft | hiredman: same error, get-bid-command doesn't resolve when compiling get-bid |
| 12:11 | hiredman | zerokarmaleft: I don't think you can use declare like that for defentity, but I don't see how you would get the error you say you are getting from that |
| 12:11 | sw1nn | hiredman: did you catch my clojurebot question earlier? basically - can we invite ClojureBot into #ldnclj? |
| 12:11 | gfredericks | \j #ldnclj |
| 12:11 | gfredericks | slash directions |
| 12:13 | hiredman | sw1nn: http://en.wikipedia.org/wiki/List_of_Internet_Relay_Chat_commands#INVITE might work |
| 12:14 | hiredman | zerokarmaleft: maybe you can use declare like that, it does like korma's macros explicitly var the names |
| 12:15 | sw1nn | hiredman: I tried it after looking at the code, but there's a flag :on-invite which may not be set? |
| 12:15 | hiredman | zerokarmaleft: what happens if you run java -classpath `lein classpath` clojure.main, then require your namespace? |
| 12:16 | zerokarmaleft | hiredman: same error |
| 12:16 | hiredman | sw1nn: ah, well |
| 12:17 | hiredman | zerokarmaleft: unlikely, given as I said the form-init bit is lein specific |
| 12:17 | zerokarmaleft | hiredman: the context is the actual source file instead of a temp file |
| 12:17 | zerokarmaleft | but it's the same var resolution error |
| 12:22 | zerokarmaleft | andyf, hiredman: gotta come back to this later, thanks for the suggestions |
| 12:24 | hiredman | zerokarmaleft: looking at the code in the patronage repo, there is no get-bid-command in that file |
| 12:26 | hiredman | zerokarmaleft: you have an extra m in your defn |
| 12:31 | dnolen | ok so in Om if we decomplect the data path and the render path we can have Datomic style queries to compute children instead of having to write silly functional code for it |
| 12:38 | pepijndevos | dnolen, whats Om? |
| 12:39 | dnolen | pepijndevos: https://github.com/swannodette/om |
| 12:39 | tbaldridge | dnolen: pedestal has a 120 line datalog engine you could also snag. or do the queries in core.logic. |
| 12:39 | pepijndevos | ah |
| 12:39 | dnolen | tbaldridge: excellent |
| 12:40 | tbaldridge | dnolen: it's super basic, but it works almost exactly like datomic's q fn https://github.com/pedestal/pedestal/blob/master/app/src/io/pedestal/app/query.clj |
| 12:41 | dnolen | tbaldridge: excellent I just want something simple |
| 12:41 | dnolen | tbaldridge: this won't be a bottleneck at all, and people will be able to write beautiful queries instead of writing the same tedious map filter reduce ops over and over again. |
| 12:42 | tbaldridge | dnolen: nice. |
| 12:43 | pepijndevos | uuh, looking at react now. it has embedded xml!? |
| 12:43 | dnolen | pepijndevos: HTML, and it's optional |
| 12:44 | pepijndevos | I see... weird |
| 12:44 | dnolen | pepijndevos: the website isn't very informative, what is awesome about React is the virtual DOM diffing and the event simulation |
| 12:44 | dnolen | which is what most of the React code is actually about |
| 12:44 | cark | dnolen : so Om redraws everything when there's a change in the "dom" ? |
| 12:44 | dnolen | cark: no |
| 12:44 | dnolen | cark: Om doesn't do any rendering, React does it will only update what actually changed |
| 12:45 | cark | dnolen: ah ok |
| 12:45 | pepijndevos | :include-macros true? hmmm |
| 12:45 | dnolen | cark: however Om can drive the React lazy diffing process from the root very efficiently because our data is immutable. |
| 12:46 | cark | i'm not familiar with react, maybe i should have a look to it |
| 12:47 | kmicu | dnolen: Can you estimate how much work is needed for GClosure Adv. Comp. Friendly React.js ? |
| 12:47 | dnolen | kmicu: no idea but I don't really care about that. |
| 12:47 | dnolen | kmicu: linking to a CDN for dev and :preamble for production works fine |
| 12:48 | dnolen | cark: I've got a post coming out later today with lots of details |
| 12:48 | kmicu | Finally. |
| 12:48 | kmicu | :) |
| 12:48 | dnolen | cark: CLJ/CLJS will get it immediately. |
| 12:48 | dnolen | CLJ/CLJS users |
| 12:49 | scottj | Are there docs on #js for cljs? |
| 12:49 | cark | do you mean it will be included in with clojurescript ? |
| 12:49 | dnolen | scottj: not but it I don't see why there needs to be |
| 12:49 | dnolen | cark: no |
| 12:49 | dnolen | scottj: #js {} for objects #js [] for arrays, that's it |
| 12:57 | gfredericks | what does #js [{}] do? |
| 12:57 | dnolen | gfredericks: an array with a map in it |
| 12:58 | gfredericks | a js obj or a cljs map? |
| 12:58 | dnolen | gfredericks: the behavior of #js has been through quite a bit |
| 12:58 | dnolen | gfredericks: #js isn't magical |
| 12:58 | dnolen | s/through/thought through |
| 12:58 | gfredericks | dnolen: I'm just pointing out that it isn't obvious |
| 12:59 | dnolen | gfredericks: it is if you think about it |
| 12:59 | eggnoggin | it'd just return a js literal like [{}] tho right? |
| 12:59 | dnolen | eggnoggin: no, think about it some more |
| 12:59 | dnolen | and why that's a really bad idea |
| 13:00 | gfredericks | something being a bad idea doesn't mean it can be ruled out in the absence of documentation |
| 13:01 | eggnoggin | a clojure vector where the 0th elem is a clojure map coerced to js ... wouldn't that be the same as typing [{}] in the js repl? |
| 13:01 | dnolen | gfredericks: I think people will figure it out pretty quickly. It should be documented and anyone can do that. |
| 13:01 | eggnoggin | aaah |
| 13:01 | gfredericks | dnolen: okay, I thought you had said it shouldn't be documented; my mistake |
| 13:01 | eggnoggin | so you'd write #js [#js {}] |
| 13:01 | dnolen | gfredericks: far as I know hardly any of the tagged literal stuff in CLJS is documented at all |
| 13:01 | eggnoggin | is that? |
| 13:01 | dnolen | eggnoggin: yes |
| 13:01 | eggnoggin | but wouldn't #js [{}] recursively coerce down to the js literals? |
| 13:02 | dnolen | eggnoggin: absolutely not |
| 13:02 | CookedGryphon | in core.async, is it possible to do an alts style statement but where I'm waiting on events *in* from one channel, or the capability to push an event to another channel? |
| 13:02 | tbaldridge | CookedGryphon: yep, look at the docs to alt! you can mix and match |
| 13:02 | tbaldridge | http://clojure.github.io/core.async/#clojure.core.async/alt! |
| 13:03 | tbaldridge | also: http://clojure.github.io/core.async/#clojure.core.async/alts! |
| 13:03 | CookedGryphon | tbaldridge: ah, I've only ever used alts!, I couldn't work out what the docstring for alt! was going on about |
| 13:06 | CookedGryphon | okay, I *think* I get what's going on... |
| 13:06 | justin_smith | I think alt! is like the equivalent of (let [chan val] (alts! [chan1 chan2 chanN]) (case chan ...)) -> (alt! chan1 ... chan2 ...) |
| 13:16 | noprompt | bitemyapp: omfg |
| 13:32 | jcromartie | so, I had previously had a nice prevalent system design going on, but now I have a requirement to have load balancing between two servers |
| 13:33 | jcromartie | now, there is no actual need to balance the load, but they want failover between VM instances in case one goes down |
| 13:34 | eggnoggin | jcromartie: are both of your apps stateless between requests? just use a reverse proxy |
| 13:36 | jcromartie | No, since I use a event sourcing design with state in memory |
| 13:36 | jcromartie | I can just as easily move state outside |
| 13:37 | jcromartie | so long as transactions are still possible |
| 13:37 | jcromartie | that means MongoDB is right out |
| 13:37 | pepijndevos | what if the load balancer goes down... |
| 13:37 | justin_smith | avout can help - it defines refs / atoms that are transperently shared between instances |
| 13:38 | jcromartie | justin_smith: nice! |
| 13:38 | justin_smith | with standard atom / ref semantics |
| 13:39 | justin_smith | depending how you were storing state that can make any changes to go from single instance with in-memory state to cluster a very smooth transition |
| 13:39 | jcromartie | it might be a little tricky if the different front ends have different versions of the app though |
| 13:39 | justin_smith | though it provides an incentive to make more small atoms/refs with separate parts of state, instead of one big one |
| 13:40 | jcromartie | yeah I am using a ref for state with an agent to write events right now |
| 13:40 | pepijndevos | how does it perform? |
| 13:40 | pepijndevos | avout |
| 13:40 | justin_smith | I haven't used in in production yet |
| 13:40 | justin_smith | it can be backed by zookeeper |
| 13:40 | justin_smith | which is designed for low latency |
| 13:41 | justin_smith | but I should really load-test it |
| 13:41 | jcromartie | this might really be overkill though |
| 13:42 | pepijndevos | if you kill a fly with a shotgun, it still dies... |
| 13:42 | clojurebot | No entiendo |
| 13:45 | danielszmulewicz | whois gf3 |
| 13:45 | danielszmulewicz | sorry |
| 13:45 | justin_smith | avout is pretty lightweight - it is basically a keystore/message queue attached to standard clojure mutation protocols |
| 13:46 | WWWest | Hi |
| 13:46 | WWWest | I just updated to clojurescript "0.0-2120", now my project takes ~15secs instead of 4 on every change with lein cljsbuild auto |
| 13:46 | WWWest | is this normal? |
| 13:49 | danielszmulewicz | WWWest: most certainly not |
| 13:49 | WWWest | I also added core.async |
| 13:49 | tbaldridge | justin_smith: avout also has some fairly bad flaws |
| 13:50 | danielszmulewicz | WWWest: Each version bump is supposed to bring performance improvement, if not, it might be a regression. |
| 13:50 | WWWest | but I have 2 go's and 3 >!, <! |
| 13:50 | tbaldridge | justin_smith: https://github.com/liebke/avout/issues/1 |
| 13:51 | justin_smith | ouch |
| 13:51 | jcromartie | tbaldridge: that's quite an issue, #1 from a year ago, still open? |
| 13:51 | justin_smith | luckily I am not counting on watches |
| 13:52 | mdrogalis | Avout not allowing you to read-every-write has burned me. |
| 13:53 | mdrogalis | Yeah, the ZK-watch thing. |
| 13:53 | pepijndevos | It seems to be a "feature" |
| 13:53 | tbaldridge | yeah, the lib is based on some flawed views of ZK and as such has basically been discontinued. |
| 13:53 | justin_smith | it looks like that is a limitation of the underlying zookeeper |
| 13:53 | mdrogalis | So I don't know if ZK itself considers them flaws. |
| 13:54 | justin_smith | flawed views as in the implementors do not understand zookeeper sufficiently? or the premise of the lib is based on a flawed understanding of zookeeper |
| 13:54 | tbaldridge | The problem is that ZK detaches watchers after each change. So if you attach a watch, then read the value then re-attach the watch you have a race condition. |
| 13:54 | mdrogalis | The ZK docs say that "it's just something you need to account for." |
| 13:56 | patchwork | The issue is that zookeeper behavior does not map to clojure watches |
| 13:56 | patchwork | So you can't expect watches on avout refs to have the same behavior as watches on regular clojure refs |
| 13:56 | pepijndevos | fu, distributed systems... |
| 13:57 | mdrogalis | Has anyone used something like ZK that doesn't have that oddity? |
| 13:57 | tbaldridge | eh, just use locks/transactions inside a machine and use other systems (message passing) outside machines. |
| 13:57 | patchwork | Leaky abstractions, yadda yadda |
| 13:57 | mdrogalis | Easier said than done, tbaldridge. At least I think so. |
| 13:58 | tbaldridge | true, it takes rethinking about your problem. But that's better than trying to get a distributed lock to work. |
| 13:58 | patchwork | So, avout is good for distributed state, but not message passing? |
| 13:59 | mdrogalis | patchwork: It's not so good for observing every change to a piece of state. |
| 13:59 | tbaldridge | I wouldn't use it for anything to be honest. It's been like 2 years since any updates were made to it. |
| 13:59 | mdrogalis | In fact - it can't. |
| 13:59 | patchwork | It seems if you want to see every change, you really want a message passing system |
| 13:59 | mdrogalis | Yeah. |
| 13:59 | patchwork | tbaldridge: So what about zookeeper in general then? |
| 13:59 | mdrogalis | I mean, it's emphemeral node feature is pretty great. |
| 14:00 | patchwork | Is avout just a bad abstraction over a good library, or is ZK itself basically flawed? |
| 14:00 | tbaldridge | No, ZK is fine for stuff like configs. I just have an issue with storing anything else in it. I wouldn't try to go and keep my application state in ZK. |
| 14:00 | patchwork | As in, maybe we need a different clojure library for zookeeper then? |
| 14:00 | tbaldridge | Now perhaps I'd keep a uuid in ZK that pointed to a datastructure on disk somewhere. |
| 14:01 | tbaldridge | I've used this: https://github.com/liebke/zookeeper-clj |
| 14:02 | tbaldridge | it works "okay" a bit temperamental. But it works fine for storing configs |
| 14:02 | patchwork | last modified 2 years ago as well! |
| 14:02 | tbaldridge | yeah |
| 14:02 | patchwork | same guy too right? |
| 14:02 | patchwork | Interesting |
| 14:02 | tbaldridge | It all depends what you're wanting to do with it. |
| 14:03 | mdrogalis | Yeah, agreed. |
| 14:06 | mdrogalis | tbaldridge: What else would you recommend if you needed CAS but didnt want ZK? |
| 14:07 | tbaldridge | ZK is fine for CAS or configs. I'm just saying I wouldn't recommend storing tons of state in ZK. Which Avout seems to be about (e.g. mapping refs to ZK). |
| 14:08 | mdrogalis | tbaldridge: Yeah, true. |
| 14:08 | mdrogalis | Ah, right. There was a list in that ACID article about which storage engines supported CAS. |
| 14:08 | mdrogalis | More than I expected |
| 14:09 | stuartsierra | The Java ZooKeeper API isn't difficult. |
| 14:09 | dnolen | Om post is up feel free to give it some HN love - https://news.ycombinator.com/newest |
| 14:09 | jcromartie | distributing state just sounds like a bad idea to me |
| 14:09 | jcromartie | so querying the db it is |
| 14:09 | dnolen | also the React 0.8 is worth upvoting they've been super nice |
| 14:10 | mdrogalis | stuartsierra: Agreed. |
| 14:10 | noncom | keywordize-keys works fine on multilevel maps, however, what if at some level there is a record and not a map? the keys do not get keywordied.. anyone knows a way around it? |
| 14:12 | stuartsierra | noncom: There's a patch already applied on Clojure 1.6 that lets `clojure.walk` support records. |
| 14:13 | noncom | stuartsierra: nice! but it is still in alpha.. maybe you could recommend a way to go then? :) |
| 14:13 | stuartsierra | copy-and-paste? |
| 14:14 | stuartsierra | It's open-source, after all. |
| 14:14 | noncom | cool! gonna do it right away! |
| 14:15 | stuartsierra | If you're interested, https://github.com/stuartsierra/clojure.walk2 is more thorough. I've also submitted that as a Clojure patch. |
| 14:15 | jcromartie | so I threw together a fun little thing that runs "tasks" with rollback |
| 14:15 | jcromartie | I am not sure I can open source it yet, gotta get that cleared up |
| 14:15 | jcromartie | but it's for doing things with side effects that may need to be rolled back |
| 14:15 | jcromartie | and it supports vectors and sets as shorthand for sequential and parallel groups of tasks |
| 14:15 | jcromartie | so you can say: (perform [a #{b c d} e]) which will perform a first, then b c and d in parallel, and then e |
| 14:16 | noncom | stuartsierra: thank you, I will looks into the sources |
| 14:16 | mikerod | stuartsierra: I'm a fan of walk2 |
| 14:17 | jcromartie | and, if any of them fail, everything that was completed is rolled back, which for collections means calling rollback on each completed member task |
| 14:17 | yedi | dnolen: how dare you post your own blog post |
| 14:17 | noncom | mikerod: sounds promising :) |
| 14:17 | yedi | i wanted to reap the karma benefits |
| 14:17 | mikerod | The docs say "This repo is for demonstration only." in walk2 |
| 14:18 | jcromartie | to define tasks that can roll back you can specify a map like {:up #() :down #()} or you can defrecord and implement perform/rollback |
| 14:18 | mikerod | However, I've had no issues and do not see any. |
| 14:18 | mikerod | You can even extend the protocol for Java-land Collections |
| 14:20 | noncom | mikerod: will it go to 1.6? |
| 14:21 | stuartsierra | The ticket is http://dev.clojure.org/jira/browse/CLJ-1239 if you want to keep track. |
| 14:23 | bitemyapp | MFW hoplon doesn't use leiningen. |
| 14:24 | bitemyapp | stuartsierra: is that RestFn patch going to get merged? |
| 14:24 | bitemyapp | the one Bloom was championing. |
| 14:24 | stuartsierra | bitemyapp: I don't know |
| 14:24 | mikerod | which patch is this? |
| 14:24 | noncom | yeah, i think it is a ery useful patch |
| 14:25 | noncom | s/ery/very |
| 14:25 | SegFaultAX | How useful? Ery useful. |
| 14:25 | bitemyapp | noprompt: I was thinking about data structures for frak. |
| 14:25 | bitemyapp | noprompt: ever done anything with finger trees or PATRICIA tries? |
| 14:26 | bitemyapp | or rather, for Frak++.hs |
| 14:26 | mikerod | noncom: What is the RestFn patch? Is there an issue related to it? |
| 14:27 | bitemyapp | noprompt: https://github.com/quchen/articles/blob/master/loeb-moeb.md |
| 14:28 | SegFaultAX | Speaking of finger trees... when will we be getting them in Clojure? :) |
| 14:29 | noncom | mikerod: i mean walk2. i do not know anything about RestFn... ? |
| 14:29 | stuartsierra | SegFaultAX: https://github.com/clojure/data.finger-tree |
| 14:29 | mikerod | oh :) |
| 14:29 | mikerod | yes, an ery useful patch indeed. |
| 14:30 | SegFaultAX | stuartsierra: Think it'll ever make it to core? |
| 14:30 | octagon | bitemyapp: you're right, hoplon doesn't use lein! |
| 14:30 | stuartsierra | SegFaultAX: Not unless something in core needs it. We want to make clojure.core smaller, not bigger. |
| 14:31 | bitemyapp | octagon: are you the proud author? |
| 14:32 | bitemyapp | SegFaultAX: finger trees are a bit tedious in a strict language. |
| 14:32 | bitemyapp | stuartsierra: is there a canonical post for ML functors in protocols? I have a utility bag that I'd like to publish for Datomic that would benefit from it. |
| 14:32 | octagon | bitemyapp: i'm Micha |
| 14:32 | stuartsierra | If anyone has a good benchmark that demonstrates a consistent, repeatable performance improvement from the patch on CLJ-1200, I would like to have it. |
| 14:32 | bitemyapp | octagon: I don't know who that is. |
| 14:32 | octagon | bitemyapp: i wrote it with alan dipert |
| 14:33 | octagon | bitemyapp: short answer: yes |
| 14:33 | octagon | bitemyapp: i still use leiningen too |
| 14:33 | jcromartie | I was accidentally running 2 instances of "yes > /dev/null &" which happens to be exactly how they used to recommend maxing out your MacBook and getting it super hot |
| 14:33 | bitemyapp | octagon: hot. |
| 14:33 | octagon | bitemyapp: leiningen just isn't good for some things |
| 14:34 | bitemyapp | octagon: by all means, explain. |
| 14:34 | octagon | bitemyapp: basically, the idea is that tasks could be middleware like in a ring app, instead of plugins, profiles, tasks, and middleware in lein |
| 14:35 | bitemyapp | octagon: leiningen has hooks for that. |
| 14:35 | octagon | bitemyapp: the priority is for boot tasks to be composable |
| 14:35 | octagon | bitemyapp: boot has only one "watch" task, for instance, that you can compose with any other task |
| 14:35 | bitemyapp | octagon: they're designed around the same principle. |
| 14:35 | bitemyapp | octagon: yes, you can do the same in Leiningen. |
| 14:36 | octagon | bitemyapp: we originally made a lein plugin, but it got unworkable pretty fast |
| 14:36 | octagon | bitemyapp: when it had to compose with lein-cljsbuild and various other things |
| 14:37 | bitemyapp | tbaldridge: the edn parsing situation is getting bad enough that we're considering layering an edn protocol on top of JSON. |
| 14:38 | bitemyapp | every little thing is breaking, none of the edn readers/parsers in Python are workable. |
| 14:38 | logic_prog | is there a way to write a websocket _client_ in clojure/java rather than cljs/javascript ? |
| 14:38 | logic_prog | I want to write a _client_ to stress test my websocket server |
| 14:38 | tbaldridge | bitemyapp: seems that a little time with pyparsing or parsley would get you want you want. |
| 14:38 | bitemyapp | logic_prog: yeah, although that'd be weird. |
| 14:38 | bitemyapp | tbaldridge: well, that "little time" is what already exists and those libraries are broken. |
| 14:38 | bitemyapp | tbaldridge: I've been incrementally fixing edn_format but I'm losing my patience with it. |
| 14:38 | jcromartie | logic_prog: you can open as many websockets as you want from JS |
| 14:39 | logic_prog | yeah, but I want to write my testing code in java |
| 14:39 | logic_prog | s/java/clojure |
| 14:39 | noncom | you can use a JS on JVM |
| 14:39 | noncom | :) |
| 14:40 | logic_prog | I would need JVM on JS |
| 14:40 | noncom | you could try using rhino or such.. |
| 14:40 | noncom | yeah, i am mostly joking. it's just that i had the same request some time ago |
| 14:40 | bitemyapp | tbaldridge: the edn spec being wrong combined with the terrible, terrible libraries out there makes using Datomic outside of Clojure incredibly painful. |
| 14:40 | jcromartie | Jetty has a websocket client library |
| 14:41 | jcromartie | http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html |
| 14:41 | bitemyapp | tbaldridge: we've lost a lot of hours to this already. |
| 14:41 | bitemyapp | but the edn spec errors really just digs the knife in. |
| 14:41 | jcromartie | logic_prog: I think that's your answer |
| 14:41 | jcromartie | include require org.eclipse.jetty.websocket/websocket-client in your dev dependencies and test away |
| 14:41 | cespare | Didn't nigel (or was it someone else?) send out a proposal for two-valued math functions (like quo, rem := n / d) a while ago? |
| 14:41 | logic_prog | jcromartie: very nice, thanks |
| 14:42 | cespare | I can't find the thread on golang-dev |
| 14:42 | tbaldridge | bitemyapp: that's the part that I'm wondering about. What spec errors are referring to? And if every single Python lib breaks, I'm wondering why. |
| 14:42 | bitemyapp | tbaldridge: the Python libs break because they're incredibly naive and untested. The edn spec is wrong about what's allowed in a symbol |
| 14:43 | bitemyapp | tbaldridge: and its over-restrictiveness relative to what Clojure actually allows in the implementation breaks code that we needed to actually use with Clojure/Datomic. |
| 14:43 | tbaldridge | what symbols are being sent from Datomic? |
| 14:43 | bitemyapp | I don't really have time for this right now |
| 14:43 | bitemyapp | if the divergence between the edn spec and what Clojure allows isn't disconcerting already, then you're not thinking ahead very far. |
| 14:45 | noprompt | garsh darn internet connection... |
| 14:45 | bitemyapp | noprompt: w/b |
| 14:45 | noprompt | bitemyapp: no sir, i can't say i have. |
| 14:45 | cespare | oops wrong chan, sorry |
| 14:45 | bitemyapp | noprompt: well I was just thinking about the data structures, tries vs. finger trees, that sort of thing - for Frak. |
| 14:45 | bitemyapp | noprompt: also I was pondering a reverse Frak. |
| 14:45 | jcromartie | are there really advantages to "lein ring server" vs just having a main namespace with a fn that starts your app? |
| 14:45 | tbaldridge | I'm just saying, we use stuff like ruby edn quite a lot and haven't had these issues, so I'm wondering what the difference is. For example, Diametric works great with the REST frontend. |
| 14:45 | jcromartie | I really don't like having a top-level handler |
| 14:45 | bitemyapp | jcromartie: no advantages, just more muggle compatible. |
| 14:46 | jcromartie | I see |
| 14:46 | jcromartie | I thought that might be the purpose |
| 14:46 | noprompt | bitemyapp: yeah i've been interested in that as well. ultimately it would be nice to write a regex parser or an api for constructing regex. |
| 14:46 | technomancy | jcromartie: I don't see the point either |
| 14:48 | noprompt | i discovered this week i'm going to be a father. looks like i'll be reading technomancy's blog more often. |
| 14:48 | bitemyapp | noprompt: wat. |
| 14:48 | technomancy | noprompt: oh nice; congrats. |
| 14:48 | bitemyapp | noprompt: congrats |
| 14:48 | TimMc | noprompt: ! |
| 14:49 | noprompt | bitemyapp: yep. i mean unless something goes wrong. |
| 14:50 | TimMc | But chances are you'll have a Little Lisper in a couple years. |
| 14:50 | bitemyapp | Haskeller, if I have my way. |
| 14:50 | bitemyapp | porque no los dos is my motto though. |
| 14:50 | TimMc | "why not both"? |
| 14:51 | technomancy | noprompt: so far I've only done one "parenting" post, but I'm sure there will be more to come. =) |
| 14:51 | technomancy | you've got lots of time to prepare |
| 14:51 | TimMc | Anyway, very exciting. |
| 14:51 | technomancy | (not that you can actually ever be prepared for something like that) |
| 14:52 | bitemyapp | I mean, all you really have to do is not kill the kid. |
| 14:52 | bitemyapp | that's roughly the standard for perpetuation of the species so far. |
| 14:52 | noprompt | technomancy: haha, this is true. you know, when i discovered she was pregnant i flipped out internally. then i saw the ultrasound on tuesday and was happy for some odd reason. |
| 14:52 | arrdem | bitemyapp: good news, I'll be helping you lurk the channel more |
| 14:52 | technomancy | noprompt: yeah it's understandably gut-wrenching |
| 14:52 | jcromartie | "some odd reason" … |
| 14:52 | jcromartie | :P |
| 14:52 | arrdem | bitemyapp: bad news, my hardware startup shut down Q_Q |
| 14:53 | patchwork | noprompt: children rewire your brain. It is evolutionary. |
| 14:53 | dmpayton | noprompt: fwiw, not killing the kid is easier than it looks. kids are pretty resilient. |
| 14:53 | noprompt | bitemyapp: my dad applied similar logic when teaching me how to drive. "the goal is to get the wagon from point a to point b without wrecking." |
| 14:53 | bitemyapp | arrdem: :( |
| 14:53 | bitemyapp | arrdem: sorry to hear that! |
| 14:54 | koalallama | noprompt: congrats |
| 14:54 | bitemyapp | tbaldridge: most promising alternative to edn_format so far is the lispreader from clojure-py. |
| 14:55 | jcromartie | The whole "you don't understand until you have kids" thing is TOTALLY true. It's literally impossible to explain without experiencing it. |
| 14:55 | tbaldridge | bitemyapp: well, we accept patches send one over and I'll merge it. |
| 14:55 | tbaldridge | (inc jcromartie) |
| 14:55 | lazybot | ⇒ 5 |
| 15:00 | jcromartie | what's a good way to mock a service for tests that doesn't depend on dynamic bindings |
| 15:00 | jcromartie | aside from implementing the service with protocols+records |
| 15:00 | jcromartie | and I may have just answered my own question |
| 15:01 | stuartsierra | yes you did |
| 15:01 | danielszmulewicz | noprompt: Secretary and core.async is pretty neat: https://www.refheap.com/22046 |
| 15:01 | noprompt | danielszmulewicz: it's fun stuff. gf3 deserves most of the credit though. :-) |
| 15:03 | noprompt | danielszmulewicz: it'd be great to have clout support cljs so there'd be one unified routing api story. |
| 15:05 | danielszmulewicz | noprompt: Is clout the thing that Compojure uses, or are they separate things? |
| 15:07 | noprompt | danielszmulewicz: yes. clout is what compojure uses for routing. i like it's design. |
| 15:07 | noprompt | danielszmulewicz: i also like the strait forward approach secretary takes too. |
| 15:07 | danielszmulewicz | noprompt: Right. +1 for a unified routing api story. |
| 15:08 | noprompt | danielszmulewicz: the neat idea is potentially being able to reuse routing code on both the server and the client. |
| 15:13 | akhudek | dnolen: your todo app has a bug, if you delete some items then try checking some boxes, the wrong boxes get checked |
| 15:13 | akhudek | dnolen: otherwise, very impressive! |
| 15:14 | danielszmulewicz | Is the todo app going to make it on the README? |
| 15:14 | danielszmulewicz | I mean on the main page of http://todomvc.com/ ? |
| 15:15 | danielszmulewicz | I see a "compile to javascript" section, but no link to Clojure-related technologies... |
| 15:31 | mikerod | I'v read through this https://groups.google.com/forum/#!topic/clojure-dev/9JB-vKjvbhE and then saw hiredman had a gist @ https://gist.github.com/hiredman/921874 . I find this interesting and think I'm being bit by it. |
| 15:32 | mikerod | Is this expected behavior or a defect? |
| 15:39 | noprompt | technomancy: i've been thinking about creating a modifier key which, when held, would allow me to type numbers on the home row. :-_ |
| 15:39 | noprompt | :-) |
| 15:39 | noprompt | the key travel to the actual number keys is too far. |
| 16:06 | technomancy | jcromartie: with-redefs doesn't use dynamic bindings |
| 16:06 | jcromartie | technomancy: thanks |
| 16:07 | jcromartie | I already moved to a protocol though :) |
| 16:07 | technomancy | =( |
| 16:07 | jcromartie | why so sad? |
| 16:07 | jcromartie | you're one of those "just use a map" purists? |
| 16:07 | mikerod | ,(eval (let [c (comp inc inc)] `(~c 1))) |
| 16:08 | clojurebot | #<ExceptionInInitializerError java.lang.ExceptionInInitializerError> |
| 16:08 | mikerod | :( |
| 16:08 | technomancy | not a fan of using protocols for anything other than extreme perf requirements |
| 16:08 | mikerod | ,(eval (let [c (comp inc inc)] (c 1))) |
| 16:08 | clojurebot | 3 |
| 16:08 | technomancy | mikerod: yeah, functions get stripped of unused environment |
| 16:08 | stuartsierra | with-redefs is still dynamic (time) scope. |
| 16:08 | jcromartie | technomancy: I think they also make sense when it comes to external services, where a mock is truly useful sometimes |
| 16:08 | technomancy | otherwise you leak a lot |
| 16:08 | jcromartie | otherwise I prefer standard functions and data |
| 16:09 | jcromartie | what do you mean leak? |
| 16:09 | technomancy | jcromartie: as long as I don't have to maintain it |
| 16:09 | technomancy | jcromartie: Imean they'd have to carry around a bunch of unrelated junk |
| 16:09 | mikerod | technomancy: is there anywhere I could look to understand this more? |
| 16:09 | jcromartie | does with-redefs work across namespaces? |
| 16:10 | technomancy | jcromartie: sure |
| 16:10 | mikerod | I guess I have a fn being AOT compiled that closes over its environment during macroexpansion time |
| 16:10 | technomancy | mikerod: not aware of any docs on the subject. this channel is surely your best resource =) |
| 16:10 | mikerod | I struggle to see a workaround, I was relying on the closure over the surrounding env |
| 16:11 | mikerod | and AOT compilation is necessary |
| 16:11 | technomancy | you can get the closure via the implicit &env arg to macros, but not with functions |
| 16:11 | jcromartie | I see… with-redefs would likely fit the bill |
| 16:11 | technomancy | see my serializable-fn lib |
| 16:11 | jcromartie | I'll keep it in mind in the future |
| 16:13 | mikerod | technomancy: yes, I have seen the &env before hmm |
| 16:14 | mikerod | I'll bang my head against my desk on this one for a bit I guess. :) |
| 16:14 | jcromartie | but then again, with protocols I can have different implementations of the services at the same time, while with-redefs is messing with globals |
| 16:14 | jcromartie | and globals are bad no? |
| 16:14 | technomancy | vars are globals |
| 16:15 | technomancy | as long as the extent of the changes are limited they're certainly easier to follow than protocols |
| 16:16 | jcromartie | yes and changing them for short periods of time seems flaky :) |
| 16:16 | jcromartie | rather than treating them as permanent always-and-forever values |
| 16:16 | jcromartie | I prefer to think of top-level vars in namespaces as constants, with the option of temporary thread-local bindings. with-redefs seems like a pretty heavy hammer. |
| 16:16 | jcromartie | but it works for a unit test |
| 16:16 | zerokarmaleft | at what point does dynamic (time) scope become an issue for with-redefs? |
| 16:17 | jcromartie | if I was running my app from a REPL and I ran my unit tests (which used with-redefs for mocks) it would break the app while the test ran |
| 16:17 | technomancy | I haven't run into any problems with them in practice |
| 16:17 | jcromartie | which while not likely to cause real (as in production server) problems is not great |
| 16:18 | zerokarmaleft | hmm, I can't imagine that disrupting development workflow |
| 16:18 | jcromartie | I can imagine making a mess but I doubt it would really go bad :) |
| 16:18 | technomancy | I would take a bit of yuckiness in tests over making the implementation more complicated simply in order to make it testable any day |
| 16:19 | jcromartie | well, my implementation went from having a ns full of functions operating on a map, to a namespace full of functions operating on a record |
| 16:19 | jcromartie | and you create the record with a constructor function that takes a map |
| 16:19 | technomancy | reloading issues around records are super annoying to track down in repl driven dev |
| 16:19 | jcromartie | yes they are |
| 16:19 | jcromartie | that would be one thing |
| 16:20 | stuartsierra | tools.namespace fixes that |
| 16:21 | jcromartie | but then again if you are depending on with-redefs to mock external services then you have to mock everything that might be called by anything else, whereas providing a mock implementation as a record puts the mock in one tidy package |
| 16:21 | technomancy | even if you save of a record in a one-off def? |
| 16:21 | technomancy | I do that all the time |
| 16:21 | technomancy | *off |
| 16:21 | stuartsierra | don't do that :) |
| 16:21 | technomancy | jcromartie: fixtrues are just functions |
| 16:21 | devinus | is anybody here using OrientDB? |
| 16:21 | stuartsierra | but yes, it will lwork |
| 16:21 | technomancy | stuartsierra: no. |
| 16:22 | technomancy | jcromartie: speaking of "one tidy package" I mean |
| 16:22 | jcromartie | yes |
| 16:22 | technomancy | in fact quite a bit tidier since they are scoped to just the tests |
| 16:23 | jcromartie | so would a reified mock service |
| 16:23 | technomancy | but you've still changed the behaviour of your impl just to support your tests |
| 16:25 | logic_prog | dumbass question: what is the reason, in the context of cljs, why I have to define macros in *.clj files and can't define them in *.cljs files |
| 16:27 | dobry-den | Since Datomic isn't ideal for counters, what would be a simple way to keep track of viewcounts for posts in my database without bringing in something like a Redis dependency? |
| 16:27 | vijaykiran | osnr: http://stackoverflow.com/questions/18381052/why-clojurescript-macros-cant-be-written-in-clojurescript |
| 16:27 | vijaykiran | oops logic_prog ^^ |
| 16:27 | logic_prog | vijaykiran: nice, thanks! |
| 16:27 | dobry-den | The simplest I could think of is an atom that stores a hash-map of post-ids and incs them. And this gets periodically serialized to viewcounts.edn |
| 16:27 | mikerod | technomancy: http://stackoverflow.com/questions/11191992/functions-with-closures-and-eval-in-clojure |
| 16:28 | mikerod | turns out there was already a stack issue on it |
| 16:28 | dobry-den | (I guess I would use an agent, rather) |
| 16:28 | mikerod | that is comforting |
| 16:28 | technomancy | it's not really an eval issue |
| 16:28 | mikerod | mine isn't coming out of eval |
| 16:28 | technomancy | ah, right |
| 16:29 | mikerod | it is the results of a fn call that is called during macro-expansion |
| 16:29 | mikerod | so it is hidden and sneaky, IMO |
| 16:29 | mikerod | I'm not doing this weird eval-syntax-quote thing |
| 16:29 | technomancy | I think I misread your first question |
| 16:30 | mikerod | I have to AOT some Clojure code where a macro, at expansion time, calls a function that returns a map pointing to some anonymous functions that close over their environment |
| 16:31 | mikerod | eh map pointing is wrong, I mean map with anonymous functions as vals |
| 16:41 | jcromartie | somebody help me out… what's that macro that lets you define a name for the intermediate result of a bunch of forms? |
| 16:41 | Profpatsch | Does the repl display the output of called Java classes? |
| 16:41 | jcromartie | like (_ it …) |
| 16:41 | zerokarmaleft | jcromartie: as->? |
| 16:42 | jcromartie | as! |
| 16:42 | jcromartie | where is that? |
| 16:42 | technomancy | Profpatsch: if they print to an outputstream that the repl is hooked up to. |
| 16:43 | jcromartie | zerokarmaleft: that's not in core right? |
| 16:43 | jcromartie | hm, it is |
| 16:43 | technomancy | not sure which repls reset System/out for you |
| 16:43 | zerokarmaleft | jcromartie: i think so |
| 16:43 | Profpatsch | technomancy: stdout, stderr? |
| 16:43 | zerokarmaleft | jcromartie: rather, I think it *is* in core |
| 16:43 | jcromartie | I couldn't find it in clojuredocs or google |
| 16:43 | technomancy | Profpatsch: you can try writing to System/out to check for yourself |
| 16:44 | maravillas | it's newer than clojuredocs has |
| 16:45 | Profpatsch | technomancy: Nope, (.println System/out "foobar") does nothing. |
| 16:45 | Profpatsch | How to hook it up then? |
| 16:45 | technomancy | Profpatsch: technically it probably went somewhere you're just not looking |
| 16:45 | technomancy | there's something like a System/setOut maybe? |
| 16:46 | technomancy | been a while |
| 16:46 | Profpatsch | technomancy: Huh, aren’t you doing any Java interop? |
| 16:46 | technomancy | not doing much of anything these days |
| 16:48 | Profpatsch | Huh, too much maintaining leiningen? |
| 16:48 | technomancy | well, that sounds bad. I am not doing much clojure, but I am learning a hell of a lot. |
| 16:49 | technomancy | no, Leiningen is just really stable and mature |
| 16:49 | technomancy | https://github.com/heroku/logplex/pull/71 <- this whole week |
| 16:50 | technomancy | I am using records, and they are terrible! |
| 16:50 | technomancy | (erlang records, but still) |
| 16:50 | Profpatsch | Huh, Erlang. Not something you program everyday. |
| 16:51 | Profpatsch | Especially at work. |
| 16:51 | mikerod | technomancy: https://gist.github.com/mrrodriguez/8046814 |
| 16:51 | mikerod | in case you had any interest, this is what I was eluding to |
| 16:51 | mikerod | just some dummy fn and macro combination to demonstrate |
| 16:52 | mikerod | I'm open to anyone else's insight on this issue as well :) |
| 16:53 | arubin | Interesting. IRCCloud displays gists inline. |
| 16:54 | bitemyapp | arubin: that's pretty appealing. |
| 16:54 | technomancy | mikerod: not really sure what you're intending there. wouldn't expect that to work. |
| 16:54 | bitemyapp | I also like my macro images to be inlined. |
| 16:54 | Profpatsch | Hm, not even (with-out-str) works for grabbing stdout in the repl … |
| 16:54 | technomancy | bitemyapp: you must trust your co-workers more than I do |
| 16:55 | technomancy | Profpatsch: with-out-str operates on *out*, not System/out |
| 16:56 | mikerod | I don't know why you wouldn't expect it to work. It is a very simplified case. |
| 16:56 | mikerod | *though |
| 16:57 | technomancy | you have a macro that returns a function object instead of a list that compiles to a function |
| 16:58 | mikerod | In the case 2 example; I want the macro to return a map that has keys -> fn objects |
| 16:59 | bitemyapp | technomancy: my coworkers are boring enough that I wouldn't worry. I'm the crazy one, remember? |
| 16:59 | mikerod | so making fn objects during macro-expansion and returning them = bad |
| 16:59 | technomancy | bitemyapp: it'll rub off on them eventually |
| 17:00 | bitemyapp | >:) |
| 17:01 | technomancy | mikerod: well the return value of the macro gets fed to the compiler |
| 17:02 | mikerod | I added a comment on the gist, where I did macroexpand-1 (to see what feeds to the compiler) ;= {:f #<user$get_map_of_fn$fn__10283 user$get_map_of_fn$fn__10283@7321803a>} |
| 17:02 | mikerod | And that fails |
| 17:02 | mikerod | with the function having the closure |
| 17:03 | mikerod | I guess I can (try) to see that this is bad |
| 17:04 | zerokarmaleft | technomancy: how would you recommend tracing execution of hook-fns added via robert-hooke? |
| 17:04 | technomancy | zerokarmaleft: if they're vars then c.t.trace should just work |
| 17:04 | zerokarmaleft | tools.trace seems to break at the point of the hook |
| 17:05 | technomancy | on the hooked var or the hook? |
| 17:05 | bitemyapp | clojure-py is pretty cool, if anyone has a need for something like that. |
| 17:06 | zerokarmaleft | technomancy: the hook itself |
| 17:06 | technomancy | hm; sorry, I don't know |
| 17:08 | pdk | , (macroexpand-1 (-> 1 2 3 4)) |
| 17:08 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 17:08 | pdk | welp |
| 17:08 | Profpatsch | technomancy: *out* should default to System/out, but *out* is a PrintWriter and System/out is a PrintStream in my repl |
| 17:09 | Profpatsch | Can I redirect System/out to the *out* PrintWriter somehow? |
| 17:09 | mikerod | ,(macroexpand-1 '(-> 1 2 3 4)) |
| 17:09 | clojurebot | (4 (3 (2 1))) |
| 17:09 | Profpatsch | Locally if possible. |
| 17:10 | mikerod | I'm not sure why clojurebot just fully expanded that macro |
| 17:10 | mikerod | pdk: You have to quote the form passed to macroexpand-1 |
| 17:10 | AeroNotix | kind of new to clojure -- can I use leiningen to find local applications/libraries? Ala $GOPATH or $PYTHONPATH or w/e? |
| 17:10 | mikerod | unless it will be evaluated |
| 17:12 | justin_smith | AeroNotix: lein finds remote deps and installs them to a local archive, you can use lein install to add something to the local archive manually |
| 17:13 | bitemyapp | AeroNotix: ls -alh ~/.m2/ |
| 17:13 | AeroNotix | justin_smith: say like I am developing a project locally and I also locally develop a library for it. Does it need to be a remote dependency too? |
| 17:14 | justin_smith | AeroNotix: no, you can use lein install to make it available locally |
| 17:14 | justin_smith | and lein uberjar to pack it up with the rest |
| 17:14 | justin_smith | but it can be convenient to put it on clojars |
| 17:15 | AeroNotix | hmm, with quicklisp for common lisp you can do this. There's a directory which it scans for quicklisp enabled projects. Anythign like this with leiningen? |
| 17:15 | technomancy | AeroNotix: lein is more focused on ensuring everything works on a fresh checkout out of the box |
| 17:16 | AeroNotix | technomancy: what does that mean in this situation? |
| 17:16 | AeroNotix | QuickLisp works fine |
| 17:16 | technomancy | you can add optimizations for local dev, but that's a step you do after correctly declaring things in :dependencies |
| 17:16 | justin_smith | AeroNotix: it works fine on whose box and after finding the deps how? |
| 17:17 | AeroNotix | justin_smith: quicklisp is a managed set of repositories. There's an index which lists where dependencies live. (ql:quickload :project-name) then walks the dependencies and grabs them all. |
| 17:17 | technomancy | from what I've heard about $GOPATH, "works fine" is not really a good description |
| 17:18 | AeroNotix | Perhaps using it would be a better way to form an opinion. |
| 17:18 | justin_smith | AeroNotix: so if I had a checkout of your source project, that is all I would need? or would I need to go download a bunch of libraries by hand? |
| 17:18 | AeroNotix | justin_smith: you need to have a quicklisp enabled system, yes. But that's similar to needing to have lein installed. |
| 17:18 | technomancy | hopefully that will never be necessary |
| 17:18 | AeroNotix | technomancy: what wouldn't be necessary? |
| 17:19 | technomancy | being forced to write go at work |
| 17:19 | AeroNotix | I'm not getting into that conversation. You're arbitrary beef is your arbitrary beef. |
| 17:19 | AeroNotix | It's a language which Clojure itself ripped off to good effect. Not sure where the problem is but whatevs. |
| 17:19 | AeroNotix | You disliking it still doesn't make me understand lein any better. |
| 17:20 | technomancy | I've made an explicit choice to avoid the slopiness around go's dependency handling |
| 17:20 | AeroNotix | I don't care. I think I made that clear :) |
| 17:20 | justin_smith | AeroNotix: lein is a dpendency manager, it doesn't use a path, instead it uses mvn project coordinates for each project so versions can be installed in parallel |
| 17:20 | AeroNotix | justin_smith: I see. |
| 17:20 | technomancy | projects should declare everything they need in order to function |
| 17:21 | AeroNotix | technomancy: cool. |
| 17:21 | AeroNotix | justin_smith: Do I need to understand mvn to use lein? |
| 17:21 | technomancy | if it's not declared in project.clj, it doesn't exist, basically |
| 17:21 | AeroNotix | technomancy: cool. |
| 17:21 | justin_smith | AeroNotix: lein generates a specific path for each artifact you need based on your dependency delcarations, and the recursive declarations generated for that |
| 17:21 | justin_smith | AeroNotix: you won't need to understand mvn |
| 17:21 | AeroNotix | (fwiw you demonstrably do not understand go's dependency tracking, technomancy but we'll leave it at that.) |
| 17:22 | technomancy | not worried, there is a huge pile of other reasons to avoid it |
| 17:22 | AeroNotix | justin_smith: so how do local projects come into this? Are there some docs somewhere about that? I looked at some SO answers and it looked like there were some specific flags for local paths |
| 17:22 | AeroNotix | technomancy: cool. |
| 17:22 | justin_smith | AeroNotix: as I said, lein install will put the project in the current directory into the local repo cache |
| 17:23 | justin_smith | then another project can declare a dep in order to find it |
| 17:23 | AeroNotix | justin_smith: OHHHH! |
| 17:23 | AeroNotix | justin_smith: I get it, I get it |
| 17:23 | justin_smith | how many times did I say "lein install" ? |
| 17:23 | AeroNotix | justin_smith: sorry, this is new to me |
| 17:23 | technomancy | so you have two projects, right? one of them is a lib? if you can put it on clojars, that will make things much easier. |
| 17:23 | AeroNotix | technomancy: baby steps |
| 17:23 | AeroNotix | also, it may not be public code. |
| 17:24 | justin_smith | AeroNotix: a difference is that every dependency is versioned |
| 17:24 | justin_smith | that is actually a huge benefit |
| 17:24 | pdk | , (macroexpand-1 '(-> 1 2))) |
| 17:24 | clojurebot | (2 1) |
| 17:24 | pdk | , (macroexpand-1 '(-> 1 2 3)) |
| 17:24 | clojurebot | (3 (2 1)) |
| 17:24 | technomancy | yeah lein is secretly an attempt to convince everyone to OSS their libs by making private repos a hassle. you heard it here first. =) |
| 17:25 | AeroNotix | technomancy: cool. |
| 17:25 | akhudek | AeroNotix: it's trivial to just locally install libraries for local dev |
| 17:25 | akhudek | AeroNotix: we do it all the time |
| 17:26 | justin_smith | akhudek: he may even know the command to do that by now |
| 17:26 | AeroNotix | justin_smith: :) |
| 17:28 | AeroNotix | hmm this is pretty cool |
| 17:29 | mikerod | technomancy: you will make Richard Stallman proud |
| 17:29 | justin_smith | AeroNotix: the ability to select versions without having to uninstall anything or manually set a path is pretty nice, I am spoiled for other environments at this point |
| 17:30 | AeroNotix | isn't this just re-using java machinery? |
| 17:30 | AeroNotix | e.g. mvn |
| 17:30 | justin_smith | yes, but edn instead of xml is a nice bonus |
| 17:30 | justin_smith | and it is more succinct |
| 17:30 | hyPiRion | well, clojure, rather. |
| 17:31 | Bronsa | mikerod: you will make RMS mad at you for confusing Open Source with Free Software |
| 17:31 | technomancy | mikerod: it's the least I could do after the whole "writing Emacs" thing. |
| 17:31 | justin_smith | AeroNotix: I am not saying no other language has it, but from what I have seen none has it quite as simple |
| 17:31 | AeroNotix | cool ok |
| 17:31 | mikerod | that's true, way to give back |
| 17:32 | mikerod | or perhaps it is pay it forward |
| 17:32 | technomancy | npm has a neat thing where you can trivially isolate dependency trees due to the way js modules work |
| 17:32 | technomancy | you can't do that for java since packages aren't first-class |
| 17:32 | TimMc | Bronsa: Not even that; you could still have binary blobs in a public place without having the source there. |
| 17:32 | technomancy | and doing it for clojure without doing it for java is kinda pointless =\ |
| 17:35 | technomancy | AeroNotix: but yeah, maven built some very good foundations we're sitting upon. not too keen on how their builds work, but their repo infrastructure is great. |
| 17:35 | AeroNotix | technomancy: cool |
| 17:36 | technomancy | I admit I would have made several design mistakes due to my rubygems background if some of those decisions hadn't already been made for me. =) |
| 17:36 | akhudek | the only thing that would make mvn better would be the ability to use multiple version of one library in one project |
| 17:37 | technomancy | akhudek: it's not really Maven's faund that Java packages are half-assed tohugh |
| 17:37 | akhudek | very true |
| 17:37 | TimMc | akhudek: I suspect that was omitted because Java doesn't generally allow for that. |
| 17:37 | technomancy | fault |
| 17:37 | technomancy | geez, my fingers |
| 17:37 | TimMc | Even though Maven "isn't just for Java". |
| 17:38 | AeroNotix | so let's say I just `lein install'd something. I fire up a repl, will it be able to access that repo? Or does it need `lein repl'? |
| 17:38 | technomancy | TimMc: well, that brokenness is baked in pretty deep |
| 17:38 | justin_smith | AeroNotix: with alembic or pomegranate it can find and load that lib |
| 17:38 | justin_smith | AeroNotix: but it is often easier to make a project.clj that declares the dep |
| 17:39 | AeroNotix | and *then* `lein repl' in the other project? |
| 17:39 | technomancy | AeroNotix: tl;dr: no, but if the project.clj hasn't changed you can use lein's checkout-deps feature to pick up changes in a library's working copy without restarting the repl |
| 17:39 | justin_smith | right, then require the dep |
| 17:39 | technomancy | (assuming you've already added it to :dependencies) |
| 17:39 | justin_smith | https://github.com/pallet/alembic |
| 17:39 | AeroNotix | cool, ok |
| 17:40 | AeroNotix | so basically, I can't just fire up a REPL and find the local cache of stuff without some third-party things. |
| 17:40 | AeroNotix | ala Python REPLs |
| 17:40 | technomancy | `lein help faq` tells you about checkout deps |
| 17:40 | AeroNotix | reading |
| 17:40 | technomancy | ...I think |
| 17:41 | justin_smith | technomancy: I think he is just asking about finding something in a repl after a lein install |
| 17:41 | justin_smith | unless I misunderstand |
| 17:41 | AeroNotix | that's correct justin_smith |
| 17:41 | Profpatsch | technomancy: I guess I have to redefine System.out to *out*. However, System/out is static. Is there a way to redefine that in Clojure? |
| 17:42 | justin_smith | AeroNotix: I think technomancy was trying to tell you how to do something more complex |
| 17:42 | AeroNotix | probably |
| 17:42 | technomancy | checkout deps confuse everyone, so I was pre-emptively over-explaining |
| 17:43 | technomancy | Profpatsch: not sure off the top of my head, but you're on the right track it sounds like |
| 17:43 | AeroNotix | I just want to have a project of code which I import via the repl.. can it be done? |
| 17:44 | technomancy | just do the `lein install; restart the repl` thing till you get the hang of that |
| 17:44 | technomancy | then once you get tired of having to restart the repl, read up on cehckout deps |
| 17:44 | AeroNotix | so when I `lein install' ALL repls have access to this via the local cache? |
| 17:45 | justin_smith | if it is referenced in project.clj or you use alembic or the like, yes |
| 17:45 | AeroNotix | ok. So not just any random repl |
| 17:45 | technomancy | `lein install` means "put this in the local repo" |
| 17:45 | technomancy | so it means that any project on your machine can declare it in project.clj |
| 17:46 | technomancy | as if it were a published dependency on clojars or whatever |
| 17:46 | justin_smith | AeroNotix: a key here is there is no implicit dependency (though there is recursive dependency). Every dependency is declared somewhere. |
| 17:46 | AeroNotix | hmm |
| 17:46 | justin_smith | AeroNotix: though there are workarounds like adding deps to profiles.clj if you want it in every repl |
| 17:46 | bitemyapp | yeah so if you want to use Datomic with Python, seriously consider clojure-py. |
| 17:47 | justin_smith | or as I mentioned there are libs that find and resolve and import deps at runtime |
| 17:47 | AeroNotix | ok thanks |
| 17:52 | AeroNotix | ahaaaa, I got it. |
| 17:53 | AeroNotix | so, if I wanted to. I could use profiles.clj to have a similar workflow to what I get in other languages (a global set of repositories) by dynamically adding the deps in the profiles.clj |
| 17:53 | AeroNotix | whilst also maintaining dependency happiness with the project's project.clj |
| 17:55 | technomancy | yeah, typically you would do that with dev tools that the project doesn't actually depend on |
| 17:55 | justin_smith | AeroNotix: well I would do it by adding a dep on alembic to profiles.clj |
| 17:55 | justin_smith | AeroNotix: but only finding deps explicitly is a huge benefit |
| 17:55 | technomancy | profilers, debuggers, refactoring tools, etc |
| 17:55 | justin_smith | AeroNotix: it makes deployment and sharing code much simpler |
| 17:56 | AeroNotix | justin_smith: if the dependencies are listed properly with project.clj how does that affect things if profiles.clj also has dependencies. Do the deps in profiles.clj get included, too? |
| 17:57 | justin_smith | AeroNotix: only one version of a dep will be pulled in, project.clj should override profiles.clj |
| 17:57 | justin_smith | they are merged |
| 17:57 | technomancy | the lists get merged. if there's overlap it can be problematic though. |
| 17:57 | technomancy | you can see the full thing with `lein deps :tree` |
| 17:57 | AeroNotix | ohh, I thought the profiles.clj dependencies were separate. |
| 17:58 | technomancy | `lein with-profile production deps :tree` for the "pristine" deps |
| 17:58 | AeroNotix | thanks all |
| 18:14 | jcromartie | alright technomancy: you've convinced me |
| 18:15 | technomancy | cool; your next mission is to use clojure.core/when for side-effects, not just for when you have a single-branch condition |
| 18:16 | bitemyapp | ooooohhhh monad comprehensions |
| 18:16 | AeroNotix | nice using # in macros for gensym. Nice touch |
| 18:16 | bitemyapp | technomancy: monad comprehensions would be nice in OCaml Async. |
| 18:25 | technomancy | I believe you but don't know what to do with this knowledge. |
| 18:25 | bitemyapp | technomancy: hum. Does OCaml have list comprehensions? |
| 18:25 | bitemyapp | the syntax in Haskell is repurposeable. |
| 18:26 | technomancy | not sure; I always just use map/iter |
| 18:26 | bitemyapp | yeah but I mean generalizing to monads |
| 18:27 | technomancy | dunno; I've only ever used two monads on purpose, and one of them was called "The GitHub Monad" |
| 18:28 | shep-home | After watching http://vimeo.com/68383317, my interest in quickcheck and friends is renewed |
| 18:28 | shep-home | mostly because I realized that my generated data can be a sequence of functions that are applied to an initial state |
| 18:29 | shep-home | which led me to try it out. It works, but I was less-than-enthused with the output from failing cases |
| 18:29 | shep-home | Is there some better string representation of functions that would help me here? |
| 18:29 | shep-home | Or perhaps some tweak to simple-check? |
| 18:30 | akurilin | Oh man, exciting day in clojureland today. |
| 18:30 | akurilin | Great post there dnolen . |
| 18:30 | shep-home | For example, ":smallest [1 (#<core$partial$fn__4190 clojure.core$partial$fn__4190@71a40dde>)]" is not helping me narrow down the problem i have introduced |
| 18:37 | edw | Hey guys, I pushed a little library in Clojure that allows folks to use etcd for configuration using the same interface they'd normally access environment variables, making development and deployment of Clojure apps on CoreOS simpler. <https://github.com/edw/scallion> |
| 18:39 | pdk | tonight is a mini accomplishment |
| 18:39 | pdk | ported -> and ->> to common without them overflowing stack or giving stupid results |
| 18:43 | devn | dnolen: the link to "Source" in your TODOMvc clone points at tastejs's github repo |
| 18:44 | devn | Just an FYI |
| 18:47 | logic_prog | do atoms have almost no overhead in cljs because javascript is single threaded? |
| 18:52 | edw | logic_prog: One would hope that you're mostly deref-ing atoms and not modifying them. It's probably the difference between writing "x + 1" and "x[0] + 1" in terms of time and space. |
| 18:53 | logic_prog | I need to have a global queue |
| 18:53 | logic_prog | I'm using (atom []) to simulate it |
| 18:53 | logic_prog | should I be doing something else? |
| 18:53 | edw | Been there. |
| 18:53 | logic_prog | I was goign to use core.async, ... but core.async has a limit on # of elements on the chan |
| 18:53 | logic_prog | edw: what did you end up doing? |
| 18:53 | logic_prog | also, I have no idea the difference between "x+1" and "x[0]+1" |
| 18:54 | edw | Probably quite small. |
| 18:54 | logic_prog | doesn't x+1 and x[0]+1 mean semantically different thigns |
| 18:54 | logic_prog | when x is a vector? |
| 18:55 | edw | logic_prog: Yeah. In the first case, x would be your queue, in the second, x is an array, the first and only element of which is your queue. |
| 18:56 | weavejester | Does anyone know if there are any issues with using Austin with the latests Clojurescript/ |
| 18:57 | edw | I'm very unfamiliar with the performance promises (if any) that JS runtimes give you about performance of adding or deleted single items from the front and/or back of an array. I'd think you could just use pop(), push(), shift(), and unshift() JS methods directly. |
| 18:57 | weavejester | Ah, actually, looking at the source code I might be missing a configuration option |
| 19:01 | weavejester | Hm, that didn't work either... |
| 19:02 | weavejester | Is anyone using anything other than Austin for cljs REPLs? |
| 19:03 | shep-home | reiddraper: https://gist.github.com/shepmaster/8048392 -- an example of the output that I am getting with simple-check |
| 19:03 | shep-home | Pretty nice tool :-) |
| 19:03 | shep-home | Thanks for your work on it! |
| 19:05 | justin_smith | shep-home: one thing that often helps is using named anonymous functions when possible. This comes up with trying to decipher stacktraces too |
| 19:07 | bitemyapp | weavejester: what's your impression of Hoplon so far? |
| 19:08 | weavejester | bitemyapp: I'd hesitate to offer an opinion as I'm not that well-versed in ClojureScript dev as yet. |
| 19:08 | bitemyapp | weavejester: I'm a little more so, I'm trying to figure out if it's solving the two-way binding problem or something bigger than that. |
| 19:08 | bitemyapp | I need to get noprompt to look at this. |
| 19:08 | weavejester | I'm still trying to set up a cljs environment for my first cljs library :) |
| 19:09 | noprompt | what's? |
| 19:09 | bitemyapp | so far it looks like it's eval + two-way binding + stateful vars getting smashed over and over. |
| 19:09 | bitemyapp | noprompt: http://hoplon.io |
| 19:09 | weavejester | Without much luck, I might add... |
| 19:09 | bitemyapp | no event stream/core.async/FRP though. |
| 19:09 | noprompt | bitemyapp: oh yes, i've seen this. a while back. |
| 19:09 | bitemyapp | noprompt: are my impressions accurate? |
| 19:09 | bitemyapp | DOM event streams smashing var state? |
| 19:09 | weavejester | I'm unable to get a REPL up that can load in any code. And I get weird warning messages. |
| 19:10 | noprompt | bitemyapp: i haven't looked at the code however. |
| 19:11 | reiddraper | shep-home: yeah, you definitely bring up a good point, and some custom output for when a test fails is on the roadmap. you wanna file an issue about it so it can be public? |
| 19:11 | weavejester | Does anyone happen to have an example of a working cljs environment with a REPL? |
| 19:11 | bitemyapp | weavejester: https://github.com/swannodette/mies |
| 19:12 | technomancy | it's really distressing that people are asking that question in what is nearly 2014 =\ |
| 19:12 | weavejester | bitemyapp: I can get that far, but I can't get a good REPL working. |
| 19:13 | bitemyapp | technomancy: more distressing that those best positioned to solve the problem have made a habit of denying there's a problem. |
| 19:13 | weavejester | So "lein trampoline cljsbuild repl" works |
| 19:13 | weavejester | But I was trying to use something tied in with nREPL |
| 19:13 | bitemyapp | weavejester: getting brepl/austin REPL working is a "building your lightsaber" rite of passage for CLJS. |
| 19:13 | technomancy | especially coming from someone who has been doing clojure web programming since before I even heard of clojure |
| 19:13 | weavejester | Like piggyback or austin |
| 19:13 | weavejester | I do feel very much like a newcomer to cljs :) |
| 19:14 | bitemyapp | weavejester: https://github.com/cemerick/austin/tree/master/browser-connected-repl-sample this is the example project for austin. |
| 19:14 | weavejester | Ironically I've avoided it for so long precisely because it seemed so hard to set up and so tricky to debug. |
| 19:14 | bitemyapp | the debugging story is better than Clojure once you actually get it working |
| 19:14 | shep-home | justin_smith: good call. Unfortunately, it doesn't help that much. Also, I'd really like to have the arguments included |
| 19:14 | bitemyapp | spoiled bastards have a stepping debugger. |
| 19:14 | weavejester | bitemyapp: Yeah, I've looked at that, too. But I can't get the (ns blah (:require ...)) |
| 19:14 | weavejester | to work |
| 19:15 | shep-home | reiddraper: can do. You want an issue for the generic (custom output) or the specific (partial functions)? |
| 19:16 | reiddraper | shep-home: custom output please, not sure there is much we can do for printing functions. but feel free to motivate with that specific case |
| 19:16 | weavejester | Austin also gives a strange warning: "WARNING: Symbol IDeref is not a protocol" |
| 19:16 | shep-home | Yup |
| 19:16 | weavejester | Which isn't present when I run the REPL through Rhino |
| 19:17 | bitemyapp | weavejester: can mostly ignore the warning IIRC |
| 19:17 | justin_smith | shep-home: well (fn invert [x & args] (apply - x args)) will print more readably than #(partial - %) and does the same thing |
| 19:17 | weavejester | bitemyapp: Oh, okay |
| 19:17 | justin_smith | invert is a terrible name for it though |
| 19:17 | bitemyapp | weavejester: what's the actual error/problem? |
| 19:18 | weavejester | bitemyapp: I'll just gist it... |
| 19:18 | bitemyapp | eggscellent. |
| 19:18 | weavejester | bitemyapp: https://gist.github.com/weavejester/8048564 |
| 19:19 | weavejester | Maybe it's because I'm not using "src" for my cljs? |
| 19:19 | weavejester | Except the warning implies it did load it up. |
| 19:20 | bitemyapp | weavejester: lein-cljsbuild has special source dir / prefix parameters. |
| 19:20 | bitemyapp | weavejester: you need to specify them so it knows where to find your namespaces. |
| 19:20 | bitemyapp | fair warning: I write clojurescript approximately once a month. I've actually written more clojure-py than CLJS in the last 30 day interval. |
| 19:21 | weavejester | bitemyapp: Oh, cljsbuild works fine. Let me show you the branch |
| 19:21 | weavejester | https://github.com/weavejester/reagi/tree/clojurescript |
| 19:21 | bitemyapp | weavejester: "works fine" is relative, you could be working with a brepl that doesn't have your namespaces rolled in. |
| 19:22 | weavejester | bitemyapp: Well, what I mean is that it compiles and works with "lein trampoline cljsbuild repl" |
| 19:22 | weavejester | Actually, let me just double-check that. |
| 19:22 | bitemyapp | weavejester: well, normally it wouldn't matter, but yeah, IDeref isn't a protocol. |
| 19:23 | weavejester | bitemyapp: what is it? |
| 19:23 | weavejester | I know in Clojure it's an interface. |
| 19:24 | weavejester | But in cljs? |
| 19:24 | bitemyapp | weavejester: do something for me first, unfuck that code long enough to test accessing your namespace as if it was a dumb one with a hello-world inside of it |
| 19:24 | bitemyapp | weavejester: get that working first, then we can broach the subject of your deftype. |
| 19:25 | bitemyapp | one thing at a time. |
| 19:25 | bitemyapp | (defn muh-fn [] (println "lol")) |
| 19:25 | weavejester | Okay - hang on, rhino-repl is still loading. |
| 19:25 | bitemyapp | I want to get your namespace loading and working in Austin. |
| 19:26 | bitemyapp | since that's the workflow you'd most likely want to work with long term. |
| 19:26 | weavejester | Yeah. |
| 19:26 | bitemyapp | when you mentioned the warning, I thought it was those generic ones you get sometimes when firing up a CLJS repl, I didn't know you were depending on that actual behavior in your code. |
| 19:26 | weavejester | Confirmed it all works fine with rhino-repl |
| 19:27 | weavejester | Yeah, I assumed IDeref was a protocol, since: https://github.com/weavejester/reagi/tree/clojurescript |
| 19:27 | bitemyapp | k, comment out the deftype/protocol crap |
| 19:27 | weavejester | Oops, I mean: https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L274 |
| 19:27 | bitemyapp | try calling a hello-world fn from your namespace in austin |
| 19:27 | bitemyapp | weavejester: In CLJS-land, nothing is true and everything is permitted. |
| 19:28 | weavejester | Okay |
| 19:28 | weavejester | Just got one function now: (defn hello [] "Hello world") |
| 19:28 | bitemyapp | perfekt. |
| 19:28 | bitemyapp | and requiring + invoking does? |
| 19:29 | weavejester | Just checking. Wiped my out and target dirs, starting up lein repl |
| 19:31 | bitemyapp | weavejester: in case you end up needing this information, I've started using clojure-py at work and it's pretty credible. |
| 19:33 | weavejester | bitemyapp: https://gist.github.com/weavejester/8048656 |
| 19:33 | weavejester | No joy |
| 19:33 | weavejester | Same error as before |
| 19:34 | shep-home | reiddraper: done, thanks! https://github.com/reiddraper/simple-check/issues/45 |
| 19:34 | weavejester | I'll try wiping out .repl, then restart. See if it's something wrong with temporary files left around. |
| 19:35 | shep-home | Now that I've done the hard part of creating the issue, I've no doubt it will be fixed soon :-) |
| 19:37 | shep-home | justin_smith: is there a way I can do (fn (...construct-a-name...) []) ? |
| 19:39 | reiddraper | @shep-home much appreciated |
| 19:40 | weavejester | Nope, same problem |
| 19:41 | weavejester | Although there's no sign of my function in "out" or ".repl" |
| 19:41 | Raynes | shep-home: You'd need a macro for that. |
| 19:41 | weavejester | cljsbuild compiled it correctly into "target/main.js" |
| 19:41 | weavejester | But I don't know how Austin knows about that. |
| 19:41 | bitemyapp | weavejester: nuts. |
| 19:43 | weavejester | bitemyapp: Maybe Austin assumes a source path of src/cljs ? |
| 19:43 | shep-home | Raynes: yeah, I found a mailing list post and was skimming through that. Thanks! |
| 19:43 | bitemyapp | weavejester: I think it only cares about the build artifact from cljsbuild. |
| 19:44 | weavejester | bitemyapp: But how does it know where cljsbuild put it? |
| 19:44 | bitemyapp | weavejester: why isn't austin in your profile plugins? |
| 19:44 | bitemyapp | weavejester: also set optimizations to simple |
| 19:45 | weavejester | bitemyapp: Well, it wouldn't make any difference if it was in profile plugins or at the top level. |
| 19:53 | weavejester | bitemyapp: setting optimizations to simple doesn't work. I'm taking the config from the sample app directly now. Then I'll try changing directories. |
| 20:03 | Bronsa | technomancy: ping |
| 20:06 | weavejester | Hm, now my system is dying. brb |
| 20:07 | technomancy | Bronsa: hi |
| 20:09 | Bronsa | technomancy: hi :), I'm trying a branch of tools.analyzer.jvm which requires core.memoize 0.5.6, unfortunately when I try to use "lein eastwood" (a linter that now uses t.analyzer) it crashes because it looks like an older version of core.cache than what core.memoize 0.5.6 needs is in leiningen's process |
| 20:11 | technomancy | Bronsa: huh, so the analyzer doesn't run in project-space? |
| 20:12 | Bronsa | technomancy: I'm.. not really familiar with how plugins work in leiningen, are you saying I should look at the dependency issue in eastwood's dependencies? |
| 20:14 | technomancy | we can bump the version in Leiningen, but I don't have any plans to cut a release in the near future. doing as much as possible in the project's JVM isolates you from problems lik ethis though. |
| 20:14 | technomancy | I guess the analyzer doesn't need to actually eval any code or access any dependencies? |
| 20:15 | technomancy | so technically it could run in either (modulo dependency conflicts) |
| 20:15 | technomancy | and running inside Leiningen's own process is certainly faster |
| 20:17 | Bronsa | hm, ok so removing the :eval-in-leiningen true solved the issuse, I guess we'll go with that for now |
| 20:18 | technomancy | oh, I see. eastwood uses eval-in-project, but for plugin projects that's not going to help? |
| 20:22 | Bronsa | technomancy: I honestly have no idea on how leiningen plugins works and what the eastwood one does. I'll let Andy or jonase handle this, sorry for bothering you |
| 20:23 | technomancy | I would definitely recommend removing :eval-in-leiningen unless you are writing a plugin. |
| 20:24 | Bronsa | technomancy: eastwood is a plugin |
| 20:25 | technomancy | oh I see; the plugin needs the analyzer; you're not hacking on the analyzer itself |
| 20:26 | technomancy | yeah, it is pretty silly that Leiningen pulls in core.cache just for its templating engine, which is pretty much guaranteed to not need it =\ |
| 20:27 | weavejester | Hum, I'm giving up on trying to get ClojureScript to work for now. |
| 20:28 | weavejester | I'll need to ask how people actually develop in ClojureScript on the mailing list. It's not nearly as straightforward as Clojure. |
| 20:31 | technomancy | Bronsa: feel free to inc: https://github.com/davidsantiago/stencil/issues/18 =) |
| 20:31 | logic_prog | argh |
| 20:31 | logic_prog | how do I do macro expansion in cljs? |
| 20:32 | logic_prog | im getting errors of not ffinding cljs.compiler and cljs.analyzer |
| 20:32 | Bronsa | technomancy: one-upped, thanks |
| 20:32 | technomancy | Bronsa: I'm sure the debian folks would love that too |
| 20:33 | Bronsa | technomancy: are they packaging lein? |
| 20:33 | technomancy | yeah, they are pretty close to getting 2.x into sid it sounds like |
| 20:34 | Bronsa | That made me die a little inside |
| 20:36 | technomancy | the fact that it currently ships 1.x? |
| 20:36 | technomancy | apparently there was a ton of cleanup they had to do |
| 20:37 | technomancy | lots of projects that don't ship with license files; some with internally inconsistent licensing |
| 20:39 | weavejester | AHA! |
| 20:40 | weavejester | The undocumented configuration option I was missing was to set the :source-paths to Clojure and ClojureScript |
| 20:40 | weavejester | :source-paths ["src" "src-cljs"] |
| 20:51 | technomancy | it doesn't let you put them both in src/? |
| 20:52 | hiredman | technomancy: you can |
| 20:54 | hiredman | he isn't clear about the option though, because while lein has a :source-path(s) so does cljsbuild |
| 20:54 | hiredman | not sure how or if they overlap |
| 20:54 | hiredman | cljsbuild's is certainly mentioned in the readme too |
| 21:39 | seangrove | What's the difference between :foreign-libs and :preamble for cljsbuild? |
| 21:50 | OldTree | Hi, clojure-noob here, was reading through source of "juxt" when I saw "reduce1." (doc reduce1) evaluates to nil, but I found one site that places reduce1 in clojure.core, clodoc.org. I'd appreciate any info on it. |
| 21:59 | alandipert | dnolen: nice work re: om! curious about https://github.com/swannodette/om/issues/9 - is this complection part of why react is so fast? |
| 22:03 | seangrove | OldTree: reduce1 is defined in the same file on line 882 |
| 22:04 | OldTree | thanks |
| 22:22 | dobladez | Any suggestions for a CI solution for a Clojure + JavaScript project ? |
| 22:23 | seangrove | dobladez: CircleCI + Phantom/Sauce Labs via WebDriver? |
| 22:24 | seangrove | + clojure.test + cemerick/clojurescript.test, depending on what kind of tests |
| 22:24 | dobladez | sounds like an option, thanks |
| 22:24 | dobladez | do you have experience with CircleCI ? |
| 22:24 | dobladez | vs., say, Jenkins ? |
| 22:24 | seangrove | Sure, used both |
| 22:25 | seangrove | Also, worked at Sauce for quite awhile, so a bit biased in that regard |
| 22:25 | dobladez | great... so, any pros/cons between Circle and Jenkins ? |
| 22:27 | seangrove | Same argument with Heroku vs Linode. Circle is slick, pretty easy to get setup, and you don't have to worry about it. And when they add things on, they do it in a sustainable way. Jenkins has a much more vast ecosystem of varying quality, it takes longer to tweak and get right, but it very flexible and you can really drill down into the box running it. |
| 22:39 | bitemyapp | arrdem: mumbur? |
| 22:40 | arrdem | bitemyapp: yeah hang on glue in hand building minis |
| 22:48 | bitemyapp | solid evening. |
| 22:48 | arrdem | iknowrite |
| 22:49 | bitemyapp | arrdem: do you like tactical shooters? |
| 22:49 | arrdem | bitemyapp: I mean I played MWO, but I don't usually go in for milsims |
| 22:50 | bitemyapp | arrdem: hum, what I'm thinking of is more realistic than CounterStrike, but similarly structured - but more fun and focused than ArmA |
| 22:50 | bitemyapp | it's on sale. |
| 22:50 | bitemyapp | I've been playing it for 4-5 years, they have a new early access thing. |
| 22:50 | arrdem | bitemyapp: title? |
| 23:23 | SegFaultAX | dobladez: I've used CircleCI and Jenkins extensively, let me know if you have any questions. |
| 23:25 | dobladez | SegFaultAX: I have quite a bit of experience with Jenkins (from past Java projects)... just wondered if it's easy to make it work with lein and the rest of the Clojure and JavaScript testing ecosystem |
| 23:25 | dobladez | so, was looking for recommendations/caveats or other options besides Jenkins and CircleCI |
| 23:27 | SegFaultAX | dobladez: It's trivial to make Clojure projects work with Jenkins. |
| 23:27 | SegFaultAX | Especially if you've done it with a similar build system before. |
| 23:27 | dobladez | great |
| 23:27 | dobladez | I see there's a leiningen plugin for it |
| 23:28 | SegFaultAX | CircleCI is /really/ expensive, and the UI, while pretty, has some pretty big issues. |
| 23:29 | SegFaultAX | One of our biggest annoyances with Circle in general was a) it ran builds pretty slowly b) it didn't do a good job of collapsing enqueued jobs for multiple commits on the same branch. |
| 23:29 | dobladez | so, with Jenkins is it easy to capture test runs from, say, Midje ? |
| 23:29 | SegFaultAX | Yes. Just archive the artifacts (which includes stdout) |
| 23:30 | SegFaultAX | Then you can go back and look at the at your leisure. |
| 23:30 | SegFaultAX | We initially started using Circle as a stopgap while we looked for a permanent CI solution. We didn't really realize how expensive it would be. |
| 23:30 | dobladez | oh with "capture" I just meant to auto-detect build failures with at least some minimal reporting about it |
| 23:31 | SegFaultAX | In the end we just built two custom machines with lots of ram and CPU. |
| 23:31 | SegFaultAX | dobladez: The easy way to do that is return a non-zero exit code. |
| 23:31 | SegFaultAX | Jenkins has extensive reporting and tracking features. |
| 23:32 | dobladez | right. OK... looks like I'll play with Circle a bit... (has a 14-day trial)... but knowning I might endup with my own Jenkins on Digital Ocean |
| 23:32 | SegFaultAX | Ugh. How big is the sweet? |
| 23:32 | SegFaultAX | I would say don't do cloud-based CI. |
| 23:33 | SegFaultAX | If you can avoid it. |
| 23:33 | SegFaultAX | Our suite is mid-sized, maybe 13 - 17k tests. It took like 24 - 30 minutes per run on Circle. |
| 23:33 | SegFaultAX | ~16 on dedicated boxes ($800 each) |
| 23:33 | clojurebot | Excuse me? |
| 23:34 | dobladez | well... it's a small project... we are only 1.5 developers... and we don't own (nor plan to purchase) hardware |
| 23:35 | SegFaultAX | Oh, well then whatever works. |
| 23:35 | SegFaultAX | Probably circle will be fine. |
| 23:35 | SegFaultAX | Or travis. |
| 23:36 | dobladez | travis is much more expensive it seems |
| 23:37 | SegFaultAX | Just use whatever works to get CI going. |
| 23:37 | dobladez | What I like about a custom Jenkins is that with DigitalOcean I can probably start fine with the $5/mo. option... and easily bump it if needed... and if that ever becomes slow, simply move the installation to local hardware |
| 23:37 | SegFaultAX | For small projects it mostly doesn't matter, and the costs of switching is low. |
| 23:39 | SegFaultAX | dobladez: Yea, plus it's easy to slave builds with Jenkins. |
| 23:39 | dobladez | SegFaultAX: curious: what are you working on? looks like a pretty big Clojure project |
| 23:40 | SegFaultAX | dobladez: Well the big one I'm referring to is Rails. |
| 23:40 | dobladez | ah, ok |
| 23:43 | SegFaultAX | dobladez: One thing I've been thinking about for a while is using Jenkins to run builds inside of docker. |
| 23:44 | dobladez | yep... I think there's already support for that |
| 23:45 | dobladez | on a prior project, we configured it with an internal "cloud" (CloudStack) using Jenkins' jclouds plugin (if I remember correctly) |
| 23:45 | dobladez | so, it launched new slaves as need |
| 23:45 | dobladez | docker containers are much faster to start though... perfect fit |
| 23:55 | SegFaultAX | dobladez: Yea, that's pretty awesome. |
| 23:56 | dobladez | SegFaultAX: gotta go... 2am here. thanks again |