2016-02-21
| 09:59 | justin_smith | python476: you can use jstack to get the stack traces of all the running threads while its in that state (if you can find the pid that's using 100% pid, then 'jstack <PID>'), if you share that in a paste we can probably figure out what's going on |
| 10:06 | python476 | hi justi |
| 10:06 | python476 | n_smith |
| 10:06 | python476 | thanks (as usual), didn't know about jstack, gonna test |
| 10:11 | python476 | here it is http://lpaste.net/152994 |
| 10:12 | justin_smith | python476: I wonder what rewrite-clj is doing... |
| 10:13 | justin_smith | python476: as far as I can see from that stack trace, rewrite-clj is in the process of parsing / analyzing your code |
| 10:13 | python476 | lots of 'waiting' threads |
| 10:14 | justin_smith | and I guess maybe it's stuck in a loop, or doing some kind of intense calculation? |
| 10:14 | justin_smith | python476: right, you can pretty much disregard the ones that say "parking" |
| 10:14 | justin_smith | but notice the one starting at line 159 |
| 10:14 | python476 | note that I launched the lein repl and didn't do anything |
| 10:14 | justin_smith | I bet that is the one consuming your CPU |
| 10:15 | justin_smith | python476: yeah, cider invokes a bunch of stuff, including apperently the rewrite-clj process |
| 10:15 | python476 | yes that's the only busy stack |
| 10:15 | justin_smith | well you can be busy without being deep, but the two often go together :) |
| 10:16 | python476 | indeed, I expected the thin stacks beind idle-busy |
| 10:16 | python476 | not stacking-mad-busy |
| 10:16 | justin_smith | for example there's another runnable at refactornrepl220SNAPSHOT.org.httpkit.client.HttpClient.run(HttpClient.java:365) |
| 10:16 | justin_smith | (like 122) |
| 10:17 | justin_smith | short stack trace but could be consuming CPU |
| 10:17 | python476 | I thought FUTEX_WAIT indicated a socket issue for some reason |
| 10:18 | justin_smith | whre do you see futex? (other than the title of the paste) |
| 10:19 | python476 | htop / strace |
| 10:19 | python476 | the only 100% cpu java thread strace shows one line with FUTEX_WAIT |
| 10:22 | justin_smith | ahh OK it's an OS thing not a JVM thing http://man7.org/linux/man-pages/man2/futex.2.html |
| 10:23 | python476 | oh you thought it was a pure code + infinite loop ? |
| 10:23 | justin_smith | python476: is this in a vm? |
| 10:23 | python476 | yes |
| 10:23 | justin_smith | python476: https://nofluffjuststuff.com/blog/pratik_patel/2010/01/solution_futex_wait_hangs_java_on_linux__ubuntu_in_vmware_or_virtual_box |
| 10:24 | python476 | ah no, not VM, I meant JVM |
| 10:24 | justin_smith | known futex issue in vms? |
| 10:24 | justin_smith | oh, OK |
| 10:24 | python476 | unfortunate abbreviation |
| 10:24 | justin_smith | so yeah this probably has nothing to do with the futex thing, that's just a jvm implementation detail and the bug is not likely there |
| 10:25 | python476 | standalone `lein repl` doesn't exhibit the problem |
| 10:25 | python476 | so it's between emacs cider nrepl lein |
| 10:25 | python476 | and PEBCAK |
| 10:25 | python476 | probably PEBCAK |
| 10:25 | justin_smith | there's likely something pathological about refactor-nrepl with your specific project / codebase |
| 10:26 | justin_smith | refactor-nrepl is likely where the issue is, based on those stacks |
| 10:26 | python476 | ah, refactor is just above rewrite-clj |
| 10:26 | justin_smith | python476: this is a total shot in the dark but you could try running lein eastwood and changing things it warns about |
| 10:27 | justin_smith | - things that eastwood warns about are likely to be things that would trip up a project that auto-parses code like that |
| 10:27 | justin_smith | or maybe more like things that would trip up refactor nrepl are also things eastwood would warn about |
| 10:29 | python476 | but there's no trace of refactor-nrepl in that project |
| 10:30 | justin_smith | python476: cider pulls in refactor-nrepl |
| 10:31 | python476 | oh ok |
| 10:31 | python476 | cider is drunk |
| 10:32 | justin_smith | python476: cider is something people like because the devs prioritize features. It's also something people dislike because the devs prioritize features. |
| 10:33 | justin_smith | python476: by using cider you are (by default at least) pulling in all the features unless you opt out, and you're using a tool with a less than stellar stability history |
| 10:33 | python476 | you don't use it ? |
| 10:33 | justin_smith | python476: I got tired of all the things breaking, stopped using it. |
| 10:33 | python476 | I tried using inf-clojure-mode to avoid big dependencies |
| 10:34 | python476 | but I have to admit cider makes the UX very nice |
| 10:34 | justin_smith | python476: I think I have an unusual philosophy of UX, in that I prefer "things not breaking" as a higher priority than "having nifty features" |
| 10:34 | python476 | that was my goal too |
| 10:34 | justin_smith | but that's OK, we can each make those decisions for ourselves as users |
| 10:34 | python476 | but so far I need a middle ground |
| 10:35 | python476 | let's see what eastwood say |
| 10:35 | justin_smith | python476: as an interim there's also disabling the refactor-nrepl plugin, I bet there's a way to do that either globally or just for that project |
| 10:36 | python476 | surely, it seems cider often leaves control to the user |
| 10:38 | TimMc | justin_smith: That's why I'm on Debian stable. :-P |
| 10:38 | TimMc | actually, oldstable at the moment, need to do the upgrade |
| 10:38 | justin_smith | TimMc: kudos, that's a typical choice of mine as well, but my current box came with ubuntu pre-installed, so I am on an ubuntu LTS |
| 10:53 | python476 | btw, what's the meaning of WARNING!!! version ranges found for: [tikkba "0.5.0"] -> [org.clojure/clojure "[1.2.0,]"] |
| 10:54 | TimMc | python476: tikkba of that version declares a dependency on any version of clojure from 1.2.0 on up. |
| 10:54 | TimMc | That's a version range, and they're generally terrible. |
| 10:54 | python476 | oh so the warning is on the lib, not project.clj |
| 10:54 | TimMc | yeah |
| 10:55 | TimMc | If you depend on a version range, or against something else that does, it means your build can break randomly at some future point. THey're very annoying to debug, as well. That's why lein recommends excluding the transitive dependency and putting in your own explicit dependency if necessary, to pin it down. |
| 10:57 | python476 | aight |
| 10:57 | python476 | I'm trying cider-jack-in with an empty src folder.. |
| 10:58 | python476 | it does burn cpu but for one minute only |
| 11:18 | justin_smith | python476: if it does that even for an empty directory, that might be worth a bug report |
| 11:19 | python476 | maybe that's just ... slow machine leading to long init times |
| 11:19 | python476 | also maybe I didn't realize it was burning cpu for a minute because one minute doesnt make a laptop hot |
| 11:20 | python476 | but before coming here today it was running for 10+ minutes |
| 11:20 | python476 | I'll keep bisecting my project to avoid disturbing others more |
| 11:20 | python476 | where do you drop a bug report ? github issues ? a ML? |
| 11:21 | justin_smith | for most clojure projects a github issue would probably be best, I'd imagine refactor-nrepl would be one of those |
| 11:24 | python476 | aight, thanks |
| 11:39 | python476 | it's getting weirder and weirder. made a new lein project, copying just the deps, local repo and a fake main, now no more repl |
| 11:39 | python476 | unless ran twice |
| 11:40 | python476 | enough bug hunt, time to read some fogus book |
| 11:53 | python476 | cider, cider, cider |
| 12:30 | TimMc | Oh no, they said "cider" three times in a mirro! |
| 12:30 | TimMc | *mirror |
| 12:52 | justin_smith | one of the unknown hazards of using the codemirror editor |
| 13:33 | CStorm | what is the best way/lib to use when i want to fire a function every, say, hour? |
| 13:34 | luma | there's Quartzite http://clojurequartz.info/ |
| 13:35 | justin_smith | CStorm: it's not super hard to just use a java.util.concurrent.ScheduledThreadPoolExecutor directly, but there's also at-at as a nice wrapper |
| 13:36 | justin_smith | https://github.com/overtone/at-at |
| 13:37 | justin_smith | if you don't need a huge thing like quartzite that is |
| 13:46 | banana` | Hey guys, I have a quick question. I am trying to do an element wise or between two list. So if I have a L1 : '(false true) and L2 : '(true false) I want to do L1 or L2 and get '(true true) back since that would be element one from both L1 and L2 ored together and then element two from both ored together. Any ideas? |
| 13:46 | justin_smith | banana`: bitwise-or? |
| 13:46 | justin_smith | oh no, boolean or |
| 13:47 | banana` | Yes a boolean or |
| 13:47 | justin_smith | ,(map #(or % %2) [false true false] [true false false]) ; banana` |
| 13:47 | clojurebot | (true true false) |
| 13:47 | justin_smith | sadly you can't just map or, since it's a macro |
| 13:47 | banana` | Ya I tried that |
| 13:48 | banana` | I think mine didn't work since I did the same thing you did but used #(or %1 %2) |
| 13:48 | banana` | Any reason why you used % instead of %1? |
| 13:48 | justin_smith | ,(map #(or %1 %2) [false true false] [true false false]) ; banana` |
| 13:48 | clojurebot | (true true false) |
| 13:48 | justin_smith | banana`: no reason at all |
| 13:48 | CStorm | thank you justin_smith |
| 13:48 | justin_smith | I don't actually use %1 very often, maybe it's a bad habit |
| 13:48 | TMA | banana`: it is one character shorte |
| 13:48 | justin_smith | haha |
| 13:49 | justin_smith | TimMc: by that logic you could replace identity with #(do %) |
| 13:49 | justin_smith | err |
| 13:49 | justin_smith | TMA: ^ - sorry of the misstag |
| 13:49 | banana` | Okay thanks! Turns out I was using apply or reduce when I tried using a macro for or |
| 13:50 | justin_smith | banana`: oh yeah, you don't need that, map handles multiple args just fine |
| 13:50 | justin_smith | banana`: but also there's for |
| 13:50 | TMA | ,do |
| 13:50 | clojurebot | #error {\n :cause "Unable to resolve symbol: do in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: do in this context"... |
| 13:50 | justin_smith | ,(#(do %) 1) |
| 13:50 | clojurebot | 1 |
| 13:50 | TMA | ,(do 1) |
| 13:50 | clojurebot | 1 |
| 13:50 | ridcully | ,(source do) |
| 13:50 | clojurebot | Source not found\n |
| 13:50 | banana` | Okay cool thanks for the help justin_smith |
| 13:51 | TMA | ,(map do [foo 1 2 3 true]) |
| 13:51 | clojurebot | #error {\n :cause "Unable to resolve symbol: do in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: do in this context"... |
| 13:51 | TMA | ,(map #(do %) [foo 1 2 3 true]) |
| 13:51 | clojurebot | #error {\n :cause "Unable to resolve symbol: foo in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: foo in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: foo in this conte... |
| 13:51 | TMA | ,(map #(do %) ['foo 1 2 3 true]) |
| 13:51 | clojurebot | (foo 1 2 3 true) |
| 13:51 | justin_smith | TMA: please don't use #(do %) instead of identity, it is equivalent but it is terrible :P |
| 13:51 | justin_smith | just saying less chars isn't strictly always better |
| 13:52 | TMA | justin_smith: I won't. |
| 13:53 | TMA | too bad do is a macro too |
| 13:53 | justin_smith | haha |
| 14:20 | pilne | so, i'm just getting around to watching the 2013 keynote by paul phillips about just how much is wrong with the compiler side of scala LMAO |
| 14:20 | pilne | god that's scary |
| 14:20 | justin_smith | oh, that's a good talk, but it's about a sad thing |
| 14:21 | pilne | 4.2billion states for int testing??? |
| 14:21 | pilne | yeah, it is sad, but lord, is that what building a language to run on the jvm entails? |
| 14:24 | CStorm | do you have a link? |
| 14:24 | pilne | https://www.youtube.com/watch?v=TS1lpKBMkgg |
| 14:25 | justin_smith | pilne: no, not at all. They had some design goals that were a poor fit for the vm. |
| 14:25 | pilne | so ambition lead to... dirty magiks that are having a ripple effect now? |
| 14:28 | justin_smith | pilne: that was my impression. |
| 14:29 | pilne | so TLDR: if you are using something else as a host, conform to it's limitations if you can't achieve what you want sanely? |
| 14:40 | justin_smith | pilne: right, but the hard part is truly understanding the limitations, I think |
| 14:45 | pilne | true... until you hit them, they aren't really waving their hands by a bonfire... |
| 17:21 | bitsynthesis | hello! when writing a plugin which supports multiple versions of clojure, how should the clojure dependency be defined? i gather that leiningen supports version ranges but recommends / warns against using them. is there an alternative? |
| 17:22 | rhg135 | depend on the earliest you have tested against and document it is what I'd do |
| 17:23 | bitsynthesis | that will always pull in that specific version of clojure if the project uses a different one |
| 17:24 | bitsynthesis | so if you're going to specify a version you may as well specify the newest version of clojure it supports, right? since it's going to pull down what it wants regardless |
| 17:24 | rhg135 | will it? I guess you can also do that |
| 17:25 | bitsynthesis | ideally i would like it to use whatever version the project already specifies, if supported |
| 17:25 | rhg135 | you can always use exclusions |
| 17:26 | rhg135 | I always thought lein used any explicit deps over those required by dependencies |
| 17:27 | TimMc | If you depend on the earliest version that works for you, you give more flexibility to people who depend on your lib. |
| 17:27 | rhg135 | oh, plugin you said |
| 17:27 | rhg135 | It'll use lein's version which is 1.8 right now iirc |
| 17:27 | TimMc | oops, didn't see that |
| 17:29 | bitsynthesis | if you specify clojure 1.6 it will use that, not lein's version or the project's version |
| 17:29 | rhg135 | wouldn't that break lein though? |
| 17:32 | TimMc | "Plugins need not declare a dependency on Clojure itself; in fact all of Leiningen's own dependencies will be available." |
| 17:32 | TimMc | https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 17:32 | rhg135 | that's what I was thinking |
| 17:33 | bitsynthesis | TimMc: aha. ok thanks guys. so maybe it is just downloading the version because it's specified, but not using it |
| 17:33 | rhg135 | you can always check at runtime |
| 17:33 | rhg135 | ,*clojure-version* |
| 17:33 | clojurebot | {:major 1, :minor 8, :incremental 0, :qualifier nil} |
| 17:57 | rhg135 | it's so quiet these days |
| 17:57 | rhg135 | ~slack |
| 17:57 | clojurebot | Cool story bro. |
| 17:57 | rhg135 | hmm |
| 18:10 | ridcully | rhg135: younger generation is taking over the web |
| 18:12 | rhg135 | ridcully: not sure if I'd say 'younger' but that is certainly possible |
| 18:15 | ridcully | or maybe its just sunday and this channel is most active on eu/us working hours |
| 18:15 | rhg135 | that sounds very likely |
| 18:16 | ridcully | or the justin_smith wake hours?! |
| 18:16 | rhg135 | I heard a rumor that he does not sleep lol |
| 18:17 | rhg135 | he only clojures |
| 18:30 | CStorm | i setup a profiles.clj with some env vars: {:dev {:env {:secret "secret"}}} – i can get them just fine in my code when i run lein ring server. but after a uberjar i guess its not in "dev" anymore. Where should i add them then? |
| 18:32 | rhg135 | usually you run on a different environment so I think usually you set it in the environment |
| 18:33 | CStorm | but if i just want to use the same secret i use in dev? |
| 18:34 | rhg135 | lein doesn't usually exist in production, I'm not sure how'd you do that |
| 18:35 | CStorm | i am running my project with java -jar file.jar |
| 18:36 | CStorm | so im not using lein. |
| 18:36 | CStorm | its just that im unsure where to put my prod enviroment variables :) |
| 18:36 | rhg135 | exactly so it won't use anything from profiles.clj |
| 18:37 | rhg135 | you set them in the environment, but I'm unsure how to reuse the dev key |
| 18:38 | rhg135 | as in env SECRET="secret" java -jar file.jar |
| 18:38 | CStorm | Ok |
| 18:38 | CStorm | Will look that up. |
| 18:38 | CStorm | Ty. |
| 18:38 | rhg135 | np |
| 18:47 | newclj | Hey, where do I put my java interface if I want to implement it in clojure? I have it in :gen-class :implements <interface>, but I'm assuming I have to put the .java file somewhere in my clojure proj? |
| 18:51 | rhg135 | it has to be a .class on the classpath |
| 18:52 | rhg135 | in lein :jvm-opts is a vector of a java source tree which will be compiled before launching the repl |
| 18:53 | newclj | @rhg135 Thanks, I'll have a look into it |
| 18:53 | rhg135 | clojure in general is great at interop |
| 19:02 | newclj | so I added a :java-source-paths [<path to .javas>] in my defproject and it seems to pick up the interface in IntelliJ, but I still get a class not found exception when running lein uberjar? |
| 19:03 | rhg135 | yes, sorry :java-source-paths. my brain is jumbled today |
| 19:04 | rhg135 | what is the contents of that dir? |
| 19:05 | newclj | a java interface and 3 .java files the interface depends on |
| 19:06 | rhg135 | in subfolders? remember java also requires a certain structure and corrent naming |
| 19:07 | newclj | hm no, just on all together in the one dir |
| 19:09 | rhg135 | for instance: com/rhg135/Test.java containing package com.rhg135; interface Test { public Object doStuff(); } |
| 19:09 | newclj | all the files are within the same package in java |
| 19:11 | rhg135 | but I'm not sure as I don't do java in my lein projects |
| 19:11 | rhg135 | or at all manually |
| 19:15 | newclj | rhg135: Fair enough, it's definitely picked up in IntelliJ now though :) so thanks for the progress |
| 19:15 | rhg135 | np |
| 19:25 | newclj | rhg135: Just had to specifiy package name in my :implements, working perfectly now :D thanks agian |
| 20:12 | rhg135 | ah ok. glad it worked |
| 20:34 | oich | is clojuresque the only clojure gradle plugin or clojure using gradle approach? |
| 20:38 | edannenbe | oich, unless gradle is a requirement, did you try boot yet? it's pretty much the gradle of clojure |
| 20:39 | bendavisnc | say hey guys, is there any way to have something similar to a javascript object in clojure, by that, i mean some hash map with an idea of "this" |
| 20:40 | justin_smith | bendavisnc: for "this" to be useful you need methods |
| 20:40 | justin_smith | bendavisnc: perhaps you want defrecord |
| 20:41 | bendavisnc | ok yeah probably |
| 20:41 | bendavisnc | all i want is some namespace to define values and methods and maybe / probably abstract methods / values as well |
| 20:41 | justin_smith | defrecord can implement methods from interfaces or protocols, and each one gets a "this" arg |
| 20:42 | justin_smith | bendavisnc: wait, namespace? |
| 20:42 | bendavisnc | are things like that completely discouraged in lisp land? |
| 20:42 | bendavisnc | yeah, like just a scope level of values |
| 20:42 | justin_smith | bendavisnc: I mean we have defrecord but we also have namespaces and their usages don't overlap |
| 20:43 | oich | edannenbe I have barely looked at boot so far. I've gotten further with leiningen. But, yes the project needs to be able to be used by people other than me and so, not boot or leinengen |
| 20:43 | bendavisnc | eh ok. i think i'm just using the word more liberally |
| 20:43 | justin_smith | namespaces are first class though, if that's what you actually want |
| 20:44 | sineer | Hi! I use core.async thread to fill up a channel and a go block to empty it. How do I wait for the thread to finish and channel to empty before main exit? |
| 20:44 | bendavisnc | ok. i think i need to rethink what i'm doing. maybe i don't need this |
| 20:45 | sineer | I've been trying to find good examples but did not find any, probably just not looking for the right thing |
| 20:45 | justin_smith | sineer: core.async/thread returns a channel, if you try to read that channel you won't get a value until the thread exits |
| 20:45 | sineer | justin_smith: ok, thanks! |
| 20:45 | justin_smith | so if your primary thread reads from that channel, that primary thread won't exit until the thread does (of course) |
| 20:46 | sineer | what about the go blocks? I doseq lots of them to empty the channel.. |
| 20:46 | justin_smith | they also each return a channel |
| 20:47 | sineer | oh yeah and now I don't doseq lots of them anymore just one go block and doseq is in my thread.. neat, thanks again! |
| 20:51 | bendavisnc | would it be a bad idea / is it possible to have a hashmap as like a base template, and have a hashmap value be lazy but a throw exception if accessed without merging first? |
| 20:52 | bendavisnc | does that make sense? |
| 20:52 | justin_smith | there are no lazy hashmaps |
| 20:52 | bendavisnc | ok but are there lazy hash map values? |
| 20:52 | justin_smith | the only thing that is lazy is a lazy-seq |
| 20:53 | bendavisnc | like a key has an expression that's not evaluated until accessed? |
| 20:53 | rhg135 | justin_smith: does not datomic do it for entities? |
| 20:53 | justin_smith | no, that does not exist |
| 20:53 | bendavisnc | value* |
| 20:53 | justin_smith | rhg135: OK, there are no lazy hash-maps in clojure.core |
| 20:54 | bendavisnc | i think i may be able to use delay for what i'm thinking |
| 20:54 | rhg135 | delay is a good compromise |
| 20:55 | rhg135 | I once thought of writing a facade over maps with delayed keys |
| 20:55 | justin_smith | bendavisnc: what does "hash map as like a base template" mean? |
| 20:56 | bendavisnc | like i'm basically trying to make an abstract class |
| 20:56 | bendavisnc | which maybe just isn't clojureish at all |
| 20:56 | justin_smith | bendavisnc: just use a hash map. They are immutable, so your function can just assoc something to it. |
| 20:56 | bendavisnc | but i want something with base values that gets extended |
| 20:57 | justin_smith | bendavisnc: that's what assoc does |
| 20:57 | justin_smith | bendavisnc: the map is immutable, assoc returns a new one with your associations performed |
| 20:57 | justin_smith | so you don't need a special template, you just need a hash map, and assoc |
| 20:57 | bendavisnc | ok but how do i say, like, this value will be in this map. or an extension of this map? |
| 20:58 | justin_smith | what is an extension? |
| 20:58 | bendavisnc | a merge call i think |
| 20:58 | rhg135 | schema, yo |
| 20:58 | bendavisnc | yeah probably |
| 20:58 | bendavisnc | base template = schema = abstract class |
| 20:58 | justin_smith | yeah, sounds like you want prismaticschema, this is not a thing in the language itself |
| 20:58 | justin_smith | bendavisnc: no he is talking about a specific library called schema |
| 20:59 | bendavisnc | ah ok thanks for the heads up |
| 20:59 | justin_smith | bendavisnc: abstract classes are abstract classes, this is the jvm so we have them too but they are not useful |
| 20:59 | rhg135 | well, asserts exist |
| 20:59 | rhg135 | ,(assert (string? (:x {}))) |
| 20:59 | clojurebot | #error {\n :cause "Assert failed: (string? (:x {}))"\n :via\n [{:type java.lang.AssertionError\n :message "Assert failed: (string? (:x {}))"\n :at [sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]}]\n :trace\n [[sandbox$eval25 invokeStatic "NO_SOURCE_FILE" 0]\n [sandbox$eval25 invoke "NO_SOURCE_FILE" -1]\n [clojure.lang.Compiler eval "Compiler.java" 6927]\n [clojure.lang.Compiler eval "Compi... |
| 20:59 | bendavisnc | right ok |
| 20:59 | justin_smith | rhg135: asserts are a supertype of type asserts |
| 20:59 | bendavisnc | i'm super new to thinking in functional terms |
| 20:59 | justin_smith | *superset |
| 20:59 | bendavisnc | let me ask this though: |
| 21:00 | rhg135 | ah right! |
| 21:00 | bendavisnc | say i have a situation, where basically i'm calling / mapping all of these functions |
| 21:00 | bendavisnc | and in all of these functions, i'm always passing the same variable as like an extra parameter that basically represents a context of information |
| 21:01 | bendavisnc | like the program is always the same, but these are our global variables |
| 21:01 | rhg135 | partial, yo |
| 21:01 | bendavisnc | hmmmm |
| 21:01 | justin_smith | bendavisnc: again with the wording, vars (the things created with def) are all globally accessible but in namespace scope |
| 21:02 | justin_smith | but yes, if you want to provide some extra data in function calls partial is very helpful |
| 21:02 | justin_smith | if it's like a boilerplate everything gets this arg thing in particular |
| 21:02 | rhg135 | (def contextify (partial partial)) |
| 21:03 | justin_smith | bendavisnc: and yes, an argument passed to every function you call is equal in power computationally to a global |
| 21:03 | justin_smith | rhg135: lol |
| 21:03 | bendavisnc | justin_smith: i get that, but what i was wondering was a. is it frowned upon? b. is there a pretty straight forward default approach to an alternative? |
| 21:04 | rhg135 | ,(((partial partial) + 1) 2 3) |
| 21:04 | clojurebot | 6 |
| 21:04 | justin_smith | bendavisnc: haskell has monads for this :) |
| 21:04 | justin_smith | you can get monads from a lib but they are weird and don't perform well and are not part of the core language |
| 21:04 | bendavisnc | justin_smith: omg, i've been trying so hard to learn that word in scala land |
| 21:05 | rhg135 | monads are great just not when you need them |
| 21:05 | bendavisnc | what i'm doing is, i basically have this program that renders an image, and i have render parameters |
| 21:05 | bendavisnc | stuff like width height etc |
| 21:06 | bendavisnc | i have files that could be like json files |
| 21:06 | bendavisnc | render parameter files |
| 21:06 | bendavisnc | and i'm just trying to figure out what to do with these files / how to incorporate the data |
| 21:07 | bendavisnc | so basically i have these hashmaps |
| 21:07 | bendavisnc | that should be an interface in java / scala land |
| 21:07 | justin_smith | interfaces do not contain data though |
| 21:07 | justin_smith | they describe methods you can call |
| 21:07 | bendavisnc | but the data fits a common interface |
| 21:07 | bendavisnc | there's always a width, etc |
| 21:08 | justin_smith | interfaces are for executable methods not data |
| 21:08 | bendavisnc | dude that's just wrong |
| 21:08 | rhg135 | a protocol can be backed by a map |
| 21:08 | bendavisnc | an interface of course can define a value |
| 21:08 | justin_smith | bendavisnc: this is the jvm, "interfaces" are a specific thing that describe methods not fields |
| 21:08 | bendavisnc | in java i guess it's a little weird, and it's actually a hard coded getter |
| 21:08 | bendavisnc | but in scala it's straight forward with traits |
| 21:09 | bendavisnc | so i guess yeah java would have to be an abstract class |
| 21:09 | bendavisnc | sorry i shouldn't say interface |
| 21:10 | rhg135 | ,(do (defprotocol A (get-a [me])) (extend-protocol A clojure.lang.PersistentMap (get-a [me] (:a me))) (get-a {:a 1})) |
| 21:10 | clojurebot | #error {\n :cause "clojure.lang.PersistentMap"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.ClassNotFoundException: clojure.lang.PersistentMap, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.ClassNotFoundException\n :message "clojure.lang.PersistentMap"\n :at [java.net.URLClassLoader$1 run "U... |
| 21:10 | justin_smith | bendavisnc: anyway, in clojure world the best thing that does the things you describe is prismatic/schema |
| 21:11 | bendavisnc | ok so yeah actually maybe this helps pin point what i wanna do? |
| 21:11 | bendavisnc | in java, this would be an interface |
| 21:11 | bendavisnc | could be* |
| 21:11 | rhg135 | that's a lot of wrapping around a map |
| 21:11 | justin_smith | prismatic/schema describes layout of immutable data |
| 21:11 | bendavisnc | and the method promise would be like public int getWidth() |
| 21:11 | justin_smith | an interface or protocol in clojure describes methods you can execute |
| 21:12 | justin_smith | what is a method promise? |
| 21:12 | bendavisnc | a signature declaration |
| 21:13 | justin_smith | bendavisnc: when you have immutable data, getters are just annoying boilerplate |
| 21:13 | justin_smith | if you need data use data, if you need methods use methods, and if you really really want to be mutable yeah use deftype or something and use getters and private things and yadda yadda |
| 21:14 | justin_smith | but the premise in clojure is we almost never need mutation, and when we do we just use a simple mutable box that only holds one value |
| 21:14 | justin_smith | (unless we need to do otherwise for compatibility reasons) |
| 21:14 | bendavisnc | justin_smith: i'm not talking mutation |
| 21:15 | justin_smith | bendavisnc: why the hell do you want getters then? |
| 21:15 | justin_smith | my point is forget about getters and interfaces, make a data declaration with prismatic/schema and just use that data |
| 21:16 | rhg135 | in java they usually used to hide the actual structure of the data, justin_smith |
| 21:16 | justin_smith | and most of the time you only need prismatic schema at system boundaries where very different systems try to interact within one program |
| 21:16 | bendavisnc | so i want to define methods that works on data |
| 21:16 | bendavisnc | immutable data |
| 21:16 | justin_smith | rhg135: I know this is usual, it's also not how we do things in clojure |
| 21:16 | justin_smith | bendavisnc: OK, define methods in a protocol |
| 21:16 | justin_smith | or just make functions instead or use methods later when you realize you actually need that (usually you do not) |
| 21:17 | rhg135 | I mean, mutability and encapsulation are complected into getters |
| 21:17 | bendavisnc | rhg135: sorry, are what into getters? |
| 21:17 | justin_smith | bendavisnc: complected means "made complicated" by joining |
| 21:17 | rhg135 | in to rather |
| 21:18 | justin_smith | bendavisnc: complecting is the opposite of that thing where you separate things that have nothing to do with each other and suddenly everything is simpler (aka simplification) |
| 21:18 | rhg135 | but yes the idea to use a function is the approach I'd take |
| 21:19 | justin_smith | rhg135: I'd assert that mutation makes getters neccessary though, so it's not neccessarily a complex |
| 21:19 | bendavisnc | thanks a ton guys for bearing with me |
| 21:19 | rhg135 | that way you only have to change it if you change the structure |
| 21:19 | bendavisnc | idk, scala made me think differently about the division between function and value |
| 21:19 | justin_smith | np, hope I don't seem impatient or overly vehement here, I get absurdly excited about these issues :) |
| 21:20 | justin_smith | scala does lots and lots of complecting |
| 21:20 | rhg135 | justin_smith: only in some cases. Most getters I've seen just do `return this.x` |
| 21:20 | bendavisnc | it made me want to program more in a way where i'm talking about values that don't exist yet |
| 21:21 | justin_smith | lazy-seqs, promises, and delays make some of this possible, but not in the haskell "everything is lazy" way of course |
| 21:21 | bendavisnc | i sorta wish i knew how to write this code in clojure |
| 21:22 | bendavisnc | def getWidth(): Int = {throw new Exception(getWidth not overriden)} |
| 21:22 | bendavisnc | i thought a delay does that but now i don't |
| 21:22 | mgaare | bendavisnc: you can't just "flatmap that shit" |
| 21:22 | rhg135 | ,(do (def data {:a (delay 1)}) (defn get-a [m] @(:a m)) (get-a data)) |
| 21:22 | clojurebot | 1 |
| 21:22 | mgaare | bendavisnc: Clojure takes a stand against concrete derivation, which it sounds like you're trying to do |
| 21:23 | bendavisnc | mgaare: i don't know what you mean by can't flatmap, but i wish i did |
| 21:24 | mgaare | bendavisnc: sorry, just little scala joke. |
| 21:24 | bendavisnc | mgaare: ah ok |
| 21:24 | bendavisnc | man i like so much about both languages |
| 21:24 | mgaare | I briefly worked at a Scala place, and some coworkers suggested that should be the official motto of the language |
| 21:24 | bendavisnc | i was sorta hoping i could treat clojure like a dynamic clojure where i could type class only when i wanted |
| 21:25 | bendavisnc | maybe that's dumb |
| 21:25 | justin_smith | clojure is a dynamic clojure, so that's a start |
| 21:25 | justin_smith | but we don't mess with types much (for better and also for worse) |
| 21:25 | bendavisnc | haha sorry, treat clojure like a dynamic scala |
| 21:26 | rhg135 | I take the python approach were a class is just a bunch of obfuscated data |
| 21:26 | justin_smith | if you want strong typing and compile time proofs as your top priority, you probably want scala not clojure |
| 21:26 | mgaare | bendavisnc: there are a few tricks you can do here. so you have your `width` function, and you're saying you don't want that to work unless some specific type is implementing it, right? |
| 21:26 | rhg135 | and on the jvm classes are mostly immutable |
| 21:26 | rhg135 | objects though... |
| 21:26 | bendavisnc | mgaare: you understand my sould |
| 21:26 | bendavisnc | soul* |
| 21:27 | mgaare | bendavisnc: so you could define a protocol, say, like this: (defprotocol Dimensions (width [this]) (height [this])) |
| 21:28 | mgaare | so if you try to call that width function on something that doesn't implement it, you'll get an exception already. |
| 21:28 | mgaare | But perhaps you want a more specific exception? Or what? |
| 21:29 | bendavisnc | mgaare: ok yeah that is what i want |
| 21:29 | bendavisnc | thanks for getting that, i don't need a compile time exception really |
| 21:29 | bendavisnc | i basically just don't want to define a value |
| 21:29 | rhg135 | mgaare: technically, if you used straight maps you'd still get an exception anyway, but it'd probably be a NPE then |
| 21:29 | bendavisnc | at a time a define it |
| 21:29 | bendavisnc | say |
| 21:29 | bendavisnc | (def width 0) |
| 21:30 | bendavisnc | and worry that my width is ever zero |
| 21:30 | bendavisnc | i should say that's not my only intention |
| 21:30 | bendavisnc | i also just want to express that there's a scope of execution with a width value |
| 21:30 | mgaare | where you're kind of going off the rails of idiomatic Clojure a bit is thinking about it in terms of some kind of abstract class that you'll subclass for implementations of this. |
| 21:31 | bendavisnc | ok yeah |
| 21:31 | bendavisnc | thanks |
| 21:31 | rhg135 | {:pre [(not (zero? n))]} |
| 21:31 | justin_smith | bendavisnc: def only creates vars, which are global mutable values inside a namespaced global scope, and our data is immutable, you can't have invalid partial state in an immutable data structure |
| 21:32 | bendavisnc | ok |
| 21:32 | bendavisnc | yeah |
| 21:32 | bendavisnc | i'm sorta a scala guy |
| 21:32 | justin_smith | bendavisnc: immutability is our cure for partial state (you might want runtime checks for other sources of invalid state of course) |
| 21:32 | bendavisnc | but i'm also just sorta a javascript guy |
| 21:33 | bendavisnc | i want something that in jquery land i would merge |
| 21:33 | bendavisnc | and then i could call a function inside it, which would have access to everything inside the called object |
| 21:33 | justin_smith | bendavisnc: "inside it" |
| 21:33 | bendavisnc | and theoretically, you could call this existing method on a template that hasn't been extended or provided values, so the method should tell you it failed |
| 21:34 | mgaare | bendavisnc: good old javascript emulated modules |
| 21:34 | bendavisnc | and that method can be getWidth for example |
| 21:34 | bendavisnc | and i guess that's just bad clojure code? |
| 21:34 | mgaare | So this way of thinking about Javascript's object model is a good fit for Clojure in some ways and a bad fit in others. |
| 21:35 | bendavisnc | i wanna write something close to |
| 21:35 | bendavisnc | myCrazyArtThing.withWidth(100).render() |
| 21:35 | justin_smith | bendavisnc: I think you will find that compared to what you are used to, clojure is not a flexible language for programming styles. But the "one true way" clojure strongly encourages with its design does actually work out pretty well. |
| 21:35 | justin_smith | bendavisnc: (render (assoc crazy-ar-thing :width 100)) |
| 21:36 | rhg135 | ,(do (defn call [m k & args] (apply (get m k) m args)) (call {})) |
| 21:36 | clojurebot | #error {\n :cause "Wrong number of args (1) passed to: sandbox/call"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (1) passed to: sandbox/call"\n :at [clojure.lang.AFn throwArity "AFn.java" 429]}]\n :trace\n [[clojure.lang.AFn throwArity "AFn.java" 429]\n [clojure.lang.RestFn invoke "RestFn.java" 412]\n [sandbox$eval26 invokeStatic "NO_SOURCE_FILE" 0]\n [sand... |
| 21:36 | rhg135 | eh, something like that would work |
| 21:36 | mgaare | Clojure's object model is really nothing like this, so thinking about templates and prototypes isn't helpful. However, Clojure records give you a lot of what you want, in that when you implement a protocol in a record, all the fields of the record are available in the scope of the function |
| 21:37 | rhg135 | the point is the passing in of the this is explicit |
| 21:37 | bendavisnc | justin_smith: that's a really interesting thing to say |
| 21:37 | amalloy | defining a protocol and a record just for scoping reasons should make you pretty sad |
| 21:37 | bendavisnc | so when ppl say clojure is flexible, they sorta need to be careful what they mean |
| 21:37 | bendavisnc | it sounds like anyways |
| 21:38 | justin_smith | bendavisnc: for example at every turn clojure makes concrete extension (inheritence) arbitrarily difficult to do. Because the language designers think it's a bad idea to use it. |
| 21:38 | justin_smith | bendavisnc: yeah, I would never call clojure flexible |
| 21:38 | rhg135 | clojure is very flexible, but flexibility has a cost |
| 21:38 | justin_smith | hmm... |
| 21:38 | rhg135 | usually it's a lot of buggy code to write |
| 21:39 | mgaare | bendavisnc: it's not flexible in the sense that javascript is flexible, which is where you can write in almost any kind of style you want but then someone writes a book called "Javascript: The Good Parts" and it's 50 pages long |
| 21:39 | bendavisnc | hahaha yeah i see what you guys are saying sorta |
| 21:39 | bendavisnc | is it a similar style philosophy to python? |
| 21:40 | mgaare | I think so, yes |
| 21:40 | bendavisnc | like i sorta feel like clojure / python are the right wingers of the programming language world |
| 21:40 | rhg135 | actually python's methods are implemented by essentially partialling the instance when you access them via an instance |
| 21:40 | justin_smith | there's a few languages I would count as opinionated, including python yeah and also ml and C even |
| 21:41 | mgaare | rhg135: I think he meant python and clojure are similar in the sense that both of them have strong opinions about the correct way to write code in the language |
| 21:41 | justin_smith | bendavisnc: if you are looking for a flexible, relatively unopinionated lang, once again scala's probably your guy (but I'm here because I agree with clojure's opinions generally) |
| 21:41 | rhg135 | yeah, I'm just pointing out objects are essentially a map with partial functions |
| 21:42 | amalloy | "partial functions" means something specific and quite different from partially-applied functions |
| 21:42 | bendavisnc | yeah |
| 21:42 | bendavisnc | i've been thinking a lot about this lately |
| 21:42 | rhg135 | yeah I meant partially applied |
| 21:43 | bendavisnc | i love lisps "data is code" mantra |
| 21:43 | rhg135 | lexicon failure |
| 21:43 | bendavisnc | and i was thinking about what type of language would be if you could extend json |
| 21:43 | bendavisnc | and im thinking that's basically, lisp, right? |
| 21:43 | justin_smith | lisp with some extra data types sure |
| 21:44 | justin_smith | clojure is that plus default immutability in many ways |
| 21:44 | bendavisnc | but yeah, i'm just saying it's a 1000 x closer that lisp's schema than to scalas |
| 21:44 | rhg135 | isn't that what xml was plus a bunch of cruft? |
| 21:44 | bendavisnc | and then another few magnitudes of lines, i guess we get to java |
| 21:45 | bendavisnc | i mean an executable json |
| 21:45 | bendavisnc | a self referential json |
| 21:45 | justin_smith | java doesn't have the data literals though |
| 21:45 | justin_smith | and doesn't do self reference nicely at all |
| 21:45 | justin_smith | (in my experience) |
| 21:45 | bendavisnc | like if i could write this code: |
| 21:46 | bendavisnc | {crazyArtProject: {width: 0, height: 0, size: this.width * this.height}} |
| 21:46 | bendavisnc | which yeah... i guess that's literally javascript |
| 21:47 | rhg135 | {"function": "add", "args": [1 2 3]} |
| 21:47 | rhg135 | indeed, json requires string keys too |
| 21:47 | bendavisnc | idk. javascript doesn't seem data first but i hoenstly don't know how to articulate that |
| 21:48 | bendavisnc | maybe i'm looking for an eager evaluation javascript |
| 21:48 | rhg135 | js is eager... |
| 21:50 | bendavisnc | shit sorry |
| 21:50 | bendavisnc | i was thinking how in js |
| 21:50 | bendavisnc | [1, 2, 3] is sorta equal to '(1 2 3) |
| 21:51 | justin_smith | ,(= [1 2 3] '(1 2 3)) |
| 21:51 | clojurebot | true |
| 21:51 | bendavisnc | that's weird |
| 21:51 | bendavisnc | or not |
| 21:51 | justin_smith | bendavisnc: structural equality |
| 21:51 | bendavisnc | sorry i'm use to java |
| 21:51 | rhg135 | not really |
| 21:52 | justin_smith | bendavisnc: if two values are immutable, and have the same effective shape, clojure typically considers them equal |
| 21:52 | rhg135 | if you use the seq interface '(1) is as good as [1] |
| 21:52 | bendavisnc | gotcha. yeah i like that |
| 21:52 | bendavisnc | so you literally never have situations of something like toList? |
| 21:53 | rhg135 | list* is sometimes used |
| 21:53 | amalloy | list* is not like toList at all |
| 21:53 | amalloy | seq kinda is |
| 21:54 | rhg135 | well I don't know scala so I only guess |
| 21:54 | rhg135 | into maybe |
| 22:03 | bendavisnc | thanks again guys for your time and insights |
| 22:03 | bendavisnc | night |
| 22:38 | solatis | ok, so, in clojure idiomatic code, what does one do when someone calls a 'find' operator which has no result? return nil? |
| 22:39 | amalloy | ,(find {} {}) |
| 22:39 | clojurebot | nil |
| 22:39 | amalloy | good thing to take inspiration from |
| 22:39 | solatis | ah that's great |
| 22:42 | TEttinger | hm, any Cursive experts around? I'm having an odd issue where at the command line lein can see deps just fine, but in IntelliJ with Cursive, none of the deps seem to be on the classpath and aren't even visible. |
| 22:43 | TEttinger | so no suggestions for deps, errors on anything defined in a def... |
| 22:43 | TEttinger | *dep |
| 22:43 | TEttinger | howdy cfleming :) |
| 22:46 | TEttinger | I've tried re-synchronizing the project.clj, I don't see any analogue to `lein deps` |
| 22:47 | TEttinger | on intellij 15.0.2 if it matters |
| 22:49 | TEttinger | appears to be cursive 1.1.0-15 |
| 22:49 | amalloy | TEttinger: try invalidating caches and restarting |
| 22:49 | TEttinger | will do |
| 22:49 | amalloy | that's often fixed intellij issues for me |
| 22:52 | TEttinger | nope, initially it opened up and there was no context on -main , like it was plain text. I closed core.clj with that in it, reopened, and highlighting came back saying dep can't be found, etc. |
| 22:52 | solatis | is there any way to force lein to re-download a specific directory when i know for sure that, even though the version is the same, the .jar has been modified? |
| 22:52 | solatis | this is about a 'internal-lib-0.1.0-SNAPSHOT'-style library |
| 22:52 | solatis | it's hosted in a private s3 repo |
| 22:52 | TEttinger | there's some flag to pass to lein deps, I think it miiiight be -U |
| 22:52 | TEttinger | I'd check the lein docs |
| 22:53 | solatis | yeah but that doesn't seem to work :/ |
| 22:53 | TEttinger | there's also the deleting-the-directory-in-.m2 approach |
| 22:54 | solatis | yeah, that second one is the one i didn't want to use |
| 22:54 | solatis | well, sucks, guess i have to do the delete-.m2 approach anyway |
| 22:55 | TEttinger | not the whole thing though |
| 22:55 | solatis | yeah i know |
| 22:55 | TEttinger | you can just delete the directory that's old oh ok |
| 22:55 | solatis | the thing is, i want to set up an agile environment where every dev always has the most up-to-date checkout of this private library |
| 22:55 | TEttinger | ha, that's exactly what I'm trying to do using jitpack.io |
| 22:56 | TEttinger | but that's more for public libs |
| 22:56 | solatis | so i am now using our continuous deploy strategy to continuously deploy to S3 |
| 22:56 | solatis | and have our devs use that as a dependency |
| 22:56 | solatis | which works great, until you update it with the same version number... |
| 22:56 | solatis | so guess we should stop doing that |
| 22:57 | TEttinger | hm, I know maven treats SNAPSHOT versions differently |
| 22:57 | solatis | hmm |
| 22:57 | solatis | thats interesting |
| 22:58 | solatis | i know in other language environments, you're able to 'symlink' to a local dependency |
| 22:58 | solatis | so do a git checkout, and then tell the build tool to use that local checkout for a certain dependency, rather than a public repo |
| 22:58 | TEttinger | yeah, you can in lein, I think. `lein install` |
| 22:58 | solatis | aha |
| 22:58 | solatis | aha! |
| 22:58 | solatis | that would solve all my problems |
| 22:58 | TEttinger | though that installs whatever the project.clj has for a version |
| 22:58 | solatis | yeah sure |
| 22:59 | TEttinger | also I am super rusty |
| 22:59 | solatis | but it's more of a situation where dev A fixed a bug in internal library, and dev B needs to be able to use that fix |
| 23:00 | TEttinger | https://github.com/technomancy/leiningen/blob/stable/doc/TUTORIAL.md#snapshot-versions |
| 23:00 | solatis | \o/ |
| 23:01 | solatis | thanks |
| 23:01 | solatis | didn't know there was that kind of logic |
| 23:01 | TEttinger | also checkout deps |
| 23:01 | TEttinger | that's a feature I haven't seen before in lein |
| 23:03 | TEttinger | solatis: it looks like checkout deps may solve more features than I thought |
| 23:04 | TEttinger | since if everyone can just get an updated copy of the source, then they'll automatically see the source changes when the code changes |
| 23:04 | TEttinger | it looks like repls will pick up on the change without restarting too |
| 23:04 | clojurebot | Cool story bro. |
| 23:05 | TEttinger | classic |
| 23:05 | solatis | nice, nice |
| 23:05 | solatis | now, where do i find a good clojure dev to hire... |
| 23:06 | solatis | i think there was a slack channel for that |
| 23:07 | TEttinger | is it a local thing? I think that may affect your hiring choices significantly |
| 23:07 | TEttinger | clojure devs in topeka kansas vs. the bay area... uh... |
| 23:09 | hiredman | if you are hiring, I am looking |
| 23:09 | mgaare | solatis: me also |
| 23:09 | TEttinger | but your name says "hired" |
| 23:10 | solatis | lol |
| 23:11 | TEttinger | mgaare: do you have any open source projects out there? one of hiredman's open source contributions just said "Cool story bro." |
| 23:11 | solatis | yeah, being around the office is required, sadly |
| 23:11 | solatis | but, I'm introducing Clojure big time on our organization |
| 23:11 | TEttinger | great! |
| 23:11 | solatis | (it's in Amsterdam) |
| 23:12 | TEttinger | that is not a bad place to live at all. |
| 23:12 | solatis | exactly, we sponsor visas |
| 23:12 | TEttinger | what's the english-speaker ratio like? if someone didn't speak dutch |
| 23:12 | solatis | we speak english exclusively at the office |
| 23:12 | TEttinger | then again dutch is about as close to english as it gets |
| 23:13 | solatis | we have several international team members already |
| 23:13 | solatis | and well, dutch people are insanely good at speaking English, on average |
| 23:13 | TEttinger | I'd expect it, the vocabulary is so close |
| 23:14 | TEttinger | even word order is similar, and english doesn't often share that |
| 23:14 | solatis | well it's rather because we're a small country, which depends a lot on other countries for trade, doing business, etc |
| 23:14 | hiredman | https://twitter.com/justincampbell/status/575447532865609728 |
| 23:14 | solatis | and we don't dub our movies, we subtitle them |
| 23:14 | solatis | etc |
| 23:14 | solatis | hiredman: hehe i know |
| 23:15 | solatis | hiredman: it's a difficult decision |
| 23:15 | solatis | i'm CTO, so i *can* make the call |
| 23:15 | solatis | but i do want people to be around the office 1 or 2 days a week _at least_ |
| 23:15 | solatis | but yeah, you're severely limiting your choices |
| 23:15 | TEttinger | I have a bunch of random generators that imitate an existing language, and if you don't stick in way more english-only markers (-ought, -augh) than should probably be there, fake english looks more like fake dutch |
| 23:16 | hiredman | there was some microsoft studies just making the rounds |
| 23:16 | solatis | TEttinger haha |
| 23:16 | hiredman | http://research.microsoft.com/apps/mobile/news.aspx?post=/en-us/news/features/nagappan-100609.aspx |
| 23:16 | solatis | hiredman: well, i worked from a low-cost country as a freelancer for 2 years, and it's definitely very much possible |
| 23:16 | hiredman | "Geographical Distance Doesn’t Matter— Much." |
| 23:17 | solatis | the problem with remote work is that it only works with really good, and independent developers |
| 23:17 | hiredman | everyone claims to hire the best |
| 23:17 | hiredman | so, everyone should have no problem with it |
| 23:17 | solatis | haha |
| 23:17 | solatis | if only that were true! sometimes you just need to expand the team and hire developers that are 'good enough' |
| 23:18 | solatis | but in general i agree with you |
| 23:18 | solatis | i can get a lot more done when i'm not at the office |
| 23:20 | TEttinger | seeing as I don't have an office, my productivity often depends on whether my cat has decided my chair is now his chair |
| 23:20 | TEttinger | so I don't have an office but I do have a boss |
| 23:20 | solatis | yes, cats can be quite dominant bosses |
| 23:20 | solatis | especially when it concerns food |
| 23:24 | TEttinger | heh, satchmo (younger cat) isn't demanding about much at all. my other cat (eddie) is very demanding about some very specific things, like his tent. we have turned a guest bed into a full-time tent for eddie, pulling the covers up over the headboard so he has a place to stay. when my brother actually needed that bed... eddie would pester him until the bed became a tent again |
| 23:25 | TEttinger | these cats are the bosses |
| 23:26 | solatis | lol |
| 23:26 | solatis | so, you actually have given your whole cat a bed |
| 23:27 | solatis | never cave to a cat's demands! |
| 23:27 | justin_smith | as opposed to people who give part of their cat a bed |
| 23:27 | solatis | you give him a pillow, and he takes the whole bed! |
| 23:27 | solatis | lol justin_smith ... it's early in the morning here, give me a break |
| 23:27 | TEttinger | yeah, eddie is pretty darn happy with that tent |
| 23:28 | TEttinger | he purrs in there constantly |
| 23:28 | solatis | my cats have to sleep outside |
| 23:28 | solatis | fuck them |
| 23:28 | solatis | my house |
| 23:28 | TEttinger | you don't have coyotes or coywolves in amsterdam |
| 23:28 | solatis | well i'm in cambodia now actually |
| 23:28 | justin_smith | TEttinger: kitty purr indicator is one of the few KPIs that aren't complet bs |
| 23:28 | solatis | you have things like snakes |
| 23:28 | TEttinger | mm |
| 23:29 | solatis | but my cats are vicious |
| 23:29 | solatis | they eat poisonous snakes for breakfast |
| 23:30 | justin_smith | "between the tuna plan, and the tent, and the blind flightless bird program, our KPI numbers look excellent this quarter" |
| 23:30 | TEttinger | coywolves are terrifying though. coyotes don't have any fear of humans. wolves can bring down larger animals than people and do so regularly. mix the two and you end up with the property of all wolf hybrids where they don't have the behavioral cues of either parent |
| 23:31 | solatis | sounds like something out of a zombie movie |
| 23:31 | TEttinger | apparently because wolf numbers have dwindled so much in the northeast US and nearby canada, wolves breed with the newly introduced coyotes out of necessity, and produce much more effective offspring |
| 23:31 | TEttinger | we just have plain coyotes here in so cal |
| 23:31 | TEttinger | but they are loud |
| 23:32 | TEttinger | all night, yipping furiously |
| 23:33 | TEttinger | they think coywolves are so effective because the whitetail deer hasn't had any common predators since people nearly wiped out wolves, so you have inexperienced deer and suddenly a predator that's just big enough to bring one down and works in groups |
| 23:33 | TEttinger | and coyotes can't bring down deer normally |
| 23:38 | TEttinger | also, if you want zombie movie, there are fish that I believe are common in cambodia and are now invasive in parts of the US. https://en.wikipedia.org/wiki/Snakehead_(fish) |
| 23:38 | TEttinger | yep, They are one of the most common staple food fish in Thailand, Cambodia, Vietnam, and other South East Asian countries, where they are extensively cultured. |
| 23:58 | solatis | TEttinger3: haha yes i am fully aware of that. fucking monkeys can be lethal over here |