2014-12-17
| 00:00 | puredanger | the sorted-set-by seems ok to me too |
| 00:00 | puredanger | given your constraints |
| 00:01 | andyf | I think union, and probably difference, can be implemented in linear time, with a bit of working out the cases. count and nth should be linear, too, so asympotically probably not the fastest possible, but maybe meets your constraints. |
| 00:01 | puredanger | I've implemented interval libraries like this in the past. they're fun! |
| 00:01 | gfredericks | the one thing that seemed sketchy was this expression: |
| 00:01 | fairuz | Hi guys. I'm starting with swagger and liberator. Have this atm: https://www.refheap.com/95023 . When trying to access the API, I'm getting #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core/dummy-resource/fn--20454> . I don't see where I miss an argument in the code. |
| 00:02 | gfredericks | (subseq cs >= entry <= entry) |
| 00:02 | andyf | Ah, you want that to work... |
| 00:02 | gfredericks | ^ to get the overlaps for an entry not in the set |
| 00:02 | gfredericks | it seems to work so far |
| 00:03 | gfredericks | but also feels like it relies on unspecified behavior |
| 00:03 | gfredericks | in particular that `entry` might be "equal to" several elements in the set |
| 00:04 | andyf | maybe do a custom implementation of that expression that first finds the earliest contiguous range that overlaps, and then seqs through the rest until it no longer overlaps? |
| 00:05 | andyf | Not sure, but maybe if you have a contiguous range [a b], you search for [a a] in the sorted-set? Not obvious to me yet if that is always correct. |
| 00:05 | gfredericks | that sounds like it can work |
| 00:05 | gfredericks | well |
| 00:06 | gfredericks | I'd have to start with (subseq cs >= entry) |
| 00:06 | gfredericks | which seems more likely to work |
| 00:06 | andyf | and then throw on a take-while |
| 00:06 | gfredericks | yeah |
| 00:06 | andyf | but if entry were always a single-element range [a a], it cuts down the brainpower required to figure out if there are bugs. |
| 00:07 | amalloy | fairuz: what is #(assoc {} :entity {:name "Foo"}) supposed to do? someone is calling that function with an argument, and it doesn't take any |
| 00:07 | andyf | Increasing one's brainpower is always good, but figuring out ways to decrease the brainpower required can look the same from far enough away :) |
| 00:08 | gfredericks | why would entry always be single-element? |
| 00:08 | andyf | Also, if you do maintain the sets as non-overlapping ranges, the comparator can simply compare left ends of ranges. |
| 00:09 | puredanger | gfredericks: http://clj-me.cgrand.net/2012/03/16/a-poor-mans-interval-tree/ in case it's interesting |
| 00:09 | fairuz | amalloy: heh yeah. Missed out that one. Thanks for finding it ;) |
| 00:10 | gfredericks | puredanger: cool thanks |
| 00:10 | amalloy | fairuz: the exception message tells you exactly where the problem is: an anonymous function inside of dummy-resource |
| 00:10 | andyf | gfredericks: I don't mean that the entries of a set-of-contiguous ranges would be single element, but if you want to search for what ranges overlap with [a b], first finding the first one >= [a a] is a good start. |
| 00:10 | amalloy | if you looked at the stacktrace as well, you would see who is calling that function |
| 00:10 | gfredericks | andyf: good point about the left ends |
| 00:11 | andyf | or something close to that -- probably an off-by-one-bug in the idea as stated. |
| 00:18 | gfredericks | oh crap I need intersection too |
| 00:18 | gfredericks | I can fake that with difference can't I |
| 00:18 | andyf | or write another linear time fn customized for it. |
| 00:20 | fairuz | amalloy: Ok thanks. I always forgot that fn_xxxx something is an anonymous function. My mind is on vacation today |
| 00:21 | gfredericks | ha that was fun to write: https://www.refheap.com/95024 |
| 00:25 | andyf | So symmetrical, I think you should find chars legal in Clojure that are visually mirror images in place of charset-1 charset-2 and left right, e.g. < > and d b |
| 00:26 | andyf | sorry, only for left right |
| 00:26 | andyf | I'm sure Unicode can help here |
| 00:28 | rritoch | gfredericks: Are these charset-1 and charset-2 the sorted sets you were talking about? If so shouldn't the intersection be at the entry level, it seems your implementation is only going to look for exact matches, but won't intersect [1 5] and [2 6] into [2 5] |
| 00:29 | gfredericks | rritoch: that should get handled correctly by difference & union |
| 00:29 | gfredericks | rritoch: the cute part here is being able to define intersection in terms of difference and union |
| 00:30 | gfredericks | so all the nasty details are in the other two functions |
| 00:32 | rritoch | gfredericks: I see, It seems like a good tool for manipulating statistics. Politicians would love this code :) |
| 00:33 | rritoch | gfredericks: Being able to find the ideal ranges to get data to look the way you want it to is a common problem in politics. I worked at a marketing research firm for about 5 years so I've seen how ugly statistics can really be. |
| 00:36 | andyf | Just listened to a Cognicast podcast episode with Michael Parenteau where he describes taking a whole day course with Edward Tufts, where one of the things he teaches is not only how to try to make nice visualizations for things, but how to work hard to avoid the possibility of being misleading. |
| 00:41 | rritoch | andyf: Lol, that wasn't in my job description. The clients were mostly major pharm. I really can't go into any more detail than that without violating a lifetime NDA. I don't think the contract is even legal but I'd rather not find out. |
| 00:44 | hydo | Can you extend a class and implement another class using proxy, or do you have to use gen-class in that case? |
| 00:46 | rritoch | hydo: You can't extend 2 classes, do you mean you want to implement another interface? |
| 00:47 | hydo | Yea, sorry, my java knowledge is trying to catch up to my lisp-y knowledge. I'm using gen-class to make a java class that extends class x and implements class y. I'd like to use proxy if possible. |
| 00:48 | rritoch | hydo: In java you can extend classes and implement interfaces, you can't implement a class but you can extend an interface. |
| 00:49 | rritoch | hydo: That being said, it seems proxy allows (proxy [className InterFace1 InterFace2 ...] ...) |
| 00:52 | hydo | Oh hell, I completely missed that in the clojuredocs proxy page. :/ And thanks for clarifying. I thought classes and interfaces were ostensibly the same. |
| 00:53 | rritoch | hydo: You can also wrap a class and create an interface that matches the classes methods, though you would probably need to use genclass in that case since you'll probably need to maintain an instance of the wrapped class in the object's state. |
| 00:53 | rritoch | hydo: In my opinion it is sad that java never allowed multiple inheritance, but you can "fake-it" by wrapping classes. |
| 00:59 | rritoch | Anyhow. I guess this is another case for me to try with andylisp. Adding multiple-inheritance to namespaces. Does clojure have any plans of adding namespace inheritance or is that a "dead" idea? |
| 01:16 | rritoch | Before I go re-inventing the wheel, does clojure have anything similar to "wait-until"? |
| 01:22 | rhg135 | rritoch: ns inheritance? |
| 01:24 | rritoch | rhg135: Yes, Something that publicly exposes vars from parent namespace(s) in the current namespace. Ex. (ns 'my.ns) (inherit 'clojure.core) would make it possible to call (my.ns/map ) |
| 01:25 | luxbock | it's not really the same thing, but https://github.com/ztellman/potemkin allows you to kind of do that |
| 01:26 | andyf | There are libraries for manually inheriting individual Vars from another namespace into the current one. |
| 01:26 | luxbock | it has a lot of other very useful stuff as well |
| 01:26 | andyf | Yeah, potemkin |
| 01:26 | rritoch | luxbock: I've looked at potemkin, and that is extremly close |
| 01:28 | rhg135 | I think ns-publics + that'd work |
| 01:30 | rritoch | As far as I know, any currently solution isn't automatic, so if you "inherit" and then add new vars to the parent, the child doesn't get them unless they re-import. |
| 01:31 | rhg135 | Editing nses once finished shouldn't be encouraged |
| 01:36 | rritoch | rhg135: I know what your saying, but loading of namespaces isn't thread-safe, so if you have two threads requiring the same file, the one thread will wait for the requires to load, and the other won't. So the second simultanious thread wouldn't see any vars in the parent namespace when it loads, and it's very possible that some threads will load some requires and not others. |
| 01:36 | rritoch | rhg135: So in the case of multiple inheritance, if two parents have the same var, which var gets used in a multithreaded environment would be almost completly random. |
| 01:37 | rhg135 | rritoch: you'd add another indirection to namespaces, now it takes code to find vars whereas before it was a lookup |
| 01:38 | rhg135 | I see |
| 01:38 | rritoch | rhg135: I don't think it would be that bad, it would be a failback to look at the parent namespaces. |
| 01:38 | andyf | Not sure, but I suspect that is the least of one's worries if doing parallel requires of the same namespaces. |
| 01:39 | rhg135 | This is what andylisp is for |
| 01:39 | rhg135 | Try. |
| 01:40 | rritoch | rhg135: I may, but even the first namespace adjustment I made isn't completely functional. Somehow the ns macro breaks out of the isolation environment. |
| 01:41 | rhg135 | Okie dokey lokey |
| 01:41 | rritoch | rhg135: I may be able to try it on a new branch though, that doesn't have the namespace isolation. |
| 01:42 | rhg135 | Git is powerful that way |
| 01:43 | rritoch | rhg135: Yeah, it is powerful, but has a price in learning curve, svn is much easier to learn and teach. |
| 01:43 | rhg135 | You can code whenever |
| 01:43 | rhg135 | Code is power, except when it's not |
| 01:44 | rhg135 | I use hg, rritoch |
| 01:44 | rhg135 | Too young to have used svn so idk |
| 01:46 | rritoch | rhg135: Lol, I guess that means you haven't used cvs either. I've actually never used it myself, I didn't care about version management for a long time. When I finally did subversion was already available. |
| 01:47 | rritoch | rhg135: I intend to eventually learn mercurial, so far I've only downloaded mercurial projects, haven't created or written to any. |
| 01:47 | rhg135 | More correctly I am old enough just I didn't start programming till '09 |
| 01:48 | rhg135 | And in python :O |
| 01:48 | rhg135 | It makes me sad and ashamed |
| 01:53 | rritoch | Is this syntax valid or am I going to break the stack? (defn wait-until [f] (loop [r (f)] (or r (recur (f)))) |
| 01:55 | rhg135 | It should work |
| 01:56 | rhg135 | If or is an if in desguise |
| 02:00 | justin_smith | rritoch: that could be expressed as (while (not (f))) |
| 02:01 | rritoch | justin_smith: Did you see my earlier message about reg_assoc? |
| 02:02 | cloudsaja | do we discuss liberator here ? |
| 02:02 | justin_smith | sure |
| 02:02 | rritoch | justin_smith: As for this wait-until, the single arity version will probably never be used, it is a system-killer that will consume all CPU resources without mercy. |
| 02:02 | justin_smith | rritoch: I just took a quick look |
| 02:03 | justin_smith | rritoch: simple enough to shove a (Thread/sleep n) into the body |
| 02:04 | cloudsaja | Can I paste code here, or should I use pastebin ? |
| 02:04 | justin_smith | pastebin please, refheap is good for clojure code |
| 02:04 | rhg135 | Refheap |
| 02:04 | rhg135 | It's nice |
| 02:08 | cloudsaja | Okay... https://www.refheap.com/95026 <-- why the "ctx" wont have "param" information in side the request ? as in (get-in ctx [:request :params "word"]) always nill... Im sure in curl I put parameters in the GET. |
| 02:09 | rhg135 | I enjoy code like a lot |
| 02:09 | justin_smith | cloudsaja: does ctx have :request in it? |
| 02:09 | cloudsaja | To test it, I did >> curl -v -L -G -d "word=tiger&a=b" GET http://localhost:8080/secret |
| 02:10 | cloudsaja | justin_smith: yes it did... but the param is empty |
| 02:11 | cloudsaja | seems like wrap-params is not working |
| 02:11 | justin_smith | can you paste the output of (get-in ctx [:request]), or better yet (clojure.pprint/pprint ctx) |
| 02:11 | cloudsaja | Ok |
| 02:11 | cloudsaja | It was |
| 02:11 | cloudsaja | {:ssl-client-cert nil, :remote-addr "127.0.0.1", :params {}, :route-params {}, :headers {"user-agent" "curl/7.35.0", "accept" "*/*", "host" "localhost:8080"}, :server-port 8080, :content-length nil, :content-type nil, :character-encoding nil, :uri "/secret", :server-name "localhost", :query-string "word=tiger", :body #<HttpInput org.eclipse.jetty.server.HttpInput@6d19ddb8>, :scheme :http, :request-method :get} |
| 02:12 | justin_smith | well, -d sets the body |
| 02:12 | cloudsaja | there are :query-string though |
| 02:12 | justin_smith | not the request parameters |
| 02:12 | justin_smith | try (slurp (:body ctx)) |
| 02:13 | justin_smith | and you really shouldn't be setting the request body for a GET |
| 02:14 | cloudsaja | There are nothing on the body... its on the query string. |
| 02:14 | cloudsaja | > GET /secret?word=tiger&a=b HTTP/1.1 |
| 02:14 | cloudsaja | This is what curl did |
| 02:14 | justin_smith | Oh, ok |
| 02:14 | justin_smith | now I see that |
| 02:15 | justin_smith | sorry, I had just never seen curl used that way |
| 02:15 | cloudsaja | np |
| 02:16 | rhg135 | Gn .+ |
| 02:17 | justin_smith | cloudsaja: yeah, in my experience wrap-params would have caught that query string and made a params map from it - was the above map from ctx or (:request ctx) ? |
| 02:17 | cloudsaja | (:request ctx) |
| 02:17 | justin_smith | check ctx itself |
| 02:17 | justin_smith | because in my experience wrap-params puts stuff directly in the top level |
| 02:18 | justin_smith | not under a :request key |
| 02:18 | cloudsaja | oh... ok. let me see |
| 02:28 | cloudsaja | justin_smith: In the ctx, there are tons of information, but they are all looks clueless, something like >> :resource {:existed? #<core$constantly$fn__4085 clojure.core$constantly$fn__4085@71baab36>, :conflict? #<core$constantly$fn__4085 clojure.core$constantly$fn__4085@163ea08f>, :handle-see-other .... and a lot lot more. |
| 02:30 | justin_smith | a trick I use for that is (defonce debug (atom nil)) and inside the handler (reset! debug ctx) then in the repl you can do things like (-> ctx keys) (->ctx :some-key type) etc. etc. etc. |
| 02:31 | cloudsaja | In so new in clojure, dont know how to do that :( |
| 02:31 | justin_smith | err, I mean (-> @debug keys) etc. |
| 02:31 | justin_smith | are you starting the server from a repl? |
| 02:31 | cloudsaja | yes i did |
| 02:32 | justin_smith | OK, then I just showed you all the code you woudl need. (defonce debut (atom nil)) would go at the top level of your code, (reset! debug ctx) would go inside your handler function, then you would do (-> @debug keys) etc. from the repl |
| 02:33 | cloudsaja | ok |
| 02:37 | cloudsaja | Okay... I got it |
| 02:38 | cloudsaja | guestbook.core=> (-> @debug :request) |
| 02:38 | cloudsaja | {:ssl-client-cert nil, :remote-addr "127.0.0.1", :params {}, :route-params {}, :headers {"user-agent" "curl/7.35.0", "accept" "*/*", "host" "localhost:8080"}, :server-port 8080, :content-length nil, :content-type nil, :character-encoding nil, :uri "/secret", :server-name "localhost", :query-string "word=tiger", :body #<HttpInput org.eclipse.jetty.server.HttpInput@239e06d7>, :scheme :http, :request-method :get} |
| 02:38 | justin_smith | right |
| 02:38 | justin_smith | so you can check the keys via (-> @debug keys) and get a key via (-> @debug :params) or whatever |
| 02:39 | cloudsaja | I can see.... (-> @debug :request :query-string) ... shows "word=tiger" |
| 02:39 | clojurebot | Gabh mo leithscéal? |
| 02:40 | justin_smith | but no :params key on @debug itself? |
| 02:40 | cloudsaja | So inside the query-tring where it goes... but not in the params... |
| 02:40 | justin_smith | what is the output of (keys @debug) |
| 02:40 | cloudsaja | Nope... (-> @debug :request :params) .. shows {} |
| 02:40 | cloudsaja | empty map |
| 02:40 | justin_smith | no, I did not say :request |
| 02:41 | justin_smith | just @debug |
| 02:41 | cloudsaja | (keys @debug) .. shows (:request :resource :representation) |
| 02:41 | justin_smith | hmm |
| 02:41 | justin_smith | OK |
| 02:42 | justin_smith | I don't know what liberator is doing here, when I have used wrap-params, it attached :params to the top level, not under a :request key |
| 02:42 | cloudsaja | Ooww |
| 02:43 | justin_smith | perhaps you need to use wrap-params differently to make it work with liberator, because it may not be seeing the data it expects (since it is hidden under :request) |
| 02:43 | cloudsaja | hmm... been craking my head on this for 3 days. no clues from google what so ever... :( maybe I should parse the :query-string then :( |
| 02:44 | justin_smith | well, wrap-params definitely expects the stuff you are getting under the :request key to be at the top level |
| 02:44 | cloudsaja | I see.. |
| 02:45 | cloudsaja | Maybe my configuration is wrong... |
| 02:46 | cloudsaja | justin_smith : Thanks alot anyway. you teach me how to debug ;) |
| 02:48 | justin_smith | try changing (get-in ctx [:request :params "word"]) to (get-in ((wrap-params :request) ctx) [:request :params :word]) (it likes to keywordize btw) |
| 02:49 | justin_smith | oh wait, I was using wrap-keyword params |
| 02:49 | justin_smith | so leave it ias [:request :params "word"] |
| 02:49 | nXqd | adsf |
| 02:50 | justin_smith | this is definitely why wrap-params is not working - its input is not shaped the way it expects, wrap-params does not look under a :request key |
| 02:51 | cloudsaja | Ughhh... I do not understand how it works, just a user though... need more and more coding hours... :D |
| 02:51 | cloudsaja | and trouble shooting... and ask questions. |
| 02:52 | justin_smith | once again - I literally gave you code you can try |
| 02:53 | cloudsaja | working on it. |
| 02:54 | justin_smith | oh wait, it should be (get-in ((wrap-params :request) ctx) [:params "word"]) |
| 02:55 | justin_smith | but you can do that directly in the repl with (get-in ((wrap-params :request) @debug) [:params "word"]) without restarting the server just to experiment |
| 02:56 | cloudsaja | it was nill |
| 02:56 | cloudsaja | nil |
| 02:56 | justin_smith | OK |
| 02:57 | justin_smith | what about (get-in ((wrap-params :request) @debug) [:params]) |
| 02:58 | cloudsaja | ((wrap-params :request) @debug) have {:ssl-client-cert nil, :remote-addr "127.0.0.1", :params {}, :route-params {}, :headers {"user-agent" "curl/7.35.0", "accept" "*/*", "host" "localhost:8080"}, :server-port 8080, :content-length nil, :content-type nil, :character-encoding nil, :uri "/secret", :server-name "localhost", :query-string "word=tiger", :body #<HttpInput org.eclipse.jetty.server.HttpInput@60e1f0c0>, :scheme :http |
| 02:59 | justin_smith | well, that's a start I guess - at least the :params key is there as expected now |
| 03:01 | cloudsaja | But isn't it the purpose of wrap-params to put things into the :params ? |
| 03:01 | justin_smith | yes, but I think we are hacking this wrong - but we are close |
| 03:02 | justin_smith | ((wrap-params identity) (:request @debug)) |
| 03:02 | justin_smith | that should be it? |
| 03:03 | cloudsaja | Woww... it works |
| 03:03 | cloudsaja | {:ssl-client-cert nil, :remote-addr "127.0.0.1", :params {"word" "tiger"}, :route-params {}, :headers {"user-agent" "curl/7.35.0", "accept" "*/*", "host" "localhost:8080"}, :server-port 8080, :content-length nil, :form-params {}, :query-params {"word" "tiger"}, :content-type nil, :character-encoding nil, :uri "/secret", :server-name "localhost", :query-string "word=tiger", :body #<HttpInput org.eclipse.jetty.server.HttpInput@60e |
| 03:03 | justin_smith | the next step would be to either make a shim so wrap-params would work in the handler definition, or one to use it inside the handler like that |
| 03:03 | cloudsaja | What the f have you done ?? it works !!. Explain man.. please |
| 03:04 | rritoch | Does anyone know how to do a parital and? I have tried (partial and 1 2) and (partial apply and 1 2) and theyr'e both throwing macro errors |
| 03:04 | justin_smith | wrap-params takes a handler as an argument, and returns a function that takes a request, adds some data and runs the handler on that modified data |
| 03:04 | rritoch | parital=partial |
| 03:05 | andyf | partial only works on functions, not macros |
| 03:06 | justin_smith | rritoch: #(reduce (fn [_ b] (if-not b (reduced b) b)) %&) |
| 03:06 | cloudsaja | I see. |
| 03:07 | justin_smith | so (wrap-params identity) says "take a request, update the :params key etc, then run identity on it |
| 03:07 | justin_smith | which of course just returns it unchanged |
| 03:08 | justin_smith | I missed a " above, sorry |
| 03:09 | rritoch | justin_smith: Thanks. That is exactly what I need. Even if it is far more complex than I hoped. |
| 03:09 | cloudsaja | justin_smith : could I just merge it to the ctx it self ? |
| 03:10 | justin_smith | (or b (reduced b)) would work too, and is a little simpler |
| 03:10 | justin_smith | cloudsaja: yeah, that is what I meant by a shim |
| 03:11 | cloudsaja | justin_smith : thanks a lot man. |
| 03:11 | justin_smith | something like (fn [handler] (fn [ctx] (update-in ctx [:request] (wrap-params identity)))) |
| 03:11 | justin_smith | and you could use that function in the place of where you have wrap-params in your original code |
| 03:11 | cloudsaja | ok |
| 03:11 | justin_smith | (not as a literal, due to how -> works, though) |
| 03:13 | justin_smith | oh wait - it would actually be (defn wrap-in-request [handler] (fn [ctx] (handler (update-in ctx [:request] (wrap-params identity))))) and then use wrap-in-request where you currently have wrap-params |
| 03:13 | justin_smith | or maybe liberator already has some way to adapt normal ring middlewares to use with liberator - it would seem like that would be a common enough thing to want to do --- or maybe they have some fancier way of doing what we do with middleware |
| 04:48 | m1dnight_ | guys, what is the name of "(-> ..)"? |
| 04:48 | m1dnight_ | For google-purposes |
| 04:48 | sveri | m1dnight_: thread macro |
| 04:48 | sveri | or threading macro |
| 04:49 | m1dnight_ | oh that's a cool one :) thanks guys |
| 04:49 | m1dnight_ | incs for everyone! |
| 04:51 | rritoch | m1dnight_: Try http://symbolhound.com |
| 04:52 | m1dnight_ | oh sweet :) |
| 04:52 | m1dnight_ | ,(inc rritoch) |
| 04:52 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: rritoch in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 04:52 | m1dnight_ | (inc rritoch) |
| 04:52 | lazybot | ⇒ 2 |
| 04:52 | m1dnight_ | there we go! |
| 04:53 | rritoch | m1dnight_: ty |
| 05:00 | Kneiva | rritoch: great link, thanks =) |
| 05:12 | m1dnight_ | http://stackoverflow.com/a/1879961/1225786 |
| 05:12 | H4ns | does anyone know the honeysql syntax for calling arbitrary (postgre)sql functions like coalesce()? The manual only speaks about one argument sql functions which have a gross syntax (i.e. :%max.id) |
| 05:12 | m1dnight_ | Could anyone tell me why the author would put the result of the thunk in a vector? |
| 05:12 | m1dnight_ | (I also asked in a comment, fwiw) |
| 05:31 | rritoch | h4ns: I haven't used it but per the documentation you can create your own function handlers https://github.com/jkk/honeysql#extensibility but it's not clear if that will work outside where, such as aggregate functions. |
| 05:32 | H4ns | rritoch: thanks - we've got numerous special purpose functions in the database that i'd like to call, so i'll probably just use sql/raw and be done with it. |
| 06:39 | joelkuiper | So say I want to write a browser extension that communicates with some external app, would it be advisable to write that external system in Clojure/Java/anything on the JVM? |
| 06:40 | joelkuiper | I'm kinda torn by this. I would like to create some cross-platform thingy that integrates well with Firefox/Chrome ... but doing it in something native seems like a hassle, but the JVM has really gotten a bad rep in doing anything consumer-side |
| 06:42 | joelkuiper | So I'm thinking "whatever, I'll just do it in the lang I'm most comfortable in, namely Java/Clojure and screw opinion" (which will also limit the option to advertise in app stores) ... or I can write the core functionality in something like C and then go through the motions of writing a GTK/Cocoa/Windows shell |
| 06:42 | joelkuiper | meh. choices. |
| 06:44 | joelkuiper | You know, I really loved the promise of the Java/JVM. Shame it didn't live up to its full potential |
| 06:51 | clgv | joelkuiper: "bad rep" is really unspecific. what are your requirements? where do you suspect problems to fulfill your requirements? |
| 06:52 | joelkuiper | clgv: Well I'd like this system to be a deamon which responds to calls from the browser. This would mean a running JVM instance for all users. I fear (although unsubstansiated, mostly) that it will that be a dealbreaker: needing to install a JVM and having a process running |
| 06:54 | clgv | joelkuiper: well a client side jvm for a browser plugin is not that lightweight as usual browser plugins |
| 06:55 | clgv | joelkuiper: firefox plugins can be implemented via javascript afair, so you could use clojurescript. a dev setup with fast feedback on changes could be a challenge though |
| 06:56 | joelkuiper | clgv: true, but its not a usual plugin. It will require access to disk and run something like Lucene, for example. By doing the bulk of the work outside the browser the hope is that I don't have to deal with quirks between Chrome/Firefox/Safari/etc |
| 06:58 | clgv | joelkuiper: well, then the question is: "Is the plugin functionality worth the installation effort?" |
| 06:58 | joelkuiper | clgv: In essence I want a single button that downloads the entire webpage, indexes it, does some named-entity recognition and writes the site as an archive to disk or cloud store. It's bookmarks on steroids, with no dep on something like Pocket (I really want this to be an offline thing) |
| 06:59 | clgv | or "Can you ease the installation effort via an automatic installer?" |
| 07:00 | dysfun | if i add a new dependency to my project.clj, is there a way to make a lein repl put the new lib in its classpath that avoids restarting? |
| 07:00 | dysfun | (such that i can just do lein deps on another terminal tab and then switch back and issue a command in the repl) |
| 07:00 | clgv | dysfun: no. |
| 07:01 | clgv | dysfun: though there is a lib to load the dependency on the repl. but that is not connected to the project.clj |
| 07:01 | dysfun | so i'm right in thinking i should hit ^D, <up>, <enter> then? |
| 07:01 | joelkuiper | clgv: good points, I'm likely overthinking this. AeroFS got away with it for a while. And it's mostly to scratch my own itch anyway. I'll start off in Clojure/Java as a proof of concept |
| 07:02 | clgv | dysfun: you could use pomegranate |
| 07:02 | dysfun | hrm, that's an idea |
| 07:17 | dysfun | is the cost of derefing an atom insignificant? |
| 07:17 | dysfun | let's say the core runloop of my application relied on it |
| 07:18 | dysfun | should i be at all concerned? |
| 07:19 | clgv | $source clojure.lang.Atom |
| 07:19 | lazybot | Source not found. |
| 07:20 | dysfun | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Atom.java |
| 07:20 | dysfun | oh, it's java.util.concurrent.atomic.AtomicReference |
| 07:22 | clgv | dysfun: should be unproblematic since there are no retries involved as for `swap!` |
| 07:22 | dysfun | that's what i thought. it's probably something like "one more pointer hop" (oh noes!) |
| 07:22 | clgv | yeah, similar to a getter method |
| 07:22 | clojurebot | Titim gan éirí ort. |
| 07:23 | clgv | getter method |
| 07:23 | clgv | similar |
| 07:23 | clgv | stupid bot ;) |
| 07:23 | dysfun | similar too foo |
| 07:23 | dysfun | similar to foo |
| 07:23 | dysfun | ,similar to foo |
| 07:23 | clgv | yeah |
| 07:23 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: similar in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 07:23 | clgv | must have been random ;) |
| 07:23 | dysfun | mebbe :) |
| 07:23 | clgv | yeah, similar to a getter method |
| 07:23 | clgv | yep, random |
| 07:25 | dysfun | okay, what if it were a function that were held in an atom? i presume there's some clever optimisations that happen down the line in hotspot that this might prevent |
| 07:27 | dysfun | (there is of course nothing so fun as second guessing what a JIT compiler will do) |
| 07:35 | clgv | dysfun: clojure functions called through clojure variables already prevent some hotspot optimizations |
| 07:36 | dysfun | clgv: *nod* |
| 07:36 | dysfun | the price you pay for dynamism |
| 07:38 | Bronsa | clgv: I remember puredanger saying that hotspot actually can inline away Var's getRawRoot |
| 07:38 | clgv | Bronsa: but then we wouldnt need invoke-dynamic at all... |
| 07:39 | clgv | Bronsa: I didn't try it yet. |
| 07:52 | CookedGryphon | how do i reduce over a collection with a transducer transform now? |
| 07:52 | CookedGryphon | Do I use (reduce f (eduction xform coll))? |
| 07:53 | CookedGryphon | or is transduce the way to do that directly? |
| 08:37 | siefca | hi guys |
| 08:38 | siefca | i need a definition |
| 08:38 | siefca | could we tell that function arguments (parameters) are lexical bindings, or is this term reserved for let forms? |
| 08:39 | djcoin | What does the form {:keys [k1 k2] :or {k1 "foo" k2 "bar" }} get expanded too ? |
| 08:41 | clgv | siefca: I wouldn't object |
| 08:42 | siefca | clgv: thx |
| 08:42 | whodidthis | can you feed instaparse result thingie back to the parser rule to generate some string |
| 08:43 | stuartsierra | siefca: Function parameters have lexical scope, so that would make sense. |
| 08:44 | piranha | djcoin: (let [k1 (:k1 arg "foo") k2 (:k2 arg "bar")] ...) |
| 08:44 | djcoin | ah yeah, simple, thanks piranha |
| 08:47 | siefca | stuartsierra: thx |
| 09:22 | clgv | ,(macroexpand-1 '(let [{:keys [k1 k2] :or {k1 "foo" k2 "bar" }} m] [k1 k2])) |
| 09:22 | clojurebot | (let* [map__27 m map__27 (if (clojure.core/seq? map__27) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__27)) map__27) k2 ...] [k1 k2]) |
| 09:22 | clgv | djcoin: ^^ |
| 09:22 | clgv | &(macroexpand-1 '(let [{:keys [k1 k2] :or {k1 "foo" k2 "bar" }} m] [k1 k2])) |
| 09:22 | lazybot | ⇒ (let* [map__15998 m map__15998 (if (clojure.core/seq? map__15998) (clojure.lang.PersistentHashMap/create (clojure.core/seq map__15998)) map__15998) k2 (clojure.core/get map__15998 :k2 "bar") k1 (clojure.core/get map__15998 :k1 "foo")] [k1 k2]) |
| 09:24 | dnolen_ | reiddraper: heh, even the half finished test.check port is already finding ClojureScript bugs |
| 09:30 | chouser | Anyone know how to make transit emit something of my choosing instead of blowing up when it tries to write something that doesn't have a handler installed? |
| 09:33 | stuartsierra | chouser: I don't know specifically, but I expect there's a way to do it. |
| 09:33 | chouser | Fressian uses a protocol for handler lookup, so you can do arbitrary resolution. Transit uses java.util.Map, apparently. |
| 09:34 | stuartsierra | Maybe add a write handler for java.lang.Object? |
| 09:35 | chouser | That approach appears to be specifically excluded. |
| 09:35 | stuartsierra | huh |
| 09:35 | stuartsierra | Maybe you can't. I know there is a default reader for unknown tags, but there may not be a default writer. |
| 09:36 | chouser | I'll keep looking. We kinda need it. |
| 09:37 | dnolen_ | chouser: this use case isn't really supported. Probably should bring it up on the transit-format list |
| 09:37 | dnolen_ | chouser: that said, not sure it could work, if there's isn't a handler how do you know how to encode it? |
| 09:37 | dnolen_ | s/not sure it could work/not sure how it could work |
| 09:38 | dnolen_ | decoding is simpler because you already have representation that you can preserve |
| 09:38 | chouser | I just want to write out something indicating failure at that point, rather than having the entire transit object fail to be written |
| 09:39 | dnolen_ | chouser: hrm, Unwriteable tagged type? could be interesting |
| 09:39 | chouser | yes, something to that effect. |
| 09:40 | chouser | There are clearly cases where a failed attempt to write should be very loud and halt things. But other times, writing *something* is better than blowing up. |
| 09:40 | stuartsierra | Looks like you could modify WriterFactory https://github.com/cognitect/transit-java/blob/5785a91c54174e02f50e48780886a55829959314/src/main/java/com/cognitect/transit/impl/WriterFactory.java#L62 to change the handler for Object. |
| 09:42 | chouser | Hm, also: https://github.com/cognitect/transit-java/blob/5785a91c54174e02f50e48780886a55829959314/src/main/java/com/cognitect/transit/impl/AbstractEmitter.java#L20 |
| 09:42 | chouser | base != Object.class |
| 09:44 | stuartsierra | It's an interesting issue: I've often wanted a printer/reader that prints "unprintable" things as #tag + toString, for things like logging. |
| 09:44 | chouser | logging. exactly. |
| 09:45 | mgaare | Terrible idea to use clojure.lang.MapEntry directly? |
| 09:45 | chouser | and alternatives like prewalking the log entry are icky |
| 09:45 | stuartsierra | and slow |
| 09:45 | llasram | stuartsierra, chouser: https://github.com/llasram/letterpress |
| 09:45 | clgv | mgaare: depends on what exactly this means |
| 09:46 | opqdonut | stuartsierra: doesn't e.g. pr-str do that? |
| 09:46 | opqdonut | ,(pr-str (Object.)) |
| 09:46 | clojurebot | "#<Object java.lang.Object@37d586>" |
| 09:46 | opqdonut | or am I missing some context |
| 09:46 | stuartsierra | opqdonut: yes, but you can't `read` that back in without an error. |
| 09:46 | opqdonut | stuartsierra: so should read return something like a special UnReadable object? |
| 09:47 | mgaare | clgv: writing a helper function for mapping over a map, and would prefer for it to return MapEntries rather than vectors or whatever |
| 09:47 | stuartsierra | opqdonut: Not in the general case, no. But it would be useful in some situations, such as analyzing log messages. |
| 09:48 | clgv | mgaare: huh why? |
| 09:49 | clgv | ,(reduce (fn [_, x] (reduced (class x))) nil {:a 10}) |
| 09:49 | clojurebot | clojure.lang.MapEntry |
| 09:49 | clgv | mgaare: with `reduce` you already have access to the map entrys. |
| 09:50 | clgv | mgaare: you are aware of reduce-kv which is much better suited for maps? |
| 09:50 | mgaare | clgv: no, haven't run into that before. will check it out |
| 09:50 | dnolen_ | chouser: I'd bring it up on the transit-format list, you'd probably want the same support everywhere |
| 09:51 | mgaare | clgv: I think that's just what I'm looking for, thanks |
| 09:51 | chouser | dnolen_: where else are you thinking, besides transit-java's writer? |
| 09:54 | dnolen_ | chouser: well I guess it just depends on your goal |
| 09:54 | dnolen_ | chouser: if you just want to produce an Unwriteable tagged value in Java and you don't care that your JS/CLJS client can't do that than nothing more to do. |
| 10:07 | dysfun | what do i use if i actually want an honest-to-$deity lock? i'm intending to hold the lock for hours at a time. |
| 10:08 | stuartsierra | dysfun: Hours at a time? ZooKeeper. |
| 10:08 | dysfun | for what i have in mind, this seems a bit overkill |
| 10:08 | craigglennie | dysfun: Or if you have MySQL and a reliable connection you can get get_lock and release_lock. But stuartsierra’s suggestion is probably better |
| 10:09 | dysfun | if i were going to do that, i'd probably use redis |
| 10:09 | stuartsierra | dysfun: There's everything in java.util.concurrent.locks, of course, plus plain old `locking` which is the same as Java's `sychronized` |
| 10:10 | dysfun | yeah, i expect java.util.concurrent has the answer |
| 10:10 | dysfun | thanks |
| 10:12 | craigglennie | Is there an equivalent to Python’s *args? I have a function that takes [x] or [x & rest] and then wants to recur with rest… but that call doesn’t get destructured into x & rest because, I think, rest is passed as a list, and not expanded (sorry if I have the wrong terminology). There’s a paste here: https://www.refheap.com/95046 |
| 10:13 | stuartsierra | craigglennie: 2 things. `recur` doesn't cross arities. |
| 10:13 | stuartsierra | But what you're looking for is `apply` |
| 10:14 | andyf | recur doesn?t cross arities ? don?t recall running across that before. |
| 10:14 | craigglennie | stuartsierra: `apply` did the trick - thanks |
| 10:15 | stuartsierra | ,(defn foo ([x] (recur x 1)) ([x y] (prn x y))) |
| 10:15 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Mismatched argument count to recur, expected: 1 args, got: 2, compiling:(NO_SOURCE_PATH:0:0)> |
| 10:16 | stuartsierra | Each arity of the function is a separate loop/recur point. |
| 10:17 | andyf | Definitely sounds like a restriction that makes implementation possible and/or more straightforward. I guess I don't use multi-arity functions often enough to have hit that before. |
| 10:17 | craigglennie | stuartsierra: Would my function be better / more idiomatic if I’d used loop and recur? |
| 10:18 | andyf | craigglennie: (prn (last x)) perhaps? |
| 10:18 | stuartsierra | craigglennie: I'm not sure what the function in your paste is trying to do, so I can't say. |
| 10:19 | andyf | craigglennie: But you will definitely get a stackoverflow exception as written for a sequence arg with a few thousand items in it. |
| 10:19 | andyf | if you do not use recur |
| 10:19 | craigglennie | andyf: Ahh, I see |
| 10:20 | craigglennie | So, generally speaking, it’s better to use recur in a recursive function to avoid overflowing the stack? |
| 10:20 | craigglennie | Unless you know you’ll only be using a short sequence? |
| 10:22 | reiddraper | dnolen_: ha, that's awesome |
| 10:22 | andyf | craigglennie: There are definitely reasonable use cases for non-recur recursion, e.g. walking tree-structured data like nested maps, data from XML sources, etc., or balanced binary tree data structures. Those are often cases where recur won't work, and the recursion depth is typically much more limited. |
| 10:23 | dysfun | the other alternative is lazy sequences, if you can rearrange your computation into something that fits into the clojure sequence functions |
| 10:23 | andyf | But for straight sequences, recur, or using sequence processing functions, are often preferred. |
| 10:25 | djcoin | clgv: sorry I was afk. Thanks a lot for providing a macroexpand explanation of :keys :or |
| 10:45 | noncom | is ther any library that allows templating of clojure data structs? |
| 10:46 | noncom | for example, if i have (def ds {:key :tag-zzz}) and if i (render-template ds {:tag-zzz "this value be here"}) and get {:key "this value be here"} ? |
| 10:46 | noncom | is there anything close to that? |
| 10:48 | hellofunk | noncom that function render-template would be simple to write, you need a full library for that, or is there more you need? |
| 10:50 | noncom | hellofunk: yeah, maybe i could write a couple of functions for that.. but i thought maybe there is already something.. |
| 10:50 | noncom | and yes, templates may be somewhat more complex |
| 10:50 | noncom | but actually these are just json templates |
| 10:51 | stuartsierra | noncom: syntax-quote is often sufficient for simple templates |
| 10:51 | noncom | in the worst case i could go with cheshire+clostaches or cheshire+selmer.. |
| 10:51 | dnolen_ | reiddraper: yeah almost done, I'll put a patch in JIRA probably later today |
| 10:51 | reiddraper | dnolen_: that was quick :) |
| 10:51 | noncom | stuartsierra: so, i just put 'a-symbol-tag there and replace it ? |
| 10:51 | noncom | does edn support quoted symbols? |
| 10:52 | dnolen_ | reiddraper: wasn't so hard now that cljs.test is a thing - most of my changes were JVM / perf related |
| 10:52 | reiddraper | right |
| 10:52 | stuartsierra | noncom: no, as in (defn my-template [x y] `[a b c ~x ~@y]) |
| 10:52 | dnolen_ | reiddraper: partial and comp are kinda slow in CLJS, just getting ridding of that and using function literals was like 5X perf boost |
| 10:52 | noncom | stuartsierra: whoa, got it.. |
| 10:53 | noncom | but will edn support that? |
| 10:53 | reiddraper | dnolen_: ha, nice |
| 10:53 | noncom | ,(read-string "`{:a ~x}") |
| 10:53 | clojurebot | (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list :a) (clojure.core/list x)))) |
| 10:53 | noncom | umm... |
| 10:53 | dnolen_ | reiddraper: I still think keyword generator is crazy slow - at some point might be worth thinking how to make all the functional stuff faster. |
| 10:53 | noncom | stuartsierra: ^^ |
| 10:54 | stuartsierra | noncom: no, I guess I don't understand the questino |
| 10:54 | zB0hs | anyone have good experience with or examples of porting a javascript react app into reagent? i want to port in pieces not at all at once. |
| 10:54 | reiddraper | dnolen_: yeah it is really slow, don't think it's in master yet but the keyword/string roundtrip test is super slow when it creates 200 character keywords, so i'm gonna just limit that to 25 or something |
| 10:54 | noncom | stuartsierra: i want to have some way to specify a template for json and store it in edn format. then work with it through cheshire |
| 10:55 | noncom | sure i may store the json in json (not edn) string and just use selmer |
| 10:55 | stuartsierra | noncom: OK, then you'll have to invent your own template format and implement it. |
| 10:55 | noncom | i see :) |
| 10:58 | noncom | stuartsierra: look: |
| 10:58 | noncom | ,(def x 1) |
| 10:58 | clojurebot | #'sandbox/x |
| 10:58 | noncom | ,(let [x 3] (eval (read-string "`{:a ~x}"))) |
| 10:59 | clojurebot | {:a 1} |
| 10:59 | noncom | how? |
| 10:59 | clojurebot | with style and grace |
| 10:59 | noncom | why x is still 1? |
| 10:59 | justin_smith | noncom: the eval env is not effected by local bindings |
| 11:00 | noncom | justin_smith: for what sake? |
| 11:04 | clgv | ,(let [x 3] (eval `{:a ~x})) |
| 11:04 | clojurebot | {:a 3} |
| 11:05 | hellofunk | that's quite interesting. read-string is changing the binding environment somehow? |
| 11:05 | clgv | hellofunk: not really |
| 11:06 | hellofunk | clgv: why is x honoring the local binding without read-string, but not with it? |
| 11:07 | clgv | ,(pr (read-string "`{:a ~x}")) |
| 11:07 | clojurebot | (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list :a) (clojure.core/list x)))) |
| 11:08 | hellofunk | ,(let [x 3] (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list :a) (clojure.core/list x))))) |
| 11:08 | clojurebot | {:a 3} |
| 11:08 | clgv | hellofunk: my example works since the expression is constructed outside of `eval` and passed to it |
| 11:08 | clgv | hellofunk: the previous example constructs the expression via `read-string` inside of `eval` |
| 11:09 | hellofunk | interesting |
| 11:09 | Bronsa | ,(let [x 3] `{:a ~x}) ;; maybe this is clearer |
| 11:09 | clojurebot | {:a 3} |
| 11:10 | clgv | ,(let [x 3] (read-string "`{:a ~x}")) |
| 11:11 | clojurebot | (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list :a) (clojure.core/list x)))) |
| 11:11 | clgv | and that one ^^ |
| 11:12 | clgv | ,(let [x 3] (eval `(let [~'x ~x] ~(read-string "`{:a ~x}"))) |
| 11:12 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 11:12 | clgv | ,(let [x 3] (eval `(let [~'x ~x] ~(read-string "`{:a ~x}")))) |
| 11:12 | clojurebot | {:a 3} |
| 11:12 | clgv | well, that's getting confusing, I guess |
| 11:14 | noncom | anyone used selmer ? |
| 11:14 | noncom | why (selmer/render "{{wow}}" {:wow "ha"}) gives IllegalArgumentException Don't know how to create ISeq from: java.lang.Boolean clojure.lang.RT.seqFrom (RT.java:505) ? |
| 11:15 | noncom | *selmer/render -> selmer.parser/render |
| 11:17 | noncom | even the example form the manual gives the same error: (selmer/render "Hello {{name}}!" {:name "Yogthos"}) |
| 11:18 | noncom | passing in a string without a {{}} inclusion, works - it just returns the string back |
| 11:19 | clgv | noncom: works like a charm via: lein try selmer "0.7.7" |
| 11:19 | noncom | yes, selmer is 0.7.7 |
| 11:19 | yogthos | can't reproduce it here either |
| 11:19 | clgv | noncom: (require 'selmer.parser/render) (selmer.parser/render "{{wow}}" {:wow "ha"}) ;=> "ha" |
| 11:20 | clgv | noncom: better restart your repl |
| 11:20 | noncom | yeah, well.. idk, maybe restart repl will work.. |
| 11:21 | clgv | noncom: if that does not work check "lein deps :tree" to see if there is a conflict with respect to Selmer |
| 11:21 | noncom | yes, it did work |
| 11:21 | noncom | weeeeeird! |
| 11:21 | clgv | weird errors always demand a repl restart after an initial check ;) |
| 11:26 | justin_smith | m1dnight_: regarding your question about [(thunk)] upthread: that way even if (thunk) returns nil, it is [nil] which is truthy, so the if-let considers it a success |
| 11:28 | hellofunk | is this a good way to drain all the values that are waiting on a channel? https://gist.github.com/hellofunk/b32c8e0d267ada0cc396 |
| 11:29 | justin_smith | dysfun: clgv: alembic has (alembic/load-project) which adds new deps from project.clj into your running repl |
| 11:31 | clgv | justin_smith: ah ok, I vaguely remembered there was something announced some time ago |
| 11:31 | vivekramaswamy | (defn symetrize-body-parts-reduce [body-parts] |
| 11:31 | vivekramaswamy | (reduce (fn [final-parts part] |
| 11:31 | vivekramaswamy | [let [final-parts (conj final-parts part)] |
| 11:31 | vivekramaswamy | (if (needs-matching-parts part) |
| 11:31 | vivekramaswamy | (conj final-parts part) |
| 11:31 | vivekramaswamy | final-parts)])) |
| 11:31 | vivekramaswamy | [] [body-parts] |
| 11:31 | vivekramaswamy | ) |
| 11:31 | clgv | ~gist |
| 11:31 | clojurebot | http://gist.github.com/ |
| 11:31 | clgv | ~paste |
| 11:31 | clojurebot | paste is https://refheap.com/ |
| 11:32 | vivekramaswamy | sorry about that, am new to irc |
| 11:32 | vivekramaswamy | how does one paste code here? |
| 11:32 | clgv | vivekramaswamy: use one of the above two sites |
| 11:32 | justin_smith | don't - put it in an external site |
| 11:33 | justin_smith | vivekramaswamy: also, that let is going to be an error, [let ...] is not valid |
| 11:33 | justin_smith | (let ...) |
| 11:34 | justin_smith | [] is for building data, () is for invoking things |
| 11:34 | vivekramaswamy | that is correct, and that is my question, in paraedit how do I replace the whole [let] with (let) |
| 11:34 | clgv | vivekramaswamy: heavily depends on your editor ;) |
| 11:35 | vivekramaswamy | I am using emacs |
| 11:35 | vivekramaswamy | + paraedit |
| 11:35 | justin_smith | vivekramaswamy: there is no single paredit command that replaces one kind of delimiter with another |
| 11:35 | vivekramaswamy | so basically I am left with deleting that whole stuff or offing paraedit mode |
| 11:36 | justin_smith | well, you can barf it all out, and slurp it into a new delimiter |
| 11:36 | Bronsa | vivekramaswamy: no, just surround the expression in () and remove the [] delimiters |
| 11:36 | justin_smith | or the opposite order, sure |
| 11:36 | Bronsa | M-( in front of the [, enter the [ and M-s |
| 11:37 | Bronsa | justin_smith: doing it in the opposite order has the advantages that it will barf the whole expression rather than only the let |
| 11:37 | clgv | "cut and paste" should work in paredit as well right? |
| 11:37 | justin_smith | yeah, it does |
| 11:37 | justin_smith | and cut and paste can "break" paredit easily |
| 11:38 | clgv | justin_smith: would have been the quickfix for the previous question ;) |
| 11:38 | vivekramaswamy | ok let me try, thanks for the quick reply |
| 11:45 | dysfun | justin_smith: sweet. thanks! |
| 12:25 | ajmccluskey | Is it possible to use tools.trace to trace a namespace in a library my project is dependent on? I keep getting ClassNotFound. |
| 12:25 | ajmccluskey | Can require and use the library fine. |
| 12:26 | justin_smith | ajmccluskey: "class not found" makes me think you are doing some.ns instead of 'some.ns |
| 12:27 | justin_smith | and yes, you can trace any namespace, regardless of where it came from |
| 12:27 | ajmccluskey | justin_smith: d'oh, you're right. Thanks. Was blindly following example in docs that didn't have the quote. |
| 13:14 | batoms | anyone here have any experience with clj-jwt |
| 13:14 | batoms | i'm trying to verify some jwt tokens generated by auth0 but i can't get it to work |
| 13:15 | batoms | i can create a working version in python using the hmac package but i can't get it workin in clojre |
| 13:23 | OscarZ | hi.. whats #'app notation doing ? |
| 13:23 | OscarZ | #' part |
| 13:24 | justin_smith | ,(macroexpand '#'foo) |
| 13:24 | clojurebot | (var foo) |
| 13:24 | justin_smith | it gets the var |
| 13:24 | justin_smith | that way, when you redefine app (maybe by reloading the file after an edit) the server which took #'app as an argument uses the new value |
| 13:24 | OscarZ | oh.. i thought app already is var.. its defined with defn |
| 13:25 | justin_smith | right |
| 13:25 | justin_smith | but when you do (run-jetty app) or whatever, then run-jetty sees the fn |
| 13:25 | justin_smith | it never sees the var, which is implicitly dereferenced |
| 13:25 | justin_smith | so it doesn't see your update, because re-running the defn form does not mutate the fn, only the var |
| 13:26 | OscarZ | oh.. so i dont have to call run-jetty again.. the new value somehow gets injected in there? |
| 13:26 | triss | so can protocols only be applied to functions with a set number of args? |
| 13:26 | justin_smith | #'app is dereferenced again every time it is used |
| 13:27 | arrdem | triss: it is possible to construct variable arity protocols, but core does not support doing so. |
| 13:27 | arrdem | I think ztellman has a library that enables this. |
| 13:27 | justin_smith | triss: every implementation of a protocol function must have the same number of args as the original definition |
| 13:27 | triss | so there's no & args in protocols? |
| 13:27 | noonian | if you define foo with def or defn it creates an instance of Var that holds the value you defined, when you reference your var as foo it looks up the var and then return the value it was holding, not the var itself |
| 13:28 | arrdem | triss: correct |
| 13:28 | triss | cheers chaps.... |
| 13:28 | triss | is it something that should be avoided? does the facility exist in a library somewhere? |
| 13:29 | arrdem | triss: a common design pattern is to have a normal fn that wraps a protocol method. Most of the time & args are used for an implicit reduction anyway so that works out. |
| 13:29 | arrdem | the ClojureScript implementation makes heavy use of this pattern as well although mainly for decoupling's sake. |
| 13:30 | OscarZ | i still dont understand.. im trying to play with http kit and its used like this: (reset! server (run-server #'app {:port 8080}))) |
| 13:30 | justin_smith | OK |
| 13:30 | justin_smith | that tells it to use #'app as it's handling function |
| 13:30 | justin_smith | ,(#'+ 2 2) |
| 13:30 | clojurebot | 4 |
| 13:30 | OscarZ | if app is function, cant it just be passed like "app" in there |
| 13:31 | justin_smith | no, because calling defn again on the same name does not change the function previously created |
| 13:31 | justin_smith | it only changes the var attached to that name |
| 13:31 | OscarZ | oh.. ok.. |
| 13:31 | justin_smith | so http-kit does not see the change, because the function does not change (functions cannot change, they are immutible) |
| 13:32 | OscarZ | i better read up on vars |
| 13:32 | hellofunk | if i'm not mistaken, only functions can be referred to as (var ..) in their place in expressions. (#'+ 5 6) works but not (let [x 5] (+ #'x 6)) |
| 13:33 | justin_smith | hellofunk: there are two problems there |
| 13:33 | justin_smith | bindings in let are not vars |
| 13:33 | hellofunk | well, same issue if def x instead of let x |
| 13:33 | OscarZ | but def does override the var doesnt it? |
| 13:33 | justin_smith | and vars are not implicitly dereferences, vars just do lookup and then invoke when invoked |
| 13:34 | SagiCZ1 | when running in REPL exceptions are sometimes (not always) swallowed completely.. any reason why this might happen? could it be Cursive at fault? |
| 13:34 | justin_smith | OscarZ: yes, it changes the var, which is why you pass the var instead of the function |
| 13:34 | hiredman | let doesn't make vars |
| 13:34 | hellofunk | justin_smith: so since functions are always invoked, that's why they work as vars instead, but non-function vars are not invoked, they are only looked-up, is taht what you are saying? |
| 13:35 | hiredman | vars are things that exist globally, named by a namespace qualified symbol |
| 13:35 | hiredman | let creates a local binding of a name to a value |
| 13:36 | OscarZ | hmm.. can you suggested some good reading that would explain how it works? |
| 13:38 | justin_smith | &(do (defn a [] 1) (defn b [f] (fn [] (f))) (def c (b a)) (def d (b #'a)) [[(c) (d)] (do (defn a [] 2) :-) [(c) (d)]]) ;; OscarZ - an example |
| 13:38 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 13:38 | justin_smith | ,(do (defn a [] 1) (defn b [f] (fn [] (f))) (def c (b a)) (def d (b #'a)) [[(c) (d)] (do (defn a [] 2) :-) [(c) (d)]]) ;; OscarZ - an example |
| 13:38 | clojurebot | [[1 1] :- [1 2]] |
| 13:39 | llasram | OscarZ: If you know Java, check out the Clojure source for the Namespace and Var classes |
| 13:39 | llasram | Should make much clear |
| 13:39 | justin_smith | OscarZ: notice that after I redefine a, d sees the new value, but c does not |
| 13:39 | OscarZ | i thought it was something like var func = function() {...} and you could redefine whatever function func points at.. as defn uses def underneath and def can override functions |
| 13:39 | justin_smith | OscarZ: the var is mutable, the function is not |
| 13:39 | justin_smith | javascript lacks this function / var distinction |
| 13:40 | SagiCZ1 | anyone experienced exceptions being swallowed? they happen in a different namespace but still? |
| 13:40 | SagiCZ1 | ,(zero? (atom 0)) |
| 13:40 | justin_smith | SagiCZ1: in my experience, bad code is over-aggressive about what exceptions it catches |
| 13:40 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Atom cannot be cast to java.lang.Number> |
| 13:41 | llasram | OscarZ: I think what you're missing is that a Var is itself a reified thing, an object, a Clojure reference type like an atom or a ref |
| 13:41 | SagiCZ1 | this exception is not thrown |
| 13:41 | justin_smith | SagiCZ1: somebody has a try-catch that catches more than it should |
| 13:41 | SagiCZ1 | i will try to try catch it in that place and print something, to see if it is thrown at all |
| 13:41 | llasram | OscarZ: For normal Clojure code, the name in the namespace points at a Var, and is never changed to point to a different Var. |
| 13:42 | justin_smith | SagiCZ1: yeah, in general, the solution is your try/catch that is closer in to the site of the error than the other one |
| 13:42 | llasram | OscarZ: The Var itself supports mutation, and recompiling a namespace to "change" a function etc modifies the Var to point to something else |
| 13:42 | justin_smith | SagiCZ1: or, you know, the library author could be less ambitious about which exception types they catch |
| 13:43 | cfleming | SagiCZ1: I see that exception being reported in the Cursive REPL |
| 13:43 | OscarZ | llasram, i see.. i thought var was simply a name that points to some thing, like function, and namespace is a container for vars |
| 13:43 | cfleming | SagiCZ1: I just tried it now. |
| 13:43 | SagiCZ1 | cfleming: yeah it works in the repl alone |
| 13:43 | cfleming | SagiCZ1: In general Cursive reports all exceptions returned by nREPL. |
| 13:43 | SagiCZ1 | is it a problem taht the exception gets thrown in a future thread? |
| 13:43 | justin_smith | OscarZ: a var is a container type, mapped to a name inside a namespace |
| 13:44 | justin_smith | SagiCZ1: yeah, you won't see it until you deref the future |
| 13:44 | cfleming | SagiCZ1: Exceptions thrown in other threads might be missed by nREPL, yeah |
| 13:44 | SagiCZ1 | bingo |
| 13:44 | OscarZ | i need to put your example into editor and indent it :) |
| 13:44 | justin_smith | OscarZ: yeah, that would likely help |
| 13:45 | SagiCZ1 | justin_smith: what if i dont deref the future at all? i just use it to start a new thread, which upon finishing mutates some swing stuff |
| 13:45 | justin_smith | SagiCZ1: then you will never see the exception |
| 13:45 | SagiCZ1 | justin_smith: is there any workaround? it really makes debugging hard |
| 13:46 | justin_smith | SagiCZ1: maybe wrap the future body with a try/catch/print |
| 13:46 | justin_smith | ,(future (try (f) (catch Exception e (.printStackTrace e)))) |
| 13:46 | clojurebot | justin_smith: Huh? |
| 13:46 | justin_smith | haha |
| 13:46 | SagiCZ1 | ok |
| 13:46 | SagiCZ1 | is clojurebot on strike? |
| 13:46 | justin_smith | you could even add a custom message before the stacktrace to remind you where that future came from / what it was for |
| 13:47 | justin_smith | he refuses to do try/catch |
| 13:47 | SagiCZ1 | i see |
| 13:47 | SagiCZ1 | is there any reason why the exceptions in future cant be printed? |
| 13:47 | SagiCZ1 | i mean printing is side effect anyways |
| 13:47 | justin_smith | SagiCZ1: they can! but there is no global try/catch wrapping the future thread |
| 13:47 | justin_smith | unlike your main repl thread |
| 13:48 | justin_smith | so you need to make your own, as above |
| 13:48 | SagiCZ1 | oh.. i didnt realize that the main repl thread is wrapped in a try catch |
| 13:48 | SagiCZ1 | good to know |
| 13:48 | justin_smith | otherwise - first time you get an exception - boom, time to restart |
| 13:48 | justin_smith | so it needs a try/catch |
| 13:49 | SagiCZ1 | it works fine.. i will remember this |
| 13:50 | SagiCZ1 | im glad it wasnt some weird bug in the ide, that would be a bummer |
| 13:52 | justin_smith | OscarZ: my example above with longer names, properly indented https://www.refheap.com/95052 |
| 13:53 | OscarZ | thanks, ill check it out.. had a bit of trouble with the earlier :/ |
| 13:54 | OscarZ | ill paste that beast to light table |
| 13:55 | OscarZ | whats :- btw ? |
| 13:55 | justin_smith | just a placeholder |
| 13:56 | justin_smith | I needed something there, because of how I was constructing the output |
| 13:56 | OscarZ | oh ok.. keyword yes |
| 13:56 | justin_smith | ,:- |
| 13:56 | clojurebot | :- |
| 13:56 | justin_smith | also, since it is before a paren, it looks like :-) |
| 13:57 | OscarZ | heh |
| 14:00 | justin_smith | https://www.refheap.com/95052 OscarZ: updated with a repl transcript, which may be more straightforward |
| 14:01 | OscarZ | thanks |
| 14:02 | OscarZ | inside run-server function, it #'app looking like just a normal function value? |
| 14:02 | OscarZ | is ^^ |
| 14:03 | OscarZ | i guess it is.. nothing special in your example |
| 14:04 | justin_smith | well, #'app is a normal var, which should resolve to something callable (likely a fucntion) |
| 14:09 | OscarZ | can it be thought like pass-by-reference instead of pass-by-value ? |
| 14:09 | amalloy | OscarZ: yes. vars are pointers to objects |
| 14:09 | amalloy | they're expected to not change much in production, but while developing you often change them as you refine function definitions or whatever |
| 14:10 | OscarZ | ok.. cool, i think i get it now.. thanks guys |
| 14:10 | OscarZ | ok |
| 14:12 | OscarZ | what is this #' thingy called ? |
| 14:13 | gfredericks | ,'#'first |
| 14:13 | clojurebot | (var first) |
| 14:13 | OscarZ | ok.. these symbols are bit hard to google :) |
| 14:14 | amalloy | $google symbolhound |
| 14:14 | lazybot | [SymbolHound: Search Better. Code Better.] http://symbolhound.com/ |
| 14:14 | amalloy | but also, as justin_smith demonstrated, you can desugar some funny symbols by quoting them and seeing how they print |
| 14:14 | amalloy | er, not justin_smith, but gfredericks |
| 14:14 | amalloy | goodness |
| 14:14 | amalloy | good morning, folks |
| 14:14 | justin_smith | amalloy: I showed him the same thing when he first asked about it, way back in the upscroll |
| 14:15 | justin_smith | good morning, amalloy |
| 14:15 | OscarZ | i wouldnt have thought to put "first" in there :) |
| 14:17 | OscarZ | i should have read this too: http://clojure.org/vars |
| 14:17 | pandeiro | is it possible to do hstore updates with yesql? |
| 14:17 | OscarZ | so you can do that per-thread too |
| 14:20 | RasterBurn | I want a namespace to "export" a function named "map" but I don't want to redefine "map" within that namespace. Is there a way to do that? |
| 14:20 | llasram | RasterBurn: Nope |
| 14:21 | RasterBurn | ok i'm looking at how core.async does it.... it just defines "map" at the end of the file so it doesn't clash :) |
| 14:21 | llasram | RasterBurn: I doubt that's actually what is happening |
| 14:21 | RasterBurn | https://github.com/clojure/core.async/blob/53bf7866f195e6ba247ff7122b99784e66e9f1bb/src/main/clojure/clojure/core/async.clj#L862 |
| 14:22 | llasram | RasterBurn: Yeah, but: https://github.com/clojure/core.async/blob/53bf7866f195e6ba247ff7122b99784e66e9f1bb/src/main/clojure/clojure/core/async.clj#L10-L11 and https://github.com/clojure/core.async/blob/53bf7866f195e6ba247ff7122b99784e66e9f1bb/src/main/clojure/clojure/core/async.clj#L307 |
| 14:23 | RasterBurn | llasram: good find. hmmmm |
| 14:23 | RasterBurn | just to suppress the warning? |
| 14:23 | llasram | I guess it prevents the namespace from compiling the first time if you accidentally use bare `map` earlier, but a second go-round will gladly refer to the same var |
| 14:23 | llasram | RasterBurn: Well, to be correct. In the standard Clojure REPL-based workflow you will be repeatedly re-compile namespaces |
| 14:24 | llasram | RasterBurn: Anyway, just follow their lead at least in terms of `:refer-clojure ... :exclude` and refer to core functions with a namespace alias |
| 14:25 | llasram | (I usually use `cc` myself, but whatever floats your boat) |
| 14:25 | RasterBurn | llasram: will do. thanks! |
| 14:34 | mskoud | What library should I look into to make a tcp proxy? Aleph? |
| 14:35 | csd_ | Would someone be able to help me figure out why this code isnt working? https://www.refheap.com/95060 |
| 14:35 | arrdem | mskoud: are you doing this for production or for learning? |
| 14:36 | arrdem | mskoud: if the former there are good C proxies already, if the latter just roll it yourself :P |
| 14:36 | arrdem | csd_: what's wrong with it? |
| 14:36 | amalloy | csd_: that is a gigantic code dump with no explanation. what is it supposed to do? what goes wrong? is there an exception? do you get output that's wrong somehow? |
| 14:36 | arrdem | amalloy: jinx |
| 14:36 | llasram | csd_: I don't know. I've never seen someone say much ;-) |
| 14:37 | csd_ | It's an attempt to solve the 8 Queens problem of placing 8 queens on a chessboard so that none of them are in check with another |
| 14:37 | mskoud | it should be able to be used in production, though not that high throughput. It'll be doing a feb DNSBL checks. |
| 14:37 | csd_ | And I don't receive any errors. I just receive () as my output |
| 14:38 | noonian | means your program thinks theres no safe places probably |
| 14:39 | csd_ | noonian: i suspect its not generating board positions correctly |
| 14:45 | csd_ | This is so odd.. I don't feel like I changed anything but now it's working |
| 14:48 | arrdem | (inc magic) |
| 14:48 | lazybot | ⇒ 1 |
| 14:48 | csd_ | OK the problem was adjoin-position |
| 14:50 | csd_ | actually i have no idea |
| 14:51 | arrdem | git diff |
| 14:52 | amalloy | arrdem: Not a git repository |
| 14:53 | arrdem | if [ -f `which git` ]; then; git init --force; else echo "fuckit" fi; |
| 15:06 | xemdetia | (inc arrdem) |
| 15:06 | lazybot | ⇒ 40 |
| 15:07 | amalloy | arrdem: docked one point for using an unnecessary semicolon |
| 15:07 | arrdem | amalloy: the one after then or the fi |
| 15:07 | arrdem | I think both are suspect |
| 15:08 | amalloy | okay, two points. i didn't bother reading to the end before i started criticizing |
| 15:08 | amalloy | also, you probably need one before the fi |
| 15:08 | kenrestivo | then; is probably incorrect |
| 15:08 | amalloy | kenrestivo: not incorrect, just unnecessary |
| 15:14 | xemdetia | still the best chuckle i've had all week |
| 15:14 | xemdetia | that is the support I needed |
| 15:19 | dnolen_ | reiddraper: the splittable PRNG stuff, definitely seems amenable to WebWorkers optimization since the amount of data moving around is quite small (if I'm thinking about this correctly) |
| 15:20 | reiddraper | dnolen_: yes |
| 15:20 | reiddraper | aphyr, gfredericks and i are trying to optimize the jvm version at the moment, too |
| 15:21 | dnolen_ | reiddraper: OK swet |
| 15:21 | dnolen_ | sweet |
| 15:23 | triss | so if you want to extend a protocol over two different types but the implimentations of there functions are the same you would typically use clojure.core/extend? |
| 15:23 | amalloy | triss: sounds good to me |
| 15:23 | triss | ok great.... how the hell do I get at clojure.core/extend? |
| 15:24 | gfredericks | get at it? |
| 15:24 | triss | do i need to require it? |
| 15:24 | triss | I thought core was whats available by default |
| 15:24 | arrdem | no, it's in clojure.core so you get it for free with (ns)'s implicit (:require [clojure.core :refer :all]) |
| 15:25 | triss | so extend should be defined and ready to go? |
| 15:25 | amalloy | yes |
| 15:25 | arrdem | $grim clojure.core/extend |
| 15:25 | lazybot | http://grimoire.arrdem.com/1.6.0/clojure.core/extend |
| 15:26 | arrdem | need to patch that.. |
| 15:26 | triss | hang on I'm in clojurescript..... |
| 15:27 | triss | should that make a difference? |
| 15:28 | arrdem | so it looks like it's cljs.core/extend-type but I'm no clojurescript expert. |
| 15:30 | amalloy | cljs doesn't have extend? |
| 15:31 | arrdem | didn't see it looking on crossclj |
| 15:31 | kenrestivo | it has extend-protocol and extend-type |
| 15:31 | amalloy | that's a weird omission |
| 15:32 | amalloy | what about "specify"? that looks like it might be related |
| 15:35 | dnolen_ | amalloy: yeah doesn't have extend, specify is still pretty static |
| 15:35 | amalloy | ohhhh, it's because extend is supposed to work at runtime or something? |
| 15:36 | dnolen_ | amalloy: pretty sure it does |
| 15:37 | amalloy | sure, on the jvm it definitely does |
| 15:37 | dnolen_ | amalloy: it could probably be made to work in ClojureScript but it's a fiddly bit of work |
| 15:37 | dnolen_ | and I think most folks get away with what's there just fine which is probably why we haven't gotten an enhancement patch yet |
| 15:51 | kenrestivo | wait, is boot not open source? |
| 15:52 | kenrestivo | i see some plugins for it which appear to be, but boot itself seems to be a closed-source executable, AFAICT. |
| 15:53 | michaniskin_ | kenrestivo: it's EPL, same as CLojure |
| 15:54 | kenrestivo | couldn't find it on github |
| 15:54 | michaniskin_ | kenrestivo: https://github.com/boot-clj/boot/blob/master/LICENSE |
| 15:54 | michaniskin_ | and in the README https://github.com/boot-clj/boot#license |
| 15:54 | kenrestivo | ah, there it is, thanks https://github.com/boot-clj/boot |
| 15:56 | tuft | does boot have anything to help with startup time for its shebang scripts? |
| 15:56 | tuft | e.g. some background process like gretch |
| 15:56 | tuft | seems like a useless feature without |
| 15:56 | michaniskin_ | tuft: boot doesn't implement anything like that |
| 15:57 | michaniskin_ | not everything is super sensitive to a 2s startup time |
| 15:57 | timvisher | is there a way to turn off :pre/:post assertions in clojurescript? *assert* doesn't seem to be bound to anything |
| 15:57 | michaniskin_ | especially things like docker container entry points, things like that |
| 15:58 | michaniskin_ | tuft: it's useful to be able to have a runnable clojure application that is distributed as a single text file |
| 15:58 | michaniskin_ | i mean it's somewhat niche, but when you need it it's handy |
| 15:59 | tuft | michaniskin_: for sure, i've been wanting something like that to start replacing python scripts, but startup time is pretty huge for iterating |
| 15:59 | michaniskin_ | you an iterate in the REPL, of course |
| 15:59 | tuft | gretch + boot could be a thing |
| 15:59 | michaniskin_ | *can |
| 15:59 | michaniskin_ | anything you can do on the command line with boot you can also do from the REPL |
| 16:00 | michaniskin_ | which eliminates the startup time when developing things |
| 16:01 | tuft | sure, my python dev process is pretty repl oriented, but usually i'm building up a larger script i want to run over and over until it's correct |
| 16:02 | tuft | plus lots of interactive applications can shell out as an extension point, which requires fast startup too |
| 16:04 | tuft | there are so many great tools in clojure land for hot reloading code and deps, you'd think you could have a daemon like gretch plus these boot self describing scripts to solve for these other use cases pretty effectively |
| 16:04 | michaniskin_ | tuft: you could accomplish it with pods if you wanted to |
| 16:04 | michaniskin_ | boot provides these |
| 16:04 | tuft | hmm, i'll read, thanks |
| 16:05 | michaniskin_ | we actually experimented with runnign boot as a server |
| 16:05 | michaniskin_ | and made a golang client for it |
| 16:05 | michaniskin_ | the client is still in the repo i think |
| 16:05 | michaniskin_ | but in the end there were annoying issues, like the JVM current working directory can't be changed |
| 16:06 | michaniskin_ | which is pretty damning for the scripting environment situation |
| 16:06 | tuft | yeah that's the worse =\ |
| 16:06 | tuft | s/worse/worst/ |
| 16:06 | michaniskin_ | but if you can work around that problem you're good to go |
| 16:07 | michaniskin_ | boot will happily eval scripts in isolated clojure runtimes all day long |
| 16:07 | tuft | seems like all jvm libs need to deal with that somehow |
| 16:07 | tuft | very cool, thanks |
| 16:09 | didi | I am sorry, I am not familiar with Clojure, but I am curious about a design decision and I wonder if there is something written about it: Why (conj coll x & xs) and not (conj coll & xs)? |
| 16:12 | justin_smith | didi: good question, many of clojure's varargs functions have a truncated version so that one can use them in apply or reduce... |
| 16:12 | justin_smith | eg. ##(= :x) |
| 16:12 | lazybot | ⇒ true |
| 16:13 | didi | justin_smith: Using `apply' is precisely what I have in mind. |
| 16:15 | justin_smith | consider into |
| 16:15 | justin_smith | ,(into [0 1 2] []) |
| 16:15 | clojurebot | [0 1 2] |
| 16:15 | justin_smith | ,(into [0 1 2] [3 4 5]) |
| 16:15 | clojurebot | [0 1 2 3 4 ...] |
| 16:16 | justin_smith | that is pretty damn close to (apply conj x), with the behavior you want |
| 16:17 | justin_smith | actually, apart from the empty coll behavior (which is what you want changed) it should be identical to (apply conj x) |
| 16:17 | justin_smith | err, (apply conj x coll) of course |
| 16:18 | didi | justin_smith: Hum. My lack of understanding of Clojure is showing. (apply conj coll (list 4 2)) => (conj coll 4 2) , right? |
| 16:19 | justin_smith | right |
| 16:19 | didi | OK, cool. |
| 16:19 | justin_smith | ,(into [1 2] (list 4 2)) |
| 16:19 | clojurebot | [1 2 4 2] |
| 16:19 | justin_smith | so you want into, is what I am saying |
| 16:19 | didi | justin_smith: Oooh. I see. |
| 16:20 | didi | ,(into (list 4 2) (list)) |
| 16:20 | clojurebot | (4 2) |
| 16:20 | didi | Right. |
| 16:20 | tuft | into probably performs better too, no? |
| 16:21 | didi | I still wonder about (apply conj coll (list)) tho. |
| 16:21 | justin_smith | didi: it should work, but won't |
| 16:21 | justin_smith | but at least into does the right thing |
| 16:21 | justin_smith | should as in, "I think it would be better if it did" |
| 16:21 | didi | Thank you, justin_smith. |
| 16:22 | justin_smith | into is helpful for when you want to preserve collection types as well |
| 16:22 | justin_smith | np |
| 16:22 | justin_smith | ,(map #(into (empty %) (map inc %)) [[1 2 3] (1 2 3) #{1 2 3}]) |
| 16:22 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 16:22 | justin_smith | ,(map #(into (empty %) (map inc %)) [[1 2 3] '(1 2 3) #{1 2 3}]) |
| 16:22 | clojurebot | ([2 3 4] (4 3 2) #{4 3 2}) |
| 16:25 | m1dnight_ | Would any emacs users here know if there is something like an outline for clojure? A list thingy that gives you the names of all functions in the file, for quick navigation |
| 16:25 | m1dnight_ | atm I'm coping with isearch |
| 16:26 | arrdem | m1dnight_: I use folding... just keep the whole thing folded and do selective expansion. |
| 16:26 | m1dnight_ | oh, does that exist?I was wondering about that as well |
| 16:26 | m1dnight_ | you mean like any regular IDE has, collapse functions? |
| 16:26 | m1dnight_ | What is the package name? |
| 16:26 | arrdem | yeah. lemme look at my dots |
| 16:27 | arrdem | (add-hook 'clojure-mode 'hs-minor-mode) |
| 16:27 | arrdem | (add-hook 'clojure-mode 'hs-hide-all) |
| 16:27 | justin_smith | m1dnight_: there is also speedbar, I wonder if anyone has extended speedbar to recognize clojure definitions for navigation |
| 16:28 | dnolen_ | reiddraper: boom, https://github.com/clojure/test.check/compare/cljs-port-patch |
| 16:28 | dnolen_ | gfredericks: also ^ |
| 16:28 | nullptr | i personally just use occur w/"defn" |
| 16:28 | dnolen_ | reiddraper: gfredericks: let me know what you want me to change before submitting a JIRA patch that y'all can apply. |
| 16:29 | dnolen_ | also dropped ClojureScript 0.0-2496 w/ dog-fooded cljs.test - testing on both CLJS itself and the development of the test.check port |
| 16:30 | reiddraper | dnolen_: amazing, thanks for all of the hard work |
| 16:30 | justin_smith | m1dnight_: in C or javascript mode speedbar gives you a menu to jump to function definitions, but one would need to make a semantic module for clojure for that to work (I see things on github but not in elpa, and I don't know if they are any good) |
| 16:30 | gfredericks | dnolen_: will this be a single maven artifact or two? |
| 16:30 | dnolen_ | gfredericks: single, same as core.async |
| 16:31 | gfredericks | dnolen_: so if we expect them to lag, should we keep separate changelogs too? |
| 16:31 | dnolen_ | gfredericks: later when Feature Expressions land, some of these should probably become .cljc files and you will see less divergence |
| 16:32 | dnolen_ | gfredericks: even so I think expecting them to say perfectly in sync will be difficult for stuff easier on the JVM, like parallel rose tree |
| 16:32 | gfredericks | otherwise the cljs stuff is second-class, right? can't infer much about the cljs features from the version? |
| 16:32 | m1dnight_ | arrdem: Do I need to install anything in particular? I've added the two lines to my .emacs file and reloaded it but nothing changed |
| 16:32 | dnolen_ | gfredericks: could keep separate from cljs stuff, but I don't see the point really |
| 16:32 | dnolen_ | gfredericks: for stuff that's portable it's a copy and paste affair |
| 16:33 | gfredericks | okay cool |
| 16:33 | arrdem | m1dnight_: hideshow has been built in since emacs 20 |
| 16:33 | arrdem | m1dnight_: but those two literal lines probably won't "just work". |
| 16:33 | gfredericks | dnolen_: thanks for pulling that together |
| 16:34 | dnolen_ | gfredericks: at the moment *everything* is supported except generators for JVM types |
| 16:34 | gfredericks | nice |
| 16:34 | m1dnight_ | oohhhh, I just discovered the occur function |
| 16:34 | m1dnight_ | that helps a lot |
| 16:38 | shem | m1dnight_: there's also helm-semantic-or-imenu |
| 16:39 | m1dnight_ | that looks good too |
| 16:40 | m1dnight_ | I'll have a look |
| 16:40 | m1dnight_ | I'm a bit of a noob with emacs, so it looks too advanced for me tbh :p |
| 16:42 | eriktjacobsen | Can anyone think of a simple strategy to only memoize a stateful function if a value is not nil? Right now I’m using core.memoize and checking the return to issue a “memo-clear!” if its nil. Because memo expects a function I’m having a hard time coming up with a strategy where I don’t basically reimplement a lookup table like memo does. |
| 16:43 | justin_smith | eriktjacobsen: memoizing anything stateful seems like a bad idea, on the face of it |
| 16:44 | eriktjacobsen | Of course. I’m using the core.memoize TTL to keep it to 10 minutes, and I also have a redis cache for a bit longer than that… want to avoid the redis socket connect when it isn’t needed |
| 16:45 | eriktjacobsen | If the function returns a value, it should be good for several hours. In the cases it returns nil, I want to keep checking because it might work the next call |
| 16:45 | justin_smith | OK, have you looked at core.cache - because this sounds more like caching than memoizing |
| 16:46 | justin_smith | https://github.com/clojure/core.cache |
| 16:46 | eriktjacobsen | Nope. Interesting those look like a lot of the same function definitions and underlying CacheProtocol usage as core.memorize |
| 16:47 | eriktjacobsen | memoize* |
| 16:47 | eriktjacobsen | Will look at it, thanks |
| 16:52 | klyed2 | don't know much clojure myself, and as justin_smith said it wouldn't be the right thing to do, but you could create a new function that will call the memoized version of the function if not nil, or the function directly if nil... |
| 16:59 | dnolen_ | reiddraper: gfredericks: let me know what tweaks you guys would like - I hope most of the port is non-controversial. Most of the file additions are around development testing and handling both browser & Node target - noisy for the repo, but doesn't make a difference for the artifact. |
| 17:00 | reiddraper | dnolen_: yeah, i hope to play around with it this evening, unlikely i'll have much to say, just want to 'see it work' on my box |
| 17:01 | dnolen_ | reiddraper: ok cool! `lein cljsbuild auto node-dev` is all you need if you got Node.js installed |
| 17:04 | eriktjacobsen | klyed2: yes, but that would result in it never getting memoized, as the memoized version would solely be nil and it would just always call the function. This is similar to my current solution of checking the value and clearing the memo if nil. I suppose I could combine both and clear it before returning the function itself, just seems clunky. Thanks though |
| 17:05 | EvanR | can i define new java subclasses in clojure |
| 17:07 | TimMc | EvanR: Not "Java subclasses" exactly -- JVM subclasses. |
| 17:07 | EvanR | how |
| 17:07 | TimMc | $google cemerick flowchart |
| 17:07 | lazybot | [Flowchart for choosing the right Clojure type definition form | cemerick] http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/ |
| 17:08 | TimMc | EvanR: ^ It's kind of messy and depends on what you need. |
| 17:08 | EvanR | basically gen-class ? |
| 17:08 | TimMc | In the worst case. |
| 17:09 | TimMc | Or I guess direct bytecode generation would be even worse, but I've never needed that. :-) |
| 17:11 | TimMc | Hmm, I never did figure out a better way to organize that flowchart. I really thought I was going to be able to propose something with fewer loops. :-) |
| 17:11 | amalloy | TimMc: even worse than that, generating java source files at runtime and compiling those |
| 17:12 | TimMc | That's worse than ASM? |
| 17:12 | TimMc | I guess it turns it into a build tool problem, which *is* pretty bad... |
| 17:17 | hiredman | actually you can do that pretty easily with lein |
| 17:21 | EvanR | the class im trying to subclass is actually auto generated, but thats another story |
| 17:25 | justin_smith | EvanR: according to the flowchard linked above, I think that means proxy |
| 19:13 | rhg331 | is there a core fn that takes (fn [x y] ...) to work on [x y] besides apply? |
| 19:14 | joegallo | why do you ask? |
| 19:14 | justin_smith | yeah, what do you need that apply doesn't do? |
| 19:14 | arrdem | why is apply out? That's exactly what it does. |
| 19:14 | amalloy | rhg331: why would there be one in addition to apply? |
| 19:14 | amalloy | (partial apply f) |
| 19:15 | gfredericks | Hey amalloy what's your guess for (re-matches "[^[x]]" "x") |
| 19:15 | amalloy | ugh. you and your nested character classes |
| 19:15 | amalloy | i'd guess no, but i don't really know anything about how these things are defined to work |
| 19:16 | gfredericks | yeah that was my guess too |
| 19:16 | gfredericks | &(re-matches #"[^[x]]" "x") |
| 19:16 | lazybot | ⇒ "x" |
| 19:16 | rhg331 | amalloy: because apply is way more general but it does work so it's good just curious |
| 19:16 | amalloy | rhg331: how is it more general? the only thing it does is exactly what you asked for |
| 19:17 | rhg331 | apply works on any seq |
| 19:18 | justin_smith | so you were considering like (fn [v] (g (v 0) (v 1))) |
| 19:20 | rhg331 | yeah i wanted somn to basically un-juxt but in retrospect juxt accepts an arbitrary num of fns |
| 19:22 | rhg331 | the stdlib never ceases to amaze me |
| 19:29 | arrdem | really? I find that for, ->, ->> and the other threading macros are the only really "hey man hold my beer watch this" awesome features. Everything else is just... really solidly done. |
| 19:31 | amalloy | arrdem: it all dovetails together in subtle ways you might not even notice, though |
| 19:31 | amalloy | like -> and ->> wouldn't be very impressive without the consistent order that functions take their arguments in |
| 19:32 | arrdem | exactly. |
| 19:32 | rhg331 | now i wonder how to break brains with comp, juxt, partial and apply |
| 19:32 | arrdem | IMO juxt is overrated. partial and apply are fun tho. |
| 19:32 | arrdem | as is comp |
| 19:33 | arrdem | (update-in .... (comp ...)) |
| 19:33 | amalloy | and that order isn't *just* for ->. for example, update-in, swap!, all that stuff |
| 19:34 | arrdem | rhg331: check this -> out https://github.com/arrdem/spitfire/blob/master/src/spitfire/whac.clj#L461 |
| 19:34 | rhg331 | juxt is fun, it bends your mind :) |
| 19:34 | amalloy | (swap! x update-in [a b] dissoc q) ;; <3 |
| 19:34 | amalloy | ~juxt |
| 19:34 | clojurebot | juxt is usually the right answer |
| 19:34 | arrdem | clojurebot is a pit of lies and deceit |
| 19:34 | arrdem | s/pit/font/g |
| 19:35 | rhg331 | goodness arrdem |
| 19:35 | rhg331 | i feel happy and sad |
| 19:35 | arrdem | I know right |
| 19:35 | arrdem | Part of me thinks that's awesome code, the rest of me doesn't even know. |
| 19:36 | rhg331 | its 100+ loc |
| 19:36 | dbasch | I’ll take higher order functions for 200, amalloy |
| 19:37 | amalloy | arrdem: it looks rife with duplication |
| 19:37 | rhg331 | arrdem: you'd make a good js dev |
| 19:37 | justin_smith | is that shade? I think he was throwing some shade |
| 19:37 | arrdem | amalloy: there's probably a good macro in there, data wise I don't think there's duplication to be leveraged but I'd be happy to be shown wrong. |
| 19:38 | arrdem | also a toy project not real code so w/e |
| 19:38 | amalloy | arrdem: look at https://github.com/arrdem/spitfire/blob/master/src/spitfire/whac.clj#L567-L577, for example. this should be a reduce over the seq [:frost :electrical :corrosion :fire] |
| 19:39 | amalloy | and :immunity_fire should be a nested key or something, [:immunity :fire] so you don't have to type all that junk out twice |
| 19:40 | amalloy | all of https://github.com/arrdem/spitfire/blob/master/src/spitfire/whac.clj#L518-L549 should be a reduce over a seq of pairs like [[:terror w.m/terror?] [:stealth w.m/stealth?]] |
| 19:40 | arrdem | really? I thought about doing that and came to the conclusion that it wasn't a net savings. |
| 19:40 | rhg331 | reduce is actually the usual right way |
| 19:41 | arrdem | hum. got some grading to do but I could get motivated to refactor that. |
| 19:42 | rhg331 | ~clojurebot |
| 19:42 | amalloy | i mean, that's 40 lines of repetition. it'd be awfully hard to write a reduce so bad that you can't get a net savings |
| 19:42 | clojurebot | clojurebot is http://images2.fanpop.com/images/photos/3000000/Arrowed-teen-girl-squad-3099521-570-420.jpg |
| 19:42 | rhg331 | hmm |
| 19:43 | justin_smith | that Arrowed-teen-girl-squad pic would be better for threading macro factoid |
| 19:43 | arrdem | amalloy: I feel like I've gotten so used to being corrected and criticized by you that I've become flippant about it, but thank you for the time and criticism. I probably wouldn't have picked up Clojure without your and the rest of the channel's help. |
| 19:44 | amalloy | justin_smith: it's probably a derived factoid from something that makes actual sense |
| 19:44 | arrdem | now back to our regularly scheduled sarcasm. |
| 19:45 | amalloy | arrdem: you're welcome. as for myself, i occasionally realize i've become a little uh...abrasive. less gentle with my feedback. i generally think people don't take that too seriously, but i should be more careful |
| 19:47 | amalloy | whaaat. why is deferent not in chrome's spellcheck dictionary |
| 19:47 | justin_smith | amalloy: in all fairness, it was quite level headed of you to suggest a helper function hidden in metadata made you want to puke, the bodily functions that would actually be called for wouldn't be appropriate for describing on S.O. |
| 19:48 | amalloy | haha. no, i don't feel bad about that one at all, justin_smith. colorful imagery helps drive home the point without having to threaten bodily harm |
| 19:49 | arrdem | KILL IT WITH FIRE |
| 19:49 | rhg331 | lately i've noticed things like #(some-fn % 'an-arg) is this advised? |
| 19:50 | justin_smith | rhg331: what's the issue with that? |
| 19:50 | arrdem | yeah since there isn't a better way to partial the "last" arg. |
| 19:50 | rhg331 | kinda like partial but not |
| 19:50 | rhg331 | ok |
| 19:50 | justin_smith | arrdem: I prefer #() over partial even when fixing early args, unless I need the result to be varargs |
| 19:51 | arrdem | hum... I feel like there's a better way to write "partial-last" than that.. |
| 19:51 | rhg331 | me too |
| 19:51 | arrdem | justin_smith: really? I'll usually go for the partial... mainly because I have editor rewriting to make it pretty. |
| 19:52 | arrdem | ("\\(partial\\)[[:space:]]" . "Ƥ") |
| 19:52 | justin_smith | arrdem: the #() is shorter (I don't have the rewriting) and why pay for varargs you don't need? it's not like #() is obfuscated |
| 19:52 | rhg331 | it complects what and how |
| 19:52 | arrdem | in my head it's a partial, so I'd rather type partial |
| 19:52 | arrdem | than type out the resulting papply function |
| 19:53 | arrdem | but w/e they both do the same thing. |
| 19:53 | rhg331 | until it doesnt |
| 19:53 | rhg331 | theres power in conveying intent |
| 20:04 | schone | hello #clojure |
| 20:04 | rhg331 | show stuff like '(partial apply juxt inc (comp first str pos?))' to c(++) devs and watch their brains implode |
| 20:05 | schone | i’m a new comer to clojure and i’m trying to read some code and understand. Can someone help me understand where the “id” variable is assigned or set, the one used in this code https://github.com/apache/storm/blob/master/storm-core/src/clj/backtype/storm/daemon/executor.clj#L508 |
| 20:05 | schone | ? |
| 20:05 | schone | MessageId is a normal java object |
| 20:05 | arrdem | rhg331: be nice otherwise they may never join us :P |
| 20:05 | rhg331 | variables arent set |
| 20:05 | arrdem | schone: that's a reference to a static method. |
| 20:06 | schone | arrdem: what static method? |
| 20:06 | schone | i dont undersand |
| 20:06 | arrdem | MessageId.makeRootId |
| 20:06 | amalloy | probably in https://github.com/apache/storm/blob/master/storm-core/src/clj/backtype/storm/daemon/executor.clj#L506, schone |
| 20:06 | rhg331 | theyre either named constants are atoms that can be pointed to another value |
| 20:07 | rhg331 | s/are/or/ |
| 20:07 | amalloy | but it's hard to know for sure without the definition of fast-list-iter |
| 20:07 | schone | i seriously don’t understand…. makeRootId is a static method that takes two params… one is given in root-id… but what is the id variable used there? |
| 20:07 | rhg331 | arrdem: theyre not nice to anyone |
| 20:07 | rhg331 | and this is nice |
| 20:08 | amalloy | schone: yeah, i don't understand the other answers you got. they don't seem to be addressing your question at all |
| 20:08 | arrdem | I spent a summer after learning Clojure writing embedded C... not having a real macro system and first class functions made for some really bad days. |
| 20:08 | schone | amalloy: but i just raelized what you told me and you are right |
| 20:08 | schone | i cant believe i didnt notice it was right there in front of me |
| 20:09 | schone | thank you! |
| 20:09 | schone | amalloy: =^ |
| 20:09 | amalloy | schone: i didn't notice it either, until i searched for "id" |
| 20:09 | amalloy | scrolled all the way to the top of that function looking for it :P |
| 20:09 | rhg331 | arrdem: not nice would be breaking into their house and modifying their code to make the pc blow up when run |
| 20:09 | dbasch | schone: fast-list-iter sets it https://github.com/apache/storm/blob/413a6952c2acabdb97a9e4d68eaa774faafc120b/storm-core/src/clj/backtype/storm/util.clj#L921 |
| 20:10 | rhg331 | im not crazy i promise |
| 20:10 | schone | amalloy: where does fast-list-iter gets it? |
| 20:10 | schone | from |
| 20:11 | dbasch | out-ids |
| 20:11 | amalloy | schone: fast-list-iter takes some bindings |
| 20:11 | timvisher | i have a single channel that's receiving keyup events, and i'm trying to filter it for 2 different kinds of commands. of course, because the go-loops responsible for reading from the channel are taking turns reading from the channel. https://github.com/timvisher/nhss-cljs/blob/undo/src/cljs/nhss/ui.cljs#L82-L97 |
| 20:11 | schone | amalloy: what does that mean that it takes some bindings? |
| 20:11 | joegallo | think of it like this (for [x (range 0 10)] ...) <--- the x is being set there, it's not coming from anywhere. :) |
| 20:11 | amalloy | it's like (for [x xs] ...). where does the x "come from"? nowhere; it's the name you specify when using for |
| 20:11 | dbasch | schone: it’s iterating over out-ids, from what I understand |
| 20:11 | timvisher | other than adding a new listener that publishes each keyup event once to 2 different channels, how do you go about doing this? |
| 20:12 | schone | ah i see |
| 20:12 | schone | so you guys are saying out-task is an individual item in the list out-tasks and id is an individual element in the out-ids list |
| 20:12 | schone | ? |
| 20:12 | timvisher | schone: that's what it looks like to me |
| 20:12 | schone | got ya |
| 20:12 | timvisher | i've never heard of fast-list-iter though. might be defined in that project |
| 20:13 | rhg331 | so succint amalloy now i can better explain it, thx |
| 20:13 | amalloy | rhg331: explain what? |
| 20:13 | rhg331 | locals |
| 20:14 | schone | thanks guys! appreciate your help amalloy dbasch and timvisher |
| 20:17 | justin_smith | rhg331: re "variables aren't set, theyre either named constants..." - vars are mutable. local bindngs are immutable, but they aren't vars either |
| 20:18 | rhg331 | justin_smith: oops i meant locals |
| 20:19 | justin_smith | rhg331: fair enough, yeah, "variable" is tricky in clojure because we don't have anything that acts strictly like a normal variable, but vars get close (and their names almost match...) |
| 20:19 | rhg331 | i like to pretend vars are only mutable when developing |
| 20:20 | rhg331 | it prevents nasty bugs |
| 20:21 | timvisher | ah. looks like split is what i want |
| 20:23 | crack_user | hey guys |
| 20:23 | crack_user | where is the bot sourcecode |
| 20:23 | justin_smith | crack_user: which bot? |
| 20:23 | justin_smith | both are on github |
| 20:23 | justin_smith | $google github lazybot |
| 20:23 | lazybot | [Raynes/lazybot · GitHub] https://github.com/Raynes/lazybot |
| 20:23 | crack_user | clojurebot |
| 20:23 | dbasch | https://github.com/hiredman/clojurebot |
| 20:23 | justin_smith | $google github clojurebot |
| 20:23 | lazybot | [hiredman/clojurebot · GitHub] https://github.com/hiredman/clojurebot |
| 20:23 | crack_user | the irc bot |
| 20:23 | justin_smith | we have two |
| 20:23 | justin_smith | both were just linked |
| 20:24 | crack_user | cool |
| 20:24 | arrdem | justin_smith: lazybot patch inc. |
| 20:25 | justin_smith | I paint a picture, and do they call me a painter? no. I build a bridge, and do they call me a bridge maker? no. But you patch a lazybot one time... |
| 20:25 | arrdem | I mean... Raynes doesn't do shit and amalloy scares everyone |
| 20:25 | arrdem | so... |
| 20:26 | Raynes | huh |
| 20:26 | arrdem | Raynes: <3 |
| 20:26 | Raynes | What did I do now |
| 20:27 | rhg331 | ... |
| 20:28 | Raynes | I mean, it's accurate. |
| 20:28 | Raynes | I do, in fact, not do shit and amalloy is pretty terrifying. |
| 20:31 | gfredericks | it's no coincidence that "amalloy" can be rearranged to spell "pretty terrifying" |
| 20:31 | arrdem | just need some bit shifting in that arrangement.... |
| 20:32 | TEttinger | I like all them lazybot devs |
| 20:32 | sevvie | <3 #clojure. nini. |
| 20:33 | rhg331 | what magic is this |
| 20:33 | TEttinger | oh yeah, Raynes and justin_smith: nice work on the latest update |
| 20:33 | TEttinger | I just updated my lazybot fork-ish that I host to use your latest commit, and it seems good. still doesn't reconnect on some netsplits |
| 20:34 | TEttinger | I didn't even lose any lucene history, which is nice |
| 20:34 | justin_smith | TEttinger: yeah, I don't think there is any netsplit handling code in fact |
| 20:34 | dbasch | amalloy also spells “yo, llama” backwards which is pretty terrifying too |
| 20:35 | justin_smith | https://www.youtube.com/watch?v=zRozKfYGFVc bone-chilling |
| 20:36 | TEttinger | oh geez, shouldn't have anagrammed that http://wordsmith.org/anagram/anagram.cgi?anagram=alan+malloy&t=1000&a=n |
| 20:37 | justin_smith | haha |
| 20:37 | TEttinger | all anomaly is good |
| 20:38 | justin_smith | one of the few that isn't insulting |
| 20:38 | gfredericks | I dunno if this helps but Alan is my middle name |
| 20:38 | TEttinger | hey, when your first name is an anagram of "anal" you're bound to have problems with any anagram |
| 20:39 | gfredericks | oh crap I never noticed my middle name was an anagram of anal |
| 20:40 | TEttinger | ... A Dick Enlarger Frays |
| 20:41 | TEttinger | your first name is Gary right? |
| 20:41 | dbasch | TEttinger: we’ll take your word for it :P |
| 20:42 | justin_smith | thin mints jungles |
| 20:43 | TEttinger | gary fredericks is an anagram for fridge sky racer |
| 20:43 | justin_smith | nth jesting muslin |
| 20:43 | TEttinger | Gritty Memento for Tommy Ettinger |
| 20:44 | timvisher | i am confused about core.async/split i think. i have a predicate which is clearly filtering the right messages into the true channel, because they're not appearing in the false channel, but what i have set up to read from the true channel isn't getting any messages… |
| 20:44 | rhg331 | mine isnt too bad |
| 20:45 | justin_smith | timvisher: does it have backpressure if one of the channels is not consumed? |
| 20:45 | timvisher | justin_smith: well, it's not a buffered channel, so yes? |
| 20:45 | rhg331 | nvm |
| 20:46 | justin_smith | timvisher: OK, was just a guess that maybe some messages weren't being read, but rereading your question it looks like you are consuming both sides anyway |
| 20:47 | rhg331 | timvisher: is anything else consuming it? |
| 20:47 | timvisher | justin_smith: yeah. what's weird is that i'm consuming the false side for sure but i don't appear to be getting anything from the true side |
| 20:47 | timvisher | rhg331: trying to figure that out now. :) |
| 20:48 | rhg331 | its a pita for sure |
| 20:51 | timvisher | if anyone has a sec, a second pair of eyes on this would be helpful. :) https://github.com/timvisher/nhss-cljs/blob/undo/src/cljs/nhss/ui.cljs#L82-L96 |
| 20:52 | timvisher | umm… nevermind. it's working now… |
| 20:52 | timvisher | ^_^ |
| 20:52 | arrdem | :shipit: |
| 20:54 | rhg331 | 0.o |
| 20:55 | gfredericks | oh dear |
| 20:55 | gfredericks | ,(re-matches #"[^[x]]" "x") |
| 20:55 | clojurebot | "x" |
| 20:55 | gfredericks | ,(re-matches #"[^[x]x]" "x") |
| 20:55 | clojurebot | nil |
| 20:56 | arrdem | gfredericks: whaaaa |
| 20:56 | gfredericks | ,(re-matches #"[^[x]x]" "y") |
| 20:56 | clojurebot | nil |
| 20:56 | gfredericks | I'm not sure how to interpret this one |
| 20:57 | rhg331 | (juxt brain-melting cool) |
| 20:57 | gfredericks | it's the "[^[x]x] doesn't match anything" rule of regexes |
| 20:57 | rhg331 | i know |
| 20:58 | gfredericks | halp |
| 20:58 | rhg331 | its weird why its there though |
| 20:59 | rhg331 | thats (and x (not x)) |
| 21:00 | gfredericks | should be (or x (not x)) if anything |
| 21:00 | rhg331 | oops yes |
| 21:01 | rhg331 | now im more confused |
| 21:02 | gfredericks | I think I can throw an "ambiguous expression" exception or something here |
| 21:05 | rhg331 | regex analysis usually leads to tears ime |
| 21:09 | gfredericks | I always feel like I'm almost there |
| 21:13 | kenrestivo | java interop always leads to tears for me |
| 21:13 | rhg331 | ^ |
| 21:14 | kenrestivo | i love example code doing "import foo.*;" leaving me trying to scramble to figure out where all these classes and constants in the example code come from. |
| 21:16 | rhg331 | import foo.*; import bar.*; import baz.*; //have fun |
| 21:16 | kenrestivo | thank FSM most clojure code has the courtesy to require :as foo or :refer [] |
| 21:16 | amalloy | kenrestivo worships finite state machines? |
| 21:16 | kenrestivo | (inc amalloy) |
| 21:16 | lazybot | ⇒ 206 |
| 21:16 | rhg331 | apparently |
| 21:17 | kenrestivo | http://en.wikipedia.org/wiki/Flying_spaghetti_monster |
| 21:17 | amalloy | i guess we all do, really. we let these computers tell us what to do, schedule our lives around what they say, and by gosh if they aren't finite state machines |
| 21:17 | amalloy | kenrestivo: i know. i like my way better |
| 21:17 | justin_smith | hallowed be his inputs and his transitions, may our sequences be accepted, amen |
| 21:18 | rhg331 | i suppose tis be true |
| 21:20 | justin_smith | kenrestivo: I bet there is something in intellij idea, or maybe even eclipse, that takes import foo.*; and tells you exactly the set of classes that matches |
| 21:20 | kenrestivo | yeah, i thought of that, firing up intellij and making it do the dirty work. or i might just clone the library's repo and try to build javadocs for it |
| 21:20 | justin_smith | in the name of the acceptor, the recognizer, and the sequence detector |
| 21:21 | wei | is there a shortcut for (fn [x] (and (not (some? x)) (empty? x))) |
| 21:21 | kenrestivo | ~fsm |
| 21:21 | clojurebot | Gabh mo leithscéal? |
| 21:21 | justin_smith | kenrestivo: I know all too well, but these finite state machine as deity riffs are too fun |
| 21:23 | rhg331 | oh FSM |
| 21:24 | gfredericks | justin_smith: the concept of an infinite state machine is heresy |
| 21:25 | amalloy | uhhhhh, isn't that function just nil?, wei? |
| 21:25 | kristof | That's what I was thinking |
| 21:25 | amalloy | you're asserting that it's not anything other than nil, and is also empty |
| 21:25 | wei | amalloy: i think you’re right, I wrote the function wrong |
| 21:25 | kristof | lol |
| 21:26 | justin_smith | gfredericks: that reminds me of that thing where certain sects of American protestants don't accept any 20th century mathematics, because to them god=infinity so multiple infinities is clearly heretical |
| 21:26 | wei | what I’m looking for is not nil or empty (e.g. “”) |
| 21:26 | rhg331 | there are infinite finite state machines too |
| 21:26 | wei | *nil or empty |
| 21:26 | amalloy | wei: and does this function need to handle non-sequential objects like :keyword? |
| 21:27 | wei | amalloy: yup. |
| 21:27 | gfredericks | justin_smith: I haven't heard that, but I suppose it's not surprising |
| 21:27 | gfredericks | at least for a small enough sect |
| 21:27 | amalloy | and you want to treat "" as falsey? you sure are in for a treat |
| 21:27 | justin_smith | wei (and (not (some? x)) (empty? x)) is just (some? x) because only nil is (not (some? ...)) and nil is always empty |
| 21:28 | amalloy | justin_smith: we already did that part. but you got it backwards; it's nil?, not some? |
| 21:28 | andyf | gfredericks: Anagram possibilities are so much greater if you can permute the bits of a binary representation! Hmm |
| 21:28 | justin_smith | oh, right, never mind |
| 21:28 | gfredericks | andyf: gee whiz man |
| 21:29 | wei | amalloy: i’m parsing form params, and unfortunately there’s no nil |
| 21:29 | andyf | Behind on reading. I don't think I am suffering from bbloomitis |
| 21:29 | amalloy | wei: if you're parsing form params, then you only have to deal with strings! |
| 21:30 | justin_smith | wei: all's fair in love, war, and parsing http data |
| 21:30 | rhg331 | andyf: oh FSM thatd be fun |
| 21:30 | gfredericks | andyf: you're not, you just nearly nerd-snipe me. I'm resisting though. |
| 21:30 | amalloy | in which case your function is just seq |
| 21:30 | wei | fair enough. that’s good enough for me, thanks guys |
| 21:31 | gfredericks | my typing has gotten a lot more error-filled lately; I must be olding |
| 21:31 | andyf | Yeah, I should be more careful offering drinks to alcoholics |
| 21:31 | rhg331 | hmm olding |
| 21:32 | kenrestivo | i thought Foo/bar is the right way to access a static method in java interop, right? |
| 21:33 | justin_smith | kenrestivo: yes, works with or without parens, for hysterical raisins |
| 21:33 | kenrestivo | because, it's not letting me do that. Foo$bar isn't working either. |
| 21:33 | justin_smith | ,(Math/PI) |
| 21:33 | clojurebot | 3.141592653589793 |
| 21:34 | kenrestivo | i've imported Foo. i can access it. i can access static fields in it, no problem. but static methods? no dice. |
| 21:34 | rhg331 | static methods otoh... |
| 21:34 | rhg331 | ,(Math/PI 3) |
| 21:34 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: No matching method: PI, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:35 | justin_smith | right, sorry, that's a field, not a method |
| 21:35 | amalloy | kenrestivo: then you're probably calling the method with the wrong arguments |
| 21:35 | rhg331 | its illogical that syntzx |
| 21:35 | kenrestivo | i'm just trying to access it in the repl at the moment |
| 21:35 | justin_smith | rhg331: yes, it's a field, but it accepts parens, most uillogical |
| 21:36 | rhg331 | ikr |
| 21:37 | kenrestivo | ah, works. |
| 21:38 | kenrestivo | i have a bad habit of executing stuff in the repl to make sure it's "there" and it's "real" (i.e. i correctly imported or required it). works with clojure functions and vars, works with java interop classes, works with java interop static fields, does not work with java interop static methods. my bad. |
| 21:39 | amalloy | kenrestivo: what? yes it does |
| 21:39 | kenrestivo | not in this case it don't |
| 21:39 | amalloy | kenrestivo: you are inventing some false cause. something else is going wrong |
| 21:39 | justin_smith | amalloy: I think he means just standalone, without parens |
| 21:39 | amalloy | oh, i see |
| 21:39 | amalloy | you are just writing Math/log |
| 21:39 | kenrestivo | right. i.e. nrepl-eval-last-expression |
| 21:40 | amalloy | that doesn't work in the repl *or* in real life |
| 21:41 | kenrestivo | ,conj |
| 21:41 | clojurebot | #<core$conj__4079 clojure.core$conj__4079@e75b0a> |
| 21:41 | kenrestivo | yeah it does :-P |
| 21:41 | justin_smith | ,Math/log |
| 21:41 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to find static field: log in class java.lang.Math, compiling:(NO_SOURCE_PATH:0:0)> |
| 21:41 | justin_smith | kenrestivo: not for static methods |
| 21:41 | justin_smith | ,(Math/log 10) |
| 21:41 | clojurebot | 2.302585092994046 |
| 21:41 | kenrestivo | right. i just rediscovered that. sorry for the noise. |
| 21:41 | rhg331 | methods arent values* |
| 21:42 | justin_smith | exactly |
| 21:43 | kristof | if only! |
| 21:43 | kristof | but Java 8 has lambdas now |
| 21:43 | rhg331 | which are objects |
| 21:43 | rhg331 | not methods |
| 21:44 | kristof | The mental leap that methods should be objects, too, is not a hard one to make. |
| 21:45 | gfredericks | ~clojure is expected to require Java >= 8 by roughly 2023 |
| 21:45 | clojurebot | Ik begrijp |
| 21:45 | rhg331 | kristof: Methods are, methods arent |
| 21:46 | kristof | rhg331: reflection is weird. |
| 21:46 | kristof | And slow! |
| 21:47 | rhg331 | yup and sorta |
| 22:07 | gfredericks | hey who uses instaparse and do you name your grammar nodes with CamelCase and why do you do that and do you have regrets. |
| 22:09 | bbloom | gfredericks: c'mon man, just pick a casing and go with it. don't worry about it |
| 22:10 | gfredericks | bbloom: I feel gross when the weird cases leak too far into the clojure code |
| 22:10 | gfredericks | so then I feel like I need a translation layer and then I'm like why is this important and wish I was just using kebabs everywhere in the first place |
| 22:10 | bbloom | gfredericks: i'd rather you feel gross than i have to feel the bugs you will create trying to hyphenize, camelize, keywordize, etc |
| 22:11 | bbloom | unless that translation later is itself a complete parser, you're likely to try to automate some mappings & you're sure to create a maintenance nightmare later |
| 22:11 | bbloom | if you want to use kebabs, use them |
| 22:11 | bbloom | if it doesn't work, just camel case it |
| 22:11 | bbloom | just pretend it's a JVM library or something :-P |
| 22:24 | andyf | Possible TIL moment: kebabs? |
| 22:25 | ddima | gfredericks: still taking apart javax regex engine? ;) |
| 22:25 | justin_smith | $google clojure github camel-snake-kebab |
| 22:26 | bbloom | andyf: -the-line-through-this-looks-like-a-kebab- |
| 22:26 | bbloom | personally, i think you need an o-prefix-too- |
| 22:27 | gfredericks | |
| 22:27 | gfredericks | ddima: totes |
| 22:27 | amalloy | bbloom: core-logic-kebab-o? |
| 22:27 | gfredericks | ddima: I'm about to declare victory |
| 22:27 | ddima | heh |
| 22:27 | ddima | sorry for interrupting anways ;) |
| 22:29 | bbloom | amalloy_: works for me |
| 22:29 | gfredericks | the cost so far has included discovering a new instaparse bug and rolling my own interval set data structure thing |
| 22:31 | ddima | I've not followed it too closely, but I've read abot your weird 'backtracking' discovery 1-2 weeks ago, late at night (CET), tried at, shat my pants, went to sleep. still amazed something like this actually is in a pretty mature implementation. lots of computering-linguist friends would die laughing ;) |
| 22:32 | gfredericks | andyf: did you see what I found today |
| 22:34 | andyf | Nested character sets are outside of my happy place |
| 22:34 | andyf | If that is what it is |
| 22:36 | ddima | heh, I think that's about how I handle it aswell |
| 22:37 | gfredericks | ~nested character sets |are| outside of my happy place |
| 22:37 | clojurebot | Ik begrijp |
| 22:40 | gfredericks | is this list of unsupported features small enough to be useful? https://github.com/gfredericks/test.chuck/tree/regexes-2#string-from-regex |
| 22:40 | andyf | ddima: What example were you referring to, out of morbid curiosity? |
| 22:41 | ddima | lett me check, pretty sure gfredericks will be quicker, as it was his |
| 22:41 | gfredericks | ums |
| 22:41 | gfredericks | I remember a discussion about backtracking but I'm not sure it was related to what I'm doing |
| 22:43 | ddima | sort of like: |
| 22:43 | ddima | ##(time (re-find #"(x+x+)+y" (apply str (repeat 100 \x)))) |
| 22:43 | ddima | ##(time (re-find #"(x+x+)+y" (apply str (repeat 10 \x)))) |
| 22:43 | lazybot | ⇒ "Elapsed time: 7.616931 msecs" nil |
| 22:43 | lazybot | Execution Timed Out! |
| 22:43 | ddima | actually exactly the thing, taken from lein-repl history ;) |
| 22:43 | andyf | You are going for a useful subset for generating matching strings, not for implementing in Clojure code, yes? |
| 22:44 | gfredericks | andyf: I'm not sure what that second half means |
| 22:44 | gfredericks | but the first half sounds right |
| 22:45 | andyf | I mean, you are not trying to handle the kind of regexes people use when parsing things. |
| 22:46 | gfredericks | well maybe; not completely at first |
| 22:46 | gfredericks | that's a valid target but it's labeled Difficult |
| 22:46 | gfredericks | i.e., I assume anybody using a regex to parse something might also want to use it to generate test data |
| 22:48 | gfredericks | I suppose the most glaring missing features are the common character classes and the anchors? |
| 22:48 | andyf | I use a few char classes frequently \s \S \d |
| 22:48 | andyf | Yeah |
| 22:49 | gfredericks | as long as I keep disallowing flags I suppose those would be easy enough |
| 22:50 | gfredericks | the javadocs actually define each of them in terms of [...] so that couldn't be easier |
| 22:55 | andyf | By disallowing flags I suppose you mean everything the Java docs call "special constructs"? Seems reasonable to leave those out. |
| 22:55 | ddima | gfredericks: regarding above example taken from you, do you have a pointer as to why it is special (meaning, why its complexity explodes like that, even though it could be "trivially" normalized to something sane), or is it actually a bug? |
| 22:56 | gfredericks | andyf: yeah that section |
| 22:57 | gfredericks | ddima: I'm not too familiar with those examples |
| 22:58 | ddima | hm, I thought it was actually something you pasted a couple of weeks ago, experimenting ;) |
| 22:58 | gfredericks | no it's from some documentation |
| 22:58 | gfredericks | regularexpressions.info probably |
| 22:59 | ddima | oh, ok |
| 22:59 | andyf | ddima: I would guess the implementation doesn't try to transform regexes into simpler forms, expecting hand written regexes not to be written like that |
| 23:01 | ddima | one could assume, I haven't spent time figuring out what the the variants of automatas could look like for this kind of expression, so uneducated surprise - but still a surprise ;) |
| 23:01 | kenrestivo | this damn library gives me an enumeration. how do i turn it into a seq? (seq foo) doesn't. |
| 23:01 | kenrestivo | hot damn |
| 23:01 | kenrestivo | ,(doc enumeration-seq) |
| 23:01 | clojurebot | "([e]); Returns a seq on a java.util.Enumeration" |
| 23:02 | kenrestivo | rich thought of everything |
| 23:13 | gfredericks | okay I take it back can't use any even number of ampersands to do a character class intersection |
| 23:20 | amalloy | bbloom: i don't have my log. what did i say that works for you? |
| 23:21 | kenrestivo | i think someone should create a twitter feed called RegExpTorture and compile all these weird edge cases in one place |
| 23:23 | ddima | that would certainly be educational |
| 23:23 | gfredericks | I thought you could because: |
| 23:23 | gfredericks | &(re-seq #"[a-f&&&&c-h]" "abcdefghijklm") |
| 23:24 | lazybot | ⇒ ("c" "d" "e" "f") |
| 23:24 | gfredericks | but... |
| 23:24 | gfredericks | &(re-seq #"[^a-f&&&&c-h]" "abcdefghijklm") |
| 23:24 | lazybot | ⇒ nil |
| 23:24 | gfredericks | whereas |
| 23:24 | gfredericks | &(re-seq #"[^a-f&&c-h]" "abcdefghijklm") |
| 23:24 | lazybot | ⇒ ("g" "h") |
| 23:24 | gfredericks | so they're not equivalent |
| 23:26 | gfredericks | the openjdk code that parses that stuff is pretty imperative and gnarly |
| 23:32 | ddima | an idea why? from the first negated case with ^a-f&&&& it feels like he would do an intersection of ^a-f && () && c-h, but obviously not in the first case. an idea? |
| 23:32 | ddima | (never tried to torture poor regexes ;)) |
| 23:33 | gfredericks | I think it's undefined behavior |
| 23:33 | gfredericks | GIGO |
| 23:33 | ddima | heh |
| 23:33 | ddima | fine ;) |
| 23:33 | ddima | fun though |
| 23:33 | rhg135 | Poor regexes? |
| 23:34 | ddima | more like rich regexes |
| 23:34 | gfredericks | I refer you to https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/regex/Pattern.java#L2426-2525 for more details :P |
| 23:34 | maxigas | unregular regexes? |
| 23:34 | clojurebot | excusez-moi |
| 23:34 | ddima | thanks gfredericks, thats exactly what I was planning to do at fucking 5:30 in the morning ;) |
| 23:35 | ddima | <bookmark> |
| 23:35 | gfredericks | clojurebot: fucking 5:30 in the morning is https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/regex/Pattern.java#L2426-2525 |
| 23:35 | clojurebot | You don't have to tell me twice. |
| 23:38 | rhg135 | That's not too bad |