2014-12-16
| 00:00 | andyf | What expressions are the \2 and \3 supposed to refer to there? |
| 00:06 | andyf | Seems like a reasonable definition would be that it could match the string "xx", where (y) matches nothing, and so does \3, but the Java regex implementation doesn't see it that way. |
| 00:09 | gfredericks | yeah that's a good summary of my thoughts |
| 00:09 | rritoch | gfredericks: There is no third term so what is the point of \3? |
| 00:09 | gfredericks | rritoch: there is |
| 00:10 | gfredericks | I wonder how easy it is to statically determine whether a regex has such impossibilities |
| 00:10 | andyf | \3 should refer to expression starting with 3rd ( |
| 00:10 | rritoch | ,(clojure.string/replace "xxx" #"((x)|(y))" "$3") |
| 00:10 | clojurebot | "" |
| 00:10 | rritoch | ,(clojure.string/replace "xxx" #"((x)|(y))" "$2") |
| 00:10 | clojurebot | "xxx" |
| 00:13 | rritoch | gfredericks: I obviously need to dig more into the docs but $3 is returning that which isn't matched ##(clojure.string/replace "dxxxe" #"((x)|(y))" "$3") |
| 00:13 | lazybot | ⇒ "de" |
| 00:14 | gfredericks | ,(clojure.string/replace "yyy" #"((x)|(y))" "$3") |
| 00:14 | clojurebot | "yyy" |
| 00:15 | gfredericks | I don't understand that "de" part |
| 00:15 | TEttinger | it's replacing it with an empty string |
| 00:15 | gfredericks | oh right |
| 00:15 | TEttinger | ##(clojure.string/replace "" #"(.)" "$9") |
| 00:15 | lazybot | ⇒ "" |
| 00:16 | TEttinger | ##(clojure.string/replace "a" #"(.)" "$9") |
| 00:16 | lazybot | java.lang.IndexOutOfBoundsException: No group 9 |
| 00:16 | TEttinger | oh! |
| 00:16 | TEttinger | interesting |
| 00:17 | TEttinger | oh ok |
| 00:17 | TEttinger | so it never matched y, so group 3, (y), was empty |
| 00:18 | TEttinger | ##(clojure.string/replace "a" #"((h)|(i)|(j))" "$4") |
| 00:18 | lazybot | ⇒ "a" |
| 00:18 | TEttinger | ##(clojure.string/replace "a" #"((a)|(h)|(i)|(j))" "$4") |
| 00:18 | lazybot | ⇒ "" |
| 00:18 | TEttinger | ##(clojure.string/replace "a" #"((a)|(h)|(i)|(j))" "$2") |
| 00:18 | lazybot | ⇒ "a" |
| 00:19 | TEttinger | so you can't use $n to get an n that is higher than the number of groups in the regex. |
| 00:19 | TEttinger | but if those groups were empty, the $n for that group will be "" |
| 00:20 | TEttinger | ##(clojure.string/replace "dxxxe" #"((x)|(y))" "$1") |
| 00:20 | lazybot | ⇒ "dxxxe" |
| 00:25 | rritoch | TEttinger: Ok, I see, my problem was that I was only working with the x values of the problem. ##(list (re-matches #"((x)|(y))\3" "xx") (re-matches #"((x)|(y))\3" "yy")) |
| 00:25 | lazybot | ⇒ (nil ["yy" "y" nil "y"]) |
| 00:26 | rritoch | gfredericks: I believe you are right, the regex you provided is unmatchable because either \2 or \3 will have a value, but not both. Or so it seems. |
| 00:42 | rritoch | Does clojure have anything similar to LPC reg_assoc? http://discworld.atuin.net/lpc/playing/documentation.c?path=/driver/efuns/strings/reg_assoc ? |
| 00:48 | justin_smith | something like this? ##(let [[a b c] (re-seq #".a." "happy and sad")] [c b a]) |
| 00:48 | lazybot | ⇒ ["sad" " an" "hap"] |
| 00:48 | justin_smith | no, that's not the same at all |
| 00:50 | rritoch | justin_smith: Yeah, this is for natural language processing, you pass it an array of patterns which are each attempted, and when a match is found it returns the token associated with that expression. |
| 00:54 | rritoch | justin_smith: I coded it once in pike https://github.com/rritoch/PikeVM/blob/master/root/boot/system-1.1/simul_efuns.pike#L648-L719 but right now I can't recall how the no-match moves forward |
| 00:55 | justin_smith | ,(condp re-find "hello" #"good" :exit #"sup" :stay #"hel" :greet) |
| 00:55 | clojurebot | :greet |
| 00:55 | justin_smith | still not it |
| 01:11 | rritoch | justin_smith: Well, either way I need to add this to my todo list, but I am not looking forward to it, but being able to tokenize a string with regular expressions is occasionally useful. |
| 01:11 | justin_smith | why not a proper parser? |
| 01:13 | rritoch | justin_smith: Parsers in java tend to be a bit slow, even if you use a stringbuilder. Regular expressions are implemented in native code in many languages so it is usually faster. I am not sure if java uses a binary library to backup regular expressions though. |
| 01:40 | Html-01 | someone is here ? ì |
| 01:41 | justin_smith | yeah, there area a few of us here |
| 01:41 | Html-01 | someone here is a unity 3d programmer ? |
| 02:04 | rritoch | Does anyone know how to monitor for creation of a certain DOM node when using PhantomJS? Specifically I want to pause until a certain condition is met, such as document.getElementById returns non-null. |
| 02:28 | BorisKourt | I can't figure out how to turn something like: {:z [[:z 262.0] [:z 262.0] [:z 262.0]] :x [[:x 262.0] [:x 262.0] [:x 262.0]] : y [[:y 262.0] [:y 262.0] [:y 262.0]]} |
| 02:28 | BorisKourt | into just this: {:z [262.0 262.0 262.0] :x [262.0 262.0 262.0] :y [262.0 262.0 262.0]} can anyone help? |
| 02:28 | BorisKourt | preserving order in the vectors |
| 02:28 | SagiCZ1 | BorisKourt: you can call set on each of the key |
| 02:28 | SagiCZ1 | ,(set [262.0 262.0 262.0]) |
| 02:28 | clojurebot | #{262.0} |
| 02:29 | SagiCZ1 | or distinct |
| 02:29 | SagiCZ1 | ,(distinct [262.0 262.0 262.0]) |
| 02:29 | clojurebot | (262.0) |
| 02:29 | SagiCZ1 | wait, nevermind |
| 02:29 | BorisKourt | [[k a] [k b] [k c]] into [a b c] |
| 02:30 | Empperi | ,(into {} (for [[k v] {:z [[:z 262.0] [:z 263.0]]}] [k (map second v)]) |
| 02:30 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 02:30 | Empperi | ,(into {} (for [[k v] {:z [[:z 262.0] [:z 263.0]]}] [k (map second v)])) |
| 02:30 | clojurebot | {:z (262.0 263.0)} |
| 02:30 | andyf | BorisKourt: Maybe you want to call #(map second %) on each value in the map? |
| 02:30 | BorisKourt | Ill try Empperi's solution one moment |
| 02:38 | BorisKourt | Empperi works perfectly thank you |
| 02:38 | Empperi | np |
| 02:55 | otti | has someone a clue how i can close database connections when using korma that is based on jdbc? |
| 03:02 | nXqd | hi guys, what is this kind of variable, does it have any special meaning or just naming convention : options# |
| 03:02 | nXqd | (let [options# (dissoc ~options :xml?)] |
| 03:07 | luxbock | nXqd: it's syntax sugar for `gensym` |
| 03:07 | luxbock | nXqd: it's used to create unique local variable names inside macros |
| 03:08 | nXqd | luxbock: thanks ! it is, I just forgot what I read yesterday ... |
| 03:16 | rhg135 | Is gensym unique per VM invocation? |
| 03:21 | andyf | rhg135: yes |
| 03:22 | rhg135 | Good, andyf , i considered UUID |
| 03:22 | rritoch | rhg135: It is not guaranteed. I tested this myself by launching (gensym "x") as the first repl command, and repeating, I received the same value. So it is not guaranteed unique |
| 03:23 | rhg135 | D: |
| 03:23 | andyf | Wait, when you say "per VM invocation" I thought you meant "within a single JVM running a single instance of Clojure". Within that, it is unique. Across different JVM invocations, the names can be the same. |
| 03:23 | rhg135 | ,(repeatedly 3 gensym) |
| 03:23 | clojurebot | (G__27 G__28 G__29) |
| 03:24 | andyf | gensym source: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L558 |
| 03:24 | rritoch | rhg135: You can use UUID to get guaranteed unique gensyms though |
| 03:24 | opqdonut | andyf: I think it's more like "per clojure classloader" or something like that, if you unload all the clojure stuff from your jvm, you'll probably get the same values again |
| 03:24 | rritoch | ,(gensym (.toString (java.util.UUID/randomUUID))) |
| 03:24 | clojurebot | 176704f8-55bc-476c-9b62-0b0c30c0a2de54 |
| 03:25 | rhg135 | im using it to label strings i get over irc |
| 03:25 | rhg135 | im not to worried |
| 03:26 | rhg135 | If i get non uniques chances are im OOM anyway |
| 03:27 | TEttinger | rhg135, add the timestamp then |
| 03:29 | rhg135 | TEttinger: it's completely possible for two people to say something |
| 03:29 | TEttinger | at the same millisecond? |
| 03:29 | TEttinger | with the same username? |
| 03:29 | rhg135 | I could lean on the fact lazybot runs sequentially |
| 03:30 | TEttinger | heh |
| 03:30 | rhg135 | But it smells ugly |
| 03:30 | andyf | If you are willing to look up new messages time stamps in the collection of previous messages, you can append a unique counter value per second or millisecond to the messages that occur at the same time. |
| 03:31 | rritoch | TEttinger: On IRC it is because of network latency, if both messages arrive on the same packet, and your code is extremly fast (such as using multiple threads). |
| 03:31 | rritoch | TEttinger: For a single threaded app, it would probably be impossible. |
| 03:34 | rhg135 | Im indexing by network channel and gensym I think I'm just being paranoid about collisions |
| 03:35 | rritoch | rhg135: A single person isn't going to be able to send two messages at the same millisecond, not even a bot. If you don't like UUID's for some reason, you could use something more exotic, like a SHA256 hash of the catenated string of username, IP, and timestamp (ms). |
| 03:36 | rritoch | rhg135: There are no known collissions of SHA256 yet. |
| 03:36 | rhg135 | rritoch: you beat me in paranoia lol |
| 03:37 | TEttinger | or inc a ref |
| 03:38 | rhg135 | Isn't this basically a gensym, assuming I run one JVM which I hope so? |
| 03:39 | rhg135 | To the counter not hashing |
| 03:40 | TEttinger | yeah, except it isn't clear how well many many gensyms work without collision |
| 03:42 | rhg135 | ,(reduce = true (repeatedly 100000 gensym)) |
| 03:42 | clojurebot | false |
| 03:42 | rhg135 | Oops |
| 03:43 | rritoch | Has anyone here used clj-webdriver? I thought I found a solution to my problem by using wait-until, but it's implementation doesn't seem to work as I keep getting "No implementation of method: :wait-until of protocol" errors. |
| 03:49 | rhg135 | Gensym seems unique |
| 04:07 | TEttinger | ,(distinct (repeatedly 100000 gensym)) |
| 04:07 | clojurebot | (G__27 G__28 G__29 G__30 G__31 ...) |
| 04:07 | TEttinger | ,(distinct? (repeatedly 100000 gensym)) |
| 04:07 | clojurebot | true |
| 04:07 | TEttinger | there we go |
| 04:08 | yogsototh | ikitommi_: thanks I just saw your message. |
| 04:18 | rhg135 | TEttinger: thx |
| 04:28 | amalloy | TEttinger: ITYM (apply distinct? ...) |
| 04:28 | amalloy | ,(distinct? (repeat 100 10)) |
| 04:28 | clojurebot | true |
| 04:29 | TEttinger | ,(apply distinct? (repeat 100 10)) |
| 04:29 | clojurebot | false |
| 04:29 | TEttinger | ,(apply distinct? (repeatedly 100000 gensym)) |
| 04:29 | clojurebot | true |
| 04:32 | rhg135 | Why is Symbol an IObj and keyword not? |
| 04:33 | andyf | I guess if you are going to stress gensym, realize that it can only return 2^32 unique gensym's, since it is based on the AtomicInteger class. |
| 04:35 | nXqd | can we disable a test in clojure by adding _ prefix ? |
| 04:35 | nXqd | skip* |
| 04:36 | luxbock | nXqd: you can ignore any expression by prepending it with #_ |
| 04:36 | nXqd | luxbock: thanks :) |
| 04:37 | luxbock | I'd like to get a sanity check for something that I'm working on |
| 04:37 | luxbock | I have a C library that I call via Clojure's JNA that crunches some data for me, and this data can take up to 50gb of memory to hold |
| 04:38 | luxbock | and I'd like to save this data on disk, and then serve it via a ring based Clojure web app |
| 04:39 | luxbock | the data is basically just a collection of double-arrays |
| 04:40 | luxbock | so I think for saving disk space I should keep it in the native data format, and I'm thinking about using ztellman's Gloss for this |
| 04:42 | luxbock | I've also thought that maybe I should use Gzip to minimize it further, and to transport it to the client for the webapp |
| 04:42 | luxbock | does this all seem sensible? |
| 04:43 | zarkone | hello all. I want to learn apache storm and try to implement my first example. In examples data in spout is always local.. Is there simple example with outer source, e.g. from websoket stream |
| 04:54 | rritoch | Is there any way to automatically ungreedy a regular expression? I tried using flag 512 from PCRE but java doesn't honor that flag for ungreedy. |
| 04:54 | rritoch | I just need to mimic the ungreedy flag of PCRE. |
| 04:55 | BorisKourt | Is there a library or set of examples that deal with analysis of numeric collections? Having a hard time describing what I need. Some sort of super rudimentary wave analysis, grab highest peaks, average amplitude, sustain, and other 'wave shape' facts? This is not related to sound. |
| 04:56 | vijaykiran | BorisKourt: doesn't Incanter have something like that ? |
| 04:56 | dysfun | incanter has loads of stuff like that |
| 04:57 | BorisKourt | It likely would, I am hesitant though as my sets of data are miniscule and this is not meant for any visual output whatsoever. Ill take a look for sure if there is no smaller alternative. |
| 05:01 | BorisKourt | Looks like its innards do have just what I want. Thanks. Now to get it into the project :) |
| 05:03 | rritoch | Will this mimic perl's /U (ungreedy) properly? (defn ungreedy [re] (re-pattern (clojure.string/replace (.toString re) #"(\*)([^?])" "$1?$2"))) |
| 05:05 | andyf | rritoch: It does not cover * at the end of regex, nor handle the difference in their meaning when they are inside of [], and it doesn't include + |
| 05:06 | andyf | probably a few other things that I'm not thinking of, but not sure |
| 05:06 | rritoch | andyf: Ok, as for the * at the end of the regex, isn't that ungreedy? |
| 05:07 | rritoch | andyf: I'll have to check but I'd think "/.*/U" would still match the entire string |
| 05:08 | andyf | parsing regex's to modify them is not something I'd do lightly, if I wanted it to be correct in all cases. |
| 05:11 | amalloy | andyf: it woulsn't be quite so bad if rritoch were actually parsing them. but just wanton string replacement is going to be a disaster. there are a *lot* of cases this ungreedy function misses that you didn't think of |
| 05:13 | amalloy | eg, #"\Qabcd*\E" |
| 05:13 | amalloy | or #"abc\*def" |
| 05:13 | amalloy | and it doesn't un-greedify the + repetition operator, or the {N,M} operator |
| 05:15 | andyf | amalloy quantifies my unnamed fears. Thanks amalloy :) |
| 05:15 | amalloy | clojurebot: amalloy |is| your unnamed fears made real |
| 05:15 | clojurebot | 'Sea, mhuise. |
| 05:16 | birdspider | hello, how would I access a inner enum value ? (https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/Pixmap.java Pixmap's Format/RGBA8888 for instance) |
| 05:19 | rhg135 | I love having a good gc |
| 05:20 | rhg135 | Pixmap$Format/xxx |
| 05:29 | andyf | rritoch: I'd suggest if you truly need PCRE capabilities, you use actual PCRE library. Going to the trouble of building it and calling it via JNI or similar mechanisms might be more pain than it is worth. |
| 05:30 | andyf | Google searches for existing PCRE library implementations in Java are not promising. |
| 05:32 | rritoch | andyf: Thanks, for now I'm just trying to see if I can just solve the currently mentioned issues. |
| 06:48 | hellofunk | is this most elegant way to assoc the same value into all the maps that are values of a sorted map? https://www.refheap.com/94984 |
| 06:49 | hellofunk | basically taking the map apart and then putting it back together. |
| 06:49 | hellofunk | i suppose an alternative would be to reduce over the map but wouldn't be more elegant |
| 06:50 | triss | is there a form of let where all functions used take the same first argument? |
| 06:50 | triss | so I say: |
| 06:50 | triss | (let [a (func ctx) |
| 06:51 | triss | b (func-two ctx) |
| 06:51 | martinklepsch | is there a reason = works for one argument as well? |
| 06:51 | triss | c (func-three ctx)] blah blah) |
| 06:51 | triss | but i don't want to type ctx all the time |
| 06:51 | jack_rabbit | triss, not that I know of... You could easily macro it if you do it often. |
| 06:52 | hellofunk | tris you could (defn f [func] (partial func ctx)) then do (let [a (f func..) b (f func-two) |
| 06:52 | hellofunk | triss ^ |
| 06:53 | hellofunk | or you could put the defn f as the first let form |
| 06:54 | triss | cheers guys. I'll have a play. |
| 06:54 | hellofunk | i can't tell if you are defining fns or calling them but you get hte idea |
| 06:55 | triss | calling them... |
| 06:55 | hellofunk | triss: (defn f [x & a] (apply x 2 a)) |
| 06:55 | hellofunk | then if you do (f inc) or (f + 5 6) whatever, the arg 2 is added to every call |
| 06:56 | triss | cheers. hellofunk that's splendid. |
| 06:56 | hellofunk | jack_rabbit: definitely don't need or want a macro for this. it's basic FP at work |
| 06:58 | triss | well it's not saving that much typing as it is.... a macro would result in cleaner code. |
| 06:58 | hellofunk | triss: no, first rule of macros, never use a macro if a good higher order function will do the trick instead |
| 06:59 | hellofunk | there is no reason for a macro here. |
| 06:59 | triss | I'm writing a little DSL for doing web audio stuff. |
| 06:59 | hellofunk | DSL's typically use macros, but the problem you've presented is not good macro material |
| 07:00 | triss | ok man. I can see why they'd be avoided. I'll bare that in mind and try and get things done functionaly. |
| 07:01 | luxbock | hellofunk: I would use reduce-kv, but I don't think it makes a big difference |
| 07:01 | hellofunk | whenever you are trying to consolidate functions, as you are, or consolidate args to functions, etc, then this is normal stuff for FP without macros |
| 07:01 | jack_rabbit | hellofunk, if he wants to write just [a (func) b (func-two)] I don't see a way around it. |
| 07:02 | hellofunk | jack_rabbit: he wants to pass other args but keep one arg the same for the functions |
| 07:03 | hellofunk | unless i misunderstood his question |
| 07:03 | jack_rabbit | I still don't see the problem with a macro, if that's what he wants to do. It's only worthwhile if he's doing it lots of places (probably not), but if he wants to do this, setting up the environment without a macro would be more code than just inserting the first parameter where it goes manually. |
| 07:04 | jack_rabbit | hellofunk, no, I reread it. I think you're right. |
| 07:05 | hellofunk | whether you are "setting up more code" by not using a macro, or setting up more code by writing the macro, either way it's all code. and in this case the important uses for macros isn't apparent here. he is not delaying evaluation of arguments, for example. |
| 07:07 | jack_rabbit | My only argument is that if this is worth doing, it's worth putting in a macro, so he doesn't need to "set up the code" everywhere. If it's not worth doing that, it's just easier and more readable to put the argument where it goes in each function call. |
| 07:08 | hellofunk | building the HOF only needs to be done once, just as writing a macro would probably be done once, so it's not causing lots of code to get written everywhere |
| 07:09 | jack_rabbit | Well, it would need to be done once for each let, no? |
| 07:10 | hellofunk | jack_rabbit: then it wouldn't go in a let, it would be its own separate function |
| 07:10 | jack_rabbit | That's fine. You'd still need something like [a (f func) b (f func-two)] which is not quite the requirement |
| 07:10 | clgv | if really need, a macro combining `let` and the `doto` like fill-in would be the way to go |
| 07:12 | jack_rabbit | unless I'm mistaken. [a (f func) b (f func-two)] doesn't seem any better than [a (func ctx) b (func-two ctx)] |
| 07:20 | clgv | jack_rabbit: that simple pattern word be solvable via `juxt` |
| 07:20 | clgv | triss: (let [[a b] ((juxt func func-two) ctx)] ...) |
| 07:24 | jack_rabbit | clgv, thanks! I was unaware of that. |
| 07:25 | jack_rabbit | clgv, although, I don't see that he could add other parameters to those functions. |
| 07:25 | triss | ah very nice. thanks clgv |
| 07:25 | hellofunk | jack_rabbit: the point is that with func and func-two, you are now having to define each of those, which isn't making anything easier |
| 07:26 | triss | func & func-two are already defined in a library |
| 07:27 | jack_rabbit | hellofunk, sorry, I miss your meaning. |
| 07:30 | jack_rabbit | At the very least, something *like* juxt could be written as a function that would satisfy triss's requirements. Not exactly to how he specified them, but close enough probably. Better than a macro. |
| 07:31 | clgv | jack_rabbit: yeah, well for the most flexible scenario you'd need a macro |
| 07:31 | jack_rabbit | clgv, right. |
| 07:31 | clgv | jack_rabbit: although the difference to an higher order function can be made pretty small |
| 07:32 | jack_rabbit | right again |
| 07:33 | clgv | (defn invoke-with-ctx [ctx & fns] (reduce #(conj %1 (%2 ctx)) [] fns)) called via (invoke-with-ctx ctx #(some-fn % arg2 arg3) #(other-fn % arg4)) |
| 07:35 | jack_rabbit | Not quite so elegant. |
| 07:36 | clgv | jack_rabbit: yeah, but probably the closest you can get with a higher order function |
| 07:37 | jack_rabbit | hmm... what about something that would result in a call like (invoke-with-ctx ctx [some-fn arg2] [other-fn arg2 arg3]) |
| 07:37 | jack_rabbit | That shouldn't be too hard. |
| 07:37 | clgv | jack_rabbit: easy to do, but not much better |
| 07:37 | jack_rabbit | Looks a little better *maybe* |
| 07:38 | clgv | you have replaced the lambdas by implicit specification... |
| 07:40 | jack_rabbit | It only looks better. Is it inferior in some way? |
| 07:41 | jack_rabbit | (apply (first fn-seq) cxt (rest fn-seq)) |
| 07:42 | jack_rabbit | ctx even |
| 07:43 | clgv | I don't think it is. More code in the implementiation but not problematic |
| 07:44 | jack_rabbit | Right. I just like the look of [some-fn arg2] better than #(some-fn % arg2) |
| 07:56 | triss | I'm feeling like a proper noob today. super slow. |
| 07:56 | triss | so if i want to adda new namespace to a project I just create a folder.... |
| 07:56 | clgv | triss: source file and potentially a folder |
| 07:56 | triss | stick my my-ns/core.cljs my-ns/thing.cljs |
| 07:57 | clgv | triss: namespace my.lib.core needs to be in my/lib/core.clj |
| 07:57 | triss | and then I can require it another namespace via (:require [my-ns :as my-ns]) |
| 07:58 | clgv | no. you need to require the full namespace |
| 07:58 | triss | oh yeah so (:require [my-ns.core :as my-ns]) |
| 07:58 | triss | ? |
| 07:58 | clgv | namespace "my.lib.core" needs to be in "my/lib/core.clj" and is required via (:require [my.lib.core :as mlc]) |
| 07:59 | triss | god dman I don't understand why it;s not being seen |
| 08:00 | triss | I get the error message: |
| 08:01 | triss | WARNING: Required namespace not provided for hm.core |
| 08:01 | triss | but hm.core lives under my source folder in hm/core.cljs |
| 08:01 | triss | clojurescript btw |
| 08:03 | clgv | triss: you got an "(ns hm.core ...)" expression in that file? |
| 08:04 | triss | yup. |
| 08:04 | triss | i just restarted the repl.... |
| 08:05 | triss | now the cljs compiler has stopped warning me but in the browser I'm told hm.core can't be found: |
| 08:06 | triss | Uncaught Error: Undefined nameToPath for hm.corebase.js |
| 08:06 | triss | erm ignore the base.js on the end of that |
| 08:07 | triss | I'm using figwheel... could that make things more complex? |
| 08:09 | clgv | triss: the provided information is not enough to be able to help you further. try to minimize the project setup until it stops failing, then you usually find the problem. |
| 08:09 | triss | cheers man will do |
| 08:11 | dnolen_ | triss: there's also a #clojurescript specific channel you might want to join. |
| 08:11 | triss | oh... hadn't spotted that. thanks dnolen. |
| 08:27 | michaelr525 | hey |
| 08:52 | thatguy | anyone have a favorite validation library for web forms? building my first and the options are almost overwheliming |
| 09:14 | SagiCZ1 | thatguy: i have no experience in this matter, but what seems so complex about it? |
| 09:25 | thatguy | probably nothing, just seeing what people have had success with |
| 09:27 | zot | random idiom: i have a variable that gets updated in a loop. go figure. in any case, is there a naming convention for these sorts of things, similar to A and A' (A-prime)? |
| 09:32 | clgv | zot: not that I know. if you don't need the old value you should bind it to the name of the loop argument to avoid errors |
| 09:33 | clgv | *you should bind the new value to the name of the loop argument |
| 09:33 | zot | generally i do, but sometimes it's useful to have both; foo-cur and foo-next work, but i thought there might be sth already "normal" |
| 09:35 | clgv | zot: not really since it is application specific anyway. in a time series calculation "v_n+1 (f v_n)" might be a documenting name |
| 09:38 | clgv | zot: I have used both "prime" and "subscript-like indices" |
| 10:01 | craigglennie | I’m trying to write a toy web-scraper for threadless.com. The site has multiple pages of links to t-shirts. I would like a function that produces a list of all the links, moving to the next page as needed. In Python I could use a generator that took the starting URL, extracted product links to a list, yielded them one-by-one, and repeated this for the next page once the list of product links was empty. If there was no next page the generator would |
| 10:01 | craigglennie | exit. How would I go about something like this in clojure? I’ve looked at lazy-seq but I’m not sure that it’s the right answer |
| 10:02 | craigglennie | I also thought about using a list comprehension, but it doesn’t seem quite right, either |
| 10:02 | SagiCZ1 | you could use lazy-seq |
| 10:02 | teslanick | You could use core.async to do something like a producer-consumer. |
| 10:04 | hellofunk | thatguy are you talking about browser-side web form validation? |
| 10:04 | craigglennie | teslanick: That sounds like what I’d want - would that also allow for the consumers to work in parallel? |
| 10:10 | teslanick | craigglennie: Yes. One go-block would consume the pages and put to a channel. Another (pool?) of go-blocks would consume the channel and generate a list of links. |
| 10:12 | ebaxt | Is there a simple way to access the constructor function (map->Name) of a record given only an instance of the record? |
| 10:16 | justin_smith | triss: quick correction - my-ns.core needs to go in src/my_ns/core.clj - note the underscore |
| 10:19 | craigglennie | teslanick: Thanks, I’ll take a look at core.async - I had wanted to parallelize this anyway |
| 10:21 | EvanR | join #haskell |
| 10:22 | EvanR | s/^/\// |
| 10:23 | justin_smith | ebaxt: it is possible, since the class of the record and the namespace it is in will match up, but there is no simple method |
| 10:24 | justin_smith | ebaxt: but if you have the thing already you can use (into (empty this-record) {:some "input"}) |
| 10:24 | justin_smith | which does what map->Name does anyway |
| 10:25 | ebaxt | justin_smith: thx, guess I will have to call qualified_record_name/name or empty the map like you say |
| 10:25 | justin_smith | well that's not "emptying the map" |
| 10:25 | justin_smith | it just makes an empty record, of the same type as the input |
| 10:25 | justin_smith | records are immutable |
| 10:26 | pjstadig | i don't think empty works on records |
| 10:26 | ebaxt | justin_smith: ah, didn't see the into. Nice, thanks a lot! |
| 10:26 | justin_smith | pjstadig: actually, you are right, my bad |
| 10:26 | justin_smith | ebaxt: never mind, i expected empty to work on records, but it does not |
| 10:26 | pjstadig | it would be nice if it did :) |
| 10:27 | pjstadig | dissoc'ing any of the basis keys in a record cause it to "degrade" to a plain hashmap |
| 10:27 | justin_smith | ,(defrecord MyRec [a b]) |
| 10:27 | clojurebot | sandbox.MyRec |
| 10:27 | justin_smith | ,(def r (MyRec. 0 1)) |
| 10:27 | clojurebot | #'sandbox/r |
| 10:27 | justin_smith | ,(into r {:a 42}) |
| 10:27 | clojurebot | #sandbox.MyRec{:a 42, :b 1} |
| 10:28 | justin_smith | so that works, but will leave the old values for anything you did not specify |
| 10:28 | EvanR | whats the difference between defrecords and maps, practically |
| 10:29 | justin_smith | you can implement protocols on records |
| 10:29 | pjstadig | EvanR: some performance differences when you access the basis fields, and you can extend protocols to them |
| 10:29 | EvanR | i implemented protocols on the map though |
| 10:29 | pjstadig | they are also a distinct type |
| 10:29 | justin_smith | EvanR: but what if you wanted to implement the protocol differently on a different map |
| 10:30 | justin_smith | records are distinct classes, so they can be extended seperately |
| 10:30 | EvanR | ok |
| 10:30 | EvanR | each record schema has to be a dedicated type/class ? |
| 10:30 | ebaxt | ,(sandbox.MyRec/create {:foo "bar}) |
| 10:30 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 10:31 | justin_smith | EvanR: defrecord creates a class |
| 10:31 | pjstadig | ,(sandbox.MyRec/create {:foo "bar"}) |
| 10:31 | clojurebot | #sandbox.MyRec{:a nil, :b nil, :foo "bar"} |
| 10:31 | ebaxt | ,(sandbox.MyRec/create {:foo "bar"}) |
| 10:31 | clojurebot | #sandbox.MyRec{:a nil, :b nil, :foo "bar"} |
| 10:31 | EvanR | like, it registers a new class name? or its anonymous |
| 10:31 | justin_smith | EvanR: there is no such thing as an anonymous class |
| 10:31 | pjstadig | ,(class MyRec) |
| 10:31 | clojurebot | java.lang.Class |
| 10:31 | clgv | EvanR: usually you should use a map. if a map is not sufficient anymore you can switch to a record. |
| 10:31 | EvanR | there isnt? |
| 10:31 | pjstadig | er |
| 10:31 | pjstadig | ,(class r) |
| 10:31 | clojurebot | sandbox.MyRec |
| 10:32 | justin_smith | EvanR: nope, the closest you get is gibberish auto-generated names |
| 10:32 | justin_smith | ,(class (fn [x] x)) |
| 10:32 | EvanR | ok that explains that |
| 10:32 | clojurebot | sandbox$eval232$fn__233 |
| 10:32 | justin_smith | names like the ones you get for fn |
| 10:37 | arkh | I was wondering if someone could explain defmulti to me. I have a map like the following: {:something/new {:id 1 :userid 100}} and like to run maps like that through a multimethod. I'm trying to do variadic argument deconstruction but I'm not getting something right |
| 10:37 | arkh | (defmulti foo (fn [[k v & xs]] k)) |
| 10:38 | justin_smith | that is not variadic |
| 10:38 | justin_smith | that is destructuring a single arg |
| 10:38 | arkh | (defmulti foo :something/new [[k v & xs]] (:id v)) |
| 10:38 | arkh | I'd like to do variadic destructuring on that single arg |
| 10:38 | andyf | arkh: Will all of your maps have a single key/value pair? If not, the particular key/value pair chosen will vary from map to map. |
| 10:39 | justin_smith | arkh: you don't need to do the & xs part at all for destructuring to work |
| 10:39 | arkh | all the maps will have a single key value pair |
| 10:39 | arkh | ok |
| 10:39 | justin_smith | ,((fn [[a b c]] c) (range)) ; arkh |
| 10:39 | clojurebot | 2 |
| 10:39 | justin_smith | where (range) of course produces an "infinite" series of numbers |
| 10:40 | arkh | I'm trying to understand that magic right now ... ; ) |
| 10:40 | justin_smith | it's not magic, destructuring does not specify the length - it only specifies which parts you have names for |
| 10:40 | justin_smith | it's not pattern matching |
| 10:41 | arkh | right - my brain just had to catch up. I think I get it now |
| 10:41 | justin_smith | also, maps through list destructuring is a bit odd, because maps are not ordered |
| 10:42 | arkh | true, but I thought it would be ok if my maps are only a single key/value pair |
| 10:42 | justin_smith | nope, nth not supported, it will fail |
| 10:42 | arkh | that's what the repl was saying too |
| 10:42 | arkh | fair enough |
| 10:42 | justin_smith | ,((fn [[a b]] b) {:a 0 :b 1}) |
| 10:42 | clojurebot | #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap> |
| 10:42 | justin_smith | ,((fn [[a b]] b) (seq {:a 0 :b 1})) |
| 10:42 | clojurebot | [:a 0] |
| 10:43 | justin_smith | so you could add seq to your defmulti definition |
| 10:43 | arkh | sure! |
| 10:43 | justin_smith | or just not try to destructure maps with list destructuring |
| 10:44 | arkh | thank you |
| 10:45 | justin_smith | haha, you could define a defmulti for your dispatch function for your defmulti |
| 10:45 | justin_smith | yo dawg, I heard you like multimethods... |
| 10:45 | arkh | no need(!) |
| 10:45 | arkh | #xzibit #yolo |
| 10:49 | craigglennie | Another question… In my toy web-scraper I am going to be extracting data from multiple sites, each with their own layouts. I’d like a common public interface to each scraper; in OO I would have an actual interface, or an abstract base class. In Clojure I could put each scraper in it’s own namespace, and just make sure each one implements the appropriate functions, but it seems like multi-methods or protocols might also be appropriate. Any |
| 10:49 | craigglennie | advice? |
| 10:49 | clojurebot | the tao of warfare is deception |
| 10:50 | justin_smith | craigglennie: if performance is not the main concern, multimethods are more flexible, and easier for interactive usage (you can actually redefine them and may not break things) |
| 10:51 | justin_smith | and a protocol is literally an interface plus some niceties - it literally compiles down to a java interface in the bytecode |
| 10:52 | craigglennie | justin_smith: Performance is not a concern (I’m still just trying to learn Clojure) so multimethods might be good. |
| 10:52 | craigglennie | Interactive usage would probably be nice, too |
| 10:52 | justin_smith | craigglennie: another option is to write a higher order function, and pass in the function that fulfills some task it needs |
| 10:53 | justin_smith | that would be the old-school-lisp (pre-clos) option |
| 10:54 | arkh | a warning on interactive usage of defmulti - it can't be redefined at the repl apparently |
| 10:54 | justin_smith | arkh: it can, you just need to undef it first |
| 10:55 | justin_smith | ,(defmulti foo :x) |
| 10:55 | clojurebot | #'sandbox/foo |
| 10:55 | justin_smith | ,(defmulti foo :y) |
| 10:55 | clojurebot | nil |
| 10:55 | justin_smith | ,(ns-unmap *ns* 'foo) |
| 10:55 | clojurebot | nil |
| 10:55 | justin_smith | ,(defmulti foo :y) |
| 10:55 | clojurebot | #'sandbox/foo |
| 10:55 | arkh | nice |
| 10:56 | justin_smith | clojure.tools.namespace has some utilities for this kind of redefinition stuff |
| 11:03 | puredanger | you can also (remove-all-methods foo) |
| 11:03 | justin_smith | oh, I was not aware that existed, cool |
| 11:04 | justin_smith | (inc puredanger) |
| 11:04 | lazybot | ⇒ 25 |
| 11:08 | andyf | Clojure cheatsheet has what I think are all multimethod-related functions/macros grouped together in a Multimethod section, including remove-all-methods: http://jafingerhut.github.io Most other related functions/macros are grouped near each other, too. |
| 11:10 | ppppaul | does read-string work with cljs? |
| 11:13 | chouser | ppppaul: yes, but consider cognitect/transit, depending on use case. |
| 11:26 | arkh | even if there's clojure on both sides of the communication is cognitect/transit still recommended from a e.g. compression standpoint? |
| 11:28 | tomjack | too bad #(partition-by f %) can't be like #(eduction (partition-by f) %) |
| 11:28 | stuartsierra | arkh: Transit will usually be faster than EDN. |
| 11:28 | puredanger | arkh: if all-Clojure, then Fressian will be faster than Transit or EDN (also does caching) |
| 11:28 | stuartsierra | arkh: Because Transit can take advantage of platform-native JSON libraries. |
| 11:29 | stuartsierra | Hi puredanger! |
| 11:29 | puredanger | HI |
| 11:30 | stuartsierra | ppppaul: read-string is in its own namespace in cljs, I think it's called cljs.reader |
| 11:30 | chouser | but fressian isn't a real option in ClojureScript yet |
| 11:31 | arkh | my use case is clojurescript on one side and clojure on the other - thanks! |
| 11:32 | puredanger | in that case, I'd use Transit |
| 11:32 | chouser | ditto |
| 11:39 | annapawlicka | mpenet: hi Max, how do I do “UPDATE users SET top_places[2] = 'riddermark' WHERE user_id = 'frodo’;” using hayt? |
| 11:44 | verma | ,(def options ["hello" "world"]) |
| 11:44 | clojurebot | #'sandbox/options |
| 11:45 | verma | ,(for [o options] {:text o :selected false}) |
| 11:45 | clojurebot | ({:text "hello", :selected false} {:text "world", :selected false}) |
| 11:45 | verma | dafuq |
| 11:45 | verma | when I am doing it here in cljs, its giving me an emtpy {} in that list |
| 11:45 | verma | checking again |
| 11:46 | ppppaul | transit is an optimization... i'll use it in the future. |
| 11:47 | ticking | everytime I use fold I get bitten by argument counts changing on mapentry, please somebody tell me that this is done with a sane reason |
| 11:49 | puredanger | ticking: don't understand what you mean |
| 11:49 | triss | so is there anything in the library that's equivalent to (comp doall repeat) |
| 11:49 | ticking | reduce and reducers/reduce have different semantics |
| 11:49 | triss | ? |
| 11:49 | stuartsierra | triss: dotimes |
| 11:49 | puredanger | ticking: you mean around maps in particular ? |
| 11:50 | ticking | puredanger: to be more precise, reduce and clojure.reducers/reduce behave differently on maps, reduce will require you a function like (fn [acc [k v]] while reducers/reduce will require (fn [acc k v] |
| 11:50 | triss | so dotimes returns the list of things it acts on? |
| 11:51 | ticking | puredanger: yeah |
| 11:51 | stuartsierra | triss: No, it's just for side effects. |
| 11:51 | ticking | triss: no |
| 11:52 | ticking | triss: most functions in clojure that do things just for side effects make this explicit by returning nil, e.g. dorun println dotimes |
| 11:53 | triss | ah ok.... |
| 11:54 | triss | so its seems doall is the only one that returns... |
| 11:54 | ticking | all yes |
| 11:54 | puredanger | ticking: yeah, it was done for efficiency I believe |
| 11:54 | triss | i suppose mapv sort of fits in there |
| 11:54 | ticking | puredanger: I think in the code there is an explicit check for this case which would seem slower to me |
| 11:55 | puredanger | I believe it has to do with parallel folding over maps but I haven't looked at in depth |
| 11:55 | stuartsierra | triss: In general, the "do" is a hint that these functions are reserved for side effects. It frequently doesn't work out well to combine the lazy-sequence functions with side effects. |
| 11:55 | ticking | puredanger: https://github.com/clojure/clojure/blob/f3259f4f34a68eae7db7efc0be9d19fa5dafbd3c/src/clj/clojure/core/reducers.clj#L77 |
| 11:55 | tomjack | ticking: I guess (r/map identity) is a "just reduce please" shim |
| 11:56 | ticking | tomjack: yeah but urgh |
| 11:56 | tomjack | (which makes some parts of me unhappy, since (r/map identity) should be identity!) |
| 11:56 | ticking | tomjack: that this "fixes" it shows how broken the current behaviour is |
| 11:56 | ticking | tomjack: yeah exactly :D |
| 11:57 | ppppaul | i'm using datascript and it comes with some readers in a file. how do i get my cljs read to use those? (right now i'm doing a (swap!...) in my application code |
| 11:58 | dnolen_ | Bronsa: ping |
| 11:58 | puredanger | ticking: the clojure map impls can .kvreduce themselves and avoid creating every intermediate entry object |
| 11:58 | puredanger | ticking: only to then tear it apart again into k and v |
| 11:59 | tomjack | but we have reduce-kv already |
| 11:59 | puredanger | the reducer impl is trying to have the best of both reduce and reduce-kv automatically |
| 11:59 | ticking | tomjack: reducers/reduce uses reduce-kv internally |
| 12:00 | puredanger | there is a ticket to consider this aspect again for transducers in 1.7 |
| 12:00 | puredanger | sorry in 1.8 |
| 12:00 | ticking | puredanger: really transducers do this to? |
| 12:00 | tomjack | I guess the auto-kv behavior is specialized for stuff like conj? |
| 12:01 | puredanger | tomjack: not sure what you're thinking of |
| 12:01 | tomjack | can't be just "I don't have to type -kv when I know I'm reducing a map", I presume |
| 12:02 | puredanger | I think there would be more double work than just that inside reducers |
| 12:02 | tomjack | so it only makes sense if the binary op is also at least ternary, like (conj coll k v) |
| 12:02 | stuartsierra | ,(conj {} :key 3) |
| 12:02 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword> |
| 12:03 | dysfun | is anyone using core.async with aleph? or is there something aleph-like people are using with it? |
| 12:03 | tomjack | ,(conj [] :key 3) |
| 12:03 | clojurebot | [:key 3] |
| 12:03 | stuartsierra | ,(conj {} [:key 3]) |
| 12:03 | clojurebot | {:key 3} |
| 12:03 | ticking | wow |
| 12:04 | stuartsierra | conj is variadic, but key/value pairs must be passed as a vector. |
| 12:04 | ticking | and this is done by transducers as well? |
| 12:04 | puredanger | no, not right now |
| 12:04 | puredanger | there's a ticket to consider this again |
| 12:05 | ticking | puredanger: do you have a link for the ticket? can't seem to find it :/ |
| 12:05 | puredanger | CLJ-1552 |
| 12:05 | ticking | puredanger: thanks :D |
| 12:05 | puredanger | http://dev.clojure.org/jira/browse/CLJ-1552 |
| 12:05 | stuartsierra | puredanger is the kinder, gentler interface to JIRA |
| 12:05 | ticking | lol |
| 12:06 | tomjack | stuartsierra: if you knew you were reducing a map, you could just call reduce-kv. so I'm trying to think of cases where the reducing fn works for either reduce or reduce-kv |
| 12:06 | puredanger | I just loaded it all into my brain and can regurgitate it at will |
| 12:06 | dysfun | there used to be a workable emacs library for doing jira things |
| 12:06 | dysfun | that was vastly preferable to the web interface |
| 12:06 | stuartsierra | tomjack: I think that would be pretty rare. |
| 12:06 | puredanger | I have a Clojure library that can access it |
| 12:06 | puredanger | that I wrote to scrape jira |
| 12:06 | dysfun | now we just need someone to finish DEUCE and we can use that, heh |
| 12:07 | ticking | puredanger: I'm begging you please don't do this :D, it is so horribly confusing and breaks abstraction in so many ways, (reduce ... foo should equal (reduce ... (map identity foo |
| 12:07 | puredanger | I'm about 90% of the way towards an automated program that can scrape it and replicate it (with history) in Datomic :) |
| 12:07 | tomjack | if it's rare, why https://github.com/clojure/clojure/blob/f3259f4f34a68eae7db7efc0be9d19fa5dafbd3c/src/clj/clojure/core/reducers.clj#L77 ? |
| 12:07 | dysfun | puredanger: great, now you have to write datomic bindings in elisp. that's gonna be *fun* |
| 12:08 | puredanger | dysfun: well I don't need that :) |
| 12:09 | puredanger | ticking: I'm mostly in agreement |
| 12:09 | kenrestivo | dysfun: aleph has its own async-like thing called manifold (in case nobody answered already) |
| 12:09 | puredanger | in a side bar, I've built a new direct iterator for maps (CLJ-1499) and also built a variant of it that would provide a new direct iterator for only-keys and only-values (which avoids this same intermediate entry cost). it was surprisingly (to me) not much faster |
| 12:09 | dysfun | i'm tickled by the idea of just treating it as a database though |
| 12:10 | dysfun | kenrestivo: yeah, i was just reading through it. i understand there's interop with core.async |
| 12:10 | ticking | puredanger: interesting, JIT being fancy? |
| 12:10 | puredanger | ticking: the cost of allocating and throwing away small Java objects is really really low these days |
| 12:10 | dysfun | i've got a brand new app and i've been looking for a reason to play with core.async, so it seems like a fun project |
| 12:11 | ticking | puredanger: long live the generational gc and david ungar :D |
| 12:11 | puredanger | heh. I've tried to get him to speak at Strange Loop a couple times, just hasn't worked out |
| 12:12 | ticking | puredanger: too bad :D, I'd love to hear some more stuff from him, self is so awesome |
| 12:13 | puredanger | he seemed interest, maybe in the future. just bad timing in the past. |
| 12:14 | puredanger | ticking: anyhow, what I got from the key/val iterator experiment was that we're not getting *that* much benefit from reduce-kv over reduce |
| 12:14 | puredanger | once you're leveraging transducers/reducers |
| 12:15 | ticking | puredanger: good to hear, every time an implicit reduce-kv is used god kills a kitten ;) |
| 12:15 | puredanger | and maybe the complexity of reduce-kv is not worth it. unrolled small collections will also possibly make this faster |
| 12:16 | ticking | puredanger: yeah, can't wait for the small fixed arity vectors |
| 12:28 | hellofunk | is this most elegant way to assoc the same value into all the maps that are values of a sorted map? https://www.refheap.com/94984 |
| 12:30 | joegallo | you might (empty sorted-map-in) rather than invoking (sorted-map) directly. |
| 12:30 | joegallo | but besides that it seems like perfectly fine code |
| 12:31 | joegallo | you also could have used a reduce rather than an into/for, but that's a matter of taste, imho |
| 12:31 | joegallo | i prefer the into/for route, but that's just me |
| 12:31 | clgv | which is the default library to implement a service via ring + compojure consuming and producing JSON? |
| 12:32 | weavejes_ | clgv: There's ring-json |
| 12:33 | clgv | weavejester: I just found that, but it's use case is serializing return values only. what is the usual setup to get the json data from the request? |
| 12:33 | weavejester | clgv: It does both |
| 12:34 | clgv | ah thank you. quick reading was too quick ;) |
| 12:35 | dnolen_ | puredanger: is CLJ-1499 ready to go? http://dev.clojure.org/jira/browse/CLJS-836 |
| 12:36 | m1dnight_ | Can I use an atom to wait() and notifyAll()? |
| 12:37 | m1dnight_ | Or should I create a seperate object for that? |
| 12:41 | EvanR | when i do future-cancel, and then the corresponding java Future.cancel "cancels a task if possible", what exactly does this mean? |
| 12:41 | EvanR | what if my "task" is blocking waiting for something |
| 12:41 | EvanR | does it really cancel? |
| 12:43 | justin_smith | EvanR: well, .cancel is a method on java.util.concurrent.Future http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean) |
| 12:43 | justin_smith | it returns a boolean that tells you whether it was actually cancellable |
| 12:45 | EvanR | so future is the recommended way to spawn a thread to do something, possibly forever? |
| 12:45 | llasram | EvanR: And the actually mechanics of the interruption will generally defer to http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt() |
| 12:45 | EvanR | llasram: thanks for that, i was really wondering |
| 12:45 | justin_smith | EvanR: it's one way to do it, and it tends to work pretty nicely |
| 12:46 | justin_smith | (inc llasram) |
| 12:46 | justin_smith | thanks for the extra info |
| 12:46 | lazybot | ⇒ 43 |
| 12:46 | EvanR | on one hand you see people saying threads cant be killed/cancels/interrupted, and then theres this interaction with Future |
| 12:46 | justin_smith | EvanR: not that they *can't* be |
| 12:46 | justin_smith | just that there is no foolproof way to do it |
| 12:46 | llasram | Exactly. It's just ultimate cooperative |
| 12:47 | llasram | ultimately |
| 12:47 | EvanR | and then theres this Thread.interrupt which suggests that it works if its sleeping or "doing IO" |
| 12:47 | EvanR | and not if its busy looping |
| 12:47 | llasram | Exactly -- that's the "cooperative" part |
| 12:48 | justin_smith | EvanR: if you have a loop in your future, check (.isInterrupted (Thread/currentThread)) before recurring |
| 12:48 | EvanR | good to know |
| 12:48 | justin_smith | a future-cancel will set the interrupted flag |
| 12:48 | justin_smith | then you are cooperating :) |
| 12:48 | EvanR | im planning to be blocking-dequeuing |
| 12:48 | EvanR | then looping |
| 12:49 | EvanR | so hopefully i dont need to check the flag explicitly |
| 12:57 | justin_smith | EvanR: I'd say a check on that flag can't hurt and could possible help "If none of the previous conditions hold then this thread's interrupt status will be set." - better safe than sorry |
| 12:58 | EvanR | yes |
| 12:58 | justin_smith | it's effectively a race condition, if you catch the thread while it isn't blocking, the interrupt is a no-op (other than setting that flag) |
| 12:59 | EvanR | hold on... what would cause a no-op? |
| 12:59 | justin_smith | the thread isn't blocking, so none of the listed exceptions are triggered |
| 12:59 | EvanR | what exceptions |
| 13:00 | justin_smith | the ones listed before "If none of the previous conditions hold then this thread's interrupt status will be set." in the docs llasram linked to |
| 13:01 | EvanR | urg |
| 13:01 | justin_smith | which makes it clear that you should check that status, to be safe ##(.isInterrupted (Thread/currentThread)) |
| 13:01 | lazybot | ⇒ false |
| 13:02 | justin_smith | you can wrap it in a function (defn alive? [] (not (.isInterrupted (Thread/currentThread)))) |
| 13:02 | EvanR | so if it happens to not be blocking on the queue, the flag will get set and obviously nothing like ClosedByInterruptedException will be thrown, and then later it will attempt to dequeue, and the flag being set doesnt make a damn of a difference? |
| 13:02 | EvanR | it will just continue? |
| 13:02 | justin_smith | as llasram meantioned, at the root, it is cooperative, you need to check that flag to cooperate |
| 13:02 | justin_smith | EvanR: exactly |
| 13:03 | EvanR | got it |
| 13:04 | EvanR | and also i need a loop recur, not normal recursion for a thread like this to work? |
| 13:04 | EvanR | or is there something like "loop forever" |
| 13:06 | justin_smith | using the function I defined above (while (alive?) ...) |
| 13:26 | danneu | building an oauth api at the moment. can anyone recommend a site with a pleasant oauth api experience that i can swaggerjack some ideas from? so far i'm aping twitter and github |
| 13:28 | danneu | took a gander at oauthbible.com and was paralyzed with indecision |
| 13:28 | ajmccluskey | danneu: Stack Overflow works well from memory |
| 13:28 | danneu | ajmccluskey: thanks |
| 13:29 | danneu | linkedin ranks up there among the worst oauth apis i've used, though |
| 13:35 | TimMc | danneu: What made it bad? |
| 13:37 | ajmccluskey | Is there a library function to check "cyclic equality"? e.g. (ce? [1 2 3] [2 3 1]) => true |
| 13:38 | justin_smith | I assume this is more strict than (= (set a) (set b)) |
| 13:39 | ajmccluskey | justin_smith: yeah - I'm looking at a path through a graph where I can start from any node in the path - so order matters, but not starting point |
| 13:39 | justin_smith | I checked clojure.math.combinatorics, it was my first guess, but seems to have nothing like that |
| 13:40 | ajmccluskey | I'm thinking I can roll my own easily enough with a rotate fn, iterate, and some |
| 13:40 | justin_smith | I bet a combination of cycle and take would be useful |
| 13:41 | justin_smith | ,(take 4 (drop 2) (range 4)) |
| 13:41 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/take> |
| 13:41 | justin_smith | err |
| 13:41 | justin_smith | ,(take 4 (drop 2 (range 4))) |
| 13:41 | clojurebot | (2 3) |
| 13:41 | justin_smith | ,(take 4 (drop 2 (cycle (range 4)))) |
| 13:41 | clojurebot | (2 3 0 1) |
| 13:42 | ajmccluskey | justin_smith: thanks, something like this should make for a neater rotate function |
| 13:43 | EvanR | calculate the cyclic equivalence class representative and compare those |
| 13:43 | triss | ok so I've got a load of static data in: resources/public/my_files |
| 13:44 | triss | how do I add a route to compojure that serves these up? |
| 13:44 | justin_smith | EvanR: that is awesome, TIL |
| 13:44 | justin_smith | (inc EvanR) |
| 13:44 | lazybot | ⇒ 7 |
| 13:44 | EvanR | wuh |
| 13:45 | justin_smith | ? |
| 13:45 | justin_smith | today I learned |
| 13:45 | EvanR | i didnt even think my idea was that great |
| 13:45 | justin_smith | heh, no, it's the right answer here |
| 13:49 | ajmccluskey | EvanR: I don't know enough maths to understand what you mean :( |
| 13:50 | TimMc | EvanR: You mean rotate to lowest-ID element or something? |
| 13:51 | TimMc | so [9 7 23 4 10] would be become [4 10 9 7 23] |
| 13:52 | EvanR | good idea ;) |
| 13:54 | justin_smith | ajmccluskey: the idea is to define a rotation that would be guaranteed to give you the same result for any rotation of the same items (eg. TimMc's suggestion of rotating so the lowest item is always first before comparing) |
| 13:55 | ajmccluskey | justim_smith: gotcha |
| 13:55 | TimMc | There's probably some higher-performing approach where you take the first element of the first path, find a match in the second path, then walk both and compare. |
| 13:55 | ajmccluskey | TimMc: EvanR: thanks |
| 13:55 | TimMc | Do you know for sure that your paths are simple cycles? |
| 13:55 | TimMc | or whatever the term would be |
| 13:56 | ajmccluskey | TimMc: I thought of that, but my paths may traverse the same node multiple times |
| 13:56 | TimMc | In that case finding the class representative could be tricky. |
| 13:56 | EvanR | sounds like a more sophisticated notion of equivalence |
| 13:57 | TimMc | Pathological cases could look like ##(take 20 (interleave (repeat 0) (range))) |
| 13:58 | lazybot | ⇒ (0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9) |
| 13:58 | TimMc | err, close enough |
| 13:58 | ajmccluskey | basically, yes |
| 13:59 | TimMc | The slow and simple approach it is! |
| 14:00 | ajmccluskey | right now I was just looking at doing this for a unit test, so the easiest approach is to manually verify that my returned path is equivalent to the expected output in the sense I'm thinking and then reorder the expected output |
| 14:00 | TimMc | This is probably a *great* opportunity to use test.check, by the way. |
| 14:01 | ajmccluskey | TimMc: good point. I'm verifying an eulerian path, so I guess I could verify that the path is valid and contains each edge only once. |
| 14:05 | ebaxt | ,(defrecord Foo [a]) |
| 14:05 | clojurebot | sandbox.Foo |
| 14:05 | ebaxt | ,(eval (list (symbol (str (-> (Foo. "a") class .getName) "/create")) {:a "a"})) |
| 14:05 | clojurebot | #sandbox.Foo{:a "a"} |
| 14:05 | ebaxt | I can't figure out how to do the above without eval, any suggestions? |
| 14:07 | gfredericks | ebaxt: what's the input? an instance of Foo? |
| 14:08 | gfredericks | ebaxt: it's not clear what the crucial part of this is that you're trying to replicate |
| 14:09 | ebaxt | gfredericks: I'm trying to call the constructor function of a record using only an instance of that record |
| 14:09 | gfredericks | ebaxt: I assume assoc wouldn't work for your use case? |
| 14:11 | ebaxt | gfredericks: So basically I want to call (map->Foo {:a "a") , only I must figure out which record by the instance passed to me |
| 14:15 | gfredericks | I don't think there's any clean way to do this, but maybe cleaner than what you have |
| 14:15 | ebaxt | gfredericks: I have a couple of workarounds.But I'm trying to understand why the above works but not (. (resolve (symbol (-> (Foo. "a") class .getName))) create {:a "a"}) |
| 14:15 | gfredericks | ,(Foo. 2) |
| 14:15 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Foo, compiling:(NO_SOURCE_PATH:0:0)> |
| 14:16 | justin_smith | . is a reader macro, you cannot synthesize args to it |
| 14:16 | justin_smith | you need eval for that |
| 14:16 | TimMc | ajmccluskey: I was thinking more that test.check might help you generate some really good pathological test cases. :-) |
| 14:16 | Bronsa | ebaxt: you have to use reflection |
| 14:16 | mgaare_ | ebaxt: you could create a Constructible protocol and implement it on the records you want, if you know them ahead of time |
| 14:17 | ebaxt | mgaare_: Yeah, that's the workaround I'm going with |
| 14:17 | mgaare | (probably with a different name, one that's spelled correctly at least) |
| 14:17 | Bronsa | ebaxt: core.incubator has a new-by-name function you can use |
| 14:18 | ajmccluskey | TimMc: my code got me past the question in my course, so I'm almost scared to go there right now. Got a deadline :p. Definitely want to throw test.check at it when I get time. |
| 14:18 | puredanger | dnolen_: re CLJ-1499, it's ready to be screened (hey, you could help with that wink wink) |
| 14:19 | dnolen_ | puredanger: heh ok |
| 14:19 | ebaxt | Bronsa: thanks, that worked |
| 14:19 | puredanger | dnolen_: I'm still mentally wondering whether I should push forward with the additional stuff I have on it for key- and val-only iterators |
| 14:20 | ebaxt | justin_smith: thanks btw, that explains it |
| 14:20 | Bronsa | puredanger: btw re: 979 I tried loading aleph/lamina/core.typed with the new patch and didn't see any slowdown in compilation times. If anything I actually saw a minor performance improvement but that was probably a random fluctiation |
| 14:21 | puredanger | Bronsa: I'm not really expecting any slowdown, but it's a question that needs to have an answer |
| 14:21 | dnolen_ | puredanger: probably not a bad idea? keys / vals is quite common. CLJS used to not have keys / vals specific iterators, adding them lot match Clojure made a huge difference. |
| 14:21 | dnolen_ | s/lot/to |
| 14:22 | puredanger | dnolen_: I added a new interface to obtain those specific iterators, then made use of them in CLJ-1602. surprisingly little improvement. |
| 14:22 | puredanger | over the improvements already in 1602 that is |
| 14:22 | puredanger | maybe a 5% additional benefit |
| 14:23 | dnolen_ | puredanger: you benching against zipmap usage or something like that? |
| 14:23 | puredanger | there's a test in 1602 |
| 14:23 | puredanger | there are so many outstanding patches with perf improvements in different areas right now, it's hard to keep them all straight :) |
| 14:24 | puredanger | reduce over maps, keys, vals, range, repeat, cycle, iterate, vec, etc! |
| 14:26 | puredanger | dnolen_: the additional iterators required the creation of a new interface (I called it MapIterable) to provide them. I wasn't sure if I was pushing it too far for a 5% benefit. |
| 14:27 | dnolen_ | puredanger: right 5% seems kind small |
| 14:28 | puredanger | it's basically just saving the cost of creating and throwing away the entry objects, but object allocation is really fast these days |
| 14:29 | puredanger | maybe I'll make a separate ticket for it so it can be evaluated separately |
| 14:34 | EvanR | justin_smith: what about easily getting exceptions from the future thread |
| 14:35 | noonian | Evan I believe if you deref a future that threw exceptions it will throw it on the thread you deref the future from so you could try/catch your deref |
| 14:35 | noonian | EvanR* |
| 14:35 | EvanR | right... |
| 14:36 | EvanR | though my main thread is busy, it cant wait forever on a particular future |
| 14:36 | EvanR | and yet another thread for this purpose seems to have the same issues |
| 14:39 | noonian | if you want to know about exceptions on your main thread but dont want to block maybe core async is appropriate? could have a channel and deref your future in another thread (of just try/catch in your future thread) and put on the channel if you get an exception |
| 14:40 | EvanR | i dont even want to know about it in the main thread |
| 14:40 | EvanR | i just want the error print out somewhere |
| 14:40 | EvanR | i guess i have to catch all exceptions in the future |
| 14:40 | noonian | can't you just wrap your call inside future in a try/catch block then? |
| 14:44 | znn | what is the difference between a channel and a message bus? |
| 14:45 | znn | or is a channel another term for a bus and vice versa? |
| 14:45 | noonian | in this context a channel is specific to core.async, its like a queue with "blocking" put/read semantics by default |
| 14:47 | zanes | Aw man. I guess instaparse can’t parse indentation? |
| 14:48 | gfredericks | zanes: I think I remember coming to that conclusion at some point |
| 14:48 | zanes | gfredericks: Sad panda. |
| 14:48 | gfredericks | is generating keywords w/ test.check a guaranteed memory leak? |
| 14:48 | reiddraper | probably |
| 14:49 | gfredericks | I can't remember if they get GC'd somehow |
| 14:49 | amalloy | EvanR: you can put a try/catch in your future that prints the exception somewhere useful, or even write a macro/function that does that. or you can set the defaultuncaughtexceptionhandler for your whole program, which controls what happens when an exception makes it out of a thread's run() method |
| 14:50 | amalloy | gfredericks: pretty sure they do get GCd |
| 14:50 | stuartsierra | Keywords are interned as WeakReferences. |
| 14:50 | amalloy | as long as you don't hang onto them, anyway |
| 14:51 | noonian | zanes: this stackoverflow talks about trying to parse indentation ala python in instaparse: http://stackoverflow.com/questions/16779676/can-i-parse-an-indentation-based-language-using-instaparse-or-any-other-clojure |
| 14:51 | zanes | noonian: Yeah, thanks. I saw that one. |
| 14:52 | zanes | Serializing it and running it through instaparse a second time feels gross. |
| 14:52 | gfredericks | stuartsierra: amalloy: yeah that was my hunch |
| 14:52 | noonian | agreed |
| 14:52 | amalloy | gfredericks: if you're interested, the relevant code is in Keyword.intern and Util.clearCache |
| 14:52 | gfredericks | has anybody written a JSONish generator for test.check yet? |
| 14:53 | amalloy | gfredericks: how would that be different from (fmap json/generate-string ...)? |
| 14:53 | gfredericks | I remember bbloom complaining about parsing json with keywords...I assume that's just because calling .intern at runtime is slow, not because of memory concerns |
| 14:53 | stuartsierra | It's not clear to me if Keyword automatically removes references to interned keywords that are never used. |
| 14:53 | bbloom | gfredericks: ignoring perf, i'm complaining semantically |
| 14:53 | puredanger | stuartsierra: yes |
| 14:54 | puredanger | that is, yes they should get removed |
| 14:54 | amalloy | stuartsierra: never used? they're used once, of course, when they get interned. but after that if nobody has any references to them, they get cleaned up |
| 14:54 | Bronsa | stuartsierra: yeah, see Util.clearCache |
| 14:54 | bbloom | the day you decide you want a map with URLs as keys is the day you say "fuck. i wish i didn't keywordize everything" |
| 14:54 | gfredericks | amalloy: it wouldn't be necessarily generating the strings, just a restricted set of scalars & collections -- e.g., only vectors (no lists/sets), no characters, only keyword keys (or strings if bbloom is looking) |
| 14:54 | gfredericks | I think I might have just started three parallel conversations |
| 14:54 | amalloy | i always weigh in with bbloom on this one |
| 14:54 | puredanger | bbloom: given the evil things URLs do with the network, I don't think I'd use java.net.URL as a key in a map |
| 14:54 | amalloy | gfredericks: it's a test of character. you've just started a fourth i think |
| 14:54 | TimMc | Ooh, this is my favorite complaint too! |
| 14:55 | bbloom | puredanger: no, i meant string encodings of URLs |
| 14:55 | stuartsierra | An interesting idea: "soft intern" — create a new keyword, but only intern it if it's already interned. |
| 14:55 | amalloy | anyone who can keep up is clearly of high moral fibre |
| 14:55 | puredanger | bbloom: withdrawn :) |
| 14:55 | bbloom | puredanger: ie anything other than a valid keyword as a property which is valid json |
| 14:55 | amalloy | stuartsierra: why would that be useful? it's not different from the regular intern except that it allocates a map entry briefly, right? |
| 14:55 | bbloom | hell, even just id numbers :5 vs "5", neither of which are 5, which is invalid json |
| 14:56 | gfredericks | k I'm prollably gonna put a json-data generator in test.chuck |
| 14:56 | stuartsierra | amalloy: It's a vague thought: If I'm creating keywords from JSON, or an HTTP request, or something, I don't want interned keywords for things which weren't already keywords in my code. |
| 14:57 | dgleeson | hello all, does anyone know if there is a way to get at the file attributes of a file in clojure? I can see how to read and write, but what if I want to know the permissions or ownership? |
| 14:57 | stuartsierra | But I guess I wouldn't want them to be keywords at all. |
| 14:57 | puredanger | gfredericks: regarding your comment N messages ago, in 1.7 keywords and symbol no longer string intern |
| 14:57 | amalloy | stuartsierra: right, exactly: you don't want keywords |
| 14:57 | amalloy | if you *did* get keywords which weren't interned, you would be inviting disaster |
| 14:57 | stuartsierra | yeah, right |
| 14:57 | stuartsierra | of course |
| 14:57 | gfredericks | puredanger: oh I remember seeing something about that; curious what the advantage is there |
| 14:57 | puredanger | intern is slow :) |
| 14:58 | gfredericks | puredanger: does that mean keyword comparisons might require string comparisons? |
| 14:58 | puredanger | keywords are still cached |
| 14:58 | dgleeson | oh, doh, I suppose I could just use the java interopt to get that |
| 14:58 | gfredericks | okay that's the detail I was missing |
| 14:58 | amalloy | gfredericks: for your json generating thing, you can just do some slight tweaks to gen/any, right? |
| 14:58 | stuartsierra | dgleeson: Yes, you will have to use Java interop. |
| 14:58 | puredanger | gfredericks: the cache code was tweaked slightly too to make it faster |
| 14:58 | gfredericks | puredanger: so before it was effectively "interning" in two steps? |
| 14:59 | gfredericks | amalloy: totes |
| 14:59 | gfredericks | amalloy: also maybe use my double generator |
| 14:59 | puredanger | gfredericks: yes, it's all tricky |
| 15:02 | gfredericks | ~it is all tricky |
| 15:02 | clojurebot | Alles klar |
| 15:04 | gfredericks | I just sampled an old json generator I wrote and got: {:--:Rb!?8:tTJi-:iB5:8*?*m false, :JJ:8:3:T (), :d+eI:L:!KXg false} |
| 15:04 | gfredericks | curious if that's even readable |
| 15:04 | gfredericks | ,{:--:Rb!?8:tTJi-:iB5:8*?*m false, :JJ:8:3:T (), :d+eI:L:!KXg false} |
| 15:04 | clojurebot | {:--:Rb!?8:tTJi-:iB5:8*?*m false, :JJ:8:3:T (), :d+eI:L:!KXg false} |
| 15:08 | TimMc | gfredericks: Make sure to throw some \u2028 and \u2029 in there for good measure. |
| 15:10 | gfredericks | TimMc: in the oven: https://github.com/gfredericks/test.chuck/tree/regexes-2#string-from-regex |
| 15:11 | TimMc | oooo |
| 15:13 | amalloy | gfredericks: i don't want test.chuck to subsume my library, but are you aware of https://github.com/amalloy/thrift-gen ? |
| 15:14 | TimMc | gfredericks: Please tell me you have a macro that turns that BNF into clojure code. :-) |
| 15:14 | gfredericks | TimMc: what? you mean instaparse? |
| 15:15 | gfredericks | amalloy: nope |
| 15:15 | TimMc | Does instaparse do that? |
| 15:15 | gfredericks | TimMc: well it turns the BNF into a parser... |
| 15:16 | amalloy | what BNF are we even talking about? |
| 15:17 | gfredericks | I hope this one, otherwise I'm even further confused: https://github.com/gfredericks/test.chuck/blob/regexes-2/resources/com/gfredericks/test/chuck/regex.bnf |
| 15:18 | amalloy | man, who looks in resources/ anyway? |
| 15:18 | uptown | i have a different generation question. i seem to spend a lot of time wrapping fns for use by controllers of some sort. 'component' for instance. has anyone tried to generate those wrappers? maybe scanning code based on metadata tags or similar? |
| 15:32 | TimMc | I think that's called spring. |
| 15:33 | TimMc | and it is the source of all evil |
| 15:36 | clrnd | hey is there something like Akka for Clojure? |
| 15:36 | xemdetia | speaking of sources of evil, does anyone know of a quick and dirty LDAP server for integration testing? |
| 15:36 | uptown | i was hoping for a clever metamacro |
| 15:36 | uptown | but i see what you mean |
| 15:40 | amalloy | i think sdegutis has something vaguely like the evil uptown is thinking of, but i don't recall the details |
| 15:42 | gfredericks | ~metamacros are functions for writing macros for writing macros for writing functions for deleting your code |
| 15:42 | clojurebot | Cool story bro. |
| 15:42 | gfredericks | ~metamacros |are| functions for writing macros for writing macros for writing functions for deleting your code |
| 15:42 | clojurebot | You don't have to tell me twice. |
| 15:49 | turbofail | clrnd: there's some libraries that do bindings for akka - https://github.com/setrar/akka-clojure |
| 15:50 | turbofail | might be a little bit dead though |
| 15:51 | clrnd | turbofail, I see, was hoping for something actually clojurist |
| 15:52 | turbofail | message-passing isn't really the clojure way™ |
| 15:53 | stuartsierra | message-passing — with queues — is totally the Clojure way! |
| 15:53 | stuartsierra | core.async + your messaging bus of choice is really all you need. |
| 15:54 | dnolen_ | reiddraper: ping |
| 15:54 | turbofail | i guess i meant more "erlang-style message passing" |
| 15:54 | reiddraper | dnolen_: pong |
| 15:55 | dnolen_ | reiddraper: I have a some real interest to just port test.check a la core.async now (rather than wait for feature expressions), I've already started, probably won't take me long to wrap it up |
| 15:55 | dnolen_ | reiddraper: would you take a patch? |
| 15:55 | clrnd | well that's not really fault tolerant |
| 15:56 | clrnd | see akka implements actor system architectures for error tolerance |
| 15:57 | reiddraper | dnolen_: yes, however, gfredericks, aphyr and i have been doing some work that may be interesting/tough to do in js. There's a branch now that uses a new RNG, and adds parallel tests, using executors, etc. |
| 15:58 | reiddraper | just anticipating some interesting merge conflicts |
| 15:58 | gfredericks | oh I'm sure JS comes with a few block ciphers |
| 15:58 | dnolen_ | reiddraper: that's I meant about core.async style - there's separate directory for all the cljs stuff, no code sharing |
| 15:58 | reiddraper | yeah, maybe it won't be too bad then |
| 15:58 | gfredericks | well actually: http://docs.closure-library.googlecode.com/git/class_goog_crypt_Aes.html |
| 15:59 | dnolen_ | reiddraper: it means copy and pasting to but honestly I don't think it's a big deal esp. when the Clojure side may be evolving faster |
| 15:59 | dnolen_ | reiddraper: ends up being nice, was true for core.async |
| 16:00 | reiddraper | dnolen_: here's what the diff looks like at the moment: https://github.com/aphyr/test.check/compare/clojure:master...feature/parallel-testing |
| 16:00 | reiddraper | dnolen_: yeah, I think that would be great. Will we be able to run the cljs tests from the command-line? |
| 16:01 | dnolen_ | reiddraper: yep that's the idea |
| 16:01 | reiddraper | excellent |
| 16:01 | dnolen_ | reiddraper: cljs.test is basically good to go in ClojureScript master |
| 16:01 | reiddraper | gfredericks: any objections? |
| 16:01 | dnolen_ | reiddraper: so I'm making sure all the clojure.test integration stuff just works similarly w/ cljs.test |
| 16:02 | gfredericks | reiddraper: nope |
| 16:03 | gfredericks | dnolen_: what system deps do you need to run the tests? same as cljs proper? |
| 16:03 | l1x | hi guys, i was wondering what am i doing wrong here https://gist.github.com/l1x/3e991063483f1204536f |
| 16:03 | l1x | it seems i cant catch that exception |
| 16:04 | amalloy | ~map |
| 16:04 | clojurebot | map is *LAZY* |
| 16:04 | amalloy | ~botsnack |
| 16:05 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 16:05 | turbofail | crypto in javascript? |
| 16:05 | amalloy | l1x: that one's for you. map is lazy. it immediately returns a lazy seq, and your try/catch completes successfully. then, the repl tries to print your map, and gets an exception while realizing the seq |
| 16:05 | gfredericks | turbofail: the new test.check RNG uses a block cipher |
| 16:05 | l1x | amalloy: ahh this is what i missed |
| 16:05 | l1x | thanks! |
| 16:05 | gfredericks | I'd like to figure out something simpler but that would require learning how to test the quality of a RNG |
| 16:06 | amalloy | l1x: this would be more apparent if you tried printing the stacktrace, by the way |
| 16:06 | dnolen_ | gfredericks: cljsbuilds w/ :notify-command, probably simplest for everyone if we just run the tests against Node.js |
| 16:06 | amalloy | the summary message that gets printed by the repl is often not terribly useful |
| 16:06 | turbofail | gfredericks: ah, so not actual crypto-crypto |
| 16:06 | EvanR | theres dieharder for testing rngs |
| 16:06 | amalloy | but if you look at the trace, and see it's inside of printing instead of inside something else... |
| 16:06 | gfredericks | turbofail: no, not crypto-crypto-crypto |
| 16:07 | reiddraper | turbofail: actual crypto, but not for the purposes of crypto |
| 16:07 | turbofail | heh |
| 16:07 | seon | hello |
| 16:07 | seon | no one from Lyon |
| 16:07 | reiddraper | turbofail: http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf |
| 16:09 | l1x | amalloy: so is there any way to catch an exception like this? |
| 16:10 | turbofail | doall |
| 16:10 | turbofail | around the map |
| 16:11 | l1x | turbofail: thanks!! |
| 16:13 | EvanR | ~filter |
| 16:13 | clojurebot | filter doesn't stop |
| 16:14 | joobus | is aleph considered stable for production work? The bottom of the github page says "Aleph is meant to be a sandbox for exploring how Clojure can be used effectively in this context.". |
| 16:17 | ben8 | hi. quick question about compojure. I'm missing a run-jetty function? |
| 16:18 | joobus | ben8: I'm guessing you are reading some example with a run-jetty function? |
| 16:18 | joobus | ben8: ring can be used with multiple servers. run-jetty runs the jetty server, and there is some include that you'll need to use it. |
| 16:18 | ben8 | I've read several of various age I guess |
| 16:19 | ben8 | ah right, it's a ring function. compojure has an app function |
| 16:20 | Petruchio | I'm having trouble getting started with Leiningen. Per the instructions, I downloaded lein (to Ubuntu), ran it, and I just get the main help menu. |
| 16:20 | joobus | Petruchio: go to a scratch directory and do 'lein new app whateveritscalled' |
| 16:21 | joobus | Petruchio: it should make a new lein folder/app with all the relevant parts if lein installed correctly |
| 16:22 | Petruchio | Ah! I didn't get it... apparently it's already installed correctly, since that worked. Thanks. |
| 16:29 | EvanR | ,(= false nil) |
| 16:29 | clojurebot | false |
| 16:29 | EvanR | just checking |
| 16:29 | gfredericks | ,(#'= false nil) |
| 16:29 | clojurebot | false |
| 16:29 | gfredericks | oh right |
| 16:30 | Bronsa | gfredericks: did you brainfart for a second and think = was a macro or what? |
| 16:31 | gfredericks | Bronsa: yeah I confused inlining with macrotude |
| 16:32 | gfredericks | I misremembered the nature of the classic wat |
| 16:32 | Bronsa | ,(#'or true true) |
| 16:32 | clojurebot | nil |
| 16:32 | gfredericks | oh also there's that other one |
| 16:32 | gfredericks | ,('= false nil) |
| 16:32 | clojurebot | nil |
| 16:32 | gfredericks | still a falsy answer, but now quite the same ;-) |
| 16:32 | Bronsa | ,('= true true) is more effective |
| 16:32 | clojurebot | true |
| 16:32 | gfredericks | not* |
| 16:33 | Bronsa | :< no wait. |
| 16:33 | Bronsa | ,('= false true) there |
| 16:33 | clojurebot | true |
| 16:33 | stuartsierra | ugh |
| 16:33 | stuartsierra | Never do that again. |
| 16:34 | gfredericks | ,(:= false true) |
| 16:34 | clojurebot | true |
| 16:34 | gfredericks | it's great that = := '= and #' are all callable |
| 16:35 | gfredericks | #'= I mean |
| 16:35 | gfredericks | ,#{= := '= #'=} |
| 16:35 | clojurebot | #{= #'clojure.core/= #<core$_EQ_ clojure.core$_EQ_@88f71a> :=} |
| 16:36 | nullptr | ,((juxt = := '= #'=) 1 2) |
| 16:36 | clojurebot | [false 2 2 false] |
| 16:37 | gfredericks | ,(let [eqs [= := '= #'=]] ((fn [[f & args]] (apply f args)) (shuffle eqs))) |
| 16:37 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol> |
| 16:37 | gfredericks | ,(let [eqs [= := '= #'=]] ((fn [[f & args]] (apply f args)) (shuffle eqs))) |
| 16:37 | clojurebot | false |
| 16:38 | gfredericks | I guess that could be written a little clearer |
| 16:38 | gfredericks | ,(let [eqs [= := '= #'=], [f & args] (shuffle eqs)] (apply f args)) |
| 16:38 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol> |
| 16:45 | l1x | joobus: i tried the netty version but it was yielding to less performance as stock compojure with jetty |
| 16:45 | ztellman | joobus: yes, it's used extensively in production, that sentence hasn't changed in three years |
| 16:46 | joobus | ztellman: thanks. |
| 16:46 | l1x | haha, i did not realize the author is here! :) |
| 16:46 | l1x | ztellman: did you measure the performance of aleph? |
| 16:46 | joobus | ztellman: I'm guessing you favor event-based architecture for web servers? |
| 16:46 | ztellman | l1x: https://github.com/ptaoussanis/clojure-web-server-benchmarks/ |
| 16:47 | ztellman | joobus: I favor having the ability to do async and streaming request/responses |
| 16:47 | ztellman | but the synchronous ring model is good enough for most cases |
| 16:48 | joobus | ztellman: yeah, i'm at the point of picking one or the other for a project right now, and at this point it is a toss-up, but I don't want to limit myself down the line. Currently, I use python's twisted framework for most of my web stuff, so I am familiar with the event-based model right now. |
| 16:49 | ztellman | joobus: the concurrency model for Aleph is pretty similar to Twisted's |
| 16:49 | joobus | i know, i've been reading your/the docs :) |
| 16:50 | ztellman | well, happy to answer any questions |
| 16:51 | l1x | ztellman: thanks |
| 16:52 | joobus | i don't have any brainbusters for you today. I did just notice that benchmarks graph has looked different every time I've looked at it. |
| 16:52 | EvanR | always run it until it breaks a speed record |
| 16:52 | EvanR | then publish i |
| 16:52 | ztellman | no, we did extensive testing across all of them, with feedback from all the authors |
| 16:53 | ztellman | mostly it's just that people are actively working on improving performance |
| 16:53 | l1x | ztellman: are you familiar with this project? https://github.com/basho/basho_bench |
| 16:53 | ztellman | a lot of the approaches used by one server tend to get borrowed, too |
| 16:53 | l1x | prefer latency + throughput together on a chart when talking about performance |
| 16:53 | ztellman | l1x: latency is in the raw data |
| 16:53 | l1x | cool |
| 16:53 | l1x | thanks |
| 17:00 | Jaood | ztellman: was the reason of the improvement in performance of Aleph from May to Nov? or is it that just performs much better with big hardware? |
| 17:01 | ztellman | jaood: May was 0.3.x, November is 0.4.x |
| 17:01 | ztellman | basically a ground-up rewrite |
| 17:01 | ztellman | a lot of the improvement is from using the latest Netty |
| 17:03 | mgaare | I've been working on updating a little TCP server app that was originally on aleph 0.3 to the stack around aleph 0.4. Liking it so far |
| 17:06 | l1x | ztellman: nice! |
| 17:06 | mgaare | ztellman: it might be nice to have a link to the aleph google group somewhere in the readme, since there's a lot of useful stuff on the group that helps fill in the gaps until the documentation catches up |
| 17:06 | l1x | i am rerunning my benchmarks just noticed the new version |
| 17:06 | Jaood | ztellman: cool, thx |
| 17:07 | ztellman | l1x: here's latency metrics from an earlier run of the benchmark https://github.com/ptaoussanis/clojure-web-server-benchmarks/blob/5fd6ec249851dd9ab08e32f590929a9a2f3cced8/results/20141025-20-40.png |
| 17:07 | ztellman | it was too tedious to do it for every run |
| 17:08 | l1x | ztellman: thanks, this is exactly why i settled on basho_bench |
| 17:08 | l1x | it just 2 commands and you are done |
| 17:09 | ztellman | l1x: might be worth investigating for this, or we just write a little turd script that turns the benchmark output into a csv |
| 17:19 | l1x | ztellman: cool |
| 17:19 | l1x | ztellman: where did the wrap-ring-handler function go from aleph? |
| 17:19 | ztellman | l1x: it's gone, aleph handlers = ring handlers |
| 17:19 | ztellman | except that aleph handlers can returned a deferred response |
| 17:20 | l1x | nice one! |
| 17:20 | noonian | long time passing |
| 17:21 | l1x | ztellman: WARNING: get already refers to: #'clojure.core/get in namespace: hystrix-event-stream-clj.core, being replaced by: #'aleph.http/get |
| 17:21 | Jaood | ztellman: does Aleph implements ring-core or it implements some ring netty adapter? |
| 17:22 | ztellman | Jaood: it follows the ring spec for requests and responses |
| 17:23 | ztellman | I'm not sure if the lein plugins for Ring would work with it, last I checked they assumed servlets but that may have changed |
| 17:27 | nicferrier | can anybody think of a good way to handle async http requests with go blocks? |
| 17:27 | amalloy | l1x: that's a warning to remind you to stop using :use |
| 17:27 | ztellman | nicferrier: aleph can do that |
| 17:27 | amalloy | (or :refer :all) |
| 17:27 | ztellman | nicferrier: you just coerce the channel returned by a go block to a Manifold deferred |
| 17:27 | nicferrier | ztellman: looking, thx. |
| 17:28 | puredanger | …. said the technologically advanced alien |
| 17:28 | puredanger | seriously, that was like the nerdiest thing I heard all day ztellman |
| 17:28 | ztellman | puredanger: I try |
| 17:28 | l1x | amalloy: you are right, i have stopped using it, but this time i got the code from my co-worker and guess what :) |
| 17:28 | l1x | thanks for pointing out though |
| 17:28 | amalloy | l1x: put the fear of god into your co-worker |
| 17:29 | l1x | :D |
| 17:29 | l1x | ztellman: i see lots of 500 errors in the logs are you interested what is happening or you are aware of these ? |
| 17:30 | ztellman | l1x: this is in the webserver-benchmark? |
| 17:30 | l1x | yes |
| 17:30 | l1x | well it seems the new code is a little bit unhappy with hystrix |
| 17:30 | ztellman | l1x: I'm not aware of any issues, happy to look at any stack traces |
| 17:31 | l1x | this is weird |
| 17:31 | l1x | the performace is up ~20% |
| 17:31 | ztellman | why is hystrix being used in the benchmarks, exactly? |
| 17:32 | l1x | http://s4.postimg.org/arrpn2x4s/summary.jpg |
| 17:32 | l1x | out stack works with hystrix |
| 17:33 | ztellman | oh, this isn't the standard benchmark, it's your service, gotcha |
| 17:33 | l1x | yes, sorry, i misunderstood your question earlier |
| 17:33 | l1x | i wanted to compare our stack + aleph 0.3 vs. our stack + aleph 0.4 |
| 17:33 | ztellman | I see |
| 17:34 | l1x | yeah it looks pretty sweet |
| 17:34 | ztellman | yeah, should be an across-the-board improvement |
| 17:34 | ztellman | but at that throughput maybe not too drastic |
| 17:34 | l1x | ok, i am going to figure out why hystrix is unhappy |
| 17:34 | l1x | this is on my 13" mbp |
| 17:34 | l1x | do you have any performance recommendation how to start up the service? |
| 17:35 | l1x | :max-threads 200 :min-threads 20 or something like that |
| 17:35 | ztellman | oh |
| 17:35 | ztellman | the defaults should be okay |
| 17:35 | ztellman | you can specify the executor |
| 17:35 | ztellman | check out aleph.flow |
| 17:35 | l1x | cool thanks! |
| 17:42 | arohner | l1x: FYI, the words "async", "performance" and "hystrix" are unlikely to go together well, depending on your load |
| 17:43 | arohner | (assuming you're using the default hystrix thread pool) |
| 17:44 | m1dnight_ | is there a function that allows me to modify the statements in tail position of a form? |
| 17:44 | m1dnight_ | im wanting to replace either all recurs (which are in tail position by definition) or otherwise the other expressions in tail position |
| 17:45 | l1x | arohner: i see, do you have any more details? we are in the initial phase of this project |
| 17:45 | l1x | so if you have more context please share it |
| 17:45 | arohner | m1dnight_: you could use a (complex, hard to write) macro to do that, but first I'd ask why |
| 17:45 | ztellman | m1dnight_: https://github.com/ztellman/vertigo/blob/master/src/vertigo/core.clj#L409-L441 |
| 17:45 | arohner | l1x: hystrix runs each command in a separate thread, so then if the command times out, it just terminates the thread |
| 17:45 | m1dnight_ | because i'm writing an actor library for my thesis and I have to have hooks when a receive block (which is my macro) finished |
| 17:46 | arohner | l1x: that works fine, but lots of threads = lots of context switching, which is a problem if you want "real" performance |
| 17:47 | arohner | l1x: if you care more about reliability, that's great. I'm just pointing it out because you were mentioning benchmarks |
| 17:47 | l1x | hmm i see what you mean |
| 17:49 | TimMc | arohner: Have you played around with their newer support for rx? |
| 17:49 | arohner | TimMc: no |
| 17:49 | TimMc | Previously there was no way for an Observable-emitting Hystrix command to register failure (leading to a circuit breaker trip) but I hear they've addressed that now. |
| 17:50 | l1x | arohner: what is the alternative way of handling a request lets say skip hystrix, just use a go block or something |
| 17:50 | l1x | is there a good pattern to lets say talk to a DB with a timeout and retry? |
| 17:50 | arohner | TimMc: I don't know enough about how Rx works. What is the recovery situation like? they still terminate your thread? |
| 17:52 | arohner | l1x: probably, but that depends on your DB drivers |
| 17:52 | arohner | l1x: if you need serious performance, the best way is to process all the async requests in the same thread, using NIO select |
| 17:53 | arohner | but that code is tricky to write, so I wouldn't recommend it unless you know you need it |
| 17:57 | l1x | hmm alright, i am going to investigate this more, thanks for the info |
| 18:06 | wildnux | hi, if i have a seq of objects (say eg, File objects i got using file-seq ), how do i turn the list into a map of name attribute of object and the object itself? |
| 18:07 | wildnux | i tried (map #(assoc m (.getName %) %) s) |
| 18:07 | wildnux | but it created many maps |
| 18:08 | justin_smith | what is m ? |
| 18:08 | amalloy | wildnux: you are looking for reduce |
| 18:08 | Bahman | wildnux: fold the list. |
| 18:08 | justin_smith | yeah, actually that does sound like a reduce |
| 18:08 | wildnux | justin_smith: the map is called inside let binding, m is empty map |
| 18:10 | wildnux | basically i was doing something like this: (let [s (filteredseqoffilesindir d) m {}] (map #(assoc m (.getName %) %) s)) |
| 18:11 | justin_smith | ,(reduce #(assoc % %2 (name %2)) {} [:a :b :c :d]) ; something like this |
| 18:11 | clojurebot | {:d "d", :c "c", :b "b", :a "a"} |
| 18:11 | justin_smith | but with (.getName %2) %2 instead |
| 18:11 | wildnux | justin_smith: cool, let me try |
| 18:12 | TimMc | arohner: Recovery situation? |
| 18:12 | justin_smith | wildnux or (group-by #(.getName %) files) - especially good if more than one file may have the same base name |
| 18:12 | wildnux | justin_smith: i tried replacing map with reduce but did not work.. probably i needed to pass empty map as well for it to fold the list |
| 18:12 | justin_smith | and it takes an extra arg, the accumulator |
| 18:12 | amalloy | it is a common beginner error to try and modify an immutable object in a for loop or a map or something |
| 18:12 | arohner | TimMc: in your Rx + hystrix situation. 'normal' hystrix terminates the thread. I was asking how Rx Hystrix recovers there |
| 18:13 | amalloy | remember that in clojure, objects never change. if m starts as {}, it will be {} forever. the way to do this sort of "incremental build-up" of an object is with a recursive function, or with reduce, which is the same thing under the hood |
| 18:14 | TimMc | arohner: Hmm, not sure. I didn't dig that much into hystrix in the first place after finding out it didn't work well with rx (at the time.) |
| 18:15 | wildnux | justin_smith: actually i am calling function on that file object so probably group-by does not work |
| 18:15 | justin_smith | why would calling a function on the file make the group-by not work? |
| 18:15 | wildnux | calling function on that object as the value of the map |
| 18:16 | justin_smith | oh, I see |
| 18:16 | wildnux | what i am trying is get list of classes from all of jar files in a directory |
| 18:17 | justin_smith | ahh, so the key is .getName and the val is some function call |
| 18:17 | wildnux | so, i have file-seq on that directory, filter jar files, create JarFile out of them and get enumeration of the contents, then again filter based on .class |
| 18:17 | wildnux | and now, i have list of classes for a single jar, i want to write a function which can give me map of jarfile name (absolute path) and the classes in them |
| 18:17 | wildnux | :) |
| 18:19 | wildnux | justin_smith: yes |
| 18:19 | justin_smith | ,(into {} (map (juxt keyword #(str % (.toUpperCase %))) ["a" "b" "c"])) |
| 18:19 | clojurebot | {:a "aA", :b "bB", :c "cC"} |
| 18:19 | justin_smith | juxt / map / into will do that trick |
| 18:20 | justin_smith | actually, for is often more readable for that (but it would do the same thing) |
| 18:20 | wildnux | justin_smith: cool, let me try juxt as well |
| 18:20 | wildnux | for some reason, i have not been able to get my head around using for for looping and collecting value easily :( |
| 18:21 | justin_smith | for is not a loop |
| 18:21 | justin_smith | it's a list comprehension |
| 18:22 | wildnux | justin_smith: what is the best way to accumulate values using for? |
| 18:22 | dbasch | justin_smith: feature request: parse chat lines that have “for” and “loop” in them, and make the bot reply |
| 18:22 | justin_smith | ,(into {} (for [c ["a" "b" "c"]] [(keyword c) (str c (.toUpperCase c))])) |
| 18:22 | clojurebot | {:a "aA", :b "bB", :c "cC"} |
| 18:22 | justin_smith | dbasch: that is a good one |
| 18:22 | justin_smith | though it could be annoying if you do it wrong |
| 18:23 | amalloy | ~for |
| 18:23 | clojurebot | for is not a loop |
| 18:23 | dbasch | feature request: make amalloy a bot |
| 18:24 | EvanR | ~though |
| 18:24 | clojurebot | Cool story bro. |
| 18:24 | wildnux | dang! |
| 18:24 | amalloy | dbasch: i did that a while ago. amalloybot was a rousing success |
| 18:24 | hyPiRion | ~amalloy |
| 18:24 | clojurebot | amalloy is the spotlight illuminating my dumb mistakes |
| 18:24 | TimMc | ~amalloybot |
| 18:24 | clojurebot | Cool story bro. |
| 18:25 | amalloy | apparently this was on march 10th: http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-03-10.txt |
| 18:26 | justin_smith | lol, I remember it like it was yesterday |
| 18:29 | m1dnight_ | Is there a particular reason that macroexpand does not do a "deep" expand? |
| 18:29 | m1dnight_ | it's simply solved by (postwalk macroexpand <form>) though, but i'm not sure |
| 18:30 | ztellman | midnight_ macroexpand is for the top-level form, by definition |
| 18:30 | amalloy | m1dnight_: because it's not the compiler, and trying to be the compiler is hard |
| 18:30 | ztellman | m1dnight_ and don't use postwalk with macroexpand, that will cause issues |
| 18:30 | ztellman | https://github.com/ztellman/riddley |
| 18:30 | amalloy | postwalk macroexpand, for example, is one of those things that works great for simple cases but breaks if you try to rely on it |
| 18:32 | amalloy | ztellman: how does that compare to the stuff in tools.macro? |
| 18:32 | m1dnight_ | hrm, any hints, then? |
| 18:32 | m1dnight_ | I can't imagine a case where it could break too, though |
| 18:32 | ztellman | amalloy: last I checked, tools.macro didn't do inline function transformation, and didn't differentiate between expressions and non-expression forms |
| 18:33 | amalloy | m1dnight_: easy. (quote (let 1)) |
| 18:33 | ztellman | m1dnight_ did you see this wen I posted it earlier? https://github.com/ztellman/vertigo/blob/master/src/vertigo/core.clj#L409-L441 |
| 18:33 | m1dnight_ | ztellman: Yes, that's what Im using |
| 18:33 | ztellman | I see |
| 18:33 | m1dnight_ | but i'm thinking that it requires an exanded form, no? |
| 18:33 | ztellman | so yeah, use riddley.walk/macroexpand-all |
| 18:33 | ztellman | and apply that |
| 18:33 | ztellman | that's what the code surrounding the quoted region does |
| 18:33 | amalloy | that's a perfectly fine expression, which produces the list (let 1). but if you postwalk macroexpand, it will break because it doesn't understand quoting |
| 18:34 | m1dnight_ | oh, I did not notice the macroexpand-all |
| 18:34 | m1dnight_ | :) sorry |
| 18:34 | ztellman | no worries |
| 18:35 | amalloy | ztellman: expressions and non-expression forms? i think i understand the difference between those two things but not what tools.macro does wrong with them |
| 18:35 | ztellman | amalloy: oh, I just meant that tools.macro didn't give you a way to walk expressions and transform them |
| 18:36 | ztellman | w.r.t. macorexpansion I think the issue is only inline functions |
| 18:36 | amalloy | inline functions? |
| 18:36 | amalloy | oh |
| 18:36 | amalloy | inlined functions :P |
| 18:36 | ztellman | :inline functions |
| 18:36 | ztellman | not handling that will break pervasive transforms pretty badly, sometimes |
| 18:36 | amalloy | yeah, fair enough, that seems like it could matter |
| 18:37 | amalloy | actually i just remembered another issue with tools.macro that is pretty interesting. i wonder if riddley handles it right |
| 18:37 | ztellman | file an issue if not |
| 18:38 | ztellman | amalloy: oh, and tools.macro passes in a nil &env, too |
| 18:38 | ztellman | again, last time I checked |
| 18:39 | amalloy | ztellman: yeah, pretty sure it does |
| 18:39 | amalloy | ztellman: riddley doesn't have macrolet, does it? |
| 18:39 | ztellman | amalloy: it trivailly could |
| 18:40 | ztellman | trivially* |
| 18:40 | amalloy | macrolet is like the only thing in tools.macro i use |
| 18:40 | ztellman | I just haven't needed it |
| 18:40 | amalloy | ztellman: (macrolet [(m [x] `(case ~x ~@(mapcat (partial repeat 2) (range 10))))] (m 9)) is a way to reproduce the problem in tools.macro |
| 18:40 | amalloy | it doesn't break for numbers smaller than 10 and 9, which is the fun part |
| 18:41 | Bronsa | amalloy: ouch. sorted map -> hash map |
| 18:41 | amalloy | Bronsa: yep |
| 18:41 | Bronsa | amalloy: I don't think that's tools.macro's fault |
| 18:41 | amalloy | Bronsa: yeah it is |
| 18:41 | Bronsa | uh ok. |
| 18:41 | amalloy | tools.macro implements something like postwalk, and does it via like (cond (map? x) (into {} (map ... x))) |
| 18:42 | Bronsa | ah, gotcha |
| 18:42 | Bronsa | ,(defmacro x [] (sorted-map 1 1)) |
| 18:42 | clojurebot | #'sandbox/x |
| 18:42 | Bronsa | ,(class (x)) |
| 18:42 | clojurebot | clojure.lang.PersistentArrayMap |
| 18:42 | Bronsa | i thought it was a case of that ^ |
| 18:42 | amalloy | i don't think so |
| 18:43 | amalloy | because the sorted map emitted by the macroexpansion of case is consumed by case* at macro time, not emitted to be eval'd |
| 18:43 | Bronsa | yeah, makes sense |
| 18:45 | ztellman | amalloy: I do handle that case correctly |
| 18:45 | ztellman | I ended up getting bit by it in automat |
| 18:45 | amalloy | ztellman: anyway, feature request: add macrolet, c'mon how can you be a macro library without macrolet |
| 18:46 | ztellman | amalloy: https://github.com/ztellman/riddley/blob/master/src/riddley/walk.clj#L161 |
| 18:46 | ztellman | yeah, ok |
| 18:50 | amalloy | ztellman: is a special-cased handler for case really the right way to do this? what if someone else writes a macro like case that needs to emit a sorted map for consumption by something else? |
| 18:50 | ztellman | amalloy: this is the underlying case* map |
| 18:51 | ztellman | if they want to handle sorted-map specially, they can define a special handler for whatever their scope is |
| 18:52 | ztellman | since we don't know what the comparator is, that's the only way we can do it |
| 18:52 | amalloy | i see, you first go through their predicate/handler function |
| 18:53 | ztellman | amalloy: right, and if the predicate fires, I don't descend any further |
| 18:53 | ztellman | you can have scoped transforms |
| 18:54 | chouser | What if I want to write some transit data, but for any object that doesn't have a write handler, I'd like to just write out a special symbol, like 'unwritable. That should be possible, right? |
| 18:55 | amalloy | ztellman: what about https://github.com/ztellman/riddley/blob/master/src/riddley/walk.clj#L242-L243 ? it won't trigger this case/case* issue because you handle that separately. but if i want to transform some of my code, and it's inside of a map that's sorted and needs to stay sorted, i don't want to have to handle that myself |
| 18:56 | ztellman | amalloy: you can halt the walk when you find a sorted map |
| 18:56 | ztellman | unless (empty sorted-map) retains the comparator? |
| 18:56 | ztellman | in which case I should change that |
| 18:56 | Bronsa | ztellman: it does |
| 18:56 | ztellman | oh! |
| 18:57 | ztellman | ok, new release forthcoming soon |
| 18:57 | amalloy | lovely |
| 18:58 | amalloy | ztellman: you can enjoy the shiny new features in 1.4 by using mapv here, too: https://github.com/ztellman/riddley/blob/master/src/riddley/walk.clj#L237 |
| 18:58 | ztellman | amalloy: eh, I'll use (into (empty x) ...) just to make sure I retain whatever weirdo vector type it is, too |
| 19:01 | amalloy | ,(var inc dec) |
| 19:01 | clojurebot | #'clojure.core/inc |
| 19:01 | amalloy | very funny, clojure |
| 19:04 | amalloy | ztellman: why is walkable? defined the way it is? is it intended to roughly correspond to "forms which could possibly be macro invocations" or what? it seems weird to say "sequential but not a vector or a map entry" |
| 19:04 | amalloy | ie, it looks kinda like a weird way to write the function seq? |
| 19:04 | ztellman | amalloy: I'm pretty sure walkable? means expression-ish |
| 19:05 | ztellman | yeah, it's only used by walk-exprs |
| 19:05 | ztellman | poor name |
| 19:06 | amalloy | i don't get expression-ish at all. vectors are expression-ish, in that they are actual expressions |
| 19:08 | amalloy | if you just used seq? instead of defining walkable? i think you'd be fine; all the uses of walkable? that exist seem to be using it to check for a special form |
| 19:08 | ztellman | amalloy: it's been a while since I looked at this code, I recall some reason seq? wasn't good enough |
| 19:08 | ztellman | just not what it was |
| 19:08 | ztellman | and I may have been wrong |
| 19:10 | amalloy | i worry because Sequential is an open interface, of course, so someone can write a sequential thing which is neither a vector nor a seq, so that you'll think it's walkable but the compiler wouldn't actually treat it as a macro invocation |
| 19:10 | ztellman | fair point |
| 19:26 | crispin | hi there crew! |
| 19:26 | crispin | I cant get *command-line-args* to work |
| 19:26 | crispin | I want to get the name of the executable, argv[0] in other languages |
| 19:26 | crispin | if I (defn -main [& args] |
| 19:27 | crispin | args is everything but the first argument |
| 19:27 | crispin | if I use *command-line-args*, the same thing with lein run, and nil with a binary |
| 19:27 | crispin | how do you get the name of the executable |
| 19:28 | crispin | Im using "lein bin" to make a standalone executable |
| 19:29 | crispin | https://github.com/Raynes/lein-bin |
| 19:30 | crispin | $ lein run arg1 arg2 |
| 19:30 | crispin | Program: arg1 |
| 19:31 | crispin | $ target/binary arg1 arg2 |
| 19:31 | crispin | Program: nil |
| 19:34 | crispin | http://rosettacode.org/wiki/Program_name#Clojure |
| 19:35 | crispin | ^ this doesnt work |
| 19:35 | justin_smith | crispin: with a *nix type system, you should find it via (System/getenv "_") |
| 19:35 | justin_smith | ,(System/getenv "_") |
| 19:35 | clojurebot | #<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv._)> |
| 19:35 | crispin | yeah its unix... let me try |
| 19:37 | crispin | $ lein run arg1 arg2 |
| 19:37 | crispin | Program: /usr/bin/java |
| 19:37 | crispin | $ target/binary arg1 arg2 |
| 19:37 | crispin | Program: nil |
| 19:37 | crispin | works with leiningen. Doesn't work with standalone |
| 19:38 | crispin | but good idea to use java interop |
| 19:38 | justin_smith | OK. Try printing the output of (System/getenv) from the standalone, there may be some env key |
| 19:38 | justin_smith | if it's anywhere at all that is |
| 19:40 | crispin | justin_smith: nope |
| 19:40 | crispin | has SHELL, and PWD |
| 19:40 | crispin | but no executable name |
| 19:40 | crispin | sheeeeet :P Am I gonna have to look up the PID in /proc? |
| 19:40 | crispin | blech |
| 19:41 | justin_smith | that's weird, because I know for a fact that the shell puts that info into env for the java process |
| 19:41 | justin_smith | so I don't know why java is hiding it from you... |
| 19:41 | crispin | it could be a side effect of lein bin |
| 19:41 | crispin | now the header of the self executable is... |
| 19:41 | crispin | :;exec java -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -client -Droll.version=0.1.0-SNAPSHOT -jar $0 "$@" |
| 19:41 | crispin | @echo off |
| 19:41 | crispin | java -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -client -Droll.version=0.1.0-SNAPSHOT -jar %1 "%~f0" %* |
| 19:41 | crispin | goto :eof |
| 19:42 | crispin | but I dont see how thats removing the /usr/bin/java |
| 19:44 | crispin | I think it must be an issue with lein-bin |
| 19:45 | crispin | will open an issue on the project and see what comes out of it |
| 19:47 | justin_smith | if nothing else, you should be able to modify that header to pass in the executable name |
| 19:51 | crispin | submitted ticket: https://github.com/Raynes/lein-bin/issues/19 |
| 19:51 | crispin | yes, thanks for your help justin_smith |
| 19:52 | justin_smith | cool info of the day "You can get anyone's SSH pubkey from GitHub via https://github.com/USERNAME.keys . Handy for giving people access to servers." |
| 19:53 | dbasch | (inc justin_smith) great to know |
| 19:54 | dbasch | (inc _) |
| 19:54 | lazybot | ⇒ 1 |
| 19:54 | dbasch | (inc justin_smith) |
| 19:54 | lazybot | ⇒ 160 |
| 20:29 | crack_user | hey guys |
| 20:30 | crack_user | some one have a good article about clojure immutability internals? |
| 20:31 | justin_smith | hyPiRion has a good series of blog posts on persistentvector |
| 20:31 | TimMc | ++ to that, good series |
| 20:31 | justin_smith | http://hypirion.com/musings/understanding-persistent-vector-pt-1 |
| 20:32 | justin_smith | (inc hyPiRion) |
| 20:32 | lazybot | ⇒ 57 |
| 20:33 | TimMc | (inc hyPiRion) |
| 20:33 | lazybot | ⇒ 58 |
| 20:36 | triss | so just to double check in clojure the theory for the most part is to keep all the do and doseq etc in the applicaion level of code? |
| 20:38 | triss | you would try not to hide these in he api and make sure its happens from a single place? |
| 20:38 | triss | or am I not getting FP? |
| 20:40 | ztellman | triss: it depends if the library needs to do side effects |
| 20:40 | ztellman | if they're interacting with Java libraries, they often do |
| 20:40 | triss | ah ok... coz thats exactly what i've been doing |
| 20:40 | triss | just had a little panic there... |
| 20:41 | triss | so this "virtual dom" idea... is that becoming really common in libs too? |
| 20:42 | triss | but mapped across different objects? |
| 20:42 | triss | the code I'm writing is fast becoming a library |
| 20:43 | triss | and I can't really work if there any best practices you could folllow for wrappng oo code |
| 20:44 | triss | ^wrapping oo java/js code in clojure style clothing |
| 20:50 | NoCreativity | Hello people |
| 20:51 | NoCreativity | Im trying to use clojure.java.jdbc and reuse a transaction, but something is going wrong and my transaction loses connection with database before I can insert all data. Does anybody has any tips ? |
| 20:51 | gratimax | can you confirm that you are actually connected to the database for some period of time |
| 20:52 | justin_smith | NoCreativity: also, that symptom can be caused by trying to use a lazy operation like map or for inside a db operation |
| 20:52 | NoCreativity | gratimax: yes! I have an answer from it with the generated primary key |
| 20:52 | justin_smith | where by the time the laziness is forced, you are no longer in the transaction context |
| 20:52 | NoCreativity | justin_smith: Aw jeez |
| 20:52 | justin_smith | so be sure you aren't doing anything lazy in the db |
| 20:53 | NoCreativity | justin_smith: Im trying to use for |
| 20:53 | justin_smith | OK, wrap it in a doall |
| 20:53 | justin_smith | or use doseq instead of for |
| 20:53 | justin_smith | laziness and resource lifetimes don't play nicely together |
| 20:53 | gratimax | well you got to it before I did :P |
| 20:53 | NoCreativity | Thx a lot, guys! |
| 20:53 | NoCreativity | I will try here |
| 20:57 | crack_user | can I convert clojure symbol to string? |
| 20:57 | justin_smith | ,(name 'sym) |
| 20:57 | clojurebot | "sym" |
| 20:57 | gfredericks | ,(name 'com.gfredericks.forks.org.clojure.test.check.generators.properties/cats) |
| 20:57 | clojurebot | "cats" |
| 20:59 | crack_user | the ' does the symbol not evaluate? |
| 20:59 | justin_smith | ,''cats |
| 20:59 | clojurebot | (quote cats) |
| 20:59 | justin_smith | it's a read syntax for quote |
| 20:59 | justin_smith | which gives you a symbol, instead of resolving it |
| 21:00 | justin_smith | ,'''cats |
| 21:00 | clojurebot | (quote (quote cats)) |
| 21:00 | justin_smith | s/symbol/value |
| 21:01 | crack_user | it makes sense |
| 21:07 | gfredericks | ,(cycle '(boots cats)) |
| 21:07 | clojurebot | (boots cats boots cats boots ...) |
| 21:10 | gfredericks | help I'm about to write a custom data structure |
| 21:14 | amalloy | gfredericks: put down the keyboard and back away slowly |
| 21:15 | NoCreativity | Im so stupid |
| 21:15 | NoCreativity | :( |
| 21:15 | NoCreativity | (sql/db-set-rollback-only! t-con) |
| 21:16 | NoCreativity | It would never commit my stuff |
| 21:17 | NoCreativity | Well... btw... I think I need more 4clojure training and reading... :( Again, thank you guys! It made my night. =] Now I'm happy again. |
| 21:18 | gfredericks | maybe I'll just start with a sorted set |
| 21:19 | justin_smith | NoCreativity: actually, since none of 4clojure deals with side effects, the gotchas of lazy-seqs are not really covered I don't think |
| 21:19 | NoCreativity | justin_smith: hmmm... Okay. This made me feel better! =D |
| 21:20 | NoCreativity | justin_smith: Well... I think these relational databases are going to help me somehow on learning datastructure functions to build data the way I want. |
| 21:20 | NoCreativity | I hope Im right. ^ ^ |
| 21:38 | TimMc | gfredericks: Stop it you're making me want to pick up Overtone again! |
| 21:39 | TimMc | boots and cats and boots and cats and boots and boots and boots and cats |
| 21:39 | gfredericks | TimMc: huh? like to play boots and cats? |
| 21:39 | TimMc | generative music in general |
| 21:40 | gfredericks | ,(repeatedly #(rand-nth '(boots boots cats))) |
| 21:40 | clojurebot | (cats boots boots cats boots ...) |
| 21:42 | TimMc | That generates long stretches of the same word. |
| 21:43 | TimMc | ,(sort-by key (frequencies (map count (partition-by identity (repeatedly 100 #(rand-nth '(boots boots cats))))))) |
| 21:43 | clojurebot | ([1 18] [2 9] [3 4] [4 4] [5 1] ...) |
| 21:44 | TimMc | True randomness is less satisfying. |
| 21:46 | justin_smith | TimMc: yeah, algorithmic composition code is often full of stuff like (repeat (+ x (rand-int y)) z) |
| 21:46 | justin_smith | though Xenakis was fond of requiring that events in his compositions fit a poisson distribution |
| 21:47 | justin_smith | he was an outlier though |
| 21:47 | justin_smith | (he also made the first GUI for making music with) |
| 21:49 | gfredericks | okay I have no idea how sorted-set-by works |
| 21:50 | gfredericks | ,(def self (sorted-set-by #(> %1 %2))) |
| 21:50 | godd2 | gfredericks you mean what it does or how it does what it does? |
| 21:50 | clojurebot | #'sandbox/self |
| 21:50 | gfredericks | ,(conj self 5 1 4 2 3) |
| 21:50 | amalloy | gfredericks: it takes a comparator, not a predicate |
| 21:50 | clojurebot | #{5 4 3 2 1} |
| 21:50 | amalloy | right? |
| 21:50 | gfredericks | ,(def self (sorted-set-by #(compare %1 %2))) |
| 21:50 | clojurebot | #'sandbox/self |
| 21:50 | gfredericks | ,(conj self 5 1 4 2 3) |
| 21:50 | clojurebot | #{1 2 3 4 5} |
| 21:50 | gfredericks | ,(def self (sorted-set-by #(compare %2 %1))) |
| 21:50 | clojurebot | #'sandbox/self |
| 21:50 | gfredericks | ,(conj self 5 1 4 2 3) |
| 21:50 | clojurebot | #{5 4 3 2 1} |
| 21:50 | gfredericks | I don't get this behavior at my repl |
| 21:51 | gfredericks | oh I bet it's that damn puget |
| 21:51 | amalloy | gfredericks: your pretty-printer is evil |
| 21:51 | amalloy | what is the draw of puget? so far all i've heard about it is weird bugs |
| 21:52 | justin_smith | PRETTY COLORS |
| 21:52 | gfredericks | compared to no pretty printer or to some other one I don't know about? |
| 21:52 | amalloy | compared to no pretty printer |
| 21:52 | gfredericks | you must never deal with data |
| 21:53 | amalloy | i manually pprint the things i want pretty |
| 21:53 | amalloy | it's not onerous |
| 21:54 | gfredericks | we each have our own stockholm syndrome |
| 21:54 | amalloy | i suppose so. but everyone else's is dumb |
| 21:55 | justin_smith | ~everyone else |is| dumb |
| 21:55 | clojurebot | 'Sea, mhuise. |
| 21:55 | gfredericks | so if I want to handle generic unicode "characters" I'm gonna use length-1-or-2 Strings is that accurate? or maybe int I guess? |
| 21:56 | justin_smith | gfredericks: the jvm native representation is 32 bit, right? |
| 21:57 | justin_smith | so, thanks to sign issues, I would think you would need a long |
| 21:57 | TimMc | gfredericks: Is this a regex generator thing? |
| 21:57 | gfredericks | TimMc: generator *from* a regex |
| 21:58 | gfredericks | justin_smith: oh snapchat maybe so; I'll just stick with strings |
| 22:02 | TimMc | "oh snapchat" |
| 22:03 | gfredericks | that's what the kids say these days right? |
| 22:04 | TimMc | I think so |
| 22:14 | andyf | gfredericks: Max code point fits in 20 or 21 bits so int is enough |
| 22:14 | gfredericks | andyf: why would justin_smith lie to me? |
| 22:15 | andyf | Yeah, still working out some kinks in his OS |
| 22:17 | andyf | There was a proposal for Unicode lib sent to clojure-Dev in early Oct 2014 . Not sure if it would have anything of use for you |
| 22:18 | justin_smith | andyf: wait, I thought it was a 32 bit representation? |
| 22:18 | gfredericks | oh the connection between code points and surrogats is nontrivial isn't it |
| 22:18 | gfredericks | sourroguhts |
| 22:18 | gfredericks | sourguts |
| 22:18 | gfredericks | soregum |
| 22:19 | andyf | Depends on what you call trivial :-). Just a bit of shifting and anding/prong |
| 22:19 | andyf | *ORing |
| 22:19 | justin_smith | "Characters whose code points are greater than U+FFFF are called supplementary characters. The Java platform uses the UTF-16 representation in char arrays and in the String and StringBuffer classes. In this representation, supplementary characters are represented as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates range (\uDC00-\uDFFF)." |
| 22:19 | justin_smith | http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html |
| 22:20 | justin_smith | so it uses UTF-16, but some characters require 2 Chars |
| 22:20 | andyf | Wikipedia pages are decent for Unicode info, too |
| 22:21 | gfredericks | justin_smith: right but the code point representation is still small |
| 22:21 | gfredericks | looks like max is ##16r10FFFF |
| 22:21 | andyf | Check out Wikipedia for code point |
| 22:21 | gfredericks | ,16r10FFFF |
| 22:21 | clojurebot | 1114111 |
| 22:22 | gfredericks | ~1114111 is totes intsable |
| 22:22 | clojurebot | Ok. |
| 22:22 | justin_smith | Unicode comprises 1,114,112 code points in the range 0hex to 10FFFFhex |
| 22:22 | justin_smith | yeah |
| 22:22 | gfredericks | half of which are snowmen characters |
| 22:22 | justin_smith | ,Integer/MAX_VALUE |
| 22:22 | clojurebot | 2147483647 |
| 22:24 | andyf | Yeah, we're good until meeting the pangalactic empire, but then different tech will be available |
| 22:24 | TEttinger | andyf, if star wars has taught me anything it's that they'll speak either english or huttese. |
| 22:25 | TEttinger | or unpronounceable rawrs |
| 22:25 | justin_smith | with occasional reverse-polish grammar |
| 22:25 | andyf | There is a how to speak wookie book with push buttons to make sounds. Hilarious |
| 22:28 | andyf | Amazon reviews for it are even entertaining |
| 22:28 | TimMc | There are entertaining Amazon reviews for toilet paper, to be fair. |
| 22:28 | TimMc | and gallon jugs of milk |
| 22:29 | TimMc | gfredericks: I'm intrigued that the max unicode char is a palindrome in decimal. |
| 22:29 | TimMc | s/char/code point/ |
| 22:29 | gfredericks | TimMc: numbers! how do they work! |
| 22:30 | TimMc | ,[16r10FF 16r10FFF 16r10FFFF 16r10FFFFF] |
| 22:30 | clojurebot | [4351 69631 1114111 17825791] |
| 22:30 | rritoch | justin_smith: I completed the reg_assoc function and the re-ungreedy, though I did end up needing to use a parser, I couldn't find a regex that would do the job. https://github.com/rritoch/andylisp/blob/master/src/clj/andylisp/regex.clj |
| 22:32 | gfredericks | TimMc: did you know that numbers that look like 100010001000100010001 are never prime? |
| 22:33 | gfredericks | no wait |
| 22:33 | gfredericks | that's probably false |
| 22:33 | andyf | The matches a short regex primes conjecture? |
| 22:34 | gfredericks | ,(apply str (repeat (rand-int 10) (rand-int 19389243))) |
| 22:34 | clojurebot | "" |
| 22:34 | gfredericks | ,(apply str (repeat (rand-int 10) (rand-int 19389243))) |
| 22:34 | clojurebot | "90907769090776909077690907769090776909077690907769090776" |
| 22:34 | gfredericks | ^ that sort of number |
| 22:34 | gfredericks | is never prime |
| 22:35 | gfredericks | okay this numeric approach makes it a lot simpler |
| 22:37 | andyf | I don't have the heart to tell you that there are undefined holes in the range of code points, and those change from one JDK to the next as more are defined. |
| 22:37 | andyf | But I don't think that should need to affect your random gen fn |
| 22:41 | gfredericks | test.check will tell me if anything weird happens |
| 22:43 | andyf | I choose to interpret that as: nothing weird happened before test.check was created |
| 22:50 | TimMc | gfredericks: If there's anything I've learned from the tiny bit of number theory I've been exposed to, it's that you can't make provable statements about prime numbers. :-P |
| 22:50 | TimMc | except that there are lots f them |
| 22:50 | justin_smith | "60 is not prime" |
| 22:51 | TimMc | there's an xkcd for this |
| 22:51 | rritoch | TimMc: Prime numbers are evil, as are the supposed "rules" about them, most of the rules you'll run into are simply invalid, like the ln(x) approaching Pi(x) as you near infinity. |
| 22:51 | TimMc | http://xkcd.com/1310/ "Goldbach Conjectures" |
| 22:52 | TimMc | rritoch: And yet they're the atoms of the number world. |
| 22:52 | rritoch | TimMc: If I recall correctly, the zeta function is the only thing in prime number theory that has provided significant results. |
| 22:53 | TimMc | The zeta function has led to significant advances in the field of fragmentary ceramics. |
| 22:54 | rritoch | TimMc: I spent a few weeks trying to crack the Pi function. I had this idea that maybe I could find a power that would match the Pi function. I found that no matter what I chose it would curl away from the real value, so I made an adjustment that would curl to ln(x) at some number in the distant future of the pattern. It probably would have worked if the rule about ln(x) was true |
| 22:54 | rritoch | TimMc: Since the ln(x) rule isn't true, it failed miserably |
| 22:55 | TimMc | "psychoceramics", that's the phrase |
| 22:56 | gfredericks | "The limit of the quotient of the two functions pi(x) and x/ln(x) as x approaches infinity is 1 |
| 22:56 | gfredericks | " |
| 22:56 | rritoch | gfredericks: Yes, that statement is false |
| 22:57 | rritoch | gfredericks: x/ln(x) eventually crosses over pi(x) |
| 22:57 | TimMc | Where? |
| 22:58 | TimMc | Reminds me of being given the https://en.wikipedia.org/wiki/P%C3%B3lya_conjecture as an extra credit assignment (but not by name) |
| 22:58 | rritoch | TimMc: I really don't know. I don't have enough computing resources to prove it, but that was the explaination I received from experts in number theory as to why curling to it didn't work. |
| 22:59 | gfredericks | finite behavior doesn't prove anything about assymptotic behavior |
| 22:59 | rritoch | TimMc: Either way, if you solve Pi(x) you solve the P(x) function, and to me Pi(x) seems easier to solve, but it's still not solved. |
| 22:59 | gfredericks | what's P(x)? |
| 22:59 | rritoch | gfredericks: The nth prime |
| 22:59 | gfredericks | ah right |
| 23:01 | rritoch | TimMc: Anyhow, my point is, take much of what you learn in number theory with a grain of salt, they are just theories, and many of them have recently been disproven, but the information hasn't fully disseminated. |
| 23:01 | TimMc | hmm |
| 23:01 | gfredericks | o_O |
| 23:02 | rritoch | TimMc: In my case, I wasted a few weeks trying to solve a nearly unsolvable problem using inaccurate information. It wasn't until I consulted the experts that I found my error. |
| 23:03 | rritoch | TimMc: They suggested I look into the zeta function, but my frustration was at the level that I really had to drop that project. |
| 23:03 | Fare | hi. Is there an easy way to build a map that mirrors the deconstructor {:keys [a b c d]} ? |
| 23:03 | Fare | of course, I could write a defmacro to do the same... |
| 23:03 | gfredericks | Fare: some util libs have a macro for it |
| 23:03 | Fare | ok |
| 23:03 | TimMc | Fare: Yeah, flatland/useful has something for that, right? |
| 23:04 | TimMc | https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L9 |
| 23:04 | TimMc | keyed |
| 23:12 | rritoch | TimMc: If your interested, this is the "project" https://www.physicsforums.com/threads/epic-fail-trying-to-solve-p-x.614121/ |
| 23:18 | rritoch | TimMc: The real problem with my attempt is there is no solution to the cosine integral, so I hit a dead-end. |
| 23:19 | gfredericks | rritoch: is that reply there what you mean about the earlier statement of the prime number theorem being wrong? |
| 23:20 | rritoch | gfredericks: Yes. |
| 23:21 | gfredericks | it doesn't seem like a contradiction to me |
| 23:21 | gfredericks | crossing over doesn't mean not approaching |
| 23:23 | rritoch | gfredericks: According to the response it doesn't approach Pi(x), it wraps around it, similar to the behavior of my function for low values of Pi(x). What I needed for my function is a case where the limit of the function approaches Pi(x) as x approaches infinity. |
| 23:24 | gfredericks | rritoch: well the limit of the quotients approaching 1 doesn't mean that they actually approach each other, and the crossing over doesn't contradict either of those |
| 23:24 | rritoch | gfredericks: It wasn't a complete loss though because if the cosine integral is solved, the accuracy of my formula could be further improved. |
| 23:26 | rritoch | gfredericks: I don't know where you learned math but x/x = 1 |
| 23:26 | tuft_ | core.match goes really nicely with instaparse |
| 23:26 | rritoch | gfredericks: I can't think of any other case where that's true |
| 23:26 | amalloy | rritoch: for most x, anyway |
| 23:27 | gfredericks | rritoch: e.g., x/(x+1) approaches 1 but x does not approach x+1 |
| 23:28 | gfredericks | so pi(x)/(x/ln(x)) approaches one but x/ln(x) does not approach pi(x) |
| 23:30 | rritoch | gfredericks: I accounted for this "issue" by curling to x/ln(x) at something like x^10, so if the prime number theory held the deviation would have been less than .01 |
| 23:31 | rritoch | gfredericks: Either way, the number was very large so it could have been floating point errors that caused some of my problems. |
| 23:34 | rritoch | gfredericks: Since clojure promotes to Big types I'm somewhat curios how reducing the floating point errors would improve the results for large primes, but I've already invested enough time in that project. I'm just waiting for someone to solve the cosine integral. |
| 23:47 | gfredericks | help I'm using a sorted-set with a partial ordering |
| 23:48 | andyf | sounds like an invitation to disaster. |
| 23:48 | andyf | help you create a total order instead, or some other way? |
| 23:49 | gfredericks | I was hoping somebody would tell me to back slowly away from the keyboadr |
| 23:49 | gfredericks | keyboard |
| 23:50 | gfredericks | andyf: I'm trying to store unions ranges of numbers (characters) efficiently |
| 23:50 | andyf | I?d recommend sending the RSVP with the answer ?no? back to disaster. |
| 23:50 | hiredman | sure, you could use a total order, but wouldn't you rather experience the rush of living like there is no tomorrow? |
| 23:51 | gfredericks | andyf: so if I do it right there shouldn't ever be two incomparable elements in a set together |
| 23:52 | andyf | elements of the set are contiguous ranges like [10,15], or elements of the set are sets of contiguous ranges? |
| 23:52 | gfredericks | the former |
| 23:52 | rritoch | gfredericks: Sets have a map impl, it "should" be possible to create a map with the behaviors you want, and then use that as the impl for the set. I dug into the source code of sets because I was looking into how to establish equality criteria in sets. |
| 23:53 | andyf | What operations do you want to do on such sets efficiently? |
| 23:54 | gfredericks | union, difference, count, nth |
| 23:54 | gfredericks | and right not I'd settle for "eh sorta efficiently" |
| 23:54 | gfredericks | in the sense of ignoring the worst-case assymptotics |
| 23:54 | gfredericks | s/not/now/ |
| 23:55 | andyf | Maybe just implement union and difference so that the contiguous ranges are always non-overlapping? |
| 23:55 | gfredericks | right that's what I'm doing |
| 23:55 | andyf | So the elements can always be compared by the beginnings of their ranges, or the ends, and you have a total order? |
| 23:56 | gfredericks | yeah within the set it's a total order |
| 23:56 | gfredericks | just not over the whole space of possible elements |
| 23:57 | andyf | you want to compare two sets-of-contiguous-ranges and put them as elements into a sorted set? |
| 23:58 | gfredericks | I'm only using sorted sets for this |
| 23:58 | gfredericks | specifically (sorted-set-by (fn [[x1 x2] [x3 x4]] (if (< x2 x3) -1 (if (< x4 x1) 1 0)))) |
| 23:58 | gfredericks | so I don't know what you mean by "put into" |
| 23:59 | andyf | if the contiguous ranges are always kept non-overlapping, then I don't see the problem yet. |
| 23:59 | andyf | e.g. if you implement union so that #{[1 5] [8 10]} with #{[4 9]} so that the result is #{[1 10]} |