2015-05-06
| 00:06 | ScottishPig | Hey, guys. I'm the noobiest noob anywhere. I'm trying to use (re-find ...) with a (let...)ed String as the regex. I can't get past the syntax here. Obviously (re-find revar "blahdeblah") doesn't work. Neither does #revar or anything else. |
| 00:07 | justin_smith | ,(re-pattern ".*") |
| 00:07 | clojurebot | #".*" |
| 00:07 | justin_smith | ScottishPig: http://conj.io |
| 00:07 | ScottishPig | Thanks. |
| 00:07 | justin_smith | it has most of the interesting stuff built into clojure.jar, all on one page |
| 00:08 | ScottishPig | Sweet. Thanks! |
| 00:18 | sobel | is there a popular library for making event reactors, maybe somewhat like the 'twisted' library in python |
| 00:24 | bbloom_ | sobel: core.async |
| 00:24 | bbloom_ | sobel: huge piles of articles, videos, etc about it |
| 00:25 | bbloom_ | see also golang & the various stuff pike et al have written about it |
| 00:25 | brehaut | bbloom_: depends if 'somewhat like twisted' means 'callback soup' |
| 00:25 | brehaut | in which case not so much |
| 00:27 | sobel | so there's not a category-winner |
| 00:27 | sobel | i can search just fine, was hoping for an opinion |
| 00:27 | brehaut | sobel: core.async. i was makign a shitty joke |
| 00:27 | ed-g | sobel: Twisted is about event loop integration, is that right? |
| 00:28 | sobel | ed-g: i guess that's accurate |
| 00:28 | mischov | sobel: You might get a better answer if you ask in terms of what you're trying to do, not how you'd do it in python. :D |
| 00:28 | justin_smith | it's about tying callbacks to event sources I thought |
| 00:28 | bbloom_ | it's just more human CPS compiler bullshit |
| 00:29 | sobel | i want to integrate events from disparate sources. i only meant twisted as a vague reference to the type of system. |
| 00:29 | justin_smith | oh, then definitely core.async |
| 00:29 | mischov | yup |
| 00:29 | sobel | it's easy enough to DIY with core.async so i'll probably just do that |
| 00:29 | justin_smith | though ztellman's manifold, and prismatic/plumbing are worth a quick look too while you are at it |
| 00:29 | mischov | Could peek at Manifold, too, but core.async is the cannon answer |
| 00:30 | mischov | Canon* |
| 00:30 | justin_smith | sobel: depending on what kind of network stuff you are talking about, sente connects websockets to core.async |
| 00:30 | justin_smith | in a way that is nice to work with in my experience |
| 00:34 | justin_smith | sobel: also, there was a book that came out recently "clojure reactive programming" about compositional event streams, and I like it so far |
| 01:30 | brainproxy | yourkit is telling me that for one of my hot loops, RT.first and RT.next are dominating the w.r.t. "own time" |
| 01:30 | brainproxy | dominating the cpu |
| 01:32 | brainproxy | now, if I can't know ahead of time exactly what kind of sequential? things are going to be looped over, is there anything I can try to cut down on the first/next time? |
| 02:51 | puredanger | brainproxy: in 1.7, you might consider using a reducible/iterable source instead of a sequence - that's generally more efficient with less allocation. |
| 02:54 | brainproxy | puredanger: good point; I may be able to provide an optimal path for some inputs, but I guess I'm stuck if inputs can be any kind of sequential coll? |
| 02:54 | brainproxy | i mean stuck with a path for some inputs which is always going to be limited by overhead of first/next |
| 02:55 | puredanger | reduce will take a reducible path if it can and a seq path if it can't |
| 02:56 | puredanger | or things built on reduce like into |
| 02:56 | brainproxy | well in this case I actually need to (loop ...) |
| 02:57 | brainproxy | I'm doing a "forward composition" thing/experiment with transducers |
| 02:57 | brainproxy | i.e. I'm handling the continuation passing rather than relying on comp |
| 05:33 | kaiyin | https://gist.github.com/kindlychung/c874be3b9554df988ced what does ~@ mean here? |
| 05:35 | wasamasa | it unsplices |
| 05:36 | TEttinger | ,`(str ~@["alpha" "beta"]) |
| 05:36 | clojurebot | (clojure.core/str "alpha" "beta") |
| 05:36 | wasamasa | aka removing one level of parentheses |
| 05:36 | TEttinger | it only works in a syntax quote though |
| 05:36 | TEttinger | (I think) |
| 05:42 | kaiyin | but ~@ks is enclosed in [], what's point in removing if you add them back anyways? |
| 05:43 | kaiyin | the point. |
| 05:46 | chipf0rk | because you're also unquoting them with this |
| 05:46 | chipf0rk | http://stackoverflow.com/questions/20260516/how-to-explain-the-env-example-in-book-clojure-programming |
| 05:47 | chipf0rk | if you didn't unquote them, the entire macro would not do what it's supposed to |
| 05:47 | chipf0rk | ~@ is called 'unquote-splice', it unquotes AND spreads the unquoted list out |
| 05:47 | clojurebot | Ik begrijp |
| 05:59 | kaiyin | chipf0rk: why not use ~ks instead? |
| 05:59 | kaiyin | ,(let [x 2 y 3 z [x y]] `(1 ~z)) |
| 05:59 | clojurebot | (1 [2 3]) |
| 06:00 | chipf0rk | try it :) it will expand to a list, the list will be executed and you'll get an error about not being able to invoke a number |
| 06:00 | chipf0rk | hence you spread it into a vector so you can use a literal |
| 06:01 | chipf0rk | debugging this macro is easier if you define it as taking the env map as an argument |
| 06:01 | kaiyin | chipf0rk: ah, i see. |
| 06:06 | kaiyin | chipf0rk: you mean something like this? (defmacro spy-env [] (let [km &env] `(prn ~km))) |
| 06:06 | kaiyin | this does not work. |
| 06:06 | isaac_rks | how do I get unbanned from a channel |
| 06:06 | bcn-flor | Could anyone help me with clojure.tools.analyzer ? Specifically, I'd like to analyze a form without evaluating the symbols inside it, I just need the AST if that makes any sense :) |
| 06:06 | wasamasa | isaac_rks: sure it's not a matter of getting a nickserv account? |
| 06:06 | isaac_rks | yes |
| 06:06 | isaac_rks | :( |
| 06:06 | wasamasa | isaac_rks: if not, speak to the channel operators in a /query |
| 06:07 | isaac_rks | thx |
| 06:07 | wasamasa | ideally another one than the person who banned you |
| 06:07 | Bronsa | bcn-flor: hi, not sure I understand what you mean |
| 06:07 | wasamasa | isaac_rks: why are you asking this here though |
| 06:07 | wasamasa | isaac_rks: this is a topic for #freenode |
| 06:07 | isaac_rks | thanks wasamasa |
| 06:07 | isaac_rks | ok |
| 06:07 | isaac_rks | im a noob at irc |
| 06:08 | isaac_rks | its some web 1.0 shit :/ |
| 06:10 | wasamasa | ... |
| 06:12 | isaac_rks | : |
| 06:12 | isaac_rks | :^) |
| 06:18 | chipf0rk | kaiyin: no, this: (defmacro spy-env [env] |
| 06:18 | chipf0rk | (let [ks (keys env)] |
| 06:18 | chipf0rk | `(prn (zipmap '~ks [~@ks])))) |
| 06:18 | chipf0rk | the same macro, but instead of getting (keys &env), you pass env as an argument and use it: (spy-env {x 1 y 2}) |
| 06:19 | chipf0rk | oops, you have to quote the map '{x 1 y 2} |
| 09:24 | tdammers | quick question here; I'm trying to store things with newlines in them in an h2 database through yesql and jdbc, but something somewhere seems to be stripping the newlines out |
| 09:24 | tdammers | is this a known issue anywhere? am I doing anything wrong? common mistake? |
| 09:26 | clojer | Can anyone help me getting Figwheel working in vim? |
| 09:27 | clojer | When I edit a core.cljs file the browser doesn't update |
| 09:27 | justin_smith | clojer: the vim part should not matter at all |
| 09:28 | clojer | justin_smith: I have a connection, just no updates. |
| 09:29 | clojer | justin_smith: I get the Clojure logo in the browser when I update the source file but nothing updates. |
| 09:29 | oddcully | clojer: have you tried with some basic setup like lein new figwheel myapp? |
| 09:29 | clojer | oddcully: Yes, that's what I'm using. |
| 09:30 | oddcully | clojer: what are you changing? do changes to the css show up? |
| 09:30 | oddcully | clojer: is your change there, after a ctrl-f5 browser reload? |
| 09:30 | clojer | oddcully: Just changing the "Hello world" text |
| 09:31 | clojer | oddcully: Yes, there after F5 |
| 09:31 | chipf0rk | you're using the default template that uses Om, right? |
| 09:32 | chipf0rk | change `defonce` to `def` if that's the case |
| 09:32 | clojer | chipf0rk: No, it uses Reagent. |
| 09:32 | chipf0rk | oh yeah it does that by default... judging from the source, it's the same line: |
| 09:32 | chipf0rk | (defonce app-state (atom {:text "Hello world!"})) |
| 09:33 | chipf0rk | needs to be def instead |
| 09:33 | chipf0rk | and then one last reload ;) |
| 09:34 | clojer | chipf0rk: BRILLIANT!! I owe you a drink. |
| 09:34 | oddcully | (inc chipf0rk) |
| 09:34 | lazybot | ⇒ 1 |
| 09:34 | chipf0rk | np :) |
| 09:34 | oddcully | clojer: but remember: this is now fine for get going. the defonce makes sence for a larger scale soon |
| 09:35 | oddcully | clojer: now your state gets overthrown each time figwheel reloads |
| 09:35 | chipf0rk | the file includes a line on this: ;; define your app data so that it doesn't get over-written on reload |
| 09:35 | chipf0rk | I think it should be more explicit on the usage of `defonce` here. might do a tiny PR as this has confused me before |
| 09:36 | clojer | oddcully: So change back to defonce before deployment? |
| 09:36 | chipf0rk | nope, change it back during development :) when your app gets to a larger scale |
| 09:36 | chipf0rk | because you don't want to lose all your accumulated state on every code change when that happens |
| 09:36 | clojer | chipf0rk: So Figwheel's no good for large apps? |
| 09:37 | oddcully | clojer: defonce does not overwrite an existing def. such you can keep and accumulate your state in your browser session |
| 09:38 | oddcully | that was the reason, why your change was not visisble |
| 09:38 | chipf0rk | guess I'm putting this the wrong way. this actually improves developing large apps. usually you change your state with swap! and the likes |
| 09:38 | oddcully | it was def(ined) once |
| 09:38 | chipf0rk | not in the definition |
| 09:39 | chipf0rk | the definition is there for initial state in the end; now imagine having clicked through your complex app to a certain state and then wanting to change the structure of your initial state |
| 09:39 | chipf0rk | if you use def and add just one entry to your state map, you save, the def gets evaluated, and your whole state you had in the browser gets thrown out the window. that's why you use defonce |
| 09:40 | chipf0rk | hope I'm making sense here... |
| 09:40 | clojer | chipf0rk: I kinda get what you're saying but does that mean Figwheel isn't appropriate for large apps? |
| 09:41 | chipf0rk | no, I'm not sure how my explanation would imply that :) |
| 09:41 | chipf0rk | can you elaborate? |
| 09:41 | clojer | chipf0rk: Well FW seems to need def instead of defonce, at least with Reagent |
| 09:41 | oddcully | it makes it in appropriate for your toy example ;) |
| 09:41 | clojer | .. but defonce is needed to protect cumulative state, no? |
| 09:42 | sritchie | clojer: you need defonce if you have some other way of updating the state |
| 09:42 | sritchie | clojer: otherwise figwheel will reset you every single time |
| 09:42 | oddcully | defonce has nothing to do with reagent, rum, or om |
| 09:42 | sritchie | oddcully: sure; it has to do with figwheel reloading code |
| 09:42 | clojer | sritchie: Yes, so it sounds like the 2 use cases are at odds, no? |
| 09:42 | oddcully | it has to do with you running basically a living/breathing application in your browser |
| 09:43 | sritchie | clojer: only for this particular tutorial where you’re changing your initial state in the file |
| 09:43 | oddcully | sritchie: that is what i am saying |
| 09:43 | sritchie | oddcully: sorry, wasn’t trying to contradict |
| 09:44 | sritchie | I had my own issues with figwheel last week, though, with reader conditionals |
| 09:44 | sritchie | figwheel was trying to load clojure-only functions |
| 09:44 | chipf0rk | oddcully: I now think i's inappropriate for the toy example too... Will open a PR on the template repo when I've figured out a concise way to explain this |
| 09:45 | sritchie | clojer: you can get around it by adding a bare “(reset! app-state {:text “Hello, world!”})” in the file |
| 09:45 | sritchie | and changing that instead |
| 09:45 | oddcully | chipf0rk: i could argue, that the section about this topic on the GH page explains this quite well |
| 09:46 | oddcully | chipf0rk: https://github.com/bhauman/lein-figwheel#writing-reloadable-code |
| 09:46 | oddcully | or better clojer: https://github.com/bhauman/lein-figwheel#writing-reloadable-code |
| 09:47 | clojer | oddcully: Thanks. That explains everything. Will study it. |
| 09:48 | chipf0rk | even better, then you'd just need a link across the repo in the main source file :) |
| 09:49 | chipf0rk | I mean @oddcully |
| 09:52 | tdammers | hah, found it |
| 09:52 | tdammers | newlines got stripped when converting from Clob to string |
| 09:52 | tdammers | serves me right for copy-pasting code from teh intarwebz without checking |
| 09:53 | tdammers | particularly, this bit: https://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples#SELECT |
| 09:54 | tdammers | the (apply str (line-seq rdr)) part effectively removes newlines |
| 10:23 | justin_smith | seems like it would be easier to just slurp it |
| 10:40 | justin_smith | sritchie: my solution for X only was to wrap the body in #?@ so one implementation gets an empty defn |
| 10:43 | timvisher | i have `(let [...] (try ... (catch ...)))`. is there anyway for paredit to wrap the let around the `...` inside the try? |
| 10:43 | timvisher | i thought for a second that i had finally found a use for paredit convolute sexp but alas, it was a foolish thought |
| 10:43 | timvisher | although it almost gets me there :) |
| 10:45 | timvisher | actually! wow. i think i finally found it! the only problem was that i then had to barf the catch form afterwards |
| 10:45 | timvisher | omg! :) |
| 10:46 | timvisher | achievment unlocked |
| 10:46 | chipf0rk | try putting the cursor before the inner ... |
| 10:46 | justin_smith | timvisher: congrats |
| 10:46 | chipf0rk | (try | ...) |
| 10:46 | timvisher | this feels even better than when i found a use for juxt in prod :) |
| 10:46 | justin_smith | haha |
| 10:48 | chipf0rk | barfing catch works too I guess :D nice one! |
| 10:49 | timvisher | chipf0rk: maybe i'm on an older version of paredit. point where you indicate still doesn't prevent me from having to barf the catch |
| 10:51 | chipf0rk | oops, you're right. only makes a difference for where the ... after try will go. |
| 11:00 | timvisher | chipf0rk: good to know. :) |
| 11:01 | timvisher | yeah i can't imagine how it could possible know about the special catch form at the end of the try. |
| 11:35 | kaiyin | could anyone help with this? http://stackoverflow.com/questions/30081343/why-doesnt-type-hinting-improve-performance-in-this-function |
| 11:37 | xemdetia | kaiyin, .substring causes a new string to be created. |
| 11:38 | justin_smith | the second function doesn't have any information that the first doesn't have - unless the clojure compiler is really that dumb that it doesn't know (or a b) will be T if a and b are both T |
| 11:42 | dnolen | justin_smith: the compiler really does very little type inference, even so kaiyin that's not a meaningful benchmark. the overhead of seqs will dominate. Even if you removed that you would probably end up with a meaningless benchmark on the JVM. |
| 11:46 | kaiyin | dnolen: ok, the task is probably too trivial. |
| 11:50 | xemdetia | kaiyin, I don't think it is even that it is trivial it's just that calling many substrings is a lousy case even in plain java. http://www.javaadvent.com/2012/12/changes-to-stringsubstring-in-java-7.html |
| 11:55 | pyr | hi clojure! |
| 11:56 | pyr | I have an idiom I use in several projects with core.async and was wondering if there was a corresponding transducer idiom I was maybe missing |
| 11:56 | pyr | I quite often do: (core.async/reduce state-update-fn some-state input-channel) |
| 11:57 | pyr | which doesn't translate 1-1 to transducers, even though it would make my tests easier (as I would be able to mimick channels with standard collections) |
| 11:59 | pyr | do you end up just doing (transduce state-update-fn identity some-state input) ? |
| 12:09 | {blake} | ,(println println) |
| 12:09 | clojurebot | #object[clojure.core$println 0xb0e7468 clojure.core$println@b0e7468]\n |
| 12:12 | {blake} | &(println println) |
| 12:12 | lazybot | ⇒ #<core$println clojure.core$println@2bdac138> nil |
| 12:15 | {blake} | The second part of this appears to be namespace$function@address. What's the first part? I mean, I guess it's not-fully-qualified-namespace$function, but I don't get why we see it. |
| 12:15 | puredanger | in the #object form you see: class-name identity-hash to-string |
| 12:16 | puredanger | lazybot is showing you the older form which was just the toString of a function in the format "class-name@identity-hash" |
| 12:17 | puredanger | actually it's #<class-name to-string> where to-string is "class-name@identity-hash" |
| 12:17 | {blake} | puredanger: OK, I figured it was something like that. So there could be a different namespace, like "myns.core" that had a "println", and it would also show up as #<core$println...>? |
| 12:18 | {blake} | puredanger: Oh, that makes more sense than "address". =P |
| 12:18 | puredanger | well as I said, that's the <= 1.6 form so now you'll never see that form |
| 12:19 | {blake} | "now" being 1.7+? |
| 12:19 | puredanger | but now you'd see #object[myns.core$println 0xdeadbeef myns.core$println@deadbeef] |
| 12:19 | puredanger | yes |
| 12:19 | {blake} | puredanger: Oh, okay, cool. I like that better. |
| 12:19 | {blake} | (inc puredanger) |
| 12:19 | lazybot | ⇒ 48 |
| 12:20 | puredanger | there is a ticket for printing something more useful for the tostring of a function (the last component of that) too |
| 12:20 | puredanger | http://dev.clojure.org/jira/browse/CLJ-1278 |
| 12:21 | {blake} | Kewl. |
| 12:21 | {blake} | Yeah, that would be a good thing. |
| 12:23 | kaiyin | vnoremap < <gv vnoremap > >gv |
| 12:23 | kaiyin | ,(let [^String y "abc"] (meta y)) |
| 12:23 | clojurebot | nil |
| 12:23 | kaiyin | isn't type info supposed to be stored in meta? |
| 12:23 | kaiyin | why isn't it working here? |
| 12:24 | sdegutis | Pop quiz: you have a sequence of either true or false values. What's the most breathtaking way to get a percent of how many are true? |
| 12:25 | {blake} | sdegutis: Outsource it to a sweatshop of southeast asian children? |
| 12:25 | sdegutis | So, (your-function [true true true false]) should result in 0.75 |
| 12:25 | sdegutis | {blake}: that's not a valid Clojure function |
| 12:25 | puredanger | sdegutis: frequencies + something with juxt ? |
| 12:25 | {blake} | sdegutis: Well, first solve AI... |
| 12:26 | sdegutis | puredanger: that's almost the solution I have, but I'm betting there's way more impressive |
| 12:26 | {blake} | *lights up the amalloy_ signal* |
| 12:26 | sdegutis | {blake}: I solved that already, put it into a toaster's firmware |
| 12:27 | {blake} | sdegutis: That's what I did. Damn thing became passive-aggressive and started burning the edges. |
| 12:27 | sdegutis | :) |
| 12:27 | puredanger | you need to tap into POPCNT to be really impressive |
| 12:27 | sdegutis | Someone sure is in a good mood today. |
| 12:28 | {blake} | Heh. I'd do something pedestrian like frequency/count. |
| 12:28 | sdegutis | There's got to be something way more functional. |
| 12:29 | puredanger | check out Integer.bitCount() to tap into hardware level bit counting :) |
| 12:29 | puredanger | PersistentHashMap uses this trick btw :) |
| 12:29 | sdegutis | What if I give you a vector and a function that returns true on some items and false on others? |
| 12:29 | {blake} | I do love me some bitcounting. |
| 12:31 | puredanger | kaiyin: your best bet for this kind of question is Bronsa :) |
| 12:31 | {blake} | Woudldn't actually matter, would it? Lazy sequence vs. function? |
| 12:32 | kaiyin | puredanger: thanks. it seems he offline at the moment? |
| 12:32 | kaiyin | is |
| 12:32 | puredanger | kaiyin: I believe in that position the compiler is using it as :tag meta on the y symbol in the let but the symbol inside the let is a different symbol |
| 12:34 | Bronsa | kaiyin: I'm not, what's the question again? :) |
| 12:34 | puredanger | iow, I don't think you can recover that in the way you expect there, but you could apply meta to the value bound to y (assuming it was something that took meta) and recover it. not sure what your actual goal is. |
| 12:34 | puredanger | Bronsa: (let [^String y "abc"] (meta y)) |
| 12:35 | Bronsa | only the compiler can access that metadata |
| 12:36 | kaiyin | ok, thanks. |
| 12:36 | Bronsa | kaiyin: you need to understand the difference between compile-time metadata and run-time metadata |
| 12:36 | kaiyin | puredanger: I don't have a specfic goal here other than the gratification of my curiosity. :-) |
| 12:37 | Bronsa | kaiyin: I guess the confusion arises from the fact that e.g. (meta ^:foo [1 2]) returns {:foo 1} |
| 12:37 | expez | Can you create default methods with definterface? |
| 12:37 | Bronsa | kaiyin: the thing is, collections are compiled in such a way that their compile-time metadata is available at runtime while everything else doesn't |
| 12:40 | kaiyin | Bronsa: you mean their metadata are removed after compilation? |
| 12:41 | Bronsa | kaiyin: not really, think about the different stages of evaluation -- the {:tag String} metadata is attached to the y symbol, which is consumed by the compiler |
| 12:42 | mpenet | pyr: depends, but if you always will reduce over the values just pass an "xform" arg to the chan |
| 12:42 | kaiyin | and then? |
| 12:42 | Bronsa | kaiyin: the clojure compiler special cases only constant collection values to preserve their compile-time/read-time metadata at runtime |
| 12:43 | kaiyin | ok |
| 12:43 | Bronsa | `y` is just a symbol mapping to a local, the read-time metadata is used by the compiler and doesn't exist at runtime |
| 12:43 | mpenet | pyr: I do something similar in qbits.jet.http/client to fold (or not) chunked responses depending on the options passed |
| 12:49 | kaiyin | ,(meta ^:foo [1 2]) |
| 12:49 | clojurebot | {:foo true} |
| 12:51 | kaiyin | Bronsa: what does this even mean? No one attached any metadata to [1 2], and then {:foo true} just comes out of nowhere... |
| 12:52 | Bronsa | kaiyin: as i said, collection values are the only thing that preserves read/compile-time metadata at runtime |
| 12:54 | kaiyin | Bronsa: but what is there to preserve? |
| 12:54 | {blake} | Speaking of elegant ways to do things: Move a decimal point two places to the left in a string. I've got "(/ (read-string (clojure.string/replace val #"[%,]" "")) 100)". |
| 12:54 | kaiyin | ,(meta ^:foofoobarbar [1 2]) |
| 12:54 | clojurebot | {:foofoobarbar true} |
| 12:56 | kaiyin | ok, i finally got it. |
| 13:04 | mpenet | ,(import (java.text NumberFormat) (java.util Locale)) |
| 13:04 | clojurebot | java.util.Locale |
| 13:05 | mpenet | ,(/ (-> (NumberFormat/getInstance Locale/FRANCE) (.parse "1221,3")) 100) |
| 13:05 | clojurebot | 12.213 |
| 13:05 | mpenet | {blake}: it's not shorter but a bit less hairy |
| 13:06 | mpenet | ah but wait, it's not really the same, you just ignore the "," position. Anyway, you get the idea |
| 13:07 | mpenet | Long/parseLong would be better than the read-string in your example then |
| 13:08 | {blake} | mpenet: Yeah, I see the problem with read-string. I need a double, tho'. |
| 13:09 | mpenet | Double/parseDouble then |
| 13:09 | Jefffrey | Hello |
| 13:09 | {blake} | mpenet: Right. That's where I ended up. |
| 13:09 | {blake} | (inc mpenet) |
| 13:09 | lazybot | ⇒ 7 |
| 13:10 | Jefffrey | Say I have a function x in some "module" sample.module. I can refer to it via `sample.module/x`, but is there a way to rename that whole `sample.module` to something else, say `a`, so that I can call `a/x`? |
| 13:11 | {blake} | Jefffrey: (require '[sample.module :as a]) |
| 13:11 | Jefffrey | {blake}: Doesn't that also import `x` in the current namespace? |
| 13:11 | {blake} | Jefffrey: You mean so that you could just say "x"? No. |
| 13:12 | {blake} | Jefffrey: That would be (require '[sample.module :refer :all]) |
| 13:12 | Jefffrey | Alright, and why is there a ' in front of that vector? |
| 13:12 | {blake} | Jefffrey: That's for doing it in the REPL. |
| 13:13 | {blake} | In your code, you'd have your namespac: |
| 13:13 | {blake} | (ns my.stuff |
| 13:13 | {blake} | (:require [sample.module :as a]) |
| 13:13 | {blake} | No ' required. (The ' keeps the reader from immediately evaluating.) |
| 13:16 | {blake} | Jefffrey: In other words, in the REPL, if you say (require [sample.module :as a]) without the ', the reader will look for a symbol called "sample.module" which you do not have. |
| 13:16 | {blake} | With the quote, you just pass the whole vector to "require", which knows you're referring to a namespace. |
| 13:16 | Jefffrey | I thought that behaviour was reserved for lists. |
| 13:17 | brainproxy | puredanger: figured out I can do a nice optimization if the caller hints (w/ metadata) that a sequential thing being passed as an argument is known to be finite; w/ that info, I can greatly reduce the number of first/next calls |
| 13:18 | {blake} | Jefffrey: Lists without the ' get interpreted as function calls, yes. |
| 13:19 | brainproxy | {blake}: except for () |
| 13:19 | brainproxy | I used to write '() as shorthand, then realized the ' isn't necessary in that case |
| 13:19 | {blake} | brainproxy: Good point. |
| 13:20 | {blake} | Jefffrey: But everything read by the reader has to be something, right? It's either a literal value or a symbol. |
| 13:20 | {blake} | So, you can't say: {arbitrary stuff} in a map, either. |
| 13:20 | {blake} | ,{arbitrary stuff} |
| 13:20 | clojurebot | #error{:cause "Unable to resolve symbol: arbitrary in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: arbitrary in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6543]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: arbitrary in this contex... |
| 13:20 | {blake} | Because ther eader doesn't know what "arbitrary" is. |
| 13:21 | Jefffrey | Right |
| 13:21 | Jefffrey | But now this code: http://pastebin.com/wHSM5e5F, gives me "Parameter declaration let should be a vector" on the record definition. |
| 13:22 | brainproxy | Jefffrey: in the HtDP/2e book, which uses a Racket dialetc, there's an explanation for how to think about the ' and ` operators |
| 13:22 | brainproxy | http://www.ccs.neu.edu/home/matthias/HtDP2e/i2-3.html |
| 13:22 | brainproxy | the same concepts apply to Clojure |
| 13:22 | Jefffrey | Thanks |
| 13:23 | brainproxy | the difference being that clojure uses ~ instead of , (comma) |
| 13:27 | {blake} | I don't see how that can be. defrecord shouldn't be affected by anything you have. |
| 13:37 | pyr | mpenet: i'm not sure i get what you mean |
| 13:40 | mpenet | c.c.async/chan can take a transducer (xform argument), which could do the reduction you describe. But this is only useful if you can afford to set this when you create the chan. |
| 13:41 | pyr | mpenet: ah ok, I wasn't aware of this |
| 13:41 | pyr | mpenet: sounds perfect |
| 13:42 | mpenet | pyr: https://github.com/mpenet/jet/blob/master/src/clj/qbits/jet/client/http.clj#L66-L74 |
| 13:42 | mpenet | it's an example of this |
| 13:43 | mpenet | it's still a chan, but N inputs, 1 output produced by the transucer |
| 13:43 | mpenet | transducer* |
| 14:56 | patchwork | Currently using clojure.java.jdbc/execute!, when I supply args of type Long they are getting converted to strings inside the sql statement? ["insert ... ? ?" a-long b-long] --> "insert ... 'a-long' 'b-long'" |
| 14:56 | patchwork | Anyone know how to control the type of the interpolation? |
| 15:02 | hiredman | what makes you think you are passing it longs? |
| 15:06 | hiredman | I ask because the simplest explanation for your input being treated like strings, is that they are in fact strings, so have you ruled that out? |
| 15:13 | amalloy | {blake}: eh? |
| 15:15 | daviid | hello. if someone writes the following in java: "public class Particles4_ implements PlugInFilter {...}", in a jar file that i symlinked to "mc.jar", so my repl is launched like this: "java -cp clojure.jar:ij-core.jar:mc.jar:cljs clojure.main", how do i know what to import so i can use it? asking because i tried this (import '(ij.plugin.filter PlugInFilter)) but get an error: (IJ/run imp "Particle4 " "white label show=Particles |
| 15:15 | daviid | minimum=120 maximum=9999999 display redirect=None") \n Unrecognized command: "Particle4 " |
| 15:16 | hiredman | that looks very IJ (that is some image library or something?) specific |
| 15:16 | daviid | hiredman: yes, it is |
| 15:17 | {blake} | amalloy: sdegutis was looking for a "breathtaking" way took calculate the percentage of trues, given a sequence of true/false. |
| 15:17 | hiredman | but as a guess, maybe "Particle4 " needs to match the name of the class? |
| 15:17 | daviid | hiredman: the class is defined in the java file as this: |
| 15:18 | daviid | public class Particles4_ implements PlugInFilter |
| 15:18 | hiredman | java also needs to be compiled to class file, you can't just load the source (maybe you have compiled it) |
| 15:18 | oddcully | Particles4_ vs Particles4 ? |
| 15:18 | hiredman | daviid: yeah, that class has an underscore in the name |
| 15:18 | {blake} | amalloy: We only had pedestrian solutions involving frequencies. |
| 15:18 | gfredericks | ,(let [{t true f false} (frequencies (repeatedly 1000 #(rand-nth [true false])))] (/ t (+ t f))) |
| 15:18 | daviid | hiredman: i did not compile |
| 15:18 | clojurebot | 51/100 |
| 15:18 | hiredman | well, there you go |
| 15:19 | amalloy | yeah, frequencies is the way to do it |
| 15:19 | daviid | Unrecognized command: "Particle4_" |
| 15:19 | amalloy | what gfredericks did is pretty good imo. if you wanted something less legible but more breathtaking, you could try to go point-free |
| 15:20 | oddcully | daviid: package? |
| 15:21 | {blake} | I like the destructuring, gfredericks. |
| 15:21 | {blake} | amalloy: What's point-free? |
| 15:21 | amalloy | ,(apply / ((juxt first (partial apply +)) (map (frequencies (repeatedly 1000 #(rand-nth [true false]))) [true false]))) |
| 15:21 | clojurebot | 64/125 |
| 15:22 | amalloy | {blake}: a programming style in which you avoid naming locals or function arguments, instead composing higher-order functions |
| 15:22 | dnolen | thanks to Jonathan Boston & Shaun Lebron ClojureScript now has a full port of clojure.pprint - https://github.com/clojure/clojurescript/commit/d0dedcb155d2c742e11d50ec79c54e5c8c4b8e73 |
| 15:22 | dnolen | monster commit, like 4000 line patch |
| 15:22 | dnolen | seriously awesome |
| 15:23 | {blake} | amalloy: Oh, I did not know that had a name. |
| 15:24 | gfredericks | amalloy: #(rand-nth [true false]) => (partial rand-nth [true false]) |
| 15:24 | amalloy | gfredericks: yeah but both are point-free so who cares |
| 15:24 | daviid | oddcully: sorry don't understand. the thing is through the fiji interface, putting this exact plugin .jar file so fiji sees it, without compiling anything, fiji loads the jar and things are usable. then i ask fiji to write the java code that mimic the user actions, it writes exactly this: (IJ/run imp "Particle4 " "white label show=Particles minimum=120 maximum=9999999 display redirect=None") |
| 15:25 | gfredericks | amalloy: having one function with zero points is a little less point-free than having no functions |
| 15:25 | gfredericks | it's like an infintesimal point |
| 15:25 | kaiyin | what's wrong with this? (defmacro mmm [& body] ~body) |
| 15:25 | amalloy | gfredericks: is it? point-free malarkey comes from haskell, where there's no such thing as a function with no arguments |
| 15:25 | TimMc | {blake}: Also sometimes called point-less programming. :-) |
| 15:26 | kaiyin | or, ,(defmacro mmm [& body] ~@body) |
| 15:26 | TimMc | s/programming/stlye/ |
| 15:26 | gfredericks | amalloy: well then we have the freedom to extend the concept to clojure as we wish and mine is obviously better than yours |
| 15:27 | TimMc | amalloy: *Obviously* gfredericks' solution is better because it involves more fns not in head position. |
| 15:28 | daviid | here is the java code that's in the jar that i'm trying to use from clojure: http://paste.lisp.org/+364S |
| 15:28 | amalloy | TimMc: i have a fix for that: (do get inc dec + * #(rand-nth [true false])) |
| 15:29 | gfredericks | ~amalloy |wins| goodest fumctional programmer on a technicality |
| 15:29 | clojurebot | A nod, you know, is as good as a wink to a blind horse. |
| 15:30 | amalloy | gfredericks: now i'll forever be known as fumctional. my secret shame |
| 15:30 | daviid | i don't know java, which is why i'm asking these stupid quizz |
| 15:30 | gfredericks | ~fumctional programming is the shady underbelly of FP |
| 15:30 | clojurebot | 'Sea, mhuise. |
| 15:31 | oddcully | daviid: i wondered, if you Particle4_ class is in a package. according to the code it ain't |
| 15:32 | oddcully | s/you/&r/ |
| 15:32 | daviid | i don't understand sorry, it's in a jar file |
| 15:32 | oddcully | daviid: never mind, my way-to-short-question was answered by your code |
| 15:35 | daviid | i thought, as for other jars, that adding it to my java path would let me use it from clojure, the problem is, not knowing java, i'm not sure that Particles4_ lands in PlugInFilter, also why fiji does not write the _ ... |
| 15:36 | daviid | maybe i should '(import Particle4_) ? |
| 15:36 | oddcully | daviid: in your example there you wrote "Particle4 " (space at the end). mind to try without it |
| 15:36 | oddcully | just guessing... |
| 15:37 | daviid | oddcully: did that already, the problem is clojure does not see that class/function ... |
| 15:37 | oddcully | if you pass it as a string, i'd expect IJ/run to pick it up via java means |
| 15:38 | daviid | well it does not but i don't know why |
| 15:38 | daviid | (IJ/run imp "Particle4 " "white label show=Particles minimum=120 maximum=9999999 display redirect=None") |
| 15:38 | daviid | Unrecognized command: "Particle4 " |
| 15:38 | daviid | so i guess it is a load/import problem? |
| 15:39 | brainproxy | is there a (potentially clunky one-off way) to put metadata on a fuction (not its var) that includes a varargs arity and yet avoid the RestFn invocation penalty of AFunction? |
| 15:41 | arohner | brainproxy: how would that work? |
| 15:41 | arohner | brainproxy: also, metadata doesn't affect how fns behave |
| 15:41 | brainproxy | arohner: yes it does |
| 15:41 | brainproxy | look at clojure.lang.AFunction |
| 15:43 | arohner | brainproxy: ah, I was thinking of .AFn |
| 15:44 | brainproxy | I wasn't sure if maybe it's possible to cook up something with gen-class that wouldn't be convenient in general but would allow a function to have attached metadata and yet not always dispatch with RestF |
| 15:44 | brainproxy | *RestFn |
| 15:44 | arohner | why are you hitting this? Are you adding lots of metadata at runtime? |
| 15:45 | brainproxy | in any case, a workaround is to make the metadata available through invoking the varargs arity with a namespaced keyword |
| 15:45 | brainproxy | since that arity isn't hit often, it's okay |
| 15:45 | brainproxy | perf wise i mean |
| 15:45 | brainproxy | yes, I'm doing some fun things with runtime metadata on funcs |
| 15:47 | daviid | am i right to say that this public class Particles4_ implements PlugInFilter will add the function "Particles4 " to the PlugInFilter namespace, which itself is defined by imagej and is imported by the java user code as import ij.plugin.filter.PlugInFilter; |
| 15:48 | amalloy | brainproxy: i mean if you want to you can (let [f (...), m {:fake true}] (reify IFn (invoke [this x] (f x)), IMeta (meta [this] m)) |
| 15:49 | amalloy | and you probably have to implement applyTo |
| 15:49 | daviid | any tutorial on how to load a java code and call it from clojure ? |
| 15:49 | amalloy | it's more work, but it's not like the implementation of with-meta for functions is complicated |
| 15:50 | brainproxy | amalloy: but invoke can't support a [this x & xs] arity, right? |
| 15:50 | oddcully | daviid: this code makes Particles4_ implement a interface from IJ. the IJ/run then takes a command as that param. what there happens is implementation of this library |
| 15:50 | amalloy | of course not. but you wouldn't want it to, because you know the function's arity |
| 15:50 | oddcully | daviid: all the guesswork done here revolved around the fact, that there was a class name involved. but the API docs suggest, that some "command" is passed there |
| 15:51 | amalloy | oh, i think i misread |
| 15:51 | brainproxy | amalloy: no, in this case I need the func to support several arities, including a varargs arity |
| 15:51 | oddcully | daviid: its hard to tell, what would make this work, without knowning the IJ lib |
| 15:51 | amalloy | brainproxy: i'm not sure what overhead you think you'd be getting around, by doing this |
| 15:51 | amalloy | the only way to avoid going through restfn is basically to reimplement restfn yourself |
| 15:52 | hiredman | (or why you are using metadata at all) |
| 15:52 | amalloy | if you want a function that supports varargs |
| 15:52 | brainproxy | amalloy: that in the [this] [this x y] [this x y & zs] I don't want dispatch to involve RestFN |
| 15:52 | brainproxy | sorry, not the &zs case |
| 15:52 | brainproxy | i meant: [this] [this x] [this x y] |
| 15:53 | daviid | oddcully: can i list what's in IJ from clojure ? |
| 15:53 | brainproxy | okay, missed your comment re: reimpl'ing restfn |
| 15:53 | amalloy | brainproxy: okay, so, here is the thing. you are returning a wrapper around some function, right, which you are using to hold the metadata |
| 15:53 | amalloy | and you want that wrapper to be exactly as general as restfn is |
| 15:54 | amalloy | so you really can't do any better performance-wise than the existing implementation of with-meta, which uses restfn |
| 15:54 | amalloy | but of course as hiredman says, putting metadata on functions is tricky business that often ends in tears |
| 15:55 | hiredman | people tend to you use "metadata" to glom on extra data to thinks that really could just be data, e.g. {:extra-data data :thing thing}, and metadata on functions has some gross issues (with-meta implies value identity, but functions have reference identity, so the whole thing is full of hazzards) |
| 15:55 | brainproxy | amalloy: i'm in deep, and it's working out fine, but I'll admit it's a bit unusual |
| 15:56 | brainproxy | I just have a function that gets called *a lot* and I don't want the RestFn penalty |
| 15:56 | brainproxy | hence, my workaround; but I would be happy with a clunky one-off impl for that function |
| 15:57 | brainproxy | as you say, it probably means doing some custom classes |
| 15:57 | amalloy | brainproxy: i don't think you're getting what i'm saying. i'm saying, all you can do is reimplement restfn, and if you do you won't be getting around the restfn penalty |
| 15:58 | brainproxy | so there's no way to have a custom wrapper dispatch w/o using RestFn on the arities that aren't vararg? |
| 16:00 | patchwork | hiredman: Yes, I have verified they are longs |
| 16:03 | hiredman | how? |
| 16:03 | clojurebot | with style and grace |
| 16:03 | hiredman | ~botsnack |
| 16:03 | clojurebot | Thanks! Can I have chocolate next time |
| 16:03 | patchwork | (class a-long) --> java.lang.Long |
| 16:04 | hiredman | and you are checking that right before you hand off to clojure.java.jdbc? |
| 16:05 | patchwork | hiredman: Yes, they are verified longs right before they are passed to clojure.java.jdbc/execute! |
| 16:06 | hiredman | what jdbc driver are you using? if I recall by default clojure.java.jdbc uses the .setObject method, which is up to the driver to interpret |
| 16:06 | kaiyin | could anyone help me figure out what went wrong with this macro? https://gist.github.com/kindlychung/c226d6e7680a31614d38 |
| 16:06 | patchwork | [postgresql/postgresql "8.4-702.jdbc4"] |
| 16:07 | hiredman | do you have any dependencies that might be doing some antisocial like globally changing how clojure.java.jdbc sets parameters? |
| 16:07 | hiredman | something |
| 16:08 | patchwork | hiredman: How could the way clojure.java.jdbc handles parameters be globally changed? |
| 16:08 | patchwork | I can look around for that... |
| 16:09 | hiredman | patchwork: there are protocols you can extend |
| 16:10 | dogonthehorizon | Hey folks, I have a bit of a puzzler: https://gist.github.com/dogonthehorizon/ba7feb3c08202f61b004 I'm attempting to compare reducers v tesser performance when operating on a sqlite result set of ~1mil rows. On a cold run tesser outperforms reducers by a good 3seconds, but on each successive run the reducers routine gets faster until it consistently outperforms tesser by about 2 seconds. Can anyone help me |
| 16:10 | dogonthehorizon | understand the performance difference over time? |
| 16:10 | hiredman | you could start with an empty project, confirm that the parameters are correct, then either add deps to the empty project until they go bad, or remove deps from your real project until it goes good |
| 16:12 | gfredericks | project bisect |
| 16:12 | justin_smith | project netsplit? |
| 16:14 | brainproxy | hiredman: execellent point re: value/identiy, but in my use case the fact that vary/with-meta changes the identity works for me |
| 16:14 | gfredericks | with-meta always changes the identity, it just sometimes doesn't change the value |
| 16:14 | hiredman | dogonthehorizon: that is sort of the definition of how a jit works |
| 16:15 | chouser | It looks like js-delete doesn't work with advance compilation. Is this a known issue? |
| 16:16 | hiredman | dogonthehorizon: I think you have a lot going on here, sqlite, some sql dsl, etc, I would load the data in to memory and try each there |
| 16:16 | dogonthehorizon | hiredman: does that mean that tesser does not take advantage of the JIT as well as core.reducers? Otherwise I'm afraid I don't follow why reducers get faster to a much larger degree than tesser :/ |
| 16:16 | brainproxy | gfredericks: good point; in my use case it's more that the value changes which makes possible what I'm doing |
| 16:16 | justin_smith | dogonthehorizon: some things can be JIT'd better than others. Not all code is equally analyzable / optimizable |
| 16:17 | hiredman | dogonthehorizon: I am not sure how that sql dsl is operating, but my understanding is the sqlite driver doesn't allow for any concurrency (although that may just be for writes) so if the results returned by that sql dsl are lazy in some way, and tesser is reading them in many threads that is going to effect things |
| 16:18 | hiredman | dogonthehorizon: tesser likely has a larger overhead to its folds to support doing them concurrently |
| 16:19 | hiredman | overhead not just in terms of cycles, but of code that exists that has to be inlined (which can blow the inlining budget) or conditionals or whatever |
| 16:20 | hiredman | and, depending on what the sql dsl is returning, calling fold there for the reduces example my just be doing a single threaded reduce |
| 16:20 | hiredman | just too many variables |
| 16:20 | dogonthehorizon | Hmm, that makes some intuitive sense. I'm using sqlkorma for the selects and its unclear from the docs whether the resultset is lazy or not. Based on my reading tesser forgoes fork/join pools (like reducers) in favor of managing threads itself. |
| 16:22 | dogonthehorizon | Good food for thought though, thanks for pointing me in the right direction folks :) |
| 16:34 | kaiyin | could anyone help with this? http://stackoverflow.com/questions/30086634/clojure-lang-arrayseq-cannot-be-cast-to-clojure-lang-ifn-error-in-macro/30086887#30086887 |
| 16:39 | brainproxy | ,(let [r (range)] (first r) (realized? r)) |
| 16:39 | clojurebot | #error{:cause "clojure.lang.Iterate cannot be cast to clojure.lang.IPending", :via [{:type java.lang.ClassCastException, :message "clojure.lang.Iterate cannot be cast to clojure.lang.IPending", :at [clojure.core$realized_QMARK_ invoke "core.clj" 7224]}], :trace [[clojure.core$realized_QMARK_ invoke "core.clj" 7224] [sandbox$eval25 invoke "NO_SOURCE_FILE" 0] [clojure.lang.Compiler eval "Compiler.ja... |
| 16:39 | brainproxy | ^ that same expression works in 1.6 |
| 16:39 | brainproxy | clojure i mean |
| 16:40 | gfredericks | kaiyin: you want (cond2 ~(next (next body))) |
| 16:40 | brainproxy | ,(let [r (map inc [1 2 3])] (first r) (realized? r)) |
| 16:40 | clojurebot | true |
| 16:40 | gfredericks | kaiyin: your line had two problems; the loud one was that you were calling (body) |
| 16:41 | puredanger | brainproxy: we are aware of this change and don't care |
| 16:41 | kaiyin | gfredericks: yeah, that one was fixed. |
| 16:41 | brainproxy | puredanger: no problem, was just curious if it's the expected behavior |
| 16:43 | kaiyin | gfredericks: ah, i see, i think it's (cond2 ~@(next (next body))) that i need. |
| 16:43 | gfredericks | kaiyin: ah right |
| 16:47 | seancorfield | Can CIDER (in Emacs) connect to a bare nREPL server (that does not use the CIDER middleware)? |
| 16:48 | Frozenlock | seancorfield: yes |
| 16:48 | Frozenlock | But you'll have limited functionality. |
| 16:53 | seancorfield | Frozenlock: that's fine... I just want a basic connection... now the more interesting question: can CIDER connect to remote bare nREPL server without attempting to use SSH and tunneling etc? |
| 16:53 | clojurebot | Pardon? |
| 16:54 | seancorfield | So far cider (0.8.1 in Emacs Live) has defeated any and all attempts of mine to persuade it to connect to remote server on a given port... |
| 16:55 | seancorfield | I found an issue (now closed) that seems related where the presence of a server in .ssh/known_hosts seemed to cause SSH behavior but that doesn't apply in my case and I still can't get it to simply use an IP and port for a basic connection |
| 16:57 | Frozenlock | Can't help really help you there; I always use ssh port forwarding when connecting to a remote repl. |
| 16:58 | Frozenlock | Wait, that's what you are doing, right? |
| 16:58 | turbofail | i feel like the nrepl server probably only allows connections from the local machine, so you have to SSH tunnel |
| 16:59 | turbofail | by default, anyway. because there's no security to speak of otherwise |
| 16:59 | amalloy | brainproxy: they're changing a number of lazy-seq producers in 1.7, to instead produce reducible things or transducer sources or whatever it is these days |
| 16:59 | Frozenlock | turbofail: I regularly connect to repl on other machines from my lan, so I doubt it's the default. |
| 17:00 | puredanger | amalloy: seqs with fast reduce paths |
| 17:00 | turbofail | Frozenlock: really? hm. that's probably not a good thing |
| 17:00 | puredanger | amalloy: although you should really not think of them as "lazy-seq" producers, they just happened to produce seqable things that were lazy seqs in the past |
| 17:01 | amalloy | puredanger: i think it would be nice if realized? returned true for things that aren't realizable, instead of throwing an exception, so that you at least get reasonable behavior out of it |
| 17:01 | amalloy | and iterate is documented to return a lazy seq |
| 17:01 | amalloy | so it's a bit harsh to tell people they shouldn't think of it as a lazy-seq producer |
| 17:02 | seancorfield | Frozenlock: with nrepl.el you could just connect directly to a remote repl without ssh |
| 17:02 | puredanger | amalloy: hmm, maybe fair in that case |
| 17:02 | puredanger | it does still produce a lazy seq, just not a LazySeq :) |
| 17:03 | seancorfield | turbofail: no, the nrepl server happily accepts lein repl :connect ip:port from another machine without ssh involved |
| 17:03 | amalloy | puredanger: 1.7 is introducing a bunch of backwards-incompatible changes, which is fine, but it feels to me like the attitude of "we're only changing the behavior of things you shouldn't have depended on" is a bit tough to swallow |
| 17:04 | amalloy | because it's not like many things in clojure really have a contract, other than "what they happen to do in this version" |
| 17:04 | puredanger | it's not introducing a "bunch" of backwards-incompatible changes |
| 17:04 | puredanger | we've gone to great lengths to remain compatible imo |
| 17:05 | puredanger | and I'm now thinking maybe we should implement IPending on those new types... |
| 17:06 | amalloy | puredanger: it's true, you're not really introducing a bunch of those changes. there's one big change, which ripples into a lot of smaller behavior changes that aren't expected |
| 17:06 | MietroP | /msg NickServ VERIFY REGISTER MietroP mmwczdwqjjza |
| 17:06 | oddcully | BUSTED |
| 17:06 | puredanger | amalloy: with great benefits. language evolution is hard. |
| 17:06 | amalloy | puredanger: sure. like i said, i think breaking changes are fine, and to be expected |
| 17:07 | brainproxy | puredanger: probably does warrant a mention in changes.md since there is an example dating back to v1.3 in that same document which calls realized? on a (range) |
| 17:07 | amalloy | what's frustrating is that i hear "this is breaking stuff that you shouldn't have done anyway" |
| 17:08 | puredanger | breaking changes are not fine and not expected |
| 17:09 | puredanger | there are a few we're aware of and decided to live with |
| 17:09 | brainproxy | I'm excited though for broad support to make transducers fast |
| 17:09 | brainproxy | I decided to dive into them last month, and it struck me how important a pattern they are |
| 17:10 | puredanger | amalloy: because Clojure is "delicately specified", we are naturally always walking a fine line |
| 17:11 | Bronsa | while on the subject, at the risk of sounding like a broken record I still think making iterate a generator when used in a reduce context is neither intuitive nor a performance win |
| 17:11 | timvisher | anyone know how to create a trigger in mysqlf from a ragtime migration? |
| 17:12 | puredanger | thinking back to when we talked about IPending, things like iterate, cycle, and (infinite) repeat are never realized because they're infinite, so it was unlikely anyone was calling realized? on them to do something useful |
| 17:12 | puredanger | but certainly for finite repeat, that might be useful, or in contexts where you don't know what you have it might be |
| 17:13 | brainproxy | it would be cool if it were possible to ask a lazy thing if it knows whether it is *fully* realized |
| 17:13 | TimMc | MietroP: ruh roh |
| 17:14 | MietroP | ? |
| 17:14 | turbofail | nice password |
| 17:14 | MietroP | hahahaa |
| 17:14 | MietroP | ok |
| 17:14 | MietroP | trying to get used to the irc |
| 17:15 | amalloy | puredanger: that's not true at all: iterate, cycle, and infinite repeat returned true for realized? all the time |
| 17:15 | amalloy | (by which i mean, often, not always) |
| 17:15 | puredanger | yeah, you're right |
| 17:15 | amalloy | it returns true if the seq is realized up to the current element, not all the way to the end |
| 17:15 | puredanger | like I said, I think it's probably worth going back to this before we release |
| 17:17 | puredanger | http://dev.clojure.org/jira/browse/CLJ-1726 |
| 17:18 | amalloy | puredanger: i think it would help a lot, at least for realized?, if (realized? 5) returned true: "5 isn't a lazy thing I understand, so I guess it must be realized." in previous versions, that would have made realized? work smoothly for seqs from iterate, since its first element is non-lazy |
| 17:18 | amalloy | (where of course i mean anything not IPending, not just 5 specifically) |
| 17:19 | puredanger | worth considering |
| 17:22 | TimMc | "Delicately specified" is one way of putting it, yes. :-) |
| 17:22 | seancorfield | Frozenlock: and the answer is that the bug is fixed in cider 0.8.2 but emacs live uses 0.8.1 and the update-live-packs script is currently broken /cc turbofail |
| 17:24 | puredanger | amalloy: I just looked at crossclj and github and I think there are very few uses for realized? with lazy seqs, although I do see a few. most are for other delayed computations. |
| 17:25 | kaiyin | how can i disable code snippets in cursive? |
| 17:26 | cfleming | kaiyin: Tools->Editor->Live Templates, uncheck "Clojure" |
| 17:27 | kaiyin | cfleming: cool! |
| 17:28 | cfleming | kaiyin: Sorry, that should be Settings->Editor->Live Templates |
| 17:28 | kaiyin | yeah, i reckoned so. :) |
| 17:30 | amalloy | puredanger: yes, most of the time when people use realized? on a lazy seq they are actually doing something pretty fragile and/or wrong |
| 17:30 | amalloy | but, eg, i know lighttable uses (used?) it to decide when to truncate a lazy seq in its instarepl |
| 17:30 | puredanger | which is to not to say that we should break it for the few people that are using it :) |
| 17:30 | cfleming | puredanger amalloy: I use realized? on lazy seqs and would be sad if that went away |
| 17:30 | puredanger | it's not going away |
| 17:31 | cfleming | puredanger: Then I'm not sad |
| 17:31 | puredanger | was just getting out my caulking gun |
| 17:31 | seancorfield | Frozenlock: update... I figured out that in order to run update-live-packs, I first need to git submodule init / git submodule update! |
| 17:32 | TimMc | Same here. |
| 17:33 | TimMc | We use it on one promise. |
| 17:33 | cfleming | puredanger: |
| 17:33 | cfleming | Oops |
| 17:34 | puredanger | TimMc: we were specifically talking about its use with lazy seqs |
| 17:34 | cfleming | puredanger: For context, I use that in the debugger, so I can show the realised elements of a seq without actually provoking any further realisation |
| 17:36 | cfleming | puredanger: Actually, looking at the code I lie - I check whether a seq implements IPending, and if so call isRealized on it. |
| 17:36 | cfleming | puredanger: is that likely to be fragile with all these new reducible things? |
| 17:36 | puredanger | there's a wee regression there, but we'll fix |
| 17:38 | amalloy | cfleming: out of curiosity, do you correctly handle seqs that are only part-lazy? like (list* -2 -1 (range))? |
| 17:39 | cfleming | amalloy: yeah. This is a renderer for anything implementing ISeq - I walk it calling next() and at each step test for IPending and call isRealized if it implements |
| 17:39 | amalloy | lovely |
| 17:39 | puredanger | and what if it doesn't? |
| 17:40 | cfleming | puredanger: Then I call first() and use the value |
| 17:41 | cfleming | I do this in two contexts - showing the values in the debugger, when I iterate the seq as described and render the values, and when just counting the number of realised elements - in that case I don't call first(), I just iterate |
| 17:41 | cfleming | I just use the IPending/isRealized check to stop iteration |
| 17:42 | puredanger | so the regression here is on returns of ~range, repeat, cycle, and iterate which now don't return IPending seqs |
| 17:43 | cfleming | puredanger: Ok, they'll blow the stack in the Cursive debugger, then |
| 17:44 | cfleming | (which should be handled elegantly, but isn't ideal) |
| 17:44 | amalloy | cfleming: wait, really? you mean that a single long non-lazy seq currently blows the debugger stack? |
| 17:45 | cfleming | amalloy: No, but instead of seeing your values rendered in the debugger you'll see a StackOverflowException |
| 17:45 | cfleming | amalloy: i.e. it'll be caught, handled and rendered nicely, but you won't see what you want to see |
| 17:45 | daviid | i'm trying to get some help from imagejdev but no answer, i guess no one uses clojure there ..., let me ask here again, here is a better description maybe: http://paste.lisp.org/+364S/1 |
| 17:45 | amalloy | cfleming: that seems super weird. can't you do it iteratively instead of recursively? |
| 17:46 | cfleming | amalloy: I'm an idiot. I do do it iteratively. So you'll see the moral equivalent of an endless spinning wheel. |
| 17:47 | amalloy | interesting |
| 17:47 | cfleming | amalloy: But you still won't see what you'd really like to see, which is the thus-far-realised elements of your seq |
| 17:47 | puredanger | how often is that none of them? |
| 17:47 | dpark | I am curious whether anyone is using om in production. I recently switched from backend to frontend, worked through the om tutorials, developed an application that works great in a dev environment, but when using advanced optimization, om seems to break. This is easily reproduced directly from the tutorial, see https://gist.github.com/daviddpark/97a4e878c83c95f1074f Any ideas? |
| 17:47 | amalloy | cfleming: suggested feature: do something like eclipse's java debugger does for arrays. which is to display the first 10 elements, and a [more] button or something like that |
| 17:48 | cfleming | puredanger: A lot of the time |
| 17:48 | puredanger | dpark: you might want to ask in #clojurescript but yes, many people use Om in production |
| 17:48 | dpark | puredanger: Thanks! Sorry, wrong window! |
| 17:49 | puredanger | cfleming: cool, just wasn't sure. I guess if you've already used it in prior code above the point where you stop you would see that |
| 17:49 | cfleming | amalloy: So if you're talking about paginating long results, IntelliJ automatically does that. I haven't added another [more] button to explicitly realise elements from the seq, though. |
| 17:49 | cfleming | puredanger: Sure, I think in 99% of the cases your seq is either 0% or 100% realised. |
| 17:50 | puredanger | if only there was a way to eagerly apply composable transformations to a collection |
| 17:50 | TimMc | puredanger: I know, just confirming we don't use it that way. |
| 17:50 | amalloy | cfleming: i meant for realize seqs. you said you currently loop over all realized elements, even if that's a lot. i was suggesting you stop after 10 items or whatever, even if #11 is realized, and wait for the user to tell you to keep going |
| 17:55 | brainproxy | puredanger: what do you mean? |
| 17:56 | puredanger | I was just making a joke about transducers and avoiding laziness when you want to :) |
| 17:57 | brainproxy | ah i see, yeah, I was thinking "hey, that's what I *thought* transducers did...", didn't realize you were joking :) |
| 17:58 | puredanger | too sly I guess |
| 17:58 | puredanger | the new LongRange actually has multiple ways it can be walked and "realization" has different senses for them |
| 17:58 | amalloy | puredanger: it was just sly enough that i was thinking of writing "wait, is this a sarcastic plug for transducers?" |
| 17:58 | amalloy | but then i realized, yes, it is |
| 17:58 | puredanger | (no pun intended) |
| 17:59 | cfleming | amalloy: Yeah, I'll add something like that sooner or later. The pagination is actually achieved by reusing the IntelliJ array renderer, which it uses for for all collections under the hood (i.e. renders them into an array then shows that). I'd have to write a new renderer to chunk it as you describe. |
| 17:59 | puredanger | you can walk a LongRange as a seq with first/next and then it's always realized (the value for first() is always computed) |
| 17:59 | puredanger | if you walk it as a chunked seq though, it may not yet have forced the chunk (although the first() is still available) |
| 17:59 | brainproxy | when I started looking at transducers, one of questions I had was whether it would be possible for members of the composition (which in turn may be the result of composition) to refer to one another |
| 18:00 | puredanger | (none of that is particularly important, just interesting to muse about) |
| 18:00 | brainproxy | so you get recursion; and/or to have lazy composition stacks that basically act as an interpreted program |
| 18:01 | puredanger | well each intermediate "step" will complete before a new value is produced. that seems bad in tandem with unbounded recursion. |
| 18:01 | kaiyin | could anyone have a look at this? http://stackoverflow.com/questions/30088399/imposing-restrictions-on-function-args-in-clojure |
| 18:02 | puredanger | breaking the first rule, have you considered a macro? :) |
| 18:02 | brainproxy | puredanger: it does require one to have a mechanism so say "go to the end", in addition to plain return or returning @reduced |
| 18:03 | brainproxy | but it's actually feasible; I went from having an impl of the idea that was 2 orders of mag. slower than normal comp to one that's only 3x - 5x slower |
| 18:03 | brainproxy | still working out some of the details, but it plays nicely with normal comp |
| 18:04 | brainproxy | i.e. you can build stacks that have "normally composed" parts and other parts which use this other kind of comp that allows for recursion/interpretation |
| 18:05 | puredanger | kaiyin: any time you find yourself writing the same thing over and over again you should try to pull it out into a function |
| 18:05 | puredanger | which you did |
| 18:05 | puredanger | if you still find yourself doing that, then it's worth considering whether a macro might help |
| 18:05 | amalloy | i dunno, puredanger, i don't think a macro is the "first" answer here for kaiyin. the answer is to make qc take extra arguments for whatever customizations you want, so you can write (qc coll 2) to check that args is 2 or whatever. or (qc {:count 2} coll) is probably better |
| 18:05 | amalloy | later you can wrap calls to qc in a macro if there's some reason to, but so far i don't really see one |
| 18:05 | puredanger | yep |
| 18:05 | amalloy | because what is the macro really going to do? it's going to do exactly what qc does, as a function |
| 18:10 | brainproxy | qc could be a function factory, could it not? so you pass in * / + etc. and you get back the equiv of f1,f2,f3 |
| 18:10 | kaiyin | amalloy: I really miss a type system here, so that when you are applying a function to a certain instance, you know for sure certain criteria are satisfied. |
| 18:14 | daviid | how can i list the content of a jar fro clojure? |
| 18:14 | puredanger | daviid: command line or programmatically? |
| 18:14 | puredanger | jar tf foo.jar |
| 18:14 | puredanger | works on the command line |
| 18:15 | oddcully | unzip -l foo.jar does too |
| 18:15 | brainproxy | kaiyin: i may misunderstand what you were asking, but does this help? https://gist.github.com/michaelsbradleyjr/6f7dc255b6b9cef60384 |
| 18:17 | TimMc | Hey, do any of y'all deploy stuff to Maven Central using Leiningen? |
| 18:17 | kaiyin | brainproxy: yeah, i guess that's a nicer way to put it than i did. thanks! |
| 18:17 | brainproxy | kaiyin: also, you could pass in predicate function/s in addition to op, paired with exception messages |
| 18:17 | TimMc | Someone at Sonatype asked if I wanted to contribute to documentation on how to do so, and I'm wondering if there's anyone I can get to review or help write it (once I get around to it.) |
| 18:18 | amalloy | daviid: also if you're using emacs, you can just open the jar file, and it auto-expands the contents to treat it as if it were a directory |
| 18:19 | oddcully | same for vim |
| 18:19 | kaiyin | brainproxy: cool. |
| 18:25 | TimMc | Fun fact: You can edit the jar of a running clojure process and use require :reload to make the changes take effect. |
| 18:25 | daviid | lost my connection again, i'm back |
| 18:25 | TimMc | So make sure to put emacs on your production servers. ;-) |
| 18:26 | brainproxy | kaiyin: this code isn't tested, but something like https://gist.github.com/michaelsbradleyjr/7a7bc10d0e28ff39759d |
| 18:29 | kaiyin | brainproxy: why do you need a doall here? |
| 18:30 | brainproxy | to force realization of the lazy seq returned by map |
| 18:30 | brainproxy | actually, there's probably a better abstraction than doall map |
| 18:30 | brainproxy | lemme see... |
| 18:33 | amalloy | brainproxy: you want doseq |
| 18:34 | brainproxy | was just cooking up a rev w/ doseq :) |
| 18:34 | amalloy | also, as currently written it's indented wrong: (apply ...) should be further right. and you don't want (apply op coll), just (op coll) |
| 18:35 | brainproxy | indeeed |
| 18:37 | brainproxy | no, you do want apply |
| 18:37 | brainproxy | kaiyin: here's the doseq version https://gist.github.com/michaelsbradleyjr/c700e265a64c2f2feb91 |
| 18:39 | amalloy | oh, i see. i thought op was the checker, but i see it's the actually-do-work function |
| 18:39 | brainproxy | right |
| 18:41 | brainproxy | kaiyin: if guarding function calls is what you're actually interested in, i.e. in addition to how to leverage HOFs, maybe look into clojure's core.contracts facility |
| 18:41 | brainproxy | also, there's :pre and :post for functions |
| 18:42 | brainproxy | see also core.typed and perhaps prismatic's schema |
| 18:42 | kaiyin | is there a log of this channel somewhere? my pc went asleep a few minutes ago, and i might missed something. |
| 18:42 | kaiyin | have missed. |
| 18:43 | brainproxy | kaiyin: see http://logs.lazybot.org/irc.freenode.net/%23clojure |
| 18:45 | kaiyin | wonderful. :-) |
| 18:52 | TimMc | ~logs |
| 18:52 | clojurebot | logs is http://clojure-log.n01se.net/ |
| 18:52 | TimMc | ^ there too |
| 18:52 | amalloy | ~lazy-logs |
| 18:52 | clojurebot | lazy-logs is http://logs.lazybot.org/ |
| 18:53 | amalloy | i know it was already linked, just pointing out that there's a factoid for it |
| 18:55 | TimMc | good to know |
| 19:00 | daviid | what information can I ask, from clojure repl, upon a jar content? |
| 19:00 | amalloy | roughly none |
| 19:01 | daviid | because i don't know how to debug my problem |
| 19:01 | daviid | java -cp clojure.jar:ij-core.jar:mc.jar:cljs clojure.main |
| 19:01 | daviid | list the content of mc.jar please ... |
| 19:01 | daviid | what functions are defined... |
| 19:01 | amalloy | don't do that from inside the repl, as people mentioned |
| 19:01 | amalloy | do it from your shell, or your editor |
| 19:02 | TimMc | It's *possible* to do it from the REPL, but I don't think anyone has made a library to make it pleasant or easy. |
| 19:03 | daviid | i need to do it from the repl |
| 19:03 | TimMc | Interesting claim, tell me more. :-) |
| 19:04 | daviid | more is how can i debug this :) http://paste.lisp.org/+364S/1 |
| 19:10 | daviid | anyone knows if Albert Cardona appears here from time to time ? he wrote http://imagej.net/Clojure_Scripting |
| 19:17 | TimMc | daviid: Remind me why you're not using leiningen? |
| 19:19 | daviid | i use emacs |
| 19:20 | daviid | i'm trying to understand why the jar works perfectly fine from fiji [which just ffer an gui over inagej] and i can't use it from clojure |
| 19:23 | TimMc | Well... it's not emacs vs. leiningen. Those are two tools that many, many people in the Clojure community use together. One is an editor (among other things!) and the other is a build tool. |
| 19:24 | TimMc | I hate to say it, but you're going to have a hard time getting help if you don't have a pretty good reason not to use an actual build tool -- people are going to get hung up on that (for good reason.) |
| 19:26 | bcm | or boot? :) |
| 19:27 | daviid | TimMc: i don't understand, I don't build anything, I'm trying to use a jar from another user, exactly the same way i'm using ij-core.jar, clojure.jar ... |
| 19:28 | daviid | I don't see how leningen would help me with that respect |
| 19:30 | amalloy | leiningen makes it a lot easier to depend on other jars, by downloading them and managing your classpath automatically |
| 19:31 | amalloy | i don't think whatever you're currently running into is related to your choice to not use leiningen, but it will be harder for anyone else to reproduce without a leiningen project |
| 19:31 | amalloy | the main problem is your insistence on doing everything from a clojure repl, when several people have told you that is the wrong way to do it and it's really hard |
| 19:41 | kaiyin | amalloy: what if the jar file is not hosted on maven or clojars? e.g. http://www.siegmann.nl/epublib |
| 19:41 | amalloy | kaiyin: first, you get a mob together with pitchforks and torches |
| 19:41 | amalloy | but then you shrug your shoulders, and install it locally under a groupid of your own |
| 19:42 | amalloy | or publish it to clojars, again under a groupid of your own |
| 19:42 | amalloy | so that you can carry on using leiningen like a civilized person, and get all your other dependencies |
| 19:43 | kaiyin | nice. |
| 19:44 | kaiyin | amalloy: how exactly do you install it locally? |
| 19:45 | amalloy | kaiyin: as i recall, if you depend on a jar that doesn't exist yet, lein prints instructions for how to install a jar with that groupid/artifactid |
| 19:46 | kaiyin | amalloy: ok, that's cool. |
| 19:46 | amalloy | hm, no it doesn't |
| 19:47 | amalloy | but http://www.elangocheran.com/blog/2013/03/installing-jar-files-locally-for-leiningen-2/ has the instructions that i think used to be printed |
| 19:49 | daviid | i think that fiji does some hidden stuff to pretend that the filsystem is as the jar has been defined, maybe |
| 19:50 | daviid | anyway, thanks all, bbl have to run |
| 20:13 | timvisher | has anyone created database triggers from clojure? |
| 20:20 | erikcw | If I have a vector of core async chans, how can I map over the that vector to take an element from each chan? I’ve tried cljs.core.async/map but that just seems to return a single item. What am I missing? |
| 20:21 | justin_smith | erikcw: (map #(<! %) chan-vec) |
| 20:22 | justin_smith | no need for a special core.async version of map when you are mapping over a vector |
| 20:22 | turbofail | will that work with goroutines? |
| 20:22 | turbofail | i feel like it wouldn't |
| 20:23 | justin_smith | ahh... |
| 20:23 | justin_smith | (map #(go (<! %)) chan-vec) maybe? I forget about that goroutine issue sometimes |
| 20:23 | erikcw | justin_smith: I get an error saying “Uncaught Error: <! used not in (go ...) block” when I try that |
| 20:23 | justin_smith | riht |
| 20:23 | justin_smith | *right |
| 20:24 | justin_smith | you would have to manually insert a go in there, or find some other solution |
| 20:24 | brainproxy | you'll still end up w/ a vector of channels |
| 20:24 | justin_smith | yeah, haha |
| 20:24 | justin_smith | right |
| 20:24 | brainproxy | i've been thinking about the same thing |
| 20:24 | brainproxy | but haven't spent any time on a "solution" yet |
| 20:25 | turbofail | the basic problem is that goroutines only capture a local continuation |
| 20:25 | brainproxy | maybe a variant of transduce |
| 20:26 | brainproxy | it would return a channel itself |
| 20:26 | erikcw | Tricky getting the values out! |
| 20:26 | brainproxy | and for each channel in the collection it would park before performing the xform and handing off to say ocnj |
| 20:26 | brainproxy | *conj |
| 20:28 | brainproxy | (<! (a/transduce xform conj [...chans...])) |
| 20:29 | brainproxy | there is a reduce function in the the core.async ns; maybe it would be sufficient to impl a/transduce with a call to that rather than regular reduce |
| 20:29 | brainproxy | not sure |
| 20:29 | justin_smith | would a merge of the channels suffice, or does it strictly need to take only one thing from each? |
| 20:30 | erikcw | justin_smith: there is only 1 thing in each |
| 20:30 | justin_smith | do they need to come in order? |
| 20:30 | erikcw | nopes |
| 20:31 | justin_smith | if no, merge will suffice I think? |
| 20:31 | erikcw | ok, I’ll give that a try |
| 20:31 | erikcw | thanks guys! |
| 20:31 | justin_smith | https://clojure.github.io/core.async/#clojure.core.async/merge |
| 20:32 | turbofail | there's always the callback API and manual CPS transformation to fall back on |
| 20:39 | brainproxy | justin_smith: the issue I see with merge is that it doesn't use the :priority option for alts! |
| 20:39 | brainproxy | so the results could be in any order, right? |
| 20:39 | brainproxy | as opposed to the order of the channels in the vector |
| 20:40 | justin_smith | right, I alreayd asked erikcw if that would be OK |
| 20:40 | justin_smith | *already |
| 20:40 | brainproxy | ah, missed that |
| 20:57 | brainproxy | justin_smith, erikcw: https://gist.github.com/michaelsbradleyjr/ca75a0d38e6e84cdabb4 |
| 21:02 | brainproxy | actually, nvm; I think alts! completes at most one of the chan ops |
| 21:06 | creese | When I have a macro that uses a third-party lib, I need to list that lib as a dependency. Why is that? |
| 21:18 | Bronsa | creese: it's a compile-time dependency and you're compiling just-in-time |