2014-12-29
| 00:55 | dweave | how does one listen for when a promise is fulfilled |
| 00:55 | dweave | is that just not a thing |
| 00:55 | justin_smith | dweave (future @promise (do-something)) |
| 00:55 | dweave | @ is the same as dereference right? |
| 00:55 | justin_smith | (do-something) won't be called until the promise is fulfilled (and this will all be done in a thread from the future thread pool) |
| 00:55 | justin_smith | it's the same as deref, yeah |
| 00:56 | justin_smith | if you want to block the current thread, just do @promise ... without the future part |
| 00:56 | justin_smith | (doc realized?) |
| 00:56 | clojurebot | "([x]); Returns true if a value has been produced for a promise, delay, future or lazy sequence." |
| 00:56 | justin_smith | realized can also be handy |
| 00:56 | justin_smith | *realized? of course |
| 00:58 | dweave | won’t the promise be dereferenced before do-something |
| 00:59 | dweave | has completed |
| 00:59 | justin_smith | it will block until the promise is fulfilled |
| 00:59 | justin_smith | so do-something can't happen until something delivers to the promise |
| 00:59 | dweave | oh i see |
| 00:59 | dweave | and do something will deliver to the promise |
| 00:59 | justin_smith | no |
| 00:59 | justin_smith | something else would have to |
| 01:00 | justin_smith | in another thread, since that one is blocked |
| 01:00 | dweave | ha oops |
| 01:00 | dweave | right i see |
| 01:00 | justin_smith | because do-something would never be called if the promise is not delivered to |
| 01:01 | dweave | so deref is always blocking? |
| 01:01 | justin_smith | yes, that's where realized? comes in |
| 01:01 | dweave | or only in this context for some reason |
| 01:01 | justin_smith | if you just want to check |
| 01:01 | dweave | ok i see |
| 01:01 | justin_smith | for delays and promises, it doesn't return until there is a value to deliver |
| 01:01 | justin_smith | though for atoms / refs / agents it won't block |
| 01:01 | justin_smith | it just gives you the value as of the moment you deref |
| 01:02 | justin_smith | it also blocks for the completion of futures |
| 01:02 | dweave | i’m more familiar with promises in various JS libs. and promises in clojure really seem more like “defereds” |
| 01:02 | justin_smith | it's a promise because any part of your code can deliver the value |
| 01:03 | dweave | right |
| 01:03 | justin_smith | and the value can only be delivered once (unlike an atom, agent, or ref that can be updated as often as you like) |
| 01:03 | justin_smith | how are promises typically used in js that is different? |
| 01:05 | dweave | promises in most implementations in JS really only exist for supplying a callback |
| 01:05 | dweave | they have a “then” method which takes a callback which accepts the future value and then returns a promise |
| 01:05 | justin_smith | yeah, the (future @promise (do-something)) followed by passing the promise to something else that delivers to it could work that way |
| 01:05 | dweave | and as such are composable |
| 01:06 | justin_smith | or better yet (future (do-something @promise)) followed by (go-realize promise) |
| 01:06 | justin_smith | where go-realize decides what value to put in that promise of course |
| 01:06 | dweave | nice |
| 01:07 | justin_smith | dweave: but core.async allows similar logic, in much more powerful combinations |
| 01:07 | dweave | yeah just exploring |
| 01:07 | dweave | thanks again |
| 01:07 | justin_smith | including situations where you have multiple elements of your logic that need to coordinate between one another at multiple steps |
| 01:08 | justin_smith | promises in clojure are much more flexible / general |
| 01:55 | alexbara` | for some reason CLJS that works fine use Chestnut, fails to compile into working JS when compiled using lein cljsbuild once Any suggestions on thing to look at? |
| 01:56 | dnolen_ | alexbara`: I'm assuming you're using :advanced? |
| 01:57 | alexbara` | dnolen_: yes. I will try using :none too |
| 01:57 | alexbara` | (:optimizations :none) I mean |
| 01:58 | dnolen_ | alexbara`: with :advanced you generally need to supply externs if you're calling into non-Closure or non-ClojureScript libraries |
| 01:58 | dnolen_ | alexbara`: generally :none is for dev, :advanced is only for production builds |
| 01:59 | alexbara` | dnolen_: I don't think we are calling into non-cljs libraries but let me investigate that idea |
| 02:00 | dnolen_ | alexbara`: that's usually the reason :advanced builds do not work - there have been some more extreme edge case but I doubt you're encountering them |
| 02:01 | dnolen_ | alexbara`: even accessing properties on JS objects requires externs under :advanced if they aren't standard browser features |
| 02:04 | alexbara` | dnolen_: aha, I bet it is the property access that might be doing it |
| 02:12 | dagda1_ | I can't find much documentation or examples of the core.async sequence functions. Can anyone point me to some concrete examples for e.g. map or take or where is the transformer function mentioned in the docs |
| 02:14 | dagda1_ | ok, transformer is now transducer but I'm struggling to find any examples of this |
| 02:14 | kenrestivo | there's not a lot out there |
| 02:14 | kenrestivo | it's very new |
| 02:15 | kenrestivo | in fact, the only use i can find in any indexed open source projects is... in transducers itself :-/ http://crossclj.info/fun/clojure.core/transduce.html |
| 02:18 | kenrestivo | the name "eduction" always makes me laugh. in 1980 when "the wall" first came out, i saw grafitti that said "we don't need no eduction". i scratched underneath it "yes, you do". |
| 02:19 | luxbock | there's some informaton here: http://gigasquidsoftware.com/blog/2014/09/06/green-eggs-and-transducers/ |
| 02:21 | luxbock | dagda1_: http://go.cognitect.com/core_async_webinar_recording |
| 02:21 | luxbock | this might be of help as well |
| 02:23 | dagda1_ | luxbock: thanks, I'm going to blog about this when I understand it. There is very little out there |
| 02:24 | luxbock | dagda1_: yeah, transducers are a 1.7 feature, which is still in alpha |
| 02:30 | zom_ | attempting to solve this |
| 02:30 | zom_ | https://www.4clojure.com/problem/26#prob-title |
| 02:30 | zom_ | i've seen a solution that uses a lazy-seq |
| 02:30 | zom_ | (fn [x] (take x ((fn fib [a b] (cons a (lazy-seq (fib b (+ a b))))) 1 1))) |
| 02:30 | zom_ | can someone with more experience walk me through it |
| 02:31 | zom_ | I get the rough idea |
| 02:31 | zom_ | we specify the number of fib numbers to generate (X) |
| 02:31 | zom_ | we then take that many from an infinite list |
| 02:32 | zom_ | but I dont'get the lazy-seq |
| 02:33 | dnolen_ | dagda1_: in core.async channels take the transducer |
| 02:33 | zom_ | does the lazy-seq target the take??? |
| 02:33 | lazybot | zom_: Yes, 100% for sure. |
| 02:35 | zom_ | so to build the list, are we just consing the a param every time? |
| 02:36 | zom_ | and only calling the recursion the number of times x is specified |
| 02:36 | zom_ | ? |
| 02:37 | nuwanda_ | the sequence is lazy, which means it's only called when the value is needed, in this case it's "needed" by calling take X |
| 02:37 | nuwanda_ | not sure if that's very clear |
| 02:38 | luxbock | zom_: does this help: https://gist.github.com/luxbock/c8ab4eaf7aabf3440cb1 ? |
| 02:44 | zom_ | luxbock: I got it, thanks |
| 03:28 | namra | hm can someone enlighten me in case of clj-tools-logging? i didn't what to throw a logger configuration in every namespace, so i thought i can split logging fns into a separate namespace and configure the logger there and when other fns in other namespaces need to log something the call log-fns from the logger-ns and provide their namespace with the call. |
| 03:28 | namra | but that doesnt seem to work |
| 03:29 | namra | nothing gets logged in this case, and no errors whatsover |
| 03:36 | dagda1_ | does anyone have an example of alt! as opposed to alts! |
| 06:27 | Empperi | oh ffs, lein uberjar seems to do implicit rm -r ./target |
| 06:27 | Empperi | meaning one cannot generate resources to target directory and then package them into uberjar |
| 06:29 | Empperi | seems to be the latest change to uberjar task... |
| 06:29 | Empperi | https://github.com/technomancy/leiningen/commit/d053f3add4ef80c572d0ed3f1a1493a8758d6cdd |
| 06:35 | Empperi | now I need to add a separate "target-resources" directory, add it into .gitignore and whatnot to make this work |
| 06:37 | Empperi | and lein clean will not be going to clean that directory now |
| 06:37 | Empperi | geesh |
| 06:37 | Empperi | makes me really want to change into boot from leiningen |
| 06:40 | Empperi | cursive doesn't support it though |
| 06:41 | devll | Is there a blog or book on "Algorithms in Clojure"? |
| 06:41 | SagiCZ1 | there is clojure cookbook... |
| 06:41 | cfleming | Empperi: I'm hoping to add boot support very soon, since I'd like to use it myself |
| 06:41 | devll | Yes. I've read the Cookbook. It's more of a API usage guide styled book. |
| 06:42 | Empperi | cfleming: you are the cursive developer? |
| 06:42 | SagiCZ1 | is boot not based on maven? |
| 06:42 | devll | I mean algorithms. |
| 06:42 | Empperi | and that is *really* good news! |
| 06:42 | cfleming | Empperi: I am |
| 06:42 | Empperi | great work with cursive btw |
| 06:42 | Empperi | love it |
| 06:42 | cfleming | Empperi: Thanks, I'm glad you're enjoying it! |
| 06:42 | Empperi | can I make an additional feature request in addition to boot support? |
| 06:42 | cfleming | Empperi: Of course, shoot |
| 06:43 | Empperi | currently cursive doesn't understand evaluated requires in autocompletes, eg. when you dynamically load libraries via (require 'whatnot) |
| 06:43 | Empperi | one could implement that by checking if the currently active repl connection knows those vars |
| 06:44 | cfleming | Empperi: It should understand those |
| 06:44 | Empperi | hmmh, it doesn't in our project at least :( |
| 06:44 | SagiCZ1 | Empperi: it usually works for me |
| 06:44 | SagiCZ1 | sometimes it doesnt load the documentation though |
| 06:44 | Empperi | we are lazy loading some libraries in order to do stuff before this java library manages to stuff at class load time |
| 06:44 | Empperi | do stuff |
| 06:45 | Empperi | and this works fine but cursive's autocomplete breaks |
| 06:45 | cfleming | Empperi: Can you give me an example of a require that isn't working for you? Are you doing something like using require with a variable rather than a constant? |
| 06:45 | Empperi | oh and we are doing it via doseq |
| 06:45 | cfleming | Ah |
| 06:45 | cfleming | In that case all bets are off :-) |
| 06:45 | Empperi | https://www.refheap.com/1c87512d6f57fea1b077c3ffc |
| 06:45 | Empperi | like that |
| 06:46 | Empperi | to make it nicer to add new dependencies |
| 06:47 | cfleming | I see - that won't work unfortunately. If you break it out into explicit requires, it will work. In fact, in your case you can just use a single require. |
| 06:47 | Empperi | true |
| 06:47 | cfleming | Which should be just as easy to add new deps to - the doseq there isn't really gaining you anything that I can see. |
| 06:49 | Empperi | need to quote each required dependency separately with plain require :) |
| 06:49 | cfleming | Empperi: https://www.refheap.com/95513 |
| 06:49 | Empperi | but I can live with that |
| 06:49 | cfleming | Yeah, that's a small price to pay for resolve support IMO |
| 06:49 | Empperi | indeed |
| 06:49 | Empperi | didn't know cursive can parse require form that way |
| 06:49 | Empperi | but makes sense |
| 06:50 | Empperi | not too hard to implement when you've already implemented the ns macro require support |
| 06:50 | cfleming | Yeah, anything where the require is explicit should work fine |
| 06:50 | cfleming | Right - in fact the ns support is implemented in terms of the require support, which is how ns works behind the scenes. |
| 06:51 | cfleming | So all the other forms like refer, import and so on work too. |
| 06:51 | Empperi | nice |
| 06:51 | Empperi | do you have some kind of guess when the boot support would be released? |
| 06:52 | cfleming | Empperi: Umm... not really, I'm sorry. It's probably a month or two away. |
| 06:52 | cfleming | Empperi: But it's definitely on the short-term roadmap. |
| 06:53 | Empperi | no problem man, just anxious little kid here who wants a new toy :) |
| 06:54 | Empperi | on a more serious note, I'd like to evaluate boot more throughly if we could move to it from leiningen in our project |
| 06:54 | Empperi | currently our developers use idea+cursive though so not really worth it until cursive supports boot |
| 06:55 | Empperi | since it is kinda pain when cursive doesn't understand dependencies etc even though one can connect to boot repl |
| 06:56 | cfleming | Empperi: Some Cursive users are already using boot, it actually doesn't need too much support. You can use the External Tools support to run boot tasks, and I think you could use a remote config to connect to the boot REPL |
| 06:56 | Empperi | cfleming: how about the dependencies? |
| 06:56 | Empperi | add manually each to your project? |
| 06:57 | cfleming | Empperi: https://gist.github.com/bsima/88969126962803a6500f |
| 06:57 | cfleming | Empperi: So you maintain a project.clj for the dependencies, and then read them in from boot |
| 06:57 | Empperi | hmm, interesting idea |
| 06:57 | Empperi | hack but not too horrible one |
| 06:58 | cfleming | Not pretty, but it's doable if you're really keen to use boot right away |
| 06:58 | Empperi | might give that one a try |
| 06:58 | Empperi | have this hobby project where I'm using boot |
| 06:59 | cfleming | Empperi: See also https://github.com/cursiveclojure/cursive/issues/665 for a way to fake the source folder support using a similar idea |
| 07:01 | Empperi | nice |
| 07:01 | Empperi | gonna definetly try these out when I get home and have some time for my hobby project |
| 07:01 | Empperi | ...which might take some time since kids and everything |
| 07:01 | cfleming | Ok, if you get it working let us know on the mailing list, a few people have been asking about it |
| 07:02 | cfleming | Yeah, kids make hobby projects tough. |
| 07:02 | cfleming | Not to mention work :) |
| 07:02 | Empperi | indeed :/ |
| 07:02 | Empperi | it would be so much more fun if one could just do the happy things! |
| 07:02 | Empperi | (not that kids aren't a 'happy thing') |
| 07:03 | Empperi | but I'll try to find some time this evening |
| 07:03 | cfleming | Empperi: Ok, no rush - like I say, it'll be a while before I get to it |
| 07:04 | Empperi | yeah, but really happy to hear you are working on it :) |
| 07:04 | Empperi | leiningen is great but it suffers from same problems as maven in many ways |
| 07:04 | cfleming | I'm planning to migrate the Cursive build to boot at some point, or at least try to, so support will definitely get much better at that point |
| 07:24 | luxbock | would you use (partial apply =) to check if every item in a collection is the same, or something else? |
| 07:26 | hellofunk | ,(doc every?) |
| 07:26 | clojurebot | "([pred coll]); Returns true if (pred x) is logical true for every x in coll, else false." |
| 07:27 | hellofunk | luxbock: ^ |
| 07:28 | luxbock | hellofunk: so you'd do (every? (partial = (first coll)) coll) ? |
| 07:29 | hellofunk | luxbock: that could work |
| 07:30 | hellofunk | luxbock: you could also reduce, though in this case every? is more focused on the problem |
| 07:30 | luxbock | my original way is less keystrokes at least, but I'm not sure which is clearer in its intention |
| 07:32 | hellofunk | luxbock: the most specialized case is the most clear, thus every? wins out over a reduce in your particular example. just like all whens can be ifs, but whens are clearer for single conds. same idea. |
| 07:33 | hellofunk | luxbock: but ultimately it is a matter of taste and style. the core clojure functions exist for a reason, so if they do the job, consider them over a more generalized approach (like reduce in this case) |
| 07:33 | luxbock | ##(let [[x & xs] [1 1 1]] (every? #{x} xs)) |
| 07:33 | lazybot | ⇒ true |
| 07:37 | hellofunk | luxbock, just be careful about values that are legitemately nil or false: |
| 07:37 | hellofunk | ,(let [[x & xs] [nil nil nil nil]] (every? #{x} xs)) |
| 07:37 | clojurebot | false |
| 07:38 | hellofunk | vs, ,(let [[x & xs] [nil nil nil nil]] (every? #(= x %) xs)) |
| 07:38 | hellofunk | (let [[x & xs] [nil nil nil nil]] (every? #(= x %) xs)) |
| 07:38 | hellofunk | ,(let [[x & xs] [nil nil nil nil]] (every? #(= x %) xs)) |
| 07:38 | clojurebot | true |
| 07:39 | luxbock | yeah good point |
| 07:50 | krat0sprakhar | hi all... quick question |
| 07:50 | krat0sprakhar | how can I apply and to a list |
| 07:50 | krat0sprakhar | (apply and '(true false true false)) |
| 07:50 | krat0sprakhar | gives me an exception |
| 07:50 | krat0sprakhar | any idea? |
| 07:51 | Bronsa | krat0sprakhar: and is a macro, you can't use it as a value |
| 07:51 | krat0sprakhar | oh! |
| 07:51 | krat0sprakhar | so its not a function like str? |
| 07:51 | Bronsa | krat0sprakhar: right |
| 07:51 | Bronsa | krat0sprakhar: to do what you want, look at `every?` |
| 07:52 | krat0sprakhar | thanks! |
| 07:52 | krat0sprakhar | thats very helpful :) |
| 07:53 | luxbock | ,(clojure.walk/macroexpand-all '(and true false true false)) |
| 07:53 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.walk> |
| 07:54 | krat0sprakhar | (and true true true) |
| 07:54 | krat0sprakhar | ,(and true true true) |
| 07:54 | clojurebot | true |
| 07:54 | krat0sprakhar | oh nice! clojurebot :D |
| 07:54 | luxbock | ,(macroexpand '(and true false true false) |
| 07:54 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 07:55 | krat0sprakhar | 4clojure is quite tough .. |
| 07:55 | krat0sprakhar | did anyone else also struggle? |
| 07:56 | hellofunk | krat0sprakhar: yeah some are tricky. the difficulty rankings (easy, medium, etc) are not very accurate either. some of the "easy" ones are hard, and some of the "hard" ones are easy, IMHO |
| 07:57 | krat0sprakhar | haha..yeah.. i've solved around ~60.. and my pace has greatly reduced.. |
| 08:06 | Integralist | Hi all, I'm new to Clojure and am trying to figure out how to call certain Thread methods available in Java. |
| 08:07 | Integralist | I'm able to call (Thread/sleep 1000) but not others like (Thread/isInterrupted) |
| 08:07 | Integralist | Does anyone know what that would be? The Java exception suggests the method isn't available, but I'm not doing anything specific for (Thread/sleep 1000) to work |
| 08:07 | Bronsa | Integralist: isInterrupted is not a static method |
| 08:08 | Integralist | Bronsa: ok, so I'd have to create instance of Thread (or access an instance to utilise that method) |
| 08:08 | Bronsa | you have to call it in a Thread instance, like (.isInterrupted some-thread-object) |
| 08:09 | Integralist | Bronsa: for a bit of context, I'm messing around with STM/concurrency https://gist.github.com/Integralist/4d7f4a5f62b4b567e419 |
| 08:10 | Bronsa | Integralist: you probably want (.isInterrupted (Thread/currentThread)) or something like that |
| 08:10 | Integralist | Bronsa: aha, gotcha. Cool I'll try that now. Thank you! |
| 08:15 | luxbock | why doesn't map-indexed have the transducer arity, or is it not yet implemented? |
| 08:17 | luxbock | ah I see: http://dev.clojure.org/jira/browse/CLJ-1601 |
| 08:33 | Integralist | Hello again, here is some code that tries to peek at the state of different threads: https://gist.github.com/Integralist/741c2577e97fd8e466a4#file-test-clj-L11-L13 but the problem I'm having is that the function suggests the current thread is the main thread, where I would have expected it to refer to the thread created by the (future ...) |
| 08:34 | Integralist | i.e. output for (Thread/currentThread) looks like: Thread[clojure-agent-send-off-pool-15,5,main] |
| 08:48 | luxbock | in a lot of the microbenchmarks I've seen that compare the core functions against their transducer versions, there are improvements from 2-3x for the transducer version |
| 08:49 | luxbock | is this because the compiler has an easier time optimizing the generated bytecode when the calls happen inside the transduce-operation? |
| 08:49 | luxbock | just wondering how come the improvements are so consistent accross the board |
| 09:36 | luxbock | heh: http://imgur.com/MleZdbO |
| 10:31 | bacon1989 | Could someone tell me what's wrong with this macro? https://www.refheap.com/aca0636be093f888e74e0beab |
| 10:31 | bacon1989 | it's complaining about keywords |
| 10:32 | bacon1989 | I suspect the (run ...) function, but i'm pretty new to macros, so i'm not too sure |
| 10:33 | Bronsa | bacon1989: how are you using it? |
| 10:34 | bacon1989 | (new-system-with-name :fixed-width-map (generate-fixed-width-map)) |
| 10:36 | bacon1989 | it fails when it tries to compile the macro, or something |
| 10:36 | bacon1989 | i'm using clojurescript, I don't know if that makes a difference |
| 10:36 | bacon1989 | it's basically complaining before I even use itj |
| 10:37 | bacon1989 | the error i'm getting is "nth not supported on this type: keyword" |
| 10:38 | bacon1989 | everything compiles fine if I don't use :require-macro |
| 10:45 | dnolen_ | if you have a ClojureScript library not listed here feel free to add it https://github.com/clojure/clojurescript/wiki#useful-libraries |
| 10:46 | rboyd | nice list |
| 10:48 | rboyd | dnolen_: any talks about om/pedestal-app merge since your joining cognitect? |
| 10:52 | dnolen_ | rboyd: no, and unlikely - pedestal has a new more focused direction - the front end is left for other tools |
| 10:55 | rboyd | dnolen_: right on. I finally had a chance to kick the tires on om a couple weeks ago. really cool stuff. one more question I had for you, what is "mies"? |
| 10:55 | rboyd | acronym? |
| 10:55 | dnolen_ | rboyd: just a minimal CLJS template - like "mies van der rohe" |
| 10:56 | dnolen_ | "less is more" |
| 10:56 | rboyd | aha. =] |
| 10:57 | dnolen_ | also landed some really big changes to how ClojureScript REPLs work to allow them to start faster |
| 10:59 | dnolen_ | breakage expected for projects that depend on cljs.repl namespace, planning on writing up notes on the changes - hoping to minimize the effect and also start talking about what assumptions should stabilize |
| 10:59 | dnolen_ | still, it's pretty sweet to have Browser, Node.js, and Rhino REPL out of the box and they can all start in a reasonable amount of time now |
| 10:59 | rboyd | I think I saw something fly across hn frontpage mentioning your speedups |
| 11:00 | bacon1989 | fixed my problem, I wasn't requiring it correctly |
| 11:00 | bacon1989 | still have issues with the namespace not being picked up on, but whateves |
| 11:01 | dnolen_ | the goal is to support just pointing a REPL at an :output-dir and it will load the analysis caches off disk - no actual analysis or compiling |
| 11:05 | dysfun | (print-system @systems) # ArityException Wrong number of args (2) passed to: repl/print-system/fn--12388 <-- WTF? |
| 11:06 | jonathanj | how do i rename a key in a map? |
| 11:07 | jonathanj | i see there's clojure.set/rename-keys but i'm not sure if that's what i should be using |
| 11:07 | bacon1989 | ,(def x {:a 1 :b 2}) |
| 11:07 | clojurebot | #'sandbox/x |
| 11:10 | bacon1989 | ,(let [old-val (:a x)] (->> x (dissoc :a) (assoc :c old-val))) |
| 11:10 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentMap> |
| 11:10 | dysfun | isn't there a shorthand for that in useful already? |
| 11:10 | bacon1989 | woops, wrong threaeding |
| 11:11 | dysfun | seems like the sort of thing it would cover |
| 11:21 | hellofunk | ,(let [x {:a 1}] (assoc (dissoc x :a) :b (:a x))) |
| 11:21 | clojurebot | {:b 1} |
| 11:22 | hellofunk | bacon1989: note there is no need to "cache" the old-val since these are immutable data structures |
| 11:54 | justin_smith | luxbock: the non-transducer versions do a lot of work that transducers don't need to do |
| 11:55 | justin_smith | ie. (map f (filter p? l)) creates two lazy seqs, when you only need 1 |
| 11:56 | justin_smith | and the more chaining you have, the bigger an improvement you get when you can drop that redundancy |
| 11:59 | justin_smith | luxbock: JIT changes bytecode execution, but does not mess with data structures, and data structures make huge performance differences |
| 12:00 | luxbock | justin_smith: alright thanks |
| 12:01 | justin_smith | that makes me wonder if JIT couldn't do amazing things if it knew our data structures were immutible |
| 12:02 | TEttinger | Pixie probably is doing that |
| 12:02 | luxbock | maybe some day |
| 12:02 | justin_smith | TEttinger: I hope so, it would be interesting to see |
| 12:02 | justin_smith | of course the haskell compiler is all over that kind of stuff |
| 12:03 | luxbock | does anyone ever directly write in JVM bytecode to tweak some inner loop the same way that people mess with assemply to optimize C code? |
| 12:03 | luxbock | assembly* |
| 12:04 | justin_smith | luxbock: well, clojure generates bytecode |
| 12:04 | justin_smith | but beyond a certain point, JIT is going to do a better job of reorganizing things than you will, since it has actual runtime profiling data on the host machine |
| 12:04 | sova | ho man, playing directly with bytecode... not an impossible task but the beauty of abstraction (i.e. programming languages) is that you don't have to |
| 12:05 | luxbock | I was just wondering if it would be possible in theory to have a Clojure library where you can create callable functions by writing the bytecode as a DSL, like does that even make sense? |
| 12:06 | luxbock | I'm not saying it would be practical or something I'm interested in but I'm just curious |
| 12:06 | patrickgombert | luxbock: tail recursion (loop .. recur) is unrolled into a loop IIRC |
| 12:06 | tcrayford____ | luxbock: I've *read* a load of jvm bytecode whilst optimizing clojure. Never really wanted to write it directly though |
| 12:06 | sova | yes you can definitely do it, if it can be done in java it can be done in clojure, and there is a library for java that plays with bytecode (and kinda lets you reverse-engineer programs) |
| 12:07 | tcrayford____ | the JIT does so much to bytecode it's not really worth optimizing at the bytecode level IMO |
| 12:07 | justin_smith | sova: in fact clojure uses the ASM.java lib to generate its own bytecode when compiling |
| 12:07 | dnolen_ | if you company is using ClojureScript in production add it here https://github.com/clojure/clojurescript/wiki/Companies-Using-ClojureScript |
| 12:07 | dnolen_ | s/you/your |
| 12:08 | sova | justin_smith: wow i did not know that. although that makes a lot of sense! |
| 12:08 | tcrayford____ | and the compiler is available at runtime |
| 12:08 | tcrayford____ | see how datomic, riemann etc compile queries into functions so the JIT can get ahold of them |
| 12:08 | justin_smith | sova: yeah, clojure does not generate any java, it compiles directly to byte code for each line of code you send to the repl |
| 12:09 | tcrayford____ | (both of those just call eval around a (fn expression) |
| 12:11 | luxbock | so clojure.asm contains everything one would need to write JVM bytecode by hand? |
| 12:11 | justin_smith | luxbock: it's just an embedded copy of the asm lib |
| 12:11 | justin_smith | which is well documented |
| 12:11 | justin_smith | and yes |
| 12:12 | justin_smith | http://asm.ow2.org/ |
| 12:12 | luxbock | I remember seeing it in use in the clj-native source files |
| 12:12 | TimMc | dnolen_: Is this going to lead to more consulting cold-emails? :-P |
| 12:12 | luxbock | that looked like some pretty dark magic to me |
| 12:13 | luxbock | https://github.com/bagucode/clj-native/blob/master/src/clj_native/structs.clj#L20 |
| 12:17 | sova | could some kind sir or madam provide a link to understanding macros with examples? |
| 12:19 | dnolen_ | TimMc: ha, I doubt it - this is not a Cognitect thing - ClojureScript GitHub is sorely lacking information about the maturity of the project |
| 12:21 | noonian | sova: maybe http://www.braveclojure.com/writing-macros/ |
| 12:21 | sova | noonian: gratitude |
| 12:22 | TimMc | dnolen_: *nod* You send code out into the void and it doesn't write home. |
| 12:22 | TimMc | Except when it breaks, I guess. :-P |
| 12:22 | dnolen_ | lol, yep |
| 12:24 | m1dnight_ | Is there a decent way to get [:key :key2] and [val1 val2] into {:key val1 :key2 val2}? atm I'm planning on mapping vector on the two lists, and then reducing them with a function that assocs them |
| 12:24 | hyPiRion | m1dnight_: zipmap? |
| 12:24 | noonian | ,(zipmap [:key :key2] ['val1 'val2]) |
| 12:24 | clojurebot | {:key2 val2, :key val1} |
| 12:24 | m1dnight_ | well i'll be damned |
| 12:25 | m1dnight_ | thanks, exactly what i was looking for |
| 12:25 | m1dnight_ | thanks, exactly what i was looking for |
| 12:25 | m1dnight_ | oops, sorry |
| 12:31 | TimMc | $findfn [:key :key2] '[val1 val2] '{:key val1 :key2 val2} |
| 12:31 | lazybot | Execution timed out. |
| 12:31 | m1dnight_ | is that implemented in a brute-force way? |
| 12:31 | TimMc | Warm up those caches, buddy. |
| 12:31 | m1dnight_ | One would guess? |
| 12:32 | lazybot | [] |
| 12:32 | TimMc | $findfn [:key :key2] '[val1 val2] '{:key val1 :key2 val2} |
| 12:32 | TimMc | yeah |
| 12:32 | justin_smith | m1dnight_: yeah, totally brute force |
| 12:32 | sova | hahah. "lazybot" says it all |
| 12:32 | sova | very cool method, gotta say |
| 12:32 | TimMc | Wrong kind of lazy. :-P |
| 12:32 | lazybot | Execution timed out. |
| 12:32 | TimMc | ... |
| 12:32 | lazybot | [] |
| 12:33 | TimMc | lazybot, what was [] the answer to? |
| 12:33 | lazybot | It's AWWWW RIGHT! |
| 12:33 | TimMc | $findfn 1 2 3 |
| 12:33 | TimMc | *sigh* |
| 12:33 | hyPiRion | TimMc: (AWWWW RIGHT!) -> [] |
| 12:33 | sova | Hahahah lazybot wins |
| 12:33 | lazybot | Execution timed out. |
| 12:34 | TimMc | Raynes: Your bot is on drugs again. |
| 12:34 | lazybot | [clojure.core/+' clojure.core/bit-xor clojure.core/unchecked-add-int clojure.core/unchecked-add clojure.core/bit-or clojure.core/+] |
| 12:34 | justin_smith | wow, that's a lot of ways to get 3 from 1 and 2 |
| 12:35 | TimMc | I don't even know if findfn filters based on arities. |
| 13:03 | justin_smith | https://github.com/Raynes/findfn/blob/master/src/findfn/core.clj it's a small namespace, looks like no |
| 13:08 | TimMc | $findfn [a 1] a 1 |
| 13:08 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0) |
| 13:10 | TimMc | $findfn "a" a |
| 13:10 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0:0) |
| 13:12 | justin_smith | $findfn "a" 'a |
| 13:13 | lazybot | Execution timed out. |
| 13:13 | justin_smith | man lazybot, that's an easy one |
| 13:13 | lazybot | [clojure.core/symbol clojure.core/read-string] |
| 13:13 | justin_smith | how weird... |
| 13:13 | justin_smith | it's timing out, and then replying.... |
| 13:14 | TimMc | with a delay |
| 13:16 | hyPiRion | dual personality |
| 13:32 | m1dnight_ | is anyone here who worked on the clojurebot? |
| 13:32 | m1dnight_ | I'm building one myself for fun but i'm stuck a bit on the irc protocol |
| 13:32 | justin_smith | I updated lazybot to use the latest irclj |
| 13:32 | justin_smith | but I didn't implement the irc protocol stuff directly |
| 13:34 | m1dnight_ | hrm, I'm wondering if a direct message can be differentiated by looking at the channel |
| 13:35 | m1dnight_ | PRIVMSG #channel :hello would be a channel because of the # |
| 13:35 | justin_smith | m1dnight_: that's exactly it, the difference between a channel message and a direct one is the channel it is on |
| 13:35 | justin_smith | otherwise they are the same thing |
| 13:37 | TimMc | because some chat clients correctly treat NOTICE as lower priority than PRIVMSG, but others treat it as a high priority notification. |
| 13:42 | m1dnight_ | haha, that's kinda cool :D |
| 13:43 | m1dnight_ | I'm thinking about how to do it architectually atm |
| 13:43 | m1dnight_ | the main point of practice :p |
| 13:55 | dangit | This is where I’m at: http://pastebin.com/BBktFWTP |
| 13:56 | dangit | Alternatively, I’m just trying to get the pid so I can kill with something stronger than .destroy, so if anyone has a rec on that… |
| 14:03 | TimMc | dangit: You need (.getInt pid p) or something. |
| 14:16 | gfredericks | hi |
| 14:16 | tcrayford____ | hi geary |
| 14:17 | dangit | TimMc: Can you elaborate? What would p be? |
| 14:17 | drbobbeaty | gfredericks: Howdy, Gary! |
| 14:17 | gfredericks | hello Tom and Bob |
| 14:18 | gfredericks | ~tcrayford is ðomas |
| 14:18 | clojurebot | Alles klar |
| 14:19 | tcrayford____ | fanks gary |
| 14:22 | llasram | gfredericks: Gæry? |
| 14:24 | gfredericks | llasram: if you want to |
| 14:25 | hyPiRion | gœry |
| 14:25 | justin_smith | dangit: TimMc: sadly, the jvm doesn't provide that info |
| 14:25 | justin_smith | amazingly enough |
| 14:26 | gfredericks | ~hyPiRion is a hyper ion |
| 14:26 | clojurebot | In Ordnung |
| 14:28 | ankanowat | what's the idiomatic way to convert a PersistentArrapMap to java.util.Map for interop with Java libs? |
| 14:28 | gfredericks | it already is one |
| 14:29 | ankanowat | it does implement the Map interface |
| 14:29 | ankanowat | why am i getting an error ... need to look deeper before more questions |
| 14:29 | noonian | what error are you seeing? |
| 14:29 | mi6x3m | Clojure I need a bit of a counseling. I am porting a GUI component which supports custom decorators. Currently a decorator is returned by the a method of the component class which can be overriden |
| 14:29 | andyf | perhaps the Java lib is trying to use a method in the interface that mutates the set contents, and those throw exceptions? |
| 14:30 | mi6x3m | also, one can set a decorator used for all sub-instances the component creates (it can copy itself) |
| 14:30 | mi6x3m | I want to emulate this with a dynamic var |
| 14:30 | mi6x3m | *decorator* |
| 14:30 | mi6x3m | but setting a binding wouldn't be enough, the value will have to be changed via set! sometimes |
| 14:30 | mi6x3m | and I don't know if it's a good idea |
| 14:31 | mi6x3m | tl;dr Is a dynamic var *decorator* a good idea |
| 14:31 | noonian | it would probably be easier to just pass in a function to use in sub-instances or something along those lines |
| 14:32 | mi6x3m | noonian: well this is the thing, you have no control over them once the parent component is created |
| 14:32 | mi6x3m | the class has a static method setDecoratorForSubInstances |
| 14:32 | mi6x3m | and this is all you got |
| 14:33 | noonian | so you're wrapping an existing java component? or trying to re-implement its functionality in clojure? |
| 14:34 | llasram | mi6x3m: Is the thing you pass in for that method an instance or a class or what? |
| 14:36 | mi6x3m | noonian: I am wrapping an existing java code |
| 14:37 | mi6x3m | yes, it's an instance of an interface |
| 14:37 | mi6x3m | and you pass that to a method |
| 14:37 | mi6x3m | basically you have 1. a method in the class XComponent you can overwrite, 2. a static method on XComponent to pass the decorator for subinstances |
| 14:38 | mi6x3m | I think i can use an additional parameter :decorator when constructing the object for the case 1. |
| 14:38 | mi6x3m | and just provide another api function for the case 2. |
| 14:38 | mi6x3m | set-default-decorator! |
| 14:41 | wink | did this end up here already? :) If you're using YYYY in your JVM service or %G in anything, fix it now https://news.ycombinator.com/item?id=8810157 |
| 14:42 | gfredericks | sounds like a case for test.check :) |
| 14:52 | jasmin | hi all. need some assistance deploying to clojars |
| 14:52 | jasmin | whatever I try I keep getting ReasonPhrase: Forbidden |
| 14:52 | jasmin | is this the best place to get some assistance with clojars deployment? |
| 14:53 | jasmin | using lein deploy clojure with a very simple project I just can't get past ReasonPhrase: Forbidden |
| 14:55 | noonian | i half remember technomancy saying he disabled ssh uploads or something due to a security vulnerability |
| 14:56 | bacon1989 | probably the RSA stuff, also you need to sign your stuff if it's not a snapshot |
| 14:56 | bacon1989 | or something |
| 14:56 | jasmin | yes i am trying with https |
| 14:57 | jasmin | i've signed it but still nothing. do I have to send my keys with gpg for it to work? |
| 14:57 | jasmin | what keyserver to use? |
| 15:09 | llasram | jasmin: Are you certain you have your clojars credentials correct? Are you able to log in to the website in a browser with them? |
| 15:10 | jasmin | yes i am |
| 15:10 | jasmin | i am going insane trying to work this out. surely it can't be this hard to deploy to clojars |
| 15:10 | llasram | Whelp, then I'm out of ideas. It's generally not hard |
| 15:10 | jasmin | once I create my gpg key and send them to a keyserver does it take long for clojars to start authenticating my request to deploy? clojars probably isn't even using a keyserver right? that is why we are asked to paste the public PGP key into the Clojar profile right? |
| 15:11 | justin_smith | jasmin: gpg is just for creating signatures for verification |
| 15:11 | justin_smith | jasmin: are you deploying a version that is already up there? it will refuse to let you do that |
| 15:12 | jasmin | i've had a look and can't find it. i've also tried to deploy under org.clojars.jasminsehic and that has the same problem |
| 15:13 | jasmin | is there something in lein i can use to get more verbose details of failure? |
| 15:13 | justin_smith | #leiningen may be helpful |
| 15:14 | jasmin | very quiet there |
| 15:15 | jasmin | can someone confirm I should be able to deploy to classic clojars under any unused group id/artifact without having to sign anything? |
| 15:15 | TimMc | jasmin: Did you say you were using "lein deply clojure"? Shouldn't that be "lein deploy clojars"? |
| 15:15 | jasmin | or is that only applicable to snapshots? |
| 15:16 | TimMc | Signing should be irrelevant. |
| 15:16 | justin_smith | not under "any unused group id" - you need perms to the group you are deploying to |
| 15:16 | jasmin | sorry yes lein deploy clojars..i typed out the wrong text in chat here |
| 15:16 | TimMc | ok |
| 15:17 | jasmin | even if its a brand new group? |
| 15:17 | justin_smith | not sure of that actually |
| 15:18 | TimMc | I think deploying to a new group creates it. |
| 15:18 | jasmin | i don't think that is the problem as I can't even deploy to the pre-allocated org.clojars group |
| 15:18 | TimMc | (and that anyone can just create a group like that) |
| 15:18 | gfredericks | TimMc: that's always happened for me, especially by accident |
| 15:19 | TimMc | *nod* |
| 15:19 | jasmin | is there a tool to verify the syntax of the clj files? |
| 15:19 | gfredericks | read will tell you if it's readable |
| 15:19 | TEttinger | parenthesis/bracket matching is most of it. |
| 15:20 | gfredericks | and eastwood will attempt to do most of everything else |
| 15:20 | jasmin | I've found one article that says Clojars gives ReasonPhrase: Forbidden when the project.clj has unknown parameters |
| 15:20 | jasmin | but for the life of me it all looks good |
| 15:20 | justin_smith | "lein do check, eastwood" catches most of the basic stuff |
| 15:21 | justin_smith | jasmin: project.clj is super freeform, I don't see why lein would care about unknown parameters |
| 15:21 | justin_smith | now if it isn't even readable, that's another thing entirely |
| 15:21 | justin_smith | any basic lein command should be informing you of that though |
| 15:22 | TimMc | I don't think clojars looks at the project.clj, but the pom.xml that is generated. |
| 15:23 | jasmin | yes that is what it looks like and pom.xml gets generated ok |
| 15:24 | dnolen_ | required reading for ClojureScript REPL maintainers https://github.com/clojure/clojurescript/wiki/Custom-REPLs |
| 15:24 | dnolen_ | cemerick: ^ I'm not sure if the Weasel guy hangs out here |
| 15:24 | jasmin | i've tried using my email address and my login as the username when it prompts me when doing lein deploy clojars but still it fails |
| 15:24 | dnolen_ | custom REPL maintainers I should say |
| 15:25 | gfredericks | jasmin: you've created an account on clojars.org? |
| 15:25 | jasmin | yep |
| 15:25 | jasmin | i've been at this now for 4 hours |
| 15:29 | jasmin | does groupid and artifact in defproject have restriction on characters that can be used. e.g. would a hypen (-) be an invalid character? it is not for pom.xml |
| 15:30 | gfredericks | I've used hyphens plenty |
| 15:30 | gfredericks | java people don't seem to mind hyphens outside of their source code |
| 15:34 | jasmin | uh uh |
| 15:34 | jasmin | Project names containing uppercase letters are not recommended |
| 15:34 | jasmin | and will be rejected by repositories like Clojars and Central |
| 15:35 | llasram | jasmin: Was that your problem? |
| 15:35 | jasmin | apparently there is an env var LEIN_BREAK_CONVENTION that will let me override this |
| 15:36 | jasmin | trying now |
| 15:36 | gfredericks | (defproject com.gfredericks/AllLower-CaseOne_Word "0.1.0-SNAPSHOT" |
| 15:36 | justin_smith | gfredericks: my favorite wifi password is "all one word, no spaces" |
| 15:36 | jasmin | that works for you? |
| 15:36 | jasmin | lol |
| 15:36 | llasram | jasmin: Err, the "forbidden" error you reported later doesn't jibe with a problem that should fix |
| 15:37 | gfredericks | justin_smith: with the network name "down currently, sorry for the inconvenience" |
| 15:38 | cemerick | dnolen_: great, thanks |
| 15:38 | jasmin | it works holy mother |
| 15:38 | TimMc | wut |
| 15:39 | jasmin | can't have caps in group id or artifact id |
| 15:39 | dnolen_ | cemerick: happy to relax the requirements if there's some unsatisfied need - but the whole idea here is for REPLs to have to do a lot less |
| 15:39 | TimMc | That seriously did it? |
| 15:39 | dnolen_ | cemerick: basically *nothing* after -setup |
| 15:39 | dnolen_ | cemerick: the whole libs tracking stuff was crazy |
| 15:39 | jasmin | yep..there goes another 4 hours spent on fighting tools |
| 15:40 | TimMc | Jasmin and the Fighting Tools |
| 15:40 | TimMc | Hmm, doesn't relaly work as a band name. |
| 15:40 | jasmin | hahah |
| 15:40 | gfredericks | I'm still confused about the order of events here |
| 15:40 | gfredericks | you had a project with capital letters this whole time? |
| 15:40 | jasmin | Fighting Foos maybe |
| 15:41 | cemerick | dnolen_: sounds good; I haven't touched these things in so long, I don't even remember what libs tracking is :-) |
| 15:41 | cemerick | lucky me |
| 15:41 | TimMc | You might open an issue with clojars to provide informative deny for group and artifact names. |
| 15:41 | dnolen_ | cemerick: having to track which libs have loaded to avoid stupid Closure errors |
| 15:41 | TimMc | (You may have to implement it yourself though.) |
| 15:41 | cemerick | ah, that |
| 15:41 | jasmin | yes..project had capital letters in it..matches the class name |
| 15:42 | dnolen_ | cemerick: the solution is to just monkey patch goog.isProvided_ and allow libs to load multiple times |
| 15:42 | gfredericks | jasmin: but you didn't read that warning from leiningen until 5 minutes ago? |
| 15:42 | jasmin | sure I will post an issue with clojars |
| 15:42 | jasmin | lein just needs to be a bit more verbose on failure in general.. |
| 15:42 | dnolen_ | cemerick: and the REPL infrastructure can do the right thing provided that CLOSURE_IMPORT_SCRIPT is bound to a function that knows how to load the dep in the JS runtime |
| 15:43 | jasmin | what warning? |
| 15:44 | gfredericks | jasmin: the one you get with `lein new FightingTools` and can bypass with LEIN_BREAK_CONVENTION |
| 15:44 | gfredericks | which you quoted earlier |
| 15:44 | jasmin | I found that in depths of desparation..using lein new to generate a brand new project.clj |
| 15:45 | jasmin | once I gave it the name it gave me that output |
| 15:45 | gfredericks | oh okay; so somehow missed it when creating the original project |
| 15:46 | jasmin | I created the project by hand originally..only 3 lines to it |
| 15:46 | gfredericks | ah ha |
| 15:46 | gfredericks | okay that makes more sense |
| 15:47 | TimMc | jasmin: Lein's idea of good project names and clojars' restrictions are not necessarily in sync, though. |
| 15:47 | justin` | what's the reason clojurescript's bit-or operation yields diferent results than clojure's? |
| 15:48 | gfredericks | with what args? |
| 15:48 | jasmin | yes. thanks for help guys, much appreciate it |
| 15:48 | gfredericks | might be those pesky doubles |
| 15:48 | jasmin | off to get some zzzz |
| 15:48 | justin` | (apply bit-or '(557831 1082379 98306 33564957 134236965)) |
| 15:48 | gfredericks | ,(apply bit-or '(557831 1082379 98306 33564957 134236965)) |
| 15:48 | clojurebot | 169471807 |
| 15:49 | justin` | cljs is giving me 1607439 |
| 15:49 | gfredericks | I think that's well within Double's integer range... |
| 15:49 | gfredericks | but hm |
| 15:49 | gfredericks | I really have no idea what bit-or means in javascript actually |
| 15:50 | gfredericks | seems kind of ambiguous |
| 15:50 | dnolen_ | justin`: might be a bug, should look at the generated JS |
| 15:50 | TimMc | &(map (partial apply bit-or) (partition 2 1 '(557831 1082379 98306 33564957 134236965))) |
| 15:50 | lazybot | ⇒ (1607439 1147915 33663263 167799613) |
| 15:50 | dnolen_ | gfredericks: all bit operations clamp to 32bit integer before application |
| 15:50 | gfredericks | ,Integer/MAX_VALUE |
| 15:50 | clojurebot | 2147483647 |
| 15:50 | gfredericks | dnolen_: okay so it's semantically all integers |
| 15:51 | justin` | ok I'll dig a little deeper wasn't sure if I was missing something obvious |
| 15:51 | gfredericks | ,(apply bit-or '(557831 1082379 98306 33564957)) |
| 15:51 | clojurebot | 35237663 |
| 15:51 | TimMc | justin`: ^ Does the above differ from CLJS in all places, some, or none? |
| 15:51 | gfredericks | ,(apply bit-or '(557831 1082379 98306)) |
| 15:51 | clojurebot | 1672975 |
| 15:51 | gfredericks | still wrong with 3 nums |
| 15:51 | gfredericks | ,(apply bit-or '(557831 1082379)) |
| 15:51 | clojurebot | 1607439 |
| 15:51 | gfredericks | ^ that's the first correct one |
| 15:52 | gfredericks | it's as if only the first two numbers are considered |
| 15:52 | TimMc | Himera doesn't allow pasting? Bleh. |
| 15:52 | gfredericks | this is according to himera |
| 15:52 | gfredericks | which allows pasting for me |
| 15:53 | dnolen_ | justin`: this is probably just bug, I don't think I've ever use bit operations higher order |
| 15:53 | justin_smith | maybe it's ignoring all args after the first two? |
| 15:53 | gfredericks | seems to |
| 15:53 | gfredericks | (apply bit-or '(2 2 399482983)) ;; => 2 |
| 15:54 | TimMc | Himera doesn't allow pasting in Firefox. |
| 15:54 | gfredericks | I'm using firefox |
| 15:55 | gfredericks | TimMc: we could keep going with this and discover that the only difference between you and me is our first names and that's what himera is discriminating with |
| 15:55 | TimMc | What version? v31.3.0 here. |
| 15:55 | dnolen_ | gfredericks: oh right, bit ops aren't variadic in CLJS at the moment |
| 15:55 | dnolen_ | only implement 2 argument arity |
| 15:55 | gfredericks | oh right it's not even about apply |
| 15:55 | TimMc | yikes |
| 15:55 | justin` | dnolen_: ok cool that makes sense then |
| 15:55 | gfredericks | broken directly too |
| 15:55 | dnolen_ | justin`: simple patch is quite welcome - this is seriously low hanging fruit :) |
| 15:56 | dangit | justin_smith: Are you saying there is no way to get a PID from a spawned process in clojure?? |
| 15:56 | lazybot | dangit: Definitely not. |
| 15:56 | justin` | dnolen_: O |
| 15:56 | justin` | dnolen_: cool I'll see what I can do :) |
| 15:56 | justin_smith | dangit: exactly, it's a stupid limitation of processes under the jvm, at least using Process / ProcessBuilder etc. |
| 15:56 | dangit | Wow |
| 15:57 | andyf | dangit: Stackoverflow may have partial answers, at least, e.g. http://stackoverflow.com/questions/4750470/how-to-get-pid-of-process-ive-just-started-within-java-program |
| 15:57 | llasram | dangit: unfortunately still relevant: http://blog.headius.com/2013/06/the-pain-of-broken-subprocess.html |
| 15:57 | justin_smith | $javadoc java.lang.Process |
| 15:57 | lazybot | http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html |
| 15:58 | dangit | I’m not from a java background. This pain is all new to me :-( |
| 15:59 | dangit | andyf: That is the route I was going for, but I can’t get the pid out of the UNIXProcess. |
| 15:59 | justin_smith | dangit: how did you attempt to get it out? |
| 16:00 | dangit | http://pastebin.com/BBktFWTP |
| 16:02 | justin_smith | I think after setting the field accessible, you can just do (.pid (:process p)) |
| 16:03 | justin_smith | also, to what end are you using the pid? There may be a less hacky option that does not require the pid. |
| 16:05 | TimMc | justin_smith: You have to use the Field instance that you set accessible to access the value. |
| 16:05 | justin_smith | TimMc: OK, I was not aware of that |
| 16:13 | augustl | is there a "make this clojure web app secure" ring middleware around? :) |
| 16:13 | andyf | augustl: Reroute all requests to /dev/null ? :-) |
| 16:14 | augustl | s/make/attempt to make/ ;) |
| 16:14 | augustl | I think friend + ring-anti-forgery should do it.. but what do I know |
| 16:22 | amalloy | i kinda think application security is something you have to think about a bit more than just sprinkling on some middleware like fairy dust |
| 16:23 | TimMc | andyf: Not enough, you also need to return malformed outputs so that you can possibly break the attacker's script. The best defense is a deniable offense. |
| 16:23 | gfredericks | {"status": e404} |
| 16:24 | SagiCZ1 | TimMc: I chuckled |
| 16:30 | augustl | amalloy: well, sure, but it would be nice to not have to resort to something like Rails for secure defaults |
| 16:30 | augustl | I want to have my cake and eat it too :) |
| 16:42 | romain_ | Hi everyone, anybody knows how to build the cljs compiler from source? |
| 16:42 | augustl | that's weird - https://github.com/ring-clojure/ring-anti-forgery/blob/f6f1edbaf4f78bea5128b3c36847b0de17d29d22/src/ring/middleware/anti_forgery.clj#L90 |
| 16:42 | augustl | why doesn't it assoc the token onto the initial request as well? |
| 16:43 | augustl | the only way to get a hold of the token in the very first request is to read the dynamic var |
| 16:44 | augustl | I suppose it would be sort of weird to "fake" the session and assoc it in manually.. But that seems like a better option to me than forcing the use of dynamic vars |
| 16:45 | dangit | justin_smith: Yeah, that didn’t work |
| 16:45 | dangit | All I want to do is start up a local dynamodb instance for my tests |
| 16:45 | dangit | And I want to kill it after the tests run. |
| 16:45 | dangit | Unfortunately SIGTERM doesn’t seem to take it down. |
| 16:47 | justin_smith | dangit: did you actually look at the api docs? there is a .kill method on processes |
| 16:47 | justin_smith | sorry, it's .destroy |
| 16:47 | dangit | Yeah, destroy isn’t working. |
| 16:47 | dangit | I think it is sending SIGTERM |
| 16:47 | justin_smith | or .destroyForcibly (equivelent to -9) |
| 16:47 | dangit | *that* I didn’t see... |
| 16:47 | justin_smith | it's a really small API... |
| 16:48 | justin_smith | oh wait, .destroyForcibly is java 8 only |
| 16:49 | dangit | Yes, the API is even smaller than you suspect ;-) |
| 16:49 | justin_smith | hopefully using 1.8 jvm is an option for you |
| 16:49 | dangit | I suppose it is. What a big hammer, though. |
| 16:52 | SagiCZ1 | when i add more bindings in for or doseq, it acts as an inner loop.. this is desirable most of the time, but what if i want to iterate two things at once in one loop? |
| 16:53 | SagiCZ1 | ,(doseq [i (repeat 3 :a) y (range 3)] (println i y)) |
| 16:53 | clojurebot | :a 0\n:a 1\n:a 2\n:a 0\n:a 1\n:a 2\n:a 0\n:a 1\n:a 2\n |
| 16:53 | SagiCZ1 | i want this to print just 3 rows |
| 16:53 | justin_smith | (for [[a b] (map list seqa seqb)] ...) |
| 16:53 | SagiCZ1 | i see |
| 16:53 | SagiCZ1 | this can work with doseq as well right? |
| 16:53 | justin_smith | yeah |
| 16:53 | noonian | ,(map println (range 3) (repeat 3 :a)) |
| 16:53 | clojurebot | (0 :a\n1 :a\nnil 2 :a\nnil nil) |
| 16:53 | andyf | That or loop, but if you like for or doseq, justin_smith's suggestion is the best I know |
| 16:54 | SagiCZ1 | ,(for [i (map list (repeat 3 :a) (range 3))] (println i)) |
| 16:54 | clojurebot | ((:a 0)\n(:a 1)\nnil (:a 2)\nnil nil) |
| 16:54 | SagiCZ1 | oh println is dumb here.. sorry |
| 16:54 | SagiCZ1 | ok thanks, i understand this will work for me |
| 16:55 | noonian | ,(map (comp println str) (range 3) (repeat 3 :a)) |
| 16:55 | clojurebot | (0:a\n1:a\nnil 2:a\nnil nil) |
| 16:55 | noonian | ,(println 1 :a) |
| 16:55 | clojurebot | 1 :a\n |
| 16:55 | noonian | printing is just weird with clojurebot |
| 16:56 | SagiCZ1 | is it? |
| 16:56 | SagiCZ1 | apart from adding \n instead of makin an actual new line it works i think |
| 16:56 | noonian | returns newlines as a string and at the same time as the return value is printed (same time means in the same irc message) |
| 16:56 | justin_smith | noonian: println inside constructing a value in a repl does the same thing |
| 16:56 | SagiCZ1 | noonian: my REPL does the same |
| 16:57 | justin_smith | random interleave of printed values and return values |
| 16:57 | SagiCZ1 | its because printing is not atomic or what not |
| 16:57 | gfredericks | ,(range) |
| 16:57 | clojurebot | (0 1 2 3 4 ...) |
| 16:58 | gfredericks | ,(map (fn [_] (pr (range))) (range)) |
| 16:58 | clojurebot | ((0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 4 ...)(0 1 2 3 ... |
| 16:58 | noonian | works pretty well for me in the repl: https://www.refheap.com/95554 |
| 16:58 | gfredericks | ha what |
| 16:58 | gfredericks | I did not expect that much output |
| 16:58 | gfredericks | and where are the nils |
| 16:59 | gfredericks | I guess it's chunking |
| 16:59 | justin_smith | yeah, thanks to chunking, the nils are somewhere after the last ... I guess |
| 16:59 | gfredericks | ,(map (fn [_] (pr (iterate inc 1))) (iterate inc 1)) |
| 16:59 | clojurebot | ((1 2 3 4 5 ...)(1 2 3 4 5 ...)nil (1 2 3 4 5 ...)nil (1 2 3 4 5 ...)nil (1 2 3 4 5 ...)nil (1 2 3 4 5 ...)nil (1 2 3 4 5 ...)...) |
| 17:00 | gfredericks | that's a little more reserved |
| 17:00 | AimHere | Looks like clojurebot is using the Schneier algorithm that can do an infinite loop twice in 5 seconds |
| 17:01 | SagiCZ1 | whats wrong with this? |
| 17:01 | SagiCZ1 | ,(let [lines [[3 2 3] [5 7 1]]] (map list lines (range lines))) |
| 17:01 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 17:01 | Bronsa | ,(range [3 2 3]) |
| 17:01 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 17:02 | Bronsa | SagiCZ1: ^ that's what you're doing |
| 17:02 | SagiCZ1 | oh.. there was supposed to be count there |
| 17:02 | SagiCZ1 | (let [lines [[3 2 3] [5 7 1]]] (map list lines (range (count lines)))) |
| 17:02 | SagiCZ1 | ok thanks Bronsa |
| 17:09 | hellofunk | ,(= (let [lines [[3 2 3] [5 7 1]]] (map list lines (range (count lines)))) (let [lines [[3 2 3] [5 7 1]]] (map list lines (range))) |
| 17:09 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 17:09 | hellofunk | ,(= (let [lines [[3 2 3] [5 7 1]]] (map list lines (range (count lines)))) (let [lines [[3 2 3] [5 7 1]]] (map list lines (range)))) |
| 17:09 | clojurebot | true |
| 17:10 | hellofunk | SagiCZ1: note you don't need the count or the lines in the range |
| 17:10 | amalloy | ,(let [lines [[3 2 3] [5 7 1]] (map-indexed (fn [i x] [x i]) lines)) |
| 17:10 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 17:10 | amalloy | ,(let [lines [[3 2 3] [5 7 1]]] (map-indexed (fn [i x] [x i]) lines)) |
| 17:10 | clojurebot | ([[3 2 3] 0] [[5 7 1] 1]) |
| 17:11 | hellofunk | SagiCZ1: ^ that way also |
| 17:17 | [blake| | O |
| 17:17 | [blake| | Whoops. |
| 17:18 | [blake| | I'm trying to "screen capture" an HTML page, one I've generated in Clojure (though CSS is involved) and trying to figure out a clean way to store the results and recall them later. |
| 17:19 | [blake| | I've got html2canvas, which is cool but it's on the client side and I can't see how to pass the canvas back to the server. (I tried serializing it but it's got circular references, apparently.) |
| 17:20 | [blake| | Feels like I'm doing it the hard way. |
| 17:23 | craigglennie | [blake|: Can you call toDataURL on your canvas and pass that to the server? |
| 17:24 | [blake| | craigglennie: Maybe! Let me see! |
| 17:33 | tolstoy` | Hm. defspec in test.check doesn't allow metadata for grouping tests. |
| 17:34 | tolstoy` | Selectors, as leiningen says it. |
| 17:34 | [blake| | (inc craigglennie) |
| 17:34 | lazybot | ⇒ 2 |
| 17:35 | [blake| | That might just work. I've got the data now, anyway. Thanks! |
| 17:36 | [blake| | It's a PNG, which isn't awesome, but maybe the simplest solution. |
| 17:41 | craigglennie | [blake|: you’re welcome |
| 17:43 | mi6x3m | llasram: still here? |
| 17:44 | mi6x3m | or noonian |
| 17:44 | mi6x3m | it's about the advantages of me having a method set-default-decorator! |
| 17:44 | noonian | hmm? |
| 17:45 | mi6x3m | noonian: remember our discussion about the decorators? |
| 17:45 | mi6x3m | for a GUI component |
| 17:45 | noonian | yeah, did you find something that works? |
| 17:46 | mi6x3m | well in the constructor function of the component I will have a :decorator argument for a decorator for that specific instance |
| 17:46 | mi6x3m | and I plan on having a method set-default-decorator! for the default decorator... |
| 17:47 | noonian | i think the set-default-decorator! is fine since you are wrapping a java thing and that is pretty much the existing interface |
| 17:47 | noonian | i'd still prefer passing in an argument if you can accomplish what you need to that way |
| 17:48 | mi6x3m | noonian: yes, well they are 2 different concepts. if you don't specify a decorator via :decorator, the default one will be used. the default is also used for the subinstances you have no control over. |
| 17:49 | mi6x3m | not exactly clojure by the book but oh well |
| 17:49 | mi6x3m | it's what the java component offers, no way around that |
| 17:49 | reiddraper | tolstoy`: (defspec ^:foo bar ...) doesn't work? |
| 17:49 | noonian | could you just have a :default-decorator you pass in as well to set the one used on sub-componenets? |
| 17:50 | mi6x3m | noonian: this is impossible to control through the Java component. set-default-decorator affects all subinstances of all constructed components |
| 17:50 | mi6x3m | there's no way to target the subinstances of one specific component |
| 17:50 | noonian | yeah, i think setting the default is fine then |
| 17:51 | SagiCZ1 | how can i get around the fact that macros cant be apply-ied? |
| 17:51 | mi6x3m | noonian: thanks a bunch for listening and helping :) |
| 17:51 | mi6x3m | (inc noonian) |
| 17:51 | lazybot | ⇒ 11 |
| 17:51 | mi6x3m | helped me a lot |
| 17:51 | noonian | SagiCZ1: depending on the macro you can often wrap it in a function and apply that |
| 17:52 | noonian | mi6x3m: no problem, good luck! |
| 17:52 | SagiCZ1 | ok |
| 17:52 | amalloy | SagiCZ1: by reframing your approach to one where applying a macro doesn't seem necessary |
| 17:52 | mi6x3m | SagiCZ1: apply is runtime, a macro is not :) |
| 17:52 | mi6x3m | can't work together at all |
| 17:53 | SagiCZ1 | amalloy: ok, i have macro add-lines that takes [plot x y] where x and y are lists of points.. i have a function that returns [x y] in a vector.. i need to apply it |
| 17:53 | amalloy | why is add-lines a macro? |
| 17:53 | SagiCZ1 | amalloy: i am not the author of that macro |
| 17:54 | amalloy | incanter? |
| 17:54 | SagiCZ1 | yes |
| 17:54 | SagiCZ1 | (apply #(add-lines %1 (first %2) (second %2)) plot (foo)) |
| 17:55 | SagiCZ1 | shouldnt this work? |
| 17:56 | SagiCZ1 | (apply #(add-lines %1 %2 %3) plot (foo)) |
| 17:56 | SagiCZ1 | this one works though |
| 17:57 | amalloy | gross. there's no reason for that to be a macro at all. can you use add-lines*, or just write your own wrapper that does the same thing? |
| 17:58 | SagiCZ1 | you looked at the source? |
| 17:59 | amalloy | yes |
| 17:59 | m1dnight_ | I need some architecture help, anybody got a second to listen? :p |
| 17:59 | amalloy | ~anyone |
| 17:59 | clojurebot | anyone is anybody |
| 17:59 | amalloy | i hate you, clojurebot |
| 17:59 | m1dnight_ | I'll just go ahead :p |
| 18:00 | m1dnight_ | I have a teeny tiny irc framework in clojure (as an exercise for architecture and clean code) but I'm having some issues with my abstraction |
| 18:01 | m1dnight_ | Atm I have a loop that listens on a socket in a loop, dispatches on each message it reads. (privmsg and what not). But I have to send on the socket as well. So at the moment I just use a write-out function I built that takes the "bot" (ref {:socket s :user {:nick n}} and picks out the socket and writes to it |
| 18:01 | SagiCZ1 | amalloy: thanks, it seems i can apply add-lines* without issues |
| 18:01 | m1dnight_ | but, if I want to make it multithreaded (e.g., callbakcs for bot functionality) I should make sure that the socket is synchronized in some way and thus abstracted |
| 18:02 | m1dnight_ | I'm thinking about making (write-out [msg]) put a function on a stack/queue in the bot, and creating a loop that executes each function on the socket |
| 18:02 | m1dnight_ | anyone got a better idea? |
| 18:03 | m1dnight_ | https://github.com/m1dnight/clojbot/tree/master/src/clojbot this is the source, if that interest someone |
| 18:04 | zophy | ok, i ran the lein script and it put a jar file in a directory.. so now what ? |
| 18:06 | zophy | oooh, i didn't use -jar.. silly me |
| 18:08 | amalloy | zophy: you should just be able to put lein's script on your PATH |
| 18:08 | amalloy | then run stuff like `lein new`, `lein jar`, whatever |
| 18:18 | zophy | oooh, i renamed lein as lein.sh, didn't know it was used beyond the download stage |
| 18:24 | dnolen_ | http://swannodette.github.io/2014/12/29/nodejs-of-my-dreams/ |
| 18:25 | dnolen_ | give the new Node.js REPL a shot when you have time |
| 18:25 | dnolen_ | for all the REPLs, in-ns, require finally work as expected |
| 19:11 | m1dnight_ | I think I pooped my REPL |
| 19:11 | m1dnight_ | I can do lein run fine (even lein clean && lein run), but lein repl fails |
| 19:11 | hellofunk | dnolen_: possible then to load a custom namespace and fns in the node repl? your example loads clojure.string, how about an original project? |
| 19:11 | m1dnight_ | #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Character> |
| 19:11 | m1dnight_ | nowhere a mention of the namespace of my current project |
| 19:12 | m1dnight_ | any tips on how to clear some cache or something? |
| 19:12 | andyf | m1dnight_: Do you have a ~/.lein/profiles.clj file? If so, it may have a syntax error. Or your project.clj file. |
| 19:12 | andyf | You should be able to tell your current project by what directory you are in, yes? |
| 19:13 | m1dnight_ | I just tried a lein repl in my home dir and that goes fine |
| 19:13 | m1dnight_ | So might be indeed that my project.clj has a syntax error |
| 19:13 | andyf | so probably an issue with a project.clj file |
| 19:13 | m1dnight_ | let me see |
| 19:13 | m1dnight_ | strange though, that the lein run goes through fine |
| 19:13 | andyf | agreed. |
| 19:14 | andyf | It may not be a syntax error, as much as a data value of an unexpected type as the value for a key in your defproject. Not all commands use all of those values, so it could be a bad value for a key used by 'lein repl' that is not used by 'lein run' |
| 19:15 | m1dnight_ | hold on, i'm going back to a default project.clj |
| 19:15 | andyf | From the error message, my first guess would be you have a string somewhere that a vector of strings is expected. |
| 19:15 | andyf | e.g. :source-paths or :test-paths |
| 19:16 | m1dnight_ | oooh |
| 19:16 | m1dnight_ | I think I just spotted it yes |
| 19:16 | andyf | When you do 'seq' on a string, you get a sequence of characters, so it can lead to error messages like that. |
| 19:16 | m1dnight_ | andyf: I had a string on my :main, instead of without quotes |
| 19:17 | m1dnight_ | (inc andyf) |
| 19:17 | lazybot | ⇒ 19 |
| 19:17 | m1dnight_ | thanks a bunch man :) |
| 19:17 | andyf | np. Maybe Eastwood should try to find simple mistakes in project.clj files ... |
| 19:18 | andyf | except when run from the cmd line, project.clj has already been run before Eastwood begins, so would need some different way to run it, probably. |
| 19:27 | dnolen_ | hellofunk: yep works, anything on the classpath as usual |
| 19:35 | amalloy | andyf: perhaps a separate piece of eastwood that runs without a project.clj, and analyzes your project.clj? |
| 19:35 | amalloy | i know lein plugin commands have some sort of no-project-needed option |
| 19:43 | andyf | amalloy: I may look into that. In this particular case, it seems like something that Leiningen itself could report with a better error message, too. |
| 19:53 | yedi_ | anyone know of any resources of how to simply hook up basic transitions (fade-in, slide-out, etc) to state changes in the OM app-state? |
| 19:56 | andyf | A library called Bardo was announced on the ClojureScript Google group a couple of weeks ago: https://github.com/pleasetrythisathome/bardo You can read the discussion surrounding the announcement on the group. |
| 19:56 | andyf | Not sure if it is what you are looking for -- haven't used it myself. |
| 19:59 | augustl | hmm, bidi doesn't seem to play nice with a repl. (bidi.ring/make-handler ["" {"/" home-page-handler/show-home-page}]) seems to somehow keep a reference to the function that the symbol points to at evaluation time, instead of resolving the symbol every time |
| 20:00 | augustl | (bidi.ring/make-handler ["" {"/" (fn [req] (home-page-handler/show-home-page req))}]) makes it work fine |
| 20:00 | augustl | talking about reloading via repl eval |
| 20:01 | amalloy | augustl: #'show-home-page |
| 20:02 | augustl | amalloy: what is #' called? So I can google it :) |
| 20:02 | amalloy | ,'#'inc |
| 20:02 | clojurebot | (var inc) |
| 20:03 | tolstoy` | sharp-tick |
| 20:03 | tolstoy` | or maybe not |
| 20:04 | andyf | augustl: The cheatsheet has a list of such symbols with some links to more info about most of them: http://jafingerhut.github.io Look for "Reader Macros" section |
| 20:04 | noonian | in clojure it is 'literal' or 'shorthand' or 'reader' syntax for vars |
| 20:05 | fairuz | augustl: http://conj.io/ calls it as var quote |
| 20:10 | augustl | andyf, fairuz thanks :) |
| 20:27 | fairuz | There's a function foo that accept [& args]. I want to call foo with (foo 123 456) but now I have [123 456] stored in bar instead, so calling (foo bar) will be wrong. How can I convert [123 456] to 123 456? |
| 20:28 | Pistahh | (appy foo bar) ? |
| 20:28 | Pistahh | (apply ...) |
| 20:28 | fairuz | ah cool |
| 20:29 | fairuz | thanks Pistahh |
| 20:29 | Pistahh | np :) |
| 20:52 | DomKM | Is anyone familiar with how feature expressions and macros in CLJS will work? |
| 20:53 | DomKM | Specifically, will macros defined in foo.cljc be available to CLJS code within that same file? |
| 21:22 | djames | Should I expect lein compile to find and compile (gen-class) forms in my code? I know it finds (ns (:gen-class ...)) |
| 21:22 | djames | Something unexpected is going on -- I'm trying to rule out some problems. |
| 21:24 | amalloy | djames: it should, so long as those forms are in namespaces that get compiled |
| 21:29 | djames | amalloy: thanks |
| 21:30 | djames | amalloy: I'm wondering if I need to think about using two passes. My `lein compile` is failing because (I think) a function references the class; e.g. foo.Bar. I thought the compile would happen first, eliminating the problem. |
| 21:31 | djames | Right now I'm putting all the gen-class stuff into a separate file and only referencing in from another file |
| 21:32 | djames | ^ "a function references the class before it is compiled" I meant to say |
| 22:00 | theme2 | Hi |
| 22:00 | theme2 | I am new to clojure |
| 22:02 | theme2 | I still don't fully understand quoting and macros, but clojure looks pretty promising to me |
| 22:14 | fairuz | theme2: hey. welcome :) |
| 22:15 | theme2 | fairuz: late answer O_o |
| 22:15 | theme2 | but later is better than never :) |
| 22:18 | TEttinger | theme2, yeah it's vacation for a lot of people and I assume that a lot of regulars are away from IRC |
| 22:18 | theme2 | TEttinger: no problem :) |
| 22:19 | TEttinger | clojure is a very very expressive language |
| 22:19 | TEttinger | I really find its ability to handle complex data cleanly and simply is almost unmatched |
| 23:36 | rritoch | Does anyone know of any leiningen plugins or clojure libraries to use SableCC in a clojure project? |
| 23:42 | rritoch | All I can find is a maven plugin, sablecc-maven-plugin but it isn't clear how I can get leiningen to execute the compiler from leiningen. |
| 23:58 | andyf | If there is a Java API, you can write some Clojure code to call that, but I have no idea how complex it might be. |