2015-09-25
| 02:16 | tianyu | this is test |
| 02:17 | tianyu | Trouble of eval clojure block within org-mode by cider : |
| 02:17 | tianyu | org-babel-execute:clojure: Wrong number of arguments: |
| 02:17 | tianyu | ((cider-buffer-ns cl-struct-nrepl-response-queue-tags t) (input |
| 02:17 | tianyu | connection session &optional ns) "Send the INPUT to the nREPL server |
| 02:17 | tianyu | synchronously.The request is dispatched via CONNECTION and SESSION. |
| 02:17 | tianyu | The code is : |
| 02:17 | tianyu | #+BEGIN_SRC clojure |
| 02:17 | tianyu | (+ 1 2) |
| 02:17 | clojurebot | 3 |
| 02:17 | tianyu | #+END_SRC |
| 02:17 | tianyu | Plz help. |
| 05:32 | anti-freeze | Hi everyone. I need some help with ui.router. For some reason, every time I refresh the browser, ui.router redirects me to main.home, which is a route on top of the main abstract route. If I remove that route, everything works as normal. Here's the source code: http://plnkr.co/edit/WEvXWkpPolm7fMN54PxS?p=catalogue . Any ideas? |
| 05:34 | anti-freeze | Wrong channel |
| 05:34 | anti-freeze | Sorr |
| 05:34 | anti-freeze | Sorry |
| 08:10 | wasamasa | now I know why it took so long to port pprint to cljs |
| 08:11 | wasamasa | it contains an implementation of CL's format |
| 10:15 | Guest24 | good morning folks |
| 10:31 | triss | hey all, is there a reason the definition of clojure.core/fn is such a dense blob of code? |
| 10:32 | triss | for example would pulling out the :pre and :post related stuff to some private functions/macros? |
| 10:35 | TimMc | I don't think there's a *good* reason, if that's what you're asking. |
| 10:35 | TimMc | Some parts of core are a crawling horror because they haven't been touched since Clojure was still in very early development, and I think the Core team is reluctant to clean up code that is working. |
| 10:36 | TimMc | There's something to be said for that. |
| 10:41 | sdegutis | When you use Components for your web app, do you even wrap your routes within a component? |
| 10:43 | kungi | sdegutis: I do. But you don't have to. |
| 10:44 | sdegutis | I'm having a hard time figuring out which things should be Components and which should just continue to be normal Clojure functions which Components call. |
| 10:44 | kungi | sdegutis: It depends on how you would like to inject your dependencies into your routes |
| 10:46 | sdegutis | Oh good point. |
| 10:49 | sdegutis | kungi: so the only practical difference is whether the functions can implicitly access record fields vs. having parameters to receive them? |
| 10:49 | sdegutis | There's no difference in terms of code-reloading? |
| 10:53 | kungi | sdegutis: As far as I see. Yes |
| 10:54 | kungi | sdegutis: You could also inject the Components into the http request through a middleware. This way you don't have to use function parameters. |
| 10:56 | craftybones | Are sets ordered by default in clojure? If so, is there a canonical way of finding the index of a member? |
| 10:56 | kungi | craftybones: no they are not ordered |
| 10:56 | craftybones | Thanks @kungi |
| 10:56 | bja | I have a component that takes an argument of things that will exist at start time on the ring-app component to be injected into the request |
| 10:56 | kungi | craftybones: there is sorted-set for that |
| 10:57 | craftybones | @kungi I don't want it sorted. I guess I'll just use a vector |
| 10:57 | xeqi | sdegutis: I usually just wrap the server, db, etc. Then I have the server build a ring handler passing in the components needed, but the ring handler/routing is just functions |
| 10:57 | bja | something like that: https://gist.github.com/b45d2dbf2fbf5ea8afe1 |
| 10:58 | bja | actually need to finish the blog post that code belongs to, it's a demo of using component to manage hot settings pushes from zookeeper |
| 11:11 | sdegutis | xeqi, kungi: thanks, very informative and helpful |
| 11:12 | sdegutis | I wonder what the downsides are of making *everything* be a Component, no random functions floating around. |
| 11:12 | sdegutis | I guess the main downside would be that it can't easily just say "okay, reload this function definition" while developing live (e.g. via CIDER), instead you have to shut down and restart the entire System component. |
| 11:16 | xeqi | sdegutis: I imagine the boiler plate for getting the setup/teardown for tests could get annoying |
| 11:18 | xeqi | though if you pushed it far enough you'd basically have immutable namespace |
| 11:18 | sdegutis | xeqi: actually that would be the easiest part: there would be a (test-system) constructor function, which creates real versions of everything, except if there are any services which leave the system (e.g. email-service-component) then it would use an in-memory version. |
| 11:19 | sdegutis | xeqi: and each in-memory component would use atoms for state so you could easily setup state and test their side-effects in tests |
| 11:20 | sdegutis | E.g. my email-service takes an atom of emails, which I have a helper-macro that resets it to an atom that it lets me name and inspect after my test runs. |
| 11:26 | xeqi | sounds like what i do, though the recent cognicast has some mention of use cases for async channels instead of atoms |
| 11:26 | xeqi | was overthinking the amount of isolation needed between tests when i mentioned the boilerplate |
| 11:27 | sdegutis | To this day I still don't understand when I need core.async. |
| 11:30 | bja | sdegutis that's only actually a downside of the current implementation of component (needing to restart everything) |
| 11:30 | sdegutis | bja: well it's not even really that much of a downside :) |
| 11:30 | bja | I've seen multiple private forks that take a new and current system and diff+ walk the system and only restart changed things |
| 11:30 | bja | yeah, it's not too bad |
| 11:32 | bja | I've actually seen people (other than myself) using com.stuartsierra.component/Lifecycle to build components but starting/managing them with heavy forks of the original codebase |
| 11:33 | sdegutis | bja: hmm I wonder why they haven't been merged back in? |
| 11:34 | bja | all of the ones except mine are private that I'm aware of |
| 11:35 | bja | and mine isn't that heavy (it just uses destructure to process dependency injection maps) |
| 11:35 | bja | there's a PR on component where stuart rejected mine, and I don't necessarily disagree with his reasons, but I find my fork useful |
| 11:41 | justin_smith | bja: I have a cljc fork |
| 11:42 | justin_smith | it's not "heavy" though, just cljc |
| 11:42 | justin_smith | one of these days I'll port all the tests to cljs.test and make a PR |
| 11:43 | bja | by heavy, I mean that almost none of the implementation details for starting/stopping are the same |
| 11:43 | bja | I think my fork is something like a 40 line diff where I add a couple functions |
| 11:43 | justin_smith | bja: but if I am using component to provide lexically closed resources with a lifespan, all components using a changed component need restarting |
| 11:43 | justin_smith | (reading scrollback now) |
| 11:48 | tianyu | An error of eval clojure within org-mode: org-babel-execute:clojure: Wrong number of arguments: ((cider-buffer-ns cl-struct-nrepl-response-queue-tags t) (input connection session &optional ns) "Send the INPUT to the nREPL server synchronously. |
| 11:48 | tianyu | The request is dispatched via CONNECTION and SESSION. |
| 11:48 | tianyu | If NS is non-nil, include it in the request." (nrepl-send-sync-request (nrepl--eval-request input session ns) connection)), 1 |
| 11:48 | tianyu | PLZ help |
| 11:49 | justin_smith | tianyu: cider changes constantly, is org-babel even supposed to be working these days? |
| 11:52 | justin_smith | or, maybe a better way to put it - which version of cider is your version of org-babel's clojure support compatible with, and are you using that version? |
| 11:54 | sdegutis | Aw, this PR could have been useful https://github.com/stuartsierra/component/pull/25 |
| 11:55 | justin_smith | yeah, I just made my own stupid helper that does that |
| 11:55 | justin_smith | (as something outside component proper) |
| 11:56 | sdegutis | Are you supposed to get System components via keyword-access? |
| 11:57 | justin_smith | yeah, the system passed into your start or stop method has all your dependencies associated on as keywords |
| 11:57 | justin_smith | or, with your selected keywords as keys |
| 11:59 | sdegutis | Right. |
| 12:00 | sdegutis | So it's idiomatic to destructure them, like (let [{:keys [db router time]} sys] ...) and use them like (get-today time) and (handle-req router req) ? |
| 12:02 | justin_smith | yeah, that seems straightforward, though it's usually nested deeper because I make components that each provide their own map of things |
| 12:02 | justin_smith | maybe you are doing it more modular so each component only provides one thing? |
| 12:03 | sdegutis | justin_smith: I'm not sure what you mean. |
| 12:03 | sdegutis | justin_smith: I have a flat list of components, but each component may depend on other components (no circular dependency though). |
| 12:04 | justin_smith | sdegutis: my components each provide a map with multiple things you might want from it |
| 12:04 | sdegutis | justin_smith: so I have [db router time-service email-service ...] but db may depend on time-service |
| 12:04 | justin_smith | wait, where is this destructuring happening again? |
| 12:04 | sdegutis | justin_smith: oh you mean each component has getters? |
| 12:04 | sdegutis | justin_smith: oh good point... I meant at the top-level entry point |
| 12:05 | justin_smith | each component associates multiple keys, and a component using it has to pick out the keys it wants |
| 12:05 | sdegutis | justin_smith: within a component, it just has the depended-upon components as record fields which are always visible |
| 12:05 | justin_smith | OK, what does destructuring at the top level entry point do for you? |
| 12:05 | sdegutis | justin_smith: oh good point.. I guess I don't need it |
| 12:05 | sdegutis | Okay, solved! |
| 12:05 | sdegutis | Thanks justin_smith. |
| 12:05 | sdegutis | justin_smith: tbh I'm mapping this out, I don't actually have code yet just a diagram |
| 12:06 | justin_smith | it was a legitimate question, but I guess "nothing" is an answer too |
| 12:06 | justin_smith | haha |
| 12:06 | sdegutis | I'm preparing for transforming my services into components (services were my ad-hoc solution I've been using before component was written) |
| 12:15 | elika | hello |
| 12:16 | blkcat | x1/win 32 |
| 12:16 | blkcat | ...wow |
| 12:16 | sdegutis | blkcat: what? |
| 12:16 | blkcat | don't mind me :D |
| 12:16 | scriptor | anyone know where LEIN_PASSWORD is coming from in https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L103 ? |
| 12:17 | sdegutis | blkcat: plz do tell |
| 12:17 | sdegutis | scriptor: its an env variable |
| 12:17 | scriptor | yes |
| 12:17 | scriptor | that much is clear |
| 12:17 | sdegutis | scriptor: you're supposed to set it |
| 12:17 | sdegutis | scriptor: that's how they work |
| 12:18 | scriptor | you misunderstand, I'm trying to figure out how leiningen is able to get LEIN_PASSWORD in the first place |
| 12:18 | scriptor | I know how to set a bash env variable |
| 12:18 | scriptor | but how does lein know that's the env variable? |
| 12:18 | sdegutis | scriptor: according to the comments above it, when it sees :env, it asks for the environment variable |
| 12:19 | sdegutis | scriptor: probably via (System/getEnvironmentVariable "LEIN_PASSWORD") or whatever the static function name is |
| 12:19 | justin_smith | sdegutis: System/getenv |
| 12:19 | sdegutis | yeah that |
| 12:19 | justin_smith | ,(System/getenv "PWD") |
| 12:19 | scriptor | but how does lein know to ask for LEIN_PASSWORD, there's no other reference to that anywhere els |
| 12:19 | clojurebot | #error {\n :cause "access denied (\"java.lang.RuntimePermission\" \"getenv.PWD\")"\n :via\n [{:type java.security.AccessControlException\n :message "access denied (\"java.lang.RuntimePermission\" \"getenv.PWD\")"\n :at [java.security.AccessControlContext checkPermission "AccessControlContext.java" 372]}]\n :trace\n [[java.security.AccessControlContext checkPermission "AccessControlContext.java... |
| 12:19 | justin_smith | :P |
| 12:19 | sdegutis | I get the naming conventions between that and System/getProperty mixed up |
| 12:19 | sdegutis | scriptor: it's hard-coded in |
| 12:20 | sdegutis | scriptor: I'm really having trouble understanding a reason for your confusion on this |
| 12:20 | scriptor | ah, so LEIN_PASSWORD is a hardcoded variable that lein looks for |
| 12:20 | sdegutis | scriptor: it's a reasonable convention that Leiningen is using, where it gives you a name of an env variable which you can then set if you choose, and gives you a way to tell it to look for it |
| 12:21 | scriptor | the comment says that an "environment variable will be used based on the key" |
| 12:21 | scriptor | since the key is :password |
| 12:22 | justin_smith | scriptor: hmm, maybe it is constructing the variable to look up based on the key? |
| 12:22 | scriptor | I was wondering if lein simply uses that key and prepends 'LEIN_' to it to create the actual environment variable name |
| 12:22 | sdegutis | scriptor: right, it's saying: if the value is a string, it uses that literally; if it's literally :env, it looks in the environment variable "LEIN_PASSWORD" for a literal string to use |
| 12:22 | scriptor | maybe |
| 12:23 | scriptor | sdegutis: the value is :env, but the key is :password, are you saying that somewhere inside lein the :password key is hardcoded to map to LEIN_PASSWORD? |
| 12:24 | justin_smith | scriptor: I think it is more likely that :foo is hardcoded to be LEIN_FOO (somewhere) but I am not finding evidence of any of this searching the lein github repo for getenv usage |
| 12:24 | sdegutis | justin_smith, scriptor: it's probably literally this code: (let [m {:password "foo"} {:keys [password]} m password (if (= password :env) (System/getenv "LEIN_PASSWORD") password)] ...) |
| 12:24 | sdegutis | Ore more clearly: (let [{:keys [password]} {:password "foo"}, password (if (= password :env) (System/getenv "LEIN_PASSWORD") password)] ...) |
| 12:24 | scriptor | so, you're not certain? |
| 12:24 | justin_smith | sdegutis: the weird thing is LEIN_PASSWORD only shows up in the readme, nowhere in code |
| 12:24 | scriptor | ^ |
| 12:25 | sdegutis | scriptor: I'm telling you that's what the documentation claims; I haven't looked at the code so I don't know, but that's what the docs are saying |
| 12:25 | sdegutis | justin_smith: ooooh |
| 12:26 | sdegutis | scriptor: ah so yeah it's probably a convention like justin_smith says, where it probably has this: (defn get-value [m k] (or (get m k) (System/getenv (format "LEIN_%s" (name k))))) |
| 12:26 | sdegutis | In which case it's doing (get-value your-map :password) |
| 12:27 | sdegutis | I bet a grep for "LEIN_" would turn that function up. |
| 12:29 | scriptor | https://github.com/technomancy/leiningen/blob/1bc9d42c430b0c94c0a25e8f869c94bb41d9b2cf/leiningen-core/src/leiningen/core/user.clj#L144 |
| 12:29 | sdegutis | there you go |
| 12:30 | scriptor | so my assumption was right, it takes the key and simply prepends LEIN_ to it |
| 12:30 | sdegutis | you got it bud |
| 12:31 | justin_smith | sdegutis: you forgot the part where it converts to SHOUTY_CASE |
| 12:31 | justin_smith | but yeah |
| 12:31 | sdegutis | touché |
| 12:31 | sdegutis | wha? why? |
| 12:32 | xemdetia | much like strfry |
| 12:32 | justin_smith | because it's silly of course |
| 12:32 | xemdetia | this is a vital part of libraries |
| 12:32 | justin_smith | xemdetia: exactly |
| 12:37 | TimMc | Wow, that's gross. |
| 12:37 | TimMc | I don't like it when variable names are constructed, it makes them hard to grep for. :-) |
| 12:38 | sdegutis | TimMc: meh it has a time and place |
| 12:38 | sdegutis | TimMc: now /function names/ on the other hand... |
| 13:14 | justin_smith | sdegutis: TimMc: worst is when entire namespaces are made that way. |
| 13:15 | sdegutis | justin_smith: never heard of that |
| 13:15 | justin_smith | there's one amazon api wrapping project in particular, turns each class in the api into a namespace, each static method gets a function wrapper |
| 13:16 | justin_smith | sdegutis: so if you go into the code looking for the code for the thing you are using, you find nothing, just the general odor of magic in the air |
| 13:17 | justin_smith | sdegutis: this macro, on line 5, creates a whole namespace full of vars and functions https://github.com/mcohen01/amazonica/blob/master/src/amazonica/aws/cloudformation.clj |
| 13:18 | justin_smith | s/macro/function - here is the function with its doc https://github.com/mcohen01/amazonica/blob/master/src/amazonica/core.clj#L884 |
| 13:19 | justin_smith | sdegutis: so someone is like "how do I use cloudformation/foo" and I go look at the source, and I'm like "wat" |
| 13:21 | jstew | Offer to rwrite it :) |
| 13:21 | justin_smith | haha |
| 13:27 | bja | amazonica is the one that manages client objects in some var (global? thread-bound?) for you right? |
| 13:28 | justin_smith | bja: sounds about right - it puts all kinds of things into vars |
| 13:29 | bja | if this is the one I'm thinking of, it was fine for devops scripts but made it worthless to my service since I was putting everything in components |
| 13:29 | jstew | vars are like violence? :) |
| 13:29 | justin_smith | jstew: vars are global, which can be inflexible |
| 13:30 | bja | I mean, it's fine if an api just handles managing the client for you, as long as there's some way to break out and pass in a particular client instead of the global thing |
| 13:31 | bja | and by some way, I don't mean reflecting/binding private stuff |
| 13:31 | jstew | Is there any value to it over just calling out to java, since that's what it's doing for you, albeit in a messy way? |
| 13:31 | bja | it has a few higher level abstractions so you don't have to paginate certain things yourself |
| 13:31 | justin_smith | bja: it was a big revelation to me that when I was working on a lib (that could potentially use globals vs. dynamic vars vs. explicit value passing) that every other method of sharing a value can be derived from explicitly passing a value to a consumer. But that's the only flexible one, the others are not inter-compatible. |
| 13:32 | bja | justin_smith: that's an excellent way of putting it |
| 13:32 | justin_smith | bja: so by using explicit passing of an arg, you leave the most flexibility for the developer making their own app |
| 13:33 | bja | I did that for clj-aws-s3 here: https://github.com/curiosity/clj-aws-s3 |
| 13:33 | bja | I think there are 3 or 4 different forks that do essentially the same thing w.r.t to removing the implicit dynamic vars |
| 13:34 | justin_smith | they can use globals or dynamic vars or atoms or deserialized objects from a db or whatever the hell they want, and it will all be compatible with explicit arg passing in the end |
| 13:34 | justin_smith | bja: hah, makes sense |
| 13:35 | bja | actually, looking at that, I probably need to type-hint all those client arguments |
| 13:36 | bja | I should profile that next week |
| 13:37 | bja | oh, forgot, clj-aws-s3 wasn't even a dynamic var, it was just a private global |
| 13:37 | bja | that was memoized so you couldn't even call it again |
| 13:37 | justin_smith | haha, nice |
| 13:37 | bja | but it had nice abstractions for s3 |
| 13:37 | bja | so it was worth forking and maintaining |
| 14:37 | preyalone | Which plugin { id ... } ... apply plugin: ... should I drop into build.gradle for Clojure projects? |
| 14:41 | RedNifre | good evening |
| 14:42 | snowell | preyalone: I don't know that there would be a build.gradle. Generally we use leiningen to build clojure projects, so you'd have project.clj instead |
| 14:44 | RedNifre | So I started with Clojure three days ago and the language looks fine to me. Now I wonder about the practical side: Is Cursive any good, how would it fit with Android Studio, is there some clojure library repository somewhere (or are clojure libraries just jars that you add to your gradle file?) how does it all fit together? |
| 14:45 | ToxicFrog | RedNifre: I can answer the clojure library repository part, at least |
| 14:45 | RedNifre | great :) |
| 14:46 | ToxicFrog | The de facto standard library repository is Clojars; if you're using Leiningen, the Clojure build tool, it knows how to download libraries from there automatically if you list them in the deps |
| 14:46 | justin_smith | we use leiningen instead of gradle - or at least 99% of us do |
| 14:46 | ToxicFrog | It also has support for fetching libraries from github and I think a few other sources |
| 14:46 | ToxicFrog | I have no idea what gradle is |
| 14:46 | justin_smith | ToxicFrog: it's like leiningen for groovy or something |
| 14:47 | preyalone | snowell: Aye, Leiningen is an optino. But I'd prefer to use one build manager for all my altJVM projects, rather than a medley of Maven + Rake + Leiningen + Grapes |
| 14:47 | RedNifre | I heard of leiningen, but have no idea what it is yet. Does it only fetch clojure libraries or can I also fetch any other jar, e.g. from maven central? |
| 14:47 | justin_smith | RedNifre: clojure libraries are hosted in any jar repo, there are some on maven central too |
| 14:47 | RedNifre | gradle is just a build tool. you have a gradle file like you have a pom file or an ant file I guess. |
| 14:48 | justin_smith | RedNifre: leiningen uses the maven spec (but not maven itself0 |
| 14:48 | justin_smith | right, leiningen is a build tool also |
| 14:48 | RedNifre | okay, so I would write some clojure code, add dependencies with leiningen, both clojure jars and regular jars and in the end I compile it into one jar that will just work like a java jar? |
| 14:48 | justin_smith | exactly |
| 14:48 | ToxicFrog | That said, clojure libraries are either jar files, or clojure source you can turn into jar files, so if you're using some non-lein build tool that consumes jars you can just feed them to it without issue. |
| 14:48 | ToxicFrog | If you're using lein it also has an "uberjar" command that combines the jars for all your libraries with the program/library you're building so that it's self-contained, which is handy for self-contained deployment. |
| 14:50 | schmudde | Yep. Leiningen user here. I'm consistently surprised at its power. Right now I need a little ClojureScript functionality as well... and I'm running that compile along with the a hosted Clojure web app. |
| 14:50 | RedNifre | ah, I think that was called "fat jar" in eclipse. |
| 14:50 | schmudde | Works great with Clojars. |
| 14:50 | snowell | RedNifre: I think you're right. Uberjar is a much cooler name |
| 14:50 | ToxicFrog | justin_smith: I don't know what groovy is either soooooo |
| 14:50 | justin_smith | ToxicFrog: yet another jvm language |
| 14:51 | justin_smith | ToxicFrog: so gradle uses groovy to build things in the way that leiningen uses clojure to build things |
| 14:52 | RedNifre | It sounds like building a simple jar that can run on a server is easy. Though I still wonder how to make use of clojure on android, either by having an app that is all clojure or by having the bulk of your code in a clojure jar but handle all the android specifics in java... |
| 14:53 | RedNifre | With gradle, your build file is a groovy program. If leiningen build files are written in edn then it should be the same concept. |
| 14:53 | ToxicFrog | aah |
| 14:53 | justin_smith | RedNifre: I'd look at one of the existing android clojure projects. Interop from clojure to java is very easy for the most part (unless you need to inherit from a specific class, that can be annoying from clojure sometimes) |
| 14:53 | justin_smith | RedNifre: they are! |
| 14:53 | RedNifre | I don't know Groovy the language, but the syntax is fine so I like gradle files :) |
| 14:53 | justin_smith | RedNifre: lein inputs being edn / clojure code, that is |
| 14:55 | bja | /join #pixie-lang |
| 14:58 | ToxicFrog | RedNifre: as far as android goes, I've only dabbled in it very briefly, but since you can call java directly from clojure very easily, there was no need for java compatibility layer or anything |
| 14:58 | ToxicFrog | The drawback is that the resulting app takes forever to load as it dynamically loads/initializes the clojure runtime and stdlib |
| 14:58 | RedNifre | oh |
| 14:59 | ToxicFrog | There is some work on improving that, not sure how far along it is -- this was back in late 2013, IIRC |
| 14:59 | xemdetia | yeah that was what I was mentioning yesterday |
| 14:59 | RedNifre | I remember trying Ruboto (JRuby for Android), but the app took 10 seconds to start back then (I think it's down to 3 seconds now, but still...). |
| 14:59 | xemdetia | part of the android system is that there is one JVM that never gets unloaded |
| 14:59 | ToxicFrog | If you can get away with running as a Chrome App or similar, you can use cljs instead of cljvm |
| 14:59 | RedNifre | hm. |
| 14:59 | ToxicFrog | Which will probably load a lot faster, although I haven't tried this outside of the test environment |
| 15:00 | RedNifre | so how long is "takes forever to load"? 1 second? 10 seconds? |
| 15:02 | ToxicFrog | RedNifre: on a Galaxy Nexus, two years ago -- ~15 seconds. |
| 15:02 | ToxicFrog | For hello world. |
| 15:02 | ToxicFrog | But like I said, there has been a lot of active work since on improving this. |
| 15:03 | ToxicFrog | E.g. some quick googling finds http://blog.ndk.io/2015/04/23/state-of-coa.html and http://clojure-android.info/skummet/ |
| 15:03 | bja | There is a lein plugin that uses a forked compiler and some tooling that does some additional optimization to make clojure on android slightly better |
| 15:04 | bja | ToxicFrog found it |
| 15:04 | bja | I think the plugin is `lein-droid` or something like that |
| 15:05 | RedNifre | yeah, I'm reading about those. |
| 15:08 | bja | I wonder if React Native boots fast enough to make it worth using cljs and something like Reagent/Om for an Android app |
| 15:08 | bja | the demo here looks interesting: https://github.com/Gonzih/reagent-native |
| 15:12 | RedNifre | What's the meaning of ^Something again? |
| 15:20 | bja | typehint |
| 15:25 | schmudde | I haven't done any mobile development work, and I don't plan on leaving emacs, but Nightcode looks like an interesting way to hit the ground running for Clojure across platforms: https://sekao.net/nightcode/ |
| 15:26 | schmudde | looks like it uses lein-droid... |
| 15:26 | schmudde | Anybody use it? |
| 15:27 | bja | RedNifre: technically it's a tag |
| 15:27 | bja | which doesn't have to be a typehint |
| 15:35 | dillap | Is there any writeups for adding reagent to an existing (non-cljs) clojure webapp? |
| 15:35 | dillap | Everything I can find assumes you are starting from scratch, and configuring the compiler and setting up figwheel is a bit intimidating. |
| 15:43 | RedNifre | hm, nightcode sure looks interesting. |
| 15:46 | sdegutis | blkcat: React Native? as opposed to Reagent? |
| 15:46 | sdegutis | Oh, Android stuff. |
| 15:57 | irctc | Is there a performance difference between running a compiled jar and using 'lein run'? |
| 15:58 | sdegutis | irctc: lein run will compile the jar and do some other fancy things, and spin up two JVMs |
| 15:59 | sdegutis | irctc: it's faster to run a jar directly, but the you don't have access to any Leiningen plugins (unless they were used to compile the jar) |
| 15:59 | irctc | gotcha |
| 15:59 | sdegutis | irctc: and it's recommended to build an uberjar (via 'lein uberjar' maybe) and deploy that jar to production for running |
| 15:59 | irctc | right, I'm doing that, just was curious about the other way |
| 15:59 | irctc | thnx |
| 16:00 | irctc | Anybody using docker to deploy clojure apps? |
| 16:09 | schmudde | irctc - I'm haven't used Docker, but my experience with Clojure and Heroku has been good so far. |
| 16:10 | codefinger | irctc: schmudde: use both! http://jkutner.github.io/2015/08/17/deploy-clojure-immutant-heroku-docker.html |
| 16:11 | schmudde | codefinger: interesting. Why would you want to use both? |
| 16:12 | codefinger | schmudde: having the locally development env is a plus. but if you are happy with your current heroku setup... i would recommend sticking with that. |
| 16:12 | codefinger | you can mix and match too. so if you set it up for Docker, you can still deploy with Git |
| 16:13 | codefinger | the addons is really key though. being able to run a "local heroku" with addons can help you debug stuff |
| 16:13 | schmudde | codefinger: I think I understand what you're saying. Don't I get the same features out of Leiningen's Environ? I have a dev environment and a production deployment. |
| 16:14 | schmudde | codefinger: Yeah, debugging is tough. I cross my fingers whenever I deploy b/c I cannot test as a "local heroku". Interesting. |
| 16:14 | codefinger | schmudde: i agree. lots of people seem to want docker support though... because reasons :) |
| 16:15 | codefinger | schmudde: wrt debugging http://jkutner.github.io/2015/05/19/heroku-remote-debug-java.html |
| 16:15 | schmudde | codefinger: Thanks for the tip. I'll dig a little deeper online. I'm new to the auto app deployment game. I've always done it manually, but my hosting provider isn't going to add JVM support any time soon. |
| 16:16 | codefinger | that's a bit of a hack. there is going to be some good/better stuff coming soon. can't really say (I work at heroku) but think nrepl :) |
| 16:16 | justin_smith | also, it's possible to go the opposite direction of docker too - something like OSv where there is no operating system, the hardware vm loads a jvm directly, and the jvm runs your code |
| 16:16 | schmudde | codefinger: Cool! |
| 16:27 | TEttinger | justin_smith: I can't remember, do you work for heroku or was it another long-time resident of #clojure ? Raynes? |
| 16:28 | justin_smith | TEttinger: technomancy once did |
| 16:28 | TEttinger | ah that would maybe explain it |
| 16:28 | justin_smith | TEttinger: being mistaken for technomancy is quite flattering |
| 16:28 | TEttinger | I know someone did it a few days ago with me |
| 16:28 | TEttinger | te* |
| 16:29 | TEttinger | (identity justin_smith) ;; BOT FAILURE |
| 16:30 | justin_smith | TEttinger: clearly what happened is my karma finally exceeded that of amalloy and so amalloy took the bot down to hide his shame |
| 16:30 | TEttinger | haha |
| 16:30 | justin_smith | (I don't think any of these things actually happened) |
| 16:31 | TEttinger | yeah amalloy stepped up his game when your karma started approaching his |
| 17:28 | devth_ | my clojure's a little rusty. easy way to pick the first function that returns non-nil when applied to a value? |
| 17:28 | justin_smith | somefn |
| 17:28 | justin_smith | (doc somefn) |
| 17:28 | clojurebot | It's greek to me. |
| 17:29 | justin_smith | some-fn but, err, that doesn't pick a function, that picks a non-nil result |
| 17:29 | devth | (doc some-fn) |
| 17:29 | clojurebot | "([p] [p1 p2] [p1 p2 p3] [p1 p2 p3 & ps]); Takes a set of predicates and returns a function f that returns the first logical true value returned by one of its composing predicates against any of its arguments, else it returns logical false. Note that f is short-circuiting in that it will stop execution on the first argument that triggers a logical true result against the original predicates." |
| 17:29 | devth | justin_smith: it works in my case. thx! |
| 17:29 | devth | not sure i ever used that even when i was writing a lot of clj |
| 17:30 | devth | ((some-fn :no :yes :bad) {:yes 1}) |
| 17:30 | devth | my original question wording wasn't precise |
| 17:30 | justin_smith | ,((some-fn :no :yes :bad) {:yes 1}) |
| 17:30 | clojurebot | 1 |
| 17:30 | justin_smith | so there are multiple keys you might find, and the first non-falsey is good |
| 17:30 | sdegutis | Wow |
| 17:31 | sdegutis | some-fn looks incredibly useful in some cases |
| 17:31 | sdegutis | Can't figure out which ones tho |
| 17:31 | justin_smith | sdegutis: stupid apis that can't decide which key your data is under |
| 17:31 | sdegutis | ah interesting, for legacy stuff |
| 17:31 | TimMc | ,(filter #(% {:yes 1}) [:no :yes :bad]) |
| 17:31 | clojurebot | (:yes) |
| 17:31 | sdegutis | what else? |
| 17:31 | devth | i'm actually using this to catch errors in stupid apis that name error message differently :) |
| 17:32 | sdegutis | TimMc: also juxt |
| 17:32 | justin_smith | sdegutis: but juxt does not short circuit |
| 17:32 | sdegutis | maybe outside the filter? |
| 17:33 | sdegutis | ,(filter #(if-let [x (% {:yes 1})] ((juxt identity %) {:yes 1})) [:no :yes :bad]) |
| 17:33 | clojurebot | (:yes) |
| 17:33 | sdegutis | or something |
| 17:33 | sdegutis | I dunno anymore |
| 17:33 | justin_smith | oh, you are trying to get the first key that got a non-nil result |
| 17:34 | justin_smith | eg. what the question might have implied (but did not in fact want) |
| 17:50 | devth | would be neat if i could do (format ":foo is a :bar / :qux" {:foo 1 :bar 2 :qux 3}) |
| 17:51 | justin_smith | devth: seems like an easy enough function to write! |
| 17:51 | devth | justin_smith: yep |
| 17:54 | devth | but instead im resorting to: (apply (partial format "%s %s: %s") (map (% vpc) [:vpc :flavor :capacity])) |
| 18:13 | justin_smith | hmm... I think a clever regex could turn that into the version you want though |
| 18:14 | justin_smith | you could even get fancy and have :2d act like %2d etc... |
| 18:49 | amalloy | devth: (apply format "..." (map ...))). there's no need for this partial nonsense |
| 18:49 | devth | oh yeah. thanks |
| 18:55 | bitraider | any good recommendations on modern web app development in clojure... tutorials/books? |
| 18:56 | sdegutis | devth: actually yeah that function would rock |
| 18:56 | sdegutis | justin_smith: regex is *never* the answer |
| 18:56 | amalloy | that function has been written a lot of times. peronally i don't really see a big advantage over the existing format function |
| 18:57 | sdegutis | amalloy: it combines (format) with destructuring, with the added benefit of being able to see what's put in the string where relative to each other |
| 18:57 | devth | just a minor advantage :) |
| 18:58 | sdegutis | amalloy: so personally I think (format2 ":name, :email" user) is nicer than (format "%s, %s" (:name user) (:email user)) |
| 18:58 | sdegutis | That said, I usually end up destructuring earlier, so it's (format "%s, %s" name email) which isn't /that/ bad |
| 18:58 | devth | y no string interpolation, clj? |
| 18:58 | devth | even scala got it :-) |
| 18:59 | justin_smith | when we decide we don't have room for features, we give them to scala |
| 18:59 | justin_smith | scala is a feature hoarder |
| 18:59 | turbofail | there's a library that has a string interpolation macro |
| 18:59 | schmudde | lol |
| 18:59 | devth | justin_smith: ha ha |
| 18:59 | sdegutis | Scala is where our features go to die. |
| 19:00 | devth | clj where every imaginable lang feature exists as a lib |
| 19:00 | sdegutis | devth: except core.async is not as flexible as it could be in a static language, even with core.typed thrown in |
| 19:00 | devth | that's interesting |
| 19:00 | sdegutis | devth: so yes, features can be added via libs, but only /to an extent/ |
| 19:01 | devth | so not exactly the same as e.g. haskell extensions |
| 19:02 | sdegutis | similar, but haskell extensions have their own limitations too.. like, it's really hard to dynamically find and refer to functions in files in the local tree |
| 19:02 | sdegutis | *local file tree |
| 19:03 | sdegutis | no one language can be everything, because some things within everything contradict each other |
| 19:05 | devth | i wonder if contradictory lang features can solved by importing features where need, like scala has done |
| 19:06 | sdegutis | There would be conflicts in libraries. |
| 19:06 | devth | but the imported feature is local to files |
| 19:06 | sdegutis | It'd be a bigger mess than it already is. |
| 19:06 | sdegutis | Consider the C++ ecosystem |
| 19:06 | devth | import scala.language.higherKinds |
| 19:06 | devth | actually isn't that how haskell works too? |
| 19:07 | sdegutis | And what if one lib requires this feature to work, and another lib is incompatible with this feature, and you need both libs? |
| 19:07 | devth | the feature is only enabled for the local file |
| 19:14 | amalloy | that's what racket does |
| 19:21 | sdegutis | amalloy: weird |
| 19:35 | noncom|2 | hmm, now thinking of the clojure and jvm startup time. could somebody tell me, why can't we have the java vm running as a service, without a restart and just wipe its memory to "restart" without actually restarting? |
| 19:36 | wink | noncom|2: have you had a look at drip or nailgun? |
| 19:36 | noncom|2 | nope |
| 19:38 | wink | noncom|2: also, https://github.com/technomancy/leiningen/wiki/Faster |
| 19:38 | noncom|2 | okay, these are practical solutions, i am going to try them out |
| 19:39 | wink | not saying there are real solutions, but people have spent thinking and tinkering ;) |
| 19:39 | noncom|2 | but i wonder what is the explanation behind that JVM cannot be clean-wiped |
| 19:40 | noncom|2 | in readme of drip it says that cake is taking this approach and it gets jvm overwhelmed by errors over time |
| 19:42 | noncom|2 | also, drip is year old, does it fit today? |
| 19:42 | xeqi | some problems might be external resources like file handlers and sockets, and stopping background threads/threadpools |
| 19:54 | tom`` | I'm trying to set up nginx in front of ring. Netstat shows it listening on ":::8080" but when I proxy_pass nginx to "http://localhost:8080" it give a 502 error. |
| 19:54 | tom`` | curl to localhost:8080 says connection refused |
| 19:55 | tom`` | but curl to :::8080 works fine |
| 21:39 | sdegutis | noncom: Component allows that workflow you're talking about |
| 21:43 | bitraider | has anyone used Luminus for web development...any comparison to Compojure ?? |
| 22:07 | retrogradeorbit | hi |
| 22:08 | hlolli | Im in a let function and I want to find the max value of list/vector with (apply max) but I get java.lang.Long cannat be cast to IFn. I assume its because the list derives from various seqs, butall wont fix. Is there an alternative finding max value of say '(1 2 3 4) list? |
| 22:09 | hlolli | butall = but doall... yes bugs make my eyes blurry |
| 22:13 | retrogradeorbit | sure max has not been rebound as a number... a long? |
| 22:15 | hlolli | if I try to cast it as long or int I get; Expecting var, but Double is mapped to class java.lang.Double |
| 22:15 | hlolli | |
| 22:15 | hlolli | ok this one was double, same for all types |
| 22:15 | retrogradeorbit | what code are you running? (apply max '(1 2 3 4)) works fine for me |
| 22:16 | retrogradeorbit | croak.macros> (apply max (map double '(1 2 3 4))) |
| 22:16 | retrogradeorbit | 4.0 |
| 22:16 | retrogradeorbit | how do I get the clojure bot here to run code? |
| 22:17 | retrogradeorbit | ~4 |
| 22:17 | clojurebot | Titim gan éirí ort. |
| 22:17 | hlolli | (apply max (map val (doall (select-keys @t-ref-buffer (modulo-keywords (if (zero? (:no @t1-ref-buffer)) 3 (:no @t1-ref-buffer))))))) |
| 22:17 | hlolli | ,(prn "code running") |
| 22:17 | hlolli | it's crambled |
| 22:17 | retrogradeorbit | ,4 |
| 22:17 | clojurebot | "code running"\n |
| 22:17 | clojurebot | 4 |
| 22:18 | retrogradeorbit | ,(apply max (map double '(1 2 3 4))) |
| 22:18 | clojurebot | 4.0 |
| 22:19 | retrogradeorbit | whats val, and max? |
| 22:19 | retrogradeorbit | reduce is the same here as apply |
| 22:20 | retrogradeorbit | ,(reduce max '(1.0 2.0 3.0)) |
| 22:20 | clojurebot | 3.0 |
| 22:20 | hlolli | the val if I do prn it's (1 1 1) with mapv [1 1 1] very simple |
| 22:20 | retrogradeorbit | (1 1 1) is not callable |
| 22:21 | hlolli | it's just that this data structure is different [1 1 1] can be different from [1 1 1] |
| 22:21 | hlolli | yes |
| 22:21 | retrogradeorbit | how can you map (1 1 1) as a function |
| 22:22 | hlolli | but I still get Don't know how to create ISeq from: java.lang.Long |
| 22:23 | retrogradeorbit | thats dirrerent to what you firs posted |
| 22:23 | retrogradeorbit | java.lang.Long cannat be cast to IFn. |
| 22:24 | hlolli` | lost internet, so I lost if you said anything last 3 min |
| 22:24 | retrogradeorbit | < retrogradeorbit> thats dirrerent to what you firs posted |
| 22:24 | retrogradeorbit | < retrogradeorbit> java.lang.Long cannat be cast to IFn. |
| 22:25 | hlolli` | yes, right, was looking at the error from high speed of errors |
| 22:26 | hlolli` | later one is correct |
| 22:28 | retrogradeorbit | does select-keys always return a sequence? always? |
| 22:28 | hlolli` | I got this to work, really really weird solution |
| 22:28 | amalloy | i would hazard a guess and say never, retrogradeorbit |
| 22:29 | hlolli` | I just made new let argument do the apply max |
| 22:29 | hlolli` | really strange I think |
| 22:30 | retrogradeorbit | hey does anyone here have chops working with connection errors in http-kit client? |
| 22:30 | retrogradeorbit | it _returns_ the error exception, not raising it |
| 22:30 | retrogradeorbit | how do I get the details inside? |
| 22:30 | retrogradeorbit | https://www.refheap.com/109969 |
| 22:31 | retrogradeorbit | how would I get access to the cause? |
| 23:32 | justin_smith | retrogradeorbit: you can use .getStackTrace to see the stack (probably not helpful to you), if you want more information check the type, if you are lucky it will be exceptioninfo |
| 23:37 | justin_smith | retrogradeorbit: .getMessage might also be informative |
| 23:37 | sdegutis | hi jus |
| 23:38 | justin_smith | hello sd |
| 23:38 | sdegutis | hows it be |
| 23:39 | justin_smith | chill, keeping it real |
| 23:39 | sdegutis | w. |
| 23:40 | sdegutis | justin_smith: hey i found out about reddit btw |
| 23:40 | sdegutis | thats where i found this https://www.youtube.com/watch?v=IikaDKvC1as&feature=share have u reddit? |
| 23:41 | justin_smith | oh man, back when Ed McMahon did more than run sweepstakes scams. |
| 23:54 | sdegutis | ye that |