2015-06-01
| 00:04 | cfleming | Does Clojure's type inference ever attempt to infer a type for apply calls? I'm guessing not, since the arity is often not known at compile time. I've tried some simple cases and it appears to not work: (.length (apply str ["Hello"])) |
| 00:06 | bbloom | cfleming: i highly doubt it infers anything differently than that the return type of apply is "object" |
| 00:07 | cfleming | bbloom: Yeah, that seems to be the case, but I've been surprised recently while implementing inference so I thought I'd ask. |
| 00:07 | bbloom | i'm not surprised that you're surprised, since it's totally ad-hoc |
| 00:09 | bbloom | cfleming: enjoyed your cognicast episode btw |
| 00:09 | cfleming | Yeah, in several cases I just copied the Compiler and Reflector code and modified it to use IntelliJ's type system. |
| 00:09 | bbloom | keep on fighting the good fight for tooling :-) |
| 00:09 | cfleming | bbloom: Thanks! It was fun. |
| 00:09 | cfleming | I haven't had time to listen to yours yet - I don't commute, so finding time to listen to podcasts is challenging. |
| 00:10 | cfleming | But the cognicast is always a good listen. |
| 00:10 | cfleming | bbloom: I'm fighting it! Although I feel like I'm fighting the language sometimes too. |
| 00:10 | bbloom | cfleming: expected as well :-) |
| 00:11 | cfleming | bbloom: This inference has been way trickier than I expected. |
| 00:11 | bbloom | so many small details interact in such complex interesting ways |
| 00:11 | bbloom | it's always harder to accommodate something you can't tweak for your needs |
| 00:11 | cfleming | Oh, I have plenty of problems with the big details too :-) |
| 00:12 | TEttinger | this is fun |
| 00:12 | TEttinger | ,(clojure.string/escape (-> (java.util.UUID/randomUUID) .getLeastSignificantBits Math/abs (Long/toString 26)) (zipmap (map char (range 48 58)) "qrstuvwxyz")) |
| 00:12 | clojurebot | "rntdifjrwkqqxx" |
| 00:16 | TEttinger | ,(-> (java.util.UUID/randomUUID) .getLeastSignificantBits Math/abs (Long/toString 26) (clojure.string/escape (zipmap (map char (range 48 58)) "qrstuvwxyz"))) |
| 00:16 | clojurebot | "tufaqxcaijixdj" |
| 00:16 | TEttinger | horse names! |
| 00:26 | kristof | The problem with java-interop is that Oracle/Sun decided on horrendously long method names. |
| 00:27 | TEttinger | neat! |
| 00:27 | TEttinger | ,(let [u (java.util.UUID/randomUUID) num-str (fn [n cs] (let [cl (count cs)] (-> n Math/abs (Long/toString cl) (clojure.string/escape (zipmap (map #(first (Long/toString % cl)) (range cl)) cs))))) consonants (num-str (.getLeastSignificantBits u) "bcdfghjklmnprstvwxyz") vowels (num-str (.getMostSignificantBits u) "aeiou")] (apply str (interleave consonants vowels))) |
| 00:27 | clojurebot | "guladawaninehozakosagidemeguyi" |
| 02:00 | xapak | 6 |
| 02:16 | borkdude | anyone here into boot? Is there any way I can have my public html/js/css in like "resources/public/js/foo.js" and have boot reload signal the browser to reload a file "/js/foo.js" and not "/public/js/foo.js"? I don't want to serve all of my app's resources |
| 02:16 | borkdude | see https://github.com/borkdude/lein2boot |
| 06:09 | Deraen | borkdude: #hoplon is the best channel to talk about boot |
| 06:12 | Deraen | borkdude: and currently, no. There is however https://github.com/adzerk-oss/boot-reload/pull/16 which would add support for it. |
| 06:39 | slavo | is there any tool for atuo generating requires and imports in emacs other than slamhound? |
| 07:02 | Glenjamin | are there some searchable channel logs somewhere? |
| 07:02 | Glenjamin | $logs |
| 07:02 | Glenjamin | ah, found them |
| 07:27 | Elvis_Presly | Hello, I have a watch on an atom, and I'm swapping the atom inside another thread |
| 07:28 | Elvis_Presly | Why the watch doesn't trigger ? I tought atom were shared against all threads |
| 07:48 | vijaykiran | slavo: somethign like this : https://github.com/clojure-emacs/clj-refactor.el/blob/master/examples/magic-requires.gif |
| 08:19 | magnars | slavo vijaykiran: this one is quite nice: https://github.com/clojure-emacs/clj-refactor.el/blob/master/examples/add-libspec.gif |
| 08:24 | slavo | magnars vijaykiran thanks! that is exacly what i was looking for |
| 08:30 | sg2002 | Hello. Is there anyone here who's using clojure.data.xml? I've found a rather weird bug in it and just want someone else to repeat it, before I'll submit it on the bug tracker. |
| 08:31 | arav93 | Hi |
| 08:31 | arav93 | How can I use leiningen on windows? |
| 08:32 | Empperi | you just download it and lein.bat |
| 08:32 | Empperi | and use it like everywhere else |
| 08:32 | Empperi | lein self-install doesn't work, that's your main problem |
| 08:32 | Empperi | it requires *nix command line tools to work |
| 08:35 | arav93_ | Hey, so leiningen for windows? |
| 08:36 | arav93_ | any idea on that? |
| 08:38 | TMA | arav93_: it works well enough under cygwin |
| 09:01 | alexyakushev | Hi everyone, are there any ClassLoader wizards online?:) |
| 09:18 | piranha | hmm... can somebody recommend me a library to implement facebook server-side authentication flow? :-) |
| 09:23 | drbobbeaty | piranha: Are you looking to connect to Facebook as a client and "do things"? Or is this to look "like" Facebook on the server you're making? |
| 09:23 | piranha | drbobbeaty: first one |
| 09:24 | drbobbeaty | piranha: I've forked a good starting point, and added a few things, but this works very well: https://github.com/drbobbeaty/clj-oauth2 |
| 09:25 | drbobbeaty | piranha: There's an example on the README.md not to connect to Facebook, etc. |
| 09:25 | piranha | drbobbeaty: thanks! |
| 09:25 | drbobbeaty | piranha: No biggie... :) |
| 09:25 | piranha | that looks nice :) |
| 09:26 | piranha | I've looked at clj-oauth2, but last update was in 2012 and I feel like Facebook loves to change things :) |
| 09:26 | drbobbeaty | piranha: It works, I've been using it quite a bit to get the OAuth2 tokens, and then re-authenticating them as they expire. I've been calling the Facebook Ad Server endpoints, and it's just fine. |
| 09:26 | piranha | hm, ok, thanks :) |
| 09:26 | piranha | drbobbeaty: do you publish your version on clojars? |
| 09:27 | piranha | or there is no need? |
| 09:27 | drbobbeaty | piranha: Haven't, I sent a pull request to the original author |
| 09:27 | piranha | ah, ok |
| 09:27 | drbobbeaty | piranha: I was hoping for it to be merged... but I don't know if it's happened yet. I haven't looked recently. |
| 09:28 | piranha | doesn't seem so :) |
| 09:28 | drbobbeaty | piranha: Not surprising. What I added were a few things for Google, and the reauthenticate function to make it easy to do that too. |
| 09:29 | drbobbeaty | piranha: i.e. they aren't critical. Just nice to have. |
| 09:30 | piranha | ah, I see |
| 09:30 | piranha | drbobbeaty: thanks! Will try that :-) |
| 09:39 | sg2002 | Is there a way to check java version from clojure repl? |
| 09:40 | sg2002 | Oh, found it. |
| 09:45 | oddcully | ,(get (System/getProperties) "java.version") |
| 09:45 | clojurebot | #error {\n :cause "denied"\n :via\n [{:type java.lang.SecurityException\n :message "denied"\n :at [clojurebot.sandbox$enable_security_manager$fn__889 invoke "sandbox.clj" 69]}]\n :trace\n [[clojurebot.sandbox$enable_security_manager$fn__889 invoke "sandbox.clj" 69]\n [clojurebot.sandbox.proxy$java.lang.SecurityManager$Door$f500ea40 checkPropertiesAccess nil -1]\n [java.lang.System getPropert... |
| 09:45 | oddcully | DENIED! |
| 09:47 | chouser | bbloom: aww, so you're not using finger trees anymore. |
| 09:47 | chouser | rrb-vector is probably faster, isn't it. |
| 09:49 | hyPiRion | For what purpose? |
| 09:50 | chouser | https://github.com/brandonbloom/fipp/commit/a2bd18a92a8480bd84a0410ae9041ed6f2fedcf0 |
| 10:20 | charlespwd | exit |
| 10:20 | xemdetia | permission denied |
| 10:22 | charlespwd | Does reading an HTTPInput with slurp prevent from rereading it later? (I'm trying to figure out why (slurp (body :req)) returns nothing when my form-params are not empty) |
| 10:22 | stuartsierra | charlespwd: yes |
| 10:24 | charlespwd | Followup question, does this mean I have to "unwrap" the middleware that parses the body if I need the raw body? |
| 10:25 | charlespwd | stuartsierra: thanks |
| 10:25 | stuartsierra | charlespwd: I think so, yes. |
| 10:26 | hyPiRion | charlespwd: Is this by any chance related to wrap-params? |
| 10:28 | mmg | is there any rumor of a 1.7 release date? I’m trying to plan my app’s upgrade schedule and if I can wait for 1.7 or not |
| 10:28 | charlespwd | hyPiRion: it would be the cause, yes. It's because I need to verify a hmac signature with the raw body. |
| 10:29 | charlespwd | And I'm not sure if I can trust form-params would be in the right order. |
| 10:35 | hyPiRion | charlespwd: Oh, I see. I tend to associate new keys into the request map. So I'd probably do something like (let [body (slurp (:body req))] (response (assoc req :body (ByteArrayInputStream. (.getBytes body)) :body-str body))) |
| 10:35 | hyPiRion | In a middleware ran before the form param one |
| 10:39 | charlespwd | hyPiRion: That is just perfect. And way more elegant than what I was about to do. |
| 10:40 | hyPiRion | oh, np. I've been there myself =) |
| 10:47 | sdegutis | Is there a way to configure the JVM to instantiate a large object graph much quicker? I have lots of memory and CPU power to spare. |
| 10:48 | TimMc | mmg: I would go ahead and test against 1.7 RC to make sure it is forward compatible. |
| 10:49 | TimMc | Is there anything you specifically want from 1.7? Otherwise, I'd stick with 1.6 since it is better characterized. |
| 10:49 | TimMc | (Sorry, probably unsolicited advice you didn't want.) |
| 10:50 | mmg | TimMc: I’m on 1.5, if I’m getting the resources to fully regression test my app, I’d rather make the jump to 1.7 instead of 1.6 and then have to do this again in 2 months |
| 10:50 | tbaldridge | mmg: also, I'd ask if there's a problem with going to RC now, and switching to the actual release in the future |
| 10:50 | sdegutis | mmg: I'm on 1.5.1 and I'm planning to move to 1.6 and then 1.7 just to be sure |
| 10:50 | tbaldridge | the changes from 1.5->1.7 are way more than 1.7RC to 1.7 release |
| 10:51 | mmg | tbaldridge: but the effort from the test perspective are the same…. |
| 10:51 | tbaldridge | There were some changes to undocumented things (the way collections are hashed, etc.) in 1.6. That's where 90% of my upgrade problems came from |
| 10:52 | tbaldridge | mmg: how long does it take to test a new Clojure release? |
| 10:52 | stain | sdegutis: try java -X and options like -Xms and -Xss -- you can also use java.io.Serializable to quickly load up from disk or something |
| 10:53 | stain | depending on the types of your graph of course |
| 10:53 | tbaldridge | in the projects I worked on it mostly involved switching the deps over, running the test suite, and then going through a normal QA/Release cycle. |
| 10:53 | tbaldridge | What took the longest was fixing bad tests that assumed ordering in hashed collections. |
| 10:54 | mmg | tbaldridge: “and then going through a normal QA/Release cycle.” that’s the part that’s a problem. resources are limited, if it needs to go through a “normal qa/release cycle” I want to make that investment once if I can |
| 10:54 | stain | sdegutis: also look at https://github.com/ptaoussanis/nippy |
| 10:54 | mmg | tbh I’m not here to talk about project management, and don’t take that the wrong way, I was hoping there might be a release date |
| 10:54 | mmg | if not, no big deal, thanks |
| 10:55 | sdegutis | Thanks. |
| 10:55 | sdegutis | I'm trying to speed up the creation of an in-memory database in Datomic. |
| 10:55 | tbaldridge | no, no release date. |
| 10:55 | sdegutis | It's relatively quick, but when I do it 600 times in a row, it takes up to a minute. |
| 11:13 | sdegutis | Back. |
| 11:16 | madmax88 | Greetings, lispers! Suppose I need coordinated, asynchronous access to a Java OutputStream and InputStream. Should I use an agent, or a ref? |
| 11:16 | sorbo_ | I might be misunderstanding, but how can you be coordinated and async? |
| 11:17 | sorbo_ | wouldn't being asynchronous mean you can't coordinate, since you don't know when things are going to come back? |
| 11:19 | madmax88 | I might have a flawed understanding of Clojure's asynchronous handling, but here's what I want to do: I have a bit of asynchronous code, and I have a couple of streams I need to write to and read to. It matters that once one thread writes to the input stream, it reads from the output stream next |
| 11:20 | madmax88 | So, I want to coordinate access between threads so this is possible |
| 11:20 | justin_smith | sorbo_: async and coordinated means the call to alter the value returns immediately (before it takes effect) but the value changes are coordinated with other changes (retried as needed to ensure all take effect) |
| 11:20 | TimMc | madmax88: (you've got read and write reversed there) |
| 11:20 | chouser | madmax88: I don't think a ref is going to help you. Any code writing to a ref will do so inside a dosync, and code in a dosync can be re-run multiple times, so not appropriate for side effects like io streams. |
| 11:21 | justin_smith | sorbo_: classic example would be bank account - you ensure that all transactions from the account take place exactly once, but the deposit you made just now might not be visible until later |
| 11:21 | m1dnight_ | How come a future that is cancelled still stops my application from exiting? |
| 11:21 | sorbo_ | justin_smith: got it |
| 11:21 | sorbo_ | but wouldn't you use a ref for that? |
| 11:21 | justin_smith | sorbo_: refs are not async |
| 11:21 | TimMc | m1dnight_: Wait 60 seconds, does it still fail to exit? |
| 11:21 | sorbo_ | true |
| 11:21 | m1dnight_ | ill check. |
| 11:21 | justin_smith | sorbo_: the update of the ref completes before the updating function returns |
| 11:22 | madmax88 | TimMc: not exactly. In this case, the input stream is a process' stdout, and the output stream is the process' stdin |
| 11:22 | stian | sorbo_: I think i would try an agent (holding both the input and output) .. if you need to deal with sideeffects. |
| 11:22 | sorbo_ | justin_smight but AFAIK Clojure doesn't have a coordinated async reference type |
| 11:22 | justin_smith | sorbo_: on the other hand eg. agents are async - you could have a long line of alterations in a queue waiting to go through before yours does |
| 11:23 | m1dnight_ | Is it the threadpool or something in the background that has a timeout if no futures are added or something? It seems to stop after a while indeed. |
| 11:23 | sorbo_ | *justin_smith rather |
| 11:23 | sorbo_ | spelling is important |
| 11:23 | TimMc | m1dnight_: That's the agent threadpool, yeah. Check out shutdown-agents. You can call it when exiting from -main. |
| 11:23 | madmax88 | stian: I have already done it with an agent, but I'm worried that once more threads are adde, it'll break |
| 11:23 | TimMc | System/exit will do it too, naturally |
| 11:23 | m1dnight_ | aha, didnt think of that in context of futures. thanks timc |
| 11:24 | justin_smith | sorbo_: I think that's right - agents are not coordinated |
| 11:24 | TimMc | m1dnight_: There are a few things in core that use those threadpools, including pmap and other concurrency tools. |
| 11:24 | sorbo_ | justin_smith right, that makes sense. |
| 11:24 | justin_smith | sorbo_: and they are the only async type of the basic clojure reference types |
| 11:24 | m1dnight_ | ,(inc TimMc) |
| 11:24 | sorbo_ | right, since both refs and atoms are sync |
| 11:24 | m1dnight_ | (inc TimMc) |
| 11:24 | clojurebot | #error {\n :cause "Unable to resolve symbol: TimMc in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: TimMc in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6543]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: TimMc in this... |
| 11:24 | m1dnight_ | sorry about that guys |
| 11:24 | justin_smith | m1dnight_: lazybot seems to be out |
| 11:24 | justin_smith | m1dnight_: it used to be that exceptions were much less spammy |
| 11:25 | justin_smith | I wonder if we can fix that again... |
| 11:25 | m1dnight_ | next time then! ill keep it mind. |
| 11:25 | justin_smith | m1dnight_: eh, it's easy to make mistakes, we should have bots that simply tell us the exception, not print out a complex object state |
| 11:25 | TimMc | amalloy_: deadbot |
| 11:54 | justin_smith | madmax88: what about agents would break with more threads? |
| 11:56 | madmax88 | After reading the documentation, I didn't think anything would, but I was still concerned. I'm a relatively new Clojure user, and I didn't want to make a mistake like that |
| 11:57 | justin_smith | madmax88: the one gotcha I guess would be if you had enough contention on the agent that the thread count and queue size got too big |
| 11:58 | justin_smith | but you'll need some other plan if you want tens of thousands of concurrent writes / reads anyway |
| 11:58 | justin_smith | nothing built in is likely to do the right thing :) |
| 11:59 | madmax88 | So if it failed, it would just fail because the threadpool gets too big? |
| 11:59 | justin_smith | or the queue size for waiting actions, one of those |
| 11:59 | justin_smith | might be fun to stress test it and find out for sure |
| 12:01 | madmax88 | Alright, sounds good. Thank you! By the way, if someone wanted to do massive amounts of concurrent io, is there a framework you'd recommend? |
| 12:01 | justin_smith | make sure whatever you are using has java.nio under the hood - and perhaps use java.nio directly |
| 12:02 | justin_smith | which requires min java version of 1.7 |
| 12:02 | justin_smith | I am not sure about frameworks, but I wouldn't be surprised if you saw ztellman or aphyr somewhere in the commit log if there was one |
| 12:03 | chouser | madmax88: have you considered core.async? |
| 12:03 | chouser | not sure if it would be a good fit for you or not |
| 12:04 | justin_smith | chouser: so maybe java.nio async filesystem access in go blocks? or is there something higher level? |
| 12:05 | SagiCZ | i was actually trying to read very large text files into channels |
| 12:05 | chouser | Not sure -- haven't been reading too closely here, but if you've got multiple threads trying to access a shared mutable resource, you can protect that resource a few ways. |
| 12:05 | SagiCZ | it was very difficult to make it work lazily.. you have to check when the last item is read to close the reader |
| 12:06 | SagiCZ | but i was possible with chans.. it couldnt work with simply lazy-seq |
| 12:06 | chouser | one is to only use that resource from inside an agent action. Another is to put a classic lock around it. Another may be to wrap it in a go block or thread and provide access via async channels. |
| 12:07 | justin_smith | chouser: makes sense. I have heard warnings about using go blocks for things that block (like IO), but maybe java.nio changes the rules for that enough for that to make sense |
| 12:07 | chouser | no, you're probably right. For io I think you'd want 'thread' instead of 'go' |
| 12:08 | SagiCZ | justin_smith: i am using go blocks for that.. never seen any warning like that, why is it a bad idea? |
| 12:08 | tbaldridge | SagiCZ: go blocks are limited to a certain number of threads |
| 12:08 | tbaldridge | thread blocks are unlimited. |
| 12:08 | justin_smith | well, I dunno about "right" - just trying to figure out what makes sense out of various bits of info I have seen |
| 12:09 | tbaldridge | So if you do this (dotimes [x 1000] (go (Thread/sleep 100000))) You will cause the threadpool to block and no other go will be able to run |
| 12:09 | SagiCZ | tbaldridge: ok what do you mean by limited to a ceratin amount of threads? do you mean only a certain amount of threads can <! from the chan? |
| 12:09 | chouser | oh. hi, tbaldridge! |
| 12:10 | SagiCZ | oh.. so only certain amount of threads can use go block simultaneously |
| 12:10 | justin_smith | SagiCZ: core.async is backed by a thread pool of fixed size, all go blocks are served from that one pool |
| 12:11 | SagiCZ | and the fixed size is smaller than 1000? |
| 12:11 | justin_smith | SagiCZ: (thread count * 2) + 42 iirc, something like that |
| 12:11 | tbaldridge | SagiCZ: so go blocks are really only callbacks with syntactic sugar. Those callbacks are run inside a dedicated thread pool. That thread pool is imited to ((NCPUS * 2) + 42). Large enough to be somewhat forgiving of blocking io. Small enough that the memory consumption/ context switching shouldn't hurt you. |
| 12:12 | justin_smith | haha, of course i meant ncpus not thread count |
| 12:12 | SagiCZ | tbaldridge: thanks.. i guess i kinda get it although i must admit that the implementation sounds like black magic |
| 12:13 | SagiCZ | btw is core.async still actively developed/used? |
| 12:13 | tbaldridge | oh yeah, core.async got trasducer support last year. And I use it daily with large enterprise clients. |
| 12:13 | SagiCZ | great to hear! |
| 12:16 | Bronsa | alexyakushev: I hacked a bit on DynamicClassLoader, I might be able to help |
| 12:20 | sdegutis | I like the idea of chaining computations that take into account the previous function's result, propagating either results or errors. Is this idiom common in Clojure? |
| 12:21 | solussd | sdegutis: you mean function composition, or are you thinking continuations? |
| 12:21 | gfredericks | or the either monad? |
| 12:21 | sdegutis | solussd: closer to an either monad |
| 12:21 | sdegutis | gfredericks: yeah that |
| 12:21 | solussd | does anybody know if it is possible to make the clojure pretty printer print each mapentry in a map on its own line? |
| 12:22 | justin_smith | sdegutis: we have nil-safe chaining with some-> / some->>, but I don't know of something that propagates errors |
| 12:22 | ToxicFrog | solussd: there's pprint, although I forget what namespace it's in |
| 12:22 | ToxicFrog | I also don't know if it's guaranteed to be repr-clean |
| 12:22 | justin_smith | ToxicFrog: it doesn't always do one entry per line |
| 12:22 | ToxicFrog | justin_smith: oh! |
| 12:22 | solussd | There’s the clojure.algo.monads library that has what you’d need to build it |
| 12:22 | justin_smith | ToxicFrog: clojure.pprint/pprint |
| 12:22 | justin_smith | ,(require 'clojure.pprint) |
| 12:22 | clojurebot | nil |
| 12:22 | justin_smith | ,(clojure.pprint/pprint {:a 0 :b 1}) |
| 12:22 | clojurebot | {:a 0, :b 1}\n |
| 12:23 | solussd | pprint doesn’t print maps with each entry on its own line— I was hoping there was a way to tell the printer to do that.. |
| 12:23 | justin_smith | see, two entries on one line |
| 12:23 | alexyakushev | Bronsa: Thank you, I think I figured that problem is not with Clojure. I'm trying to load Clojure in an environment with different classloader, and it fails when it tries to load pre-compiled Clojure classes (e.g. clojure.stacktrace) |
| 12:23 | alexyakushev | Bronsa: Now I think the problem is with that parent non-Sun classloader |
| 12:24 | SagiCZ | when you make a defrecord or defprotocol is it available only in its current namespace? |
| 12:25 | tcrayford____ | SagiCZ: nope. Protocols define functions just like normal functions |
| 12:25 | sdegutis | saltsa: thanks, though I've heard bad things about using literal Haskell monads in Clojure considering Clojure can't dispatch differently on 0-param functions like Haskell can |
| 12:25 | sdegutis | I meant solussd sorry |
| 12:25 | tcrayford____ | SagiCZ: and records are just java classes under the hood (they also define map->MyRecord and ->MyRecord functions for creating them) |
| 12:26 | justin_smith | SagiCZ: some things are bound to vars, and those are only accessible from the namespace, some things are made as classes, which are available for usage or import via the namespace's corresponding package |
| 12:26 | SagiCZ | tcrayford____: so are they classes in the default package? |
| 12:26 | solussd | sdegutis, Yeah, I don’t have much real-world experience using monads in clojure— I used the maybe monad for some exception handling once. |
| 12:26 | justin_smith | SagiCZ: no, my.ns/MyRecord is of class my.ns.MyRecord |
| 12:27 | justin_smith | but you should require the namespace before using the class, to ensure it is constructed by clojure |
| 12:28 | SagiCZ | i see.. i will need some function that would automatically require all ns in a specified directory then |
| 12:28 | tcrayford____ | SagiCZ: what're you building? |
| 12:30 | SagiCZ | tcrayford____: the truth is I would need some help with the design, but it is a pretty complex thing so I first I need to find out what questions to ask |
| 12:30 | justin_smith | sounds like DI |
| 12:30 | justin_smith | SagiCZ: just a hunch - code against some protocol and not the specific records, and make sure the protocols are required |
| 12:30 | tcrayford____ | SagiCZ: would strongly recomend against any API that involves the filesystem, namespaces or vars. They tend to be pretty weird to use |
| 12:30 | justin_smith | but given the level of info here I could be way off base |
| 12:31 | tcrayford____ | (likewise) |
| 12:31 | SagiCZ | justin_smith: if I require the protocols .. I then just have to require those records that I want to instantiate, correct? |
| 12:33 | SagiCZ | simply said.. there is an event queue.. and then there is a group of animals that consume the queue.. each animal can behave differently (traditional polymorphism).. but since the behavior is pretty complex I want to define each animal (defrecord) in its own namespace... exactly as with Java classes... before that I used multimethods but I found them unnecessary since I dispatch only on the type of the animal and nothing else |
| 12:35 | SagiCZ1 | ~lazy-logs |
| 12:35 | clojurebot | lazy-logs is http://logs.lazybot.org/ |
| 12:35 | tcrayford____ | SagiCZ: so why can't your API consumer pass the instantiated set of animals into your queue? Constructing them via reflectiony magic seems pretty weird to me |
| 12:35 | tcrayford____ | (but might be missing context) |
| 12:36 | SagiCZ1 | well they have to be instantiated somewhere right? |
| 12:36 | tcrayford____ | right, but you can just call (map->MyRecord) a few times |
| 12:37 | SagiCZ1 | wait what? sorry I dont know this construct |
| 12:37 | SagiCZ1 | i thought records are instantiated like this (MyRecord. params) |
| 12:37 | tcrayford____ | when you define a record, it also defines these functions: ->MyRecord |
| 12:37 | tcrayford____ | and map->MyRecord |
| 12:37 | tcrayford____ | (the first is positional, the latter takes a map) |
| 12:38 | SagiCZ1 | wow it does! |
| 12:39 | SagiCZ1 | but these functions are automatically defined in the same ns as the record right |
| 12:39 | sdegutis | Time to write tons of really really bad code because deadline. |
| 12:43 | tcrayford____ | SagiCZ1: right |
| 12:44 | SagiCZ1 | so instead of requiring the record class with :import I will have to :require the namespace |
| 12:44 | bendlas | tbaldridge: any plans to unify clojure.core.async and cljs.core.async, now that reader conditionals are here? |
| 12:45 | tbaldridge | it could possibly be done, but that would lock users of core.async into 1.7. |
| 12:45 | tbaldridge | Also the CLJS go macro needs to be unified with the CLJ go macro and that requires a CLJS version of tools.analyzer. Not sure what the status is on that. |
| 12:47 | bendlas | tbaldridge: tools.analyzer.js, I'd really like to see that extracted from clojurescript |
| 12:48 | bendlas | would start it myself, if I didn't feel guilty about finishing data.xml before |
| 12:49 | bendlas | tbaldridge: one thing that contrib projects would benefit massively from, is a maven plugin to backport files with reader tags to older clojure versions |
| 12:50 | bendlas | that way, users of older clojure versions could benefit from reader tags as well |
| 12:50 | bendlas | like, treat older clojure versions as just another read-cond feature |
| 12:53 | dfletcher | heh some? is a sligtly odd name for the opposite of nil?. i just typed (filter some? results). sounds way more sloppy than it actually is. "oh you know, just give me some results, whatevs" :) |
| 12:54 | gfredericks | ~clojure is all about slightly odd names |
| 12:54 | clojurebot | You don't have to tell me twice. |
| 12:54 | cap10morgan | We're using Datomic for our data persistence layer, but we have run into some situations where we need to store arbitrary EDN data whose structure isn't known ahead of time. Datomic doesn't seem like a great fit for this. What are other folks in the Clojure community using here? (Or do we have it wrong and Datomic is great for this?) |
| 12:59 | bendlas | cap10morgan: I store blobs by their content-hash in the file system, like git does, and then store the file hash into datomic |
| 12:59 | bendlas | you could do the same with edn data, by storing it fressian-encoded |
| 12:59 | cap10morgan | bendlas: hmm, interesting |
| 13:00 | bendlas | cap10morgan: that is, as long as you don't need any indices over parts of that EDN |
| 13:01 | cap10morgan | bendlas: we do sometimes. what we're imagining now is that incoming data would say "these key-values are identifiers that I'd like to use to query for this data in the future and the rest is just a blob I want you to store for me" |
| 13:01 | cap10morgan | for the former I was thinking of dynmically adding attributes to the datomic schema |
| 13:02 | bendlas | yeah, that could work |
| 13:02 | bendlas | cap10morgan: here is my blob store, of you don't want to reimplement it: https://github.com/webnf/webnf/blob/master/filestore/src/webnf/filestore.clj |
| 13:02 | cap10morgan | bendlas: cool, thanks. I'll check it out. |
| 13:13 | sdegutis | Is there something like defmulti/defmethod, but that will dispatch based on which key exists? |
| 13:14 | sdegutis | I have different maps, and I want to dispatch based on which map has which key. |
| 13:14 | sdegutis | I can easily do this with cond, but that doesn't allow extension from without. |
| 13:15 | devth | is `difference` the idiomatic way to remove a single item from a set? |
| 13:15 | solussd | sdegutis: you can do it with defmulti, too |
| 13:15 | sdegutis | Oh maybe (partial contains?) |
| 13:16 | solussd | well, your dispatch function would still have to enumerate all possibilities .. guess that isn’t quite what you want. |
| 13:17 | sdegutis | Right. |
| 13:17 | sdegutis | Any other things Clojure has to offer for this? |
| 13:19 | luxbock | sdegutis: what should happen if more than one of the keys are present? |
| 13:19 | sdegutis | luxbock: they never will be |
| 13:19 | xemdetia | sdegutis, did anyone mention core.match and defun https://github.com/killme2008/defun |
| 13:20 | sdegutis | xemdetia: you ;) |
| 13:20 | xemdetia | o |
| 13:20 | sdegutis | xemdetia: just now I mean ;) |
| 13:20 | solussd | maybe you should make the key the value of the :type key in metadata and dispatch using the `type` function. :) |
| 13:20 | sdegutis | xemdetia: anyway core.match doesn't allow extension from without |
| 13:20 | l1x | hi guys, any om/reagent person around? i have few questions how to design a brand new application using reagent or om |
| 13:20 | sdegutis | xemdetia: same with defun |
| 13:25 | xemdetia | sdegutis, can you explain what you mean by 'extension from without' |
| 13:25 | sdegutis | xemdetia: in another file, I want to add another handler |
| 13:25 | sdegutis | another defmethod so to speak |
| 13:26 | justin_smith | l1x: #clojurescript will likely be more helpful. I highly recommend setting up figwheel from the very start. |
| 13:26 | justin_smith | devth: you can use dissoc on sets ##(dissoc #{:a :b} :a) |
| 13:26 | justin_smith | ,(dissoc #{:a :b} :a) |
| 13:27 | clojurebot | #error {\n :cause "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.PersistentHashSet cannot be cast to clojure.lang.IPersistentMap"\n :at [clojure.lang.RT dissoc "RT.java" 834]}]\n :trace\n [[clojure.lang.RT dissoc "RT.java" 834]\n [clojure.core$dissoc invoke "core.clj" 1438]\n [sandbox$eval2... |
| 13:27 | devth | justin_smith: oh nice didn't know that. thanks |
| 13:27 | justin_smith | n/m bran fart |
| 13:27 | devth | ah |
| 13:27 | devth | i thought i had tried it :) |
| 13:27 | tbaldridge | ,(disj #{:a :b} :a) |
| 13:27 | clojurebot | #{:b} |
| 13:27 | justin_smith | that's the one! |
| 13:27 | justin_smith | (inc tbaldridge) |
| 13:27 | devth | tbaldridge: ty |
| 13:27 | sorbo_ | l1x: +1 for justin_smith's recommendations (checking out #clojurescript && using figwheel) |
| 13:28 | l1x | justin_smith: thanks! |
| 13:28 | l1x | i have figwheel and it is amazing |
| 13:28 | justin_smith | figwheel is great, and easier to start with it than to add it later |
| 13:28 | J_Arcane | Figwheel is indeed quite handy. |
| 13:28 | luxbock | sdegutis: if you know all the keys that can be present when you create the defmulti, then you could use (fn [m] (some #{:foo :bar :baz} (keys m))) as the dispatch function |
| 13:29 | J_Arcane | Even if you don't use the REPL functions, just having a live reloading to the actual running javascript instead of just autorecompile saves significant pain. |
| 13:31 | sdegutis | ok thanks |
| 13:33 | sorbo_ | the fact that it picks up CSS is great too |
| 13:34 | sorbo_ | !lein scss once from inside Vim & it updates after compilation |
| 13:34 | sorbo_ | slower than the on-edit changes to CLJS but still great |
| 13:35 | travisrodman | sdegutis: are you still looking for an answer to this question? |
| 13:35 | justin_smith | sorbo_: see also lein less auto |
| 13:36 | sdegutis | travisrodman: sure |
| 13:36 | travisrodman | sdegutis: cool... |
| 13:37 | travisrodman | a system I wroted needed plugins to be loaded, at runtime, and add them as message handlers to a running system |
| 13:37 | sorbo_ | justin_smith: oh nice |
| 13:37 | travisrodman | it sounds a little like what you are describing |
| 13:38 | travisrodman | so, to make this happen, I had a file watcher on a directory, looking for new files to be dropped, but this could be any io to get the text into your system |
| 13:39 | travisrodman | on system startup, I had a map, stored in an atop and a dispatching function that took a key and '& args' to pass to the function |
| 13:40 | travisrodman | then, I wrote a macro of the form (defhandler KEY (fn [d] ... )) that would expand to install the function in the map |
| 13:40 | travisrodman | all of the functions would get handed the sequence of args, and pulling the function related to the key was trivial. |
| 13:41 | travisrodman | I then just applied the matching function to then arguments, which the writers of the handlers were able to produce, and it was an extensible plugin system for a running system |
| 13:42 | travisrodman | does that seem like a viable answer to your issue? |
| 13:43 | travisrodman | so, the essentiall calling function looked like this: ((get fn-map :key) args) |
| 13:44 | sdegutis | neat |
| 13:45 | sdegutis | I think I solved it with (defmulti my-fn #(partial contains? %)) |
| 13:45 | travisrodman | the defhandler code above was similar to: (assoc fn-map (keyword key) (fn...)) |
| 13:45 | travisrodman | okay... cool |
| 13:45 | sdegutis | thanks travisrodman |
| 13:45 | travisrodman | np |
| 13:55 | sdegutis | never mind. solved it with (cond). |
| 13:55 | sdegutis | cuz deadline |
| 13:57 | solussd | use case, since the values are compile-time literals |
| 13:57 | travisrodman | i read once, all the most interesting functions contain a cond |
| 13:58 | travisrodman | :b# |
| 13:58 | travisrodman | argh... sorry vim command... |
| 13:58 | sdegutis | solussd: don't see how that's possible here |
| 13:59 | sdegutis | solussd: I'm switching based on keys that may exist inside the map |
| 13:59 | Shayanjm | in cider, is there some equivalent to the 'up' button in terminal? i.e: autofilling the last expression sent to the REPL without executing it? |
| 13:59 | solussd | oh right- |
| 13:59 | solussd | condp ? :) that’d be a little nicer |
| 14:00 | justin_smith | Shayanjm: M-p |
| 14:00 | sdegutis | solussd: ah yeah totally |
| 14:00 | justin_smith | that is, Meta-p |
| 14:01 | justin_smith | Shayanjm: also, if you have something partially typed, it acts similar to Control-R in the terminal |
| 14:01 | Shayanjm | ooh, awesome thanks justin_smith |
| 14:25 | sdegutis | You know how idiomatic Clojure advocates consuming and returning raw data and letting call-sites interpret that data? |
| 14:28 | postpunkjustin | sdegutis: could you give an example? I'm not sure what you mean. |
| 14:29 | sdegutis | I bet justin_smith could give the best example. |
| 14:29 | sdegutis | He's super good at Clojure. |
| 14:30 | postpunkjustin | yes, yes he is. |
| 14:30 | xemdetia | I think he means more the general lisp style of call a function with a value and return value' after the operation has completed |
| 14:32 | postpunkjustin | sdegutis: are you asking a question or making a point? |
| 14:34 | sdegutis | xemdetia: no I mean that Clojure is very data-oriented rather than type-oriented or abstraction-oriented |
| 14:34 | sdegutis | xemdetia: it has a few abstractions, such as how anything can implement IFn or IAssoc or whatever |
| 14:34 | sdegutis | but mostly, you just work with raw functions and raw data |
| 14:35 | xemdetia | yes, that's the quality of a lisp |
| 14:35 | justin_smith | raw-dogging, the language |
| 14:35 | sdegutis | I'm starting to notice that this usually leads to lots of tight coupling. |
| 14:36 | justin_smith | sdegutis: because I return a hash-map, I am tightly coupled to other code in that I force it to consume a hash-map? |
| 14:36 | justin_smith | or do you mean the implicit structure of that hash-map |
| 14:36 | sdegutis | justin_smith: I guess I mean the keys in your map example |
| 14:37 | sdegutis | justin_smith: and that the structure of any data can't easily change once someone starts consuming it |
| 14:37 | justin_smith | for that, I find prismatic/schema helps reintroduce sanity |
| 14:37 | justin_smith | at the least, it explicitly describes the expected shape of the data structures |
| 14:39 | sidharth1 | sometimes i'm a clumsy developer, so i'm wondering if there is a way i can determine at run time whether my clojure code is running in the cider nrepl or running from a jar or standalone jar ? |
| 14:41 | mikerod | justin_smith: I find prismatic/schema gets addictive |
| 14:41 | mikerod | then I start wanting to put schema on nearly everything |
| 14:41 | justin_smith | sidharth1: you could determine this based on the classpath, or by the output of (System/getenv "pwd"), or (.getHostName (java.net.InetAddress/getLocalHost)) |
| 14:42 | justin_smith | mikerod: and this is a problem? |
| 14:42 | mikerod | then I start feeling like I'm not doing dynamic typing anymore |
| 14:42 | mikerod | :P |
| 14:42 | justin_smith | sidharth1: a real solution is determining your runtim via something like environ |
| 14:42 | mikerod | even though it isn't "statically checked" |
| 14:42 | sidharth1 | justin_smith: wow, great thoughts |
| 14:42 | justin_smith | mikerod: heh, at least schema is strictly opt-in |
| 14:42 | mikerod | yes, I tend to turn them on during testing |
| 14:42 | justin_smith | sidharth1: of course by "pwd" I actually meant "PWD |
| 14:42 | mikerod | I'm just making an observation though and schema doesn't really get in the way as much as a static checker would |
| 14:43 | justin_smith | mikerod: and unlike core.typed (for better and worse) it doesn't force transitive usage of its annotations |
| 14:43 | mikerod | we tend to find schema very useful for its consistent documentation style as well |
| 14:43 | justin_smith | yup |
| 14:43 | mikerod | good point on the non-forced transitives |
| 14:49 | dnolen | ClojureScript 0.0-3308 released https://groups.google.com/forum/#!topic/clojurescript/kNIKpsFgvyk |
| 14:53 | celwell | Hi, I want a function to return its value quickly (it's part of a web service user action on a mobile app) but the function needs to initiate an email sending. Should I use future to call the email sending function? |
| 14:54 | justin_smith | celwell: as long as the reply doesn't need to indicate to the client that the email send succeeded, sure |
| 14:55 | celwell | cool, and I won't have any issues with threads building up? do they get killed automatically? |
| 14:55 | celwell | after evald? |
| 14:55 | justin_smith | celwell: futures execute immediately and their thread is returned to the available pool when they finish executing |
| 14:56 | celwell | thanks |
| 14:56 | justin_smith | if you hold onto a handle to the future, it will be available for later examination of the return value / receipt of exceptions it may have encountered |
| 14:57 | justin_smith | celwell: one thing to watch out for is by default you don't see errors unless you access the future's value, but stuartsierra had a good blog post about this recently |
| 14:57 | celwell | But I have exceptions logged for it, that would work still right? |
| 14:57 | justin_smith | celwell: http://stuartsierra.com/2015/05/27/clojure-uncaught-exceptions |
| 14:58 | justin_smith | celwell: if you are explicitly using try catch that should work out - be sure to check out that blog post |
| 14:58 | justin_smith | there are some tricky corners there |
| 16:22 | amalloy | andyf: i'm curious why you're so enthusiastic about flatland/ordered |
| 16:23 | bmorphism | Hi, I'm trying to speed up some parallel code (https://www.refheap.com/666e0750586b3c05232d067d2) and was wondering if anything else could be changed to improve it? Would appreciate any feedback! |
| 16:26 | justin_smith | ~pmap |
| 16:26 | clojurebot | pmap is requires syntax quoting which most of the time |
| 16:26 | andyf | bmorphism: You have a pmap whose function does very little work there, only a format call on a string I'm guessing is not terribly large. |
| 16:27 | justin_smith | ~pmap |
| 16:27 | clojurebot | pmap is not what you want |
| 16:27 | justin_smith | that's the one I was going for |
| 16:27 | andyf | pmap creates a separate thread object for every function call, which is a lot of overhead for a quick function |
| 16:27 | tbaldrid_ | bmorphism: I'd look into core.async's pipeline functions |
| 16:28 | bmorphism | andyf: thanks, took it out |
| 16:28 | tbaldrid_ | but yeah, it will still have some overhead |
| 16:28 | andyf | bmorphism: It also was not obvious what size the batches were in your remaining pmap use |
| 16:30 | andyf | pmap can be used to get parallelism speedup, but I'd estimate that you would want the individual function calls to take on the order of a second or so of CPU time to see it (i.e. closer to the order of a second than to 1 millisecond or less) |
| 16:30 | tbaldrid_ | andyf: I wonder what would happen if he put a partition before the pmap, and then a concat at after |
| 16:30 | bmorphism | tbaldrid_: will do, I've seen mapcat> in the docs; I've tried transducers and 1.7.0-RC1, for better or worse: https://www.refheap.com/a81642a4f0927a8079a65ba7e |
| 16:30 | tbaldrid_ | poor-man's batching |
| 16:30 | bmorphism | andyf: All words from the Unix words file =) |
| 16:31 | bmorphism | Switching the inner pmap to map has improved performance substantially! (from ~5MB / sec written to disk to ~9 MB / sec on my machine) |
| 16:31 | tbaldrid_ | bmorphism: https://clojure.github.io/core.async/#clojure.core.async/pipeline |
| 16:32 | tbaldrid_ | bmorphism: one of the problems with your transducer example is that you're still using sequences |
| 16:33 | bmorphism | tbaldrid_: pipeline looks very promising! shoving the transformations into it to see what I can get now |
| 16:33 | tbaldrid_ | If you want some serious performance you'll want to use transducers from start to finish. That means making a file that implements IReduce and a reducing function to write to disk |
| 16:33 | andyf | bmorphism: Put (set! *warn-on-reflection* true) after the ns form and recompile to get reflection warnings. You may not have any, but if you do, and they are in a hot code path, figure out how to eliminate them, usually via type hitns |
| 16:34 | tbaldrid_ | doing that I've easily done way above 17MB/sec for this sort of thing before |
| 16:34 | andyf | hints |
| 16:34 | tbaldrid_ | also take a look at: https://github.com/thebusby/iota |
| 16:36 | andyf | minor point, but (format "%s\n" s) will create a copy of s before it is written out. You might want to try calling .write method twice with s and then "\n", or use a method that appends the newline for you. |
| 16:37 | bmorphism | tbaldrid_: Thanks! Do you have any open examples of transducers-throughout? I'm very new to the concept |
| 16:37 | bmorphism | andyf: No warnings so far, and good point about format, making it a double-write; I used (str ...) before, but afaik that also creates a copy |
| 16:38 | andyf | bmorphism: yes, str also creates a copy, at least if it has multiple args. Not sure if it only has 1. |
| 16:39 | justin_smith | ,(apply identical? ((juxt identity str) "word")) ; andyf |
| 16:39 | clojurebot | true |
| 16:42 | justin_smith | ,(apply identical? ((juxt identity (partial format "%s")) "word")) |
| 16:42 | clojurebot | false |
| 16:43 | andyf | bmorphism: Isn't number-ending called with a 'batch' of one word only? |
| 16:43 | justin_smith | ,(apply (juxt = identical?) ((juxt identity (partial format "%s")) "word")) |
| 16:43 | clojurebot | [true false] |
| 16:45 | andyf | bmorphism: Have you tested performance with all pmap calls replaced with map ? |
| 16:45 | bmorphism | andyf: Oh, as such, yes, sorry -- I meant that the words come in lazily from the reader, reading the text file with all the words |
| 16:46 | bmorphism | andyf: I seem to recall that it was slower, testing again |
| 16:47 | andyf | Might want to compare run time with (format "%s%s" word %) replaced with (str word %) to see if there is any difference. I don't know how those compare off-hand. |
| 16:47 | bmorphism | andyf: Wow, substantially better ~14 MB / sec now! |
| 16:48 | andyf | bmorphism: Yeah, your pmap batches are so small that the creation of threads is slowing you down noticeably. |
| 16:49 | bmorphism | andyf: I also got a few reflection warnings |
| 16:49 | bmorphism | call to method write on java.io.Writer can't be res |
| 16:49 | bmorphism | olved (argument types: unknown). |
| 16:49 | bmorphism | woops, sorry about multiline |
| 16:51 | andyf | prefixing w with a type hint of ^java.io.Writer, and/or the 2nd arg to .write with ^String, may help eliminate those. |
| 16:51 | andyf | Probably the String one, given the message. |
| 16:51 | bmorphism | Up to 25 MB/s having replaced format with str, gotta love the SSD! |
| 16:54 | andyf | amalloy: Sorry, didn't notice your message before now. It fills a request made by people I've seen periodically on the Google group. Since I've made link to it in the cheat sheet, I figured I'd try making sure its docs were reasonable for relative newcomers. |
| 16:55 | andyf | amalloy: I don't plan on enhancing it indefinitely. Don't worry :) |
| 16:56 | tbaldrid_ | bmorphism: another thing you can do is pass the output stream into the add-ending function, that will allow you to remove all calls to str. |
| 16:56 | tbaldrid_ | Strings are immutable, so each call to str involves a O(n) copy of the input strings |
| 16:59 | bmorphism | tbaldrid_: Interesting! So instead of mapping #(str ...), map two .writes, one for word and another the ending? |
| 17:00 | tbaldrid_ | right. |
| 17:00 | tbaldrid_ | it's less functional, but it should be faster. |
| 17:00 | tbaldrid_ | you can get rid of all the mapcats, conj, etc. |
| 17:02 | bmorphism | Will test in that version as well! Even still, 5MB / sec -> 25 MB / sec for a few simple changes is a great success! Thanks andyf, tbaldrid_! |
| 17:03 | SagiCZ1 | when calling a protocol function on an instance of record i have to use the dot notation right? |
| 17:13 | credulous | Starting to use Korma -- where is the best place to put the defdb macro calls? In entities.clj where I define the entities? |
| 17:41 | gfredericks | SagiCZ1: no, protocol functions can be called as regular functions |
| 17:41 | gfredericks | ,(defprotocol Foo (foo [_])) |
| 17:41 | clojurebot | Foo |
| 17:41 | SagiCZ1 | yeah.. i had some other issues with my project |
| 17:41 | SagiCZ1 | i dont really understand how the defprotocol works and what has to be required to be able to implement it in a different ns |
| 17:45 | gfredericks | the protocol itself and all the associated functions are vars |
| 17:45 | gfredericks | so they get required as normal |
| 17:45 | SagiCZ1 | really |
| 17:45 | SagiCZ1 | so i dont have to (:import Classname) ? |
| 17:45 | gfredericks | both defprotocol and defrecord generate classes/interfaces, which have to be imported specially, *HOWEVER* you can usually get away with not using the classes/interfaces at all |
| 17:46 | SagiCZ1 | that sounds odd |
| 17:47 | gfredericks | not sure how to make it sound not odd |
| 17:47 | SagiCZ1 | how am i supposed to know when i can get a way with it |
| 17:48 | gfredericks | protocols you almost never need the interface |
| 17:49 | gfredericks | records you only do if you have to actually use the class name, like if you're extending a multimethod or using extend-type or extend-class or something like that |
| 17:49 | gfredericks | anywhere you could use a normal java class as well |
| 17:49 | SagiCZ1 | i see.. well that explains it well |
| 17:49 | gfredericks | you don't need to call the constructors directly because defrecord generates two constructor fns for you |
| 17:50 | gfredericks | ,(defrecord Heyo [a b c]) |
| 17:50 | clojurebot | sandbox.Heyo |
| 17:50 | gfredericks | ,(->Heyo 1 2 3) |
| 17:50 | clojurebot | #sandbox.Heyo{:a 1, :b 2, :c 3} |
| 17:50 | gfredericks | ,(map->Heyo {:a 3}) |
| 17:50 | clojurebot | #sandbox.Heyo{:a 3, :b nil, :c nil} |
| 17:50 | gfredericks | and those are regular vars that you can require |
| 17:50 | SagiCZ1 | yeah i found that out today |
| 17:50 | SagiCZ1 | so they are regular vars but they are invisible in the source code |
| 17:50 | gfredericks | so I rarely ever import anymore w.r.t. records and protocols |
| 17:50 | gfredericks | yep |
| 17:51 | SagiCZ1 | Cursive is just not cooperating |
| 17:52 | SagiCZ1 | and I only ever say nice thing about Cursive |
| 17:56 | SagiCZ1 | is cfleming ever around anymore? |
| 17:58 | sdegutis | Ok. Finished working for the day. Ready to answer Clojure questions! Who's up? |
| 17:59 | justin_smith | sdegutis: how do I pronounce ->> |
| 17:59 | sdegutis | justin_smith: pewpew! |
| 18:00 | postpunkjustin | thread last? |
| 18:00 | SagiCZ1 | gfredericks: when you talked about that I have to import the class name only when I actually need it.. when I implement protocol in a record thats the case right? |
| 18:00 | sdegutis | damn it shia no, its pewpew |
| 18:00 | gfredericks | SagiCZ1: no |
| 18:01 | gfredericks | ,(defprotocol P) |
| 18:01 | clojurebot | P |
| 18:01 | gfredericks | I guess I can't demo it in the repl bot nevermind |
| 18:01 | SagiCZ1 | i think i get it |
| 18:01 | SagiCZ1 | P is not a class name |
| 18:01 | SagiCZ1 | its the var with the protocol |
| 18:01 | gfredericks | the class is also called P |
| 18:02 | gfredericks | ,(type P) |
| 18:02 | clojurebot | clojure.lang.PersistentArrayMap |
| 18:02 | justin_smith | ,(type @#'P) |
| 18:02 | clojurebot | clojure.lang.PersistentArrayMap |
| 18:02 | gfredericks | ,*ns* |
| 18:02 | clojurebot | #object[clojure.lang.Namespace 0x2d75ca0a "sandbox"] |
| 18:02 | gfredericks | ,(type sandbox.P) |
| 18:02 | clojurebot | java.lang.Class |
| 18:03 | justin_smith | ,(import '(sandbox P)) |
| 18:03 | clojurebot | #error {\n :cause "clojure.lang.Var cannot be cast to java.lang.Class"\n :via\n [{:type java.lang.ClassCastException\n :message "clojure.lang.Var cannot be cast to java.lang.Class"\n :at [clojure.lang.Namespace referenceClass "Namespace.java" 129]}]\n :trace\n [[clojure.lang.Namespace referenceClass "Namespace.java" 129]\n [clojure.lang.Namespace importClass "Namespace.java" 158]\n [clojure.... |
| 18:04 | SagiCZ1 | the protocol var contains a lot of stuff |
| 18:05 | gfredericks | yep |
| 18:06 | profil | I am feeling really stupid now, but how do I conjoin to vectors? from [1 2] [3 4] to [1 2 3 4] |
| 18:06 | justin_smith | ,(into [1 2] [3 4]) |
| 18:06 | clojurebot | [1 2 3 4] |
| 18:07 | profil | justin_smith: will the order be preserved? |
| 18:07 | SagiCZ1 | ,(into [] (concat [1 2] [3 4])) |
| 18:07 | justin_smith | yes |
| 18:07 | clojurebot | [1 2 3 4] |
| 18:07 | justin_smith | SagiCZ1: that concat is not needed |
| 18:07 | SagiCZ1 | use mine if you want a worse and uglier version |
| 18:07 | justin_smith | haha |
| 18:08 | justin_smith | profil: into is not order-preserving for other types, but for vectors it appends in the intuitive way |
| 18:08 | amalloy | more specifically, into is just repeated conj. knowing that, you can deduce how it will behave for other types |
| 18:09 | SagiCZ1 | can i access "this" in defrecord? |
| 18:09 | profil | great, thanks :) |
| 18:09 | justin_smith | SagiCZ1: it's the guaranteed first argument to every protocol method |
| 18:09 | cfleming | SagiCZ1: What's up? |
| 18:10 | SagiCZ1 | justin_smith: so if the method in protocol has 1 argument the implementation should have two? |
| 18:10 | justin_smith | SagiCZ1: the method in protocol should specify the this arg, iirc |
| 18:11 | SagiCZ1 | hmm |
| 18:11 | justin_smith | SagiCZ1: for example, defprotocol should complain if you don't specify at least one arg (which will always be this) |
| 18:12 | justin_smith | The resulting functions dispatch on the type of their first argument, and thus must have at least one argument |
| 18:12 | justin_smith | to quote http://clojure.org/protocols |
| 18:13 | SagiCZ1 | yeah.. i see.. so it really is just a different api to multimethod system |
| 18:13 | justin_smith | SagiCZ1: not at all. A multimethod could dispatch by inc'ing the second arg |
| 18:13 | justin_smith | they are not constrained on dispatch or argument count |
| 18:14 | justin_smith | they are very similar to the common usage of defmulti, sure |
| 18:14 | SagiCZ1 | cfleming: Hi I tried to msg you |
| 18:14 | gfredericks | ,(defmulti second-arg-inc'd-in-words (fn [a b] (inc b))) |
| 18:14 | clojurebot | #'sandbox/second-arg-inc'd-in-words |
| 18:14 | SagiCZ1 | justin_smith: yeah i meant that.. |
| 18:14 | gfredericks | ,(defmethod second-arg-inc'd-in-words 71 [_ _] :seventy-one) |
| 18:14 | clojurebot | #object[clojure.lang.MultiFn 0x1d75b8d5 "clojure.lang.MultiFn@1d75b8d5"] |
| 18:14 | gfredericks | ,(second-arg-inc'd-in-words "WORDS" (* 2 5 7)) |
| 18:14 | clojurebot | :seventy-one |
| 18:14 | SagiCZ1 | justin_smith: its how i was always using multimethods |
| 18:15 | justin_smith | SagiCZ1: yeah, it's how most people use them, just being clear that multimethods are actually much more flexible than that |
| 18:15 | justin_smith | gfredericks: that's an amazing multimethod |
| 18:15 | SagiCZ1 | justin_smith: yep i know.. but since I dont need the flexibility I am going back to protocol and defrecords |
| 18:15 | justin_smith | SagiCZ1: that's what I would do too, yeah |
| 18:16 | gfredericks | justin_smith: #protip |
| 18:18 | justin_smith | gfredericks: now I am wondering if seventy-one, the lib, could use a multimethod that returns :seventy-one if the second arg is 71, and throws an exception otherwise |
| 18:18 | gfredericks | it could be called "validate" |
| 18:18 | justin_smith | indeed! |
| 18:19 | gfredericks | also would accept a pr for (defn seventy-one? [n] (= n seventy-one)) |
| 18:29 | SagiCZ1 | this happens to me when working with core.async> |
| 18:29 | SagiCZ1 | NullPointerException [trace missing] |
| 18:31 | justin_smith | SagiCZ1: yes, core.async does weird things to the call stack |
| 18:31 | SagiCZ1 | that seems like a serious disadvantage |
| 18:32 | justin_smith | SagiCZ1: asserts and try/catch can help |
| 18:32 | SagiCZ1 | good idea |
| 18:32 | andyf | Is it core.async specifically, or is this perhaps maybe an instance of the JVM sometimes optimizing away the stack trace, which can be improved upon with a command line option when starting the JVM, e.g. http://stackoverflow.com/questions/2411487/nullpointerexception-in-java-with-no-stacktrace |
| 18:32 | justin_smith | but the very nature of core.async is to compile a state machine, so a normal stack is a lot to ask |
| 18:32 | SagiCZ1 | will try that too andyf |
| 18:33 | justin_smith | andyf: even if a full stack trace were available, you can't expect more than async-thread-pool-dispatcher -> run-go-block -> maybe the name of the function that got the exception |
| 19:08 | Seylerius | There anything to do proofs of clojure code? |
| 19:11 | postpunkjustin | Seylerius: do you mean formal proofs like you'd find in Coq or Agda? |
| 19:15 | amalloy | you can't even prove it's clojure code! could be common lisp with a lot of sneaky reader macros |
| 19:16 | postpunkjustin | what if that's all it ever was |
| 19:17 | andyf | Seylerius: I attended a talk years ago where someone was demonstrating formal proofs of the behavior of Java byte code. I haven't heard of anything similar that is specifically for Clojure. |
| 19:18 | andyf | ambrosebs is working on core.typed, which is an optional type system for Clojure that can prove some type-system-like things about specially annotated Clojure code, but that is probably not what you are asking about. |
| 19:18 | sg2002 | Hello again. Is there anyone using this: https://github.com/AvisoNovate/pretty directly and not under timbre? How do you set pretty exceptions up? |
| 19:18 | andyf | The system used to prove things about behavior of Java byte code was ACL2: http://www.cs.utexas.edu/users/moore/acl2/ |
| 19:19 | andyf | I suspect using it to repeat their work, or extending it for nontrivial-sized Clojure programs, would be a significant chunk of work. |
| 19:28 | postpunkjustin | Yeah, I'm sure it would be easier to implement Clojure code extraction for Coq or something, since it already (kinda) works for Scheme |
| 19:37 | credulous | Any fans of Yesql? I'm having trouble with a toy example... |
| 19:38 | credulous | -- name: insert-user<! |
| 19:38 | credulous | INSERT INTO users (fname, lname, email, level, is_active, password_digest) |
| 19:38 | credulous | VALUES |
| 19:38 | credulous | (:fname :lname :email :level, 1, :password_digest) |
| 19:38 | credulous | is the sum total of users.sql |
| 19:38 | credulous | user> (defquery insert-user "distillednotes/models/users.sql" {:connection db-spec}) |
| 19:39 | credulous | 1. Caused by clojure.lang.ExceptionInfo |
| 19:39 | credulous | Parse error at line 2, column 4: -- name: insert-user<! ^ Expected |
| 19:39 | credulous | one of: NOT NAME_TAG "\t" " " |
| 19:39 | credulous | {:index 24, |
| 19:39 | credulous | :reason |
| 19:39 | credulous | [{:tag :negative-lookahead, :expecting {:NOT "NAME_TAG"}} |
| 19:39 | credulous | {:tag :string, :expecting "\t"} |
| 19:39 | credulous | {:tag :string, :expecting " "}], |
| 19:39 | credulous | :text "-- name: insert-user<!", |
| 19:39 | credulous | :column 4, |
| 19:39 | credulous | :line 2} |
| 19:39 | credulous | core.clj: 4403 clojure.core/ex-info |
| 19:39 | credulous | instaparse_util.clj: 18 yesql.instaparse-util/process-instaparse-result |
| 19:39 | credulous | queryfile_parser.clj: 42 yesql.queryfile-parser/parse-tagged-queries |
| 19:39 | credulous | core.clj: 28 yesql.core/defquery* |
| 19:39 | credulous | AFn.java: 160 clojure.lang.AFn/applyToHelper |
| 19:39 | credulous | AFn.java: 144 clojure.lang.AFn/applyTo |
| 19:39 | credulous | Urk that was ugly, sorry |
| 19:54 | andyf | credulous: Please use a paste web site and put links to them here. |
| 19:56 | amalloy | andyf: i think credulous knows that, given the apology after pasting |
| 19:57 | credulous | Won't happen again, sorry. |
| 19:57 | credulous | https://gist.github.com/rodfrey/456f92feb6ca33bb9826 |
| 20:08 | sg2002 | Hey guys, can someone tell me the current status of closeable sequences? While dealing with my data.xml stuff, I found this discussion: https://groups.google.com/forum/#!topic/clojure/2JDLF9E934o . So was it ever realized in any way? |
| 20:14 | andyf | sg2002: I am pretty sure the answer is no. |
| 20:17 | andyf | The last comment on this page says Rich considers it an open problem: http://dev.clojure.org/display/design/Resource+Scopes |
| 20:18 | andyf | I don't recall seeing this library before. I have no idea how useful it may be: https://github.com/pjstadig/scopes |
| 20:19 | andyf | Wrapping the body of a with-open with doall or dorun can sometimes eliminate the laziness that is causing problems. |
| 20:22 | gfredericks | andyf: sg2002: I really like hiredman's idea of using reducers instead of lazy seqs for that kind of stuff |
| 20:22 | amalloy | andyf: i think it's kinda a "closed problem", in that it seems like the wrong way to do things. all of the efforts at resource management have gone in some other direction |
| 20:22 | gfredericks | although technically I have never tried it |
| 20:22 | amalloy | eg reducers, as gfredericks has just said |
| 20:22 | gfredericks | somebody find that weird aws hiredman url |
| 20:22 | hiredman | ~reducers |
| 20:22 | clojurebot | reducers are http://clojure.com/blog/2012/05/08/reducers-a-library-and-model-for-collection-processing.html |
| 20:23 | hiredman | http://ce2144dc-f7c9-4f54-8fb6-7321a4c318db.s3.amazonaws.com/reducers.html |
| 20:23 | hiredman | the uuid is actually a hex encoding of the last few digits of PI |
| 20:24 | gfredericks | PI is over everybody is switching to TAU |
| 20:26 | andyf | TAU isn't half of what PI used to be. |
| 20:27 | sg2002 | andyf: Thanks for the info. |
| 20:28 | gfredericks | andyf: well put |
| 20:28 | fredfe | Has anyone ever tried putting data validation (like with bouncer) as ring middleware? Like with a redirect in case of a bad validation? |
| 21:11 | bbloom | chouser: yeah, moved to rrb vectors (they should be in core by now!) |
| 21:11 | bbloom | but 2-3 ft was great for a while :-) |
| 21:12 | bbloom | theoretical beauty has just got nothing on cache friendly hackery |
| 21:14 | credulous | My Yesql problem was solved by putting a newline at the top of the file, before the first "-- name:" tag. Is there an obvious reason that should be? |
| 21:39 | cryptack | hey, can someone explain when to use condp over cond? I'm not quite certain I follow the examples in clojuredocs.org |
| 22:11 | wei_ | is Avout still the go-to for managing a distributed system, or is there a more up-to-date alternative? |
| 23:04 | justin_smith | cryptack: it makes sense to use condp if you are repeating the same two argument check function for each case |
| 23:04 | CuteStat | how much is your website worth? find out at http://www.criosphinx.net/site-worth for more information visit https://www.criosphinx.net - Sell your website for top dollar get a free apparaisal |
| 23:04 | justin_smith | amalloy: you around? |
| 23:05 | amalloy | sure, what's up? |
| 23:05 | cryptack | justin_smith: not certain I follow yet? can you give me a small example? |
| 23:05 | amalloy | oh. i guess i can ban that driveby |
| 23:05 | cryptack | justin_smith: cond seems to be able to allow you to apply any function check you want, in order, and I understand case, in that it allows a specific field eval |
| 23:05 | cryptack | justin_smith: but condp, seems odd to me still... |
| 23:06 | amalloy | they've already logged off, and probably will never use that nick again, though |
| 23:07 | justin_smith | cryptack: condp is useful precisely because it is more limited |
| 23:07 | justin_smith | which means you know exactly how each clause is going to work |
| 23:07 | justin_smith | aids understanding |
| 23:08 | justin_smith | also, it allows you to use the result of the dispatch function in your clause |
| 23:28 | dumptruckman | hmm |
| 23:28 | dumptruckman | i want to turn (map-players move entities) into something like (-> entities (map-players move)) |
| 23:28 | dumptruckman | so i can add more processes to the chain |
| 23:29 | dumptruckman | but that doesn't work so i thought (-> entities (partial map-players move)) would do it but that also doesn't work -. |
| 23:30 | dumptruckman | OH |
| 23:30 | dumptruckman | oh.. i wanted ->> |
| 23:41 | dumptruckman | alright, say i have an array of maps and in the maps i have an :x and :y |
| 23:41 | dumptruckman | is there some handy way to check if there's a particular :x and :y value amongst the maps and to get the map it belongs to? |
| 23:42 | justin_smith | (first (filter #(= (:x %) v) maps)) |
| 23:42 | justin_smith | that's probably the most straightforward method you'll find |
| 23:42 | clojurebot | I don't understand. |
| 23:43 | dumptruckman | but i need both the :x and :y at the same time |
| 23:43 | dumptruckman | i was wondering if maybe i could restructing the map |
| 23:43 | justin_smith | oh, sure |
| 23:43 | dumptruckman | restructure* |
| 23:44 | justin_smith | make the predicat #(select-keys % [:x :y] {:x my-x :y my-y}) |
| 23:44 | justin_smith | err, bad braces |
| 23:44 | justin_smith | #(= (select-keys % [:x :y]) {:x my-x :y my-y}) |
| 23:45 | dumptruckman | like i have [{:foo bar :x 2 :y 3} {:foo baz :x 1 :y 3}] and turn into {[2 3] {:foo bar :x 2 :y 3} [1 3] {:foo baz :x 1 :y 3}] |
| 23:45 | dumptruckman | something like that |
| 23:45 | justin_smith | dumptruckman: select-keys does that for you, but in a much more useful way |
| 23:45 | dumptruckman | hmm |
| 23:46 | justin_smith | another options is #(= ((juxt :x :y) %) [my-x my-y]) |
| 23:46 | justin_smith | ,((juxt :x :y) {:x 0 :a :e :f "foo" :y 1}) |
| 23:46 | clojurebot | [0 1] |
| 23:46 | justin_smith | which is closer to what you proposed above |
| 23:47 | dumptruckman | hrmm i don't think select-keys does what i want |
| 23:47 | justin_smith | but I think select-keys may convey your intent better than juxt |
| 23:47 | dumptruckman | cause i need to be able to know what map the x and y belong to |
| 23:47 | dumptruckman | so i can compare that maps to another |
| 23:47 | amalloy | dumptruckman: what do you imagine happening if there are two different maps with the same x and y? |
| 23:47 | justin_smith | ,(select-keys [:x :y] {:x 0 :a :e :f "foo" :y 1}) |
| 23:47 | clojurebot | {} |
| 23:47 | justin_smith | err |
| 23:47 | dumptruckman | amalloy: bad stuff probably |
| 23:47 | justin_smith | ,(select-keys {:x 0 :a :e :f "foo" :y 1} [:x :y]) |
| 23:47 | clojurebot | {:x 0, :y 1} |
| 23:48 | amalloy | you're using [x y] as the key in your map, which can't support duplicates, when it seems perfectly plausible for a duplicate to exist |
| 23:48 | dumptruckman | i mean i could certainly traverse the map to do what i wnat |
| 23:48 | dumptruckman | but i just figured there's a more clojurey way |
| 23:48 | amalloy | i mean it's not hard |
| 23:48 | justin_smith | oh, wait |
| 23:48 | justin_smith | that's close to being group-by |
| 23:48 | amalloy | justin_smith: it is group by |
| 23:48 | justin_smith | except group-by would give you a collection for each x/y pair |
| 23:48 | justin_smith | instead of one item |
| 23:49 | dumptruckman | i want to find all the maps that contain a particular x and y |
| 23:49 | justin_smith | either group-by or filter can do that, depends how many x/y pairs you want to look up - if more than one or two I would do it via group-by |
| 23:49 | dumptruckman | but i need to know if that map has a particular POJO inside it |
| 23:49 | dumptruckman | if so i don't care about it |
| 23:50 | amalloy | dumptruckman: your requests are contradictory. the latest thing you've asked for is the opposite of the example input/output you gave. perhaps you should be clearer about what you need to do and/or why |
| 23:50 | dumptruckman | ok |
| 23:50 | dumptruckman | i will try |
| 23:52 | dumptruckman | i have a map contain a java object and a coordinate pair. i have a vector of a bunch of these same maps with non-equal java objects and mostly different coordinates. i need to find out which of those maps in the vector matches the first map, but i want to ignore the first map itself, which exists in the vector |
| 23:52 | dumptruckman | my actual goal is collision detection |
| 23:53 | justin_smith | OK, I would use a filter that tests the x, y, and pojo |
| 23:53 | dumptruckman | the vector is all the objects on screen, i'm trying to find out if one of the objects is in the same coords as another, excluding itself since that will always be the case |
| 23:53 | amalloy | okay, so you are searching through a sequence for any number of objects which meet a specific criterion (which, here, is "has the same x/y, but not that other thing" |
| 23:53 | justin_smith | if you were looking up more than one x/y I would suggest group-by instead |
| 23:54 | dumptruckman | just one x and y |
| 23:54 | dumptruckman | i'll look at filter |
| 23:54 | dumptruckman | amalloy: yes, basically |
| 23:54 | amalloy | then you are doing exactly a filter |
| 23:54 | dumptruckman | or precisely |
| 23:54 | dumptruckman | k |
| 23:55 | dumptruckman | oh yeah, duh |
| 23:55 | dumptruckman | thank you! |
| 23:57 | currentoor | so what do people usually use for oath? |
| 23:57 | currentoor | anyone try this? |
| 23:57 | currentoor | https://github.com/mattrepl/clj-oauth |