2016-01-06
| 00:15 | sdegutis | Do any of yall use components for /everything/ in your system? |
| 02:59 | BRODUS | anyone ever use the functions in cider-client.el? trying to understand why 'cider-nrepl-request:eval' only contains a session id in the callback... |
| 03:21 | owlbird | which web server has a better performance, I tried ring-jetty-adapter, but it was worse than Tomcat/Java. |
| 03:42 | kungi | owlbird: there is a clojure web server benchmark here: https://github.com/ptaoussanis/clojure-web-server-benchmarks |
| 03:49 | qsys | about transitioning from Java to Clojure: most, if not all, books and tutorials about Clojure spent a great deal about data structures, immutability, ... rather early. Java interop, classes, reification and such all come later. That scares Java devs quite often. So well, just an idea, wouldn't it be useful to have a book/tutorial/manual that starts with making classes etc in Clojure, and building up to data structures later? |
| 03:50 | qsys | Start from 'do it the Java-way in Clojure' and simplify it by introducing clojure concepts step by step? |
| 03:50 | TEttinger | qsys, good in principle, but bad for making good clojure code |
| 03:51 | TEttinger | you can use amap in place of map when using arrays instead of vectors, but... it will be uglier |
| 03:51 | TEttinger | clojure the clojure way tends to be vastly shorter than clojure the java way or java the java way |
| 03:51 | qsys | Yeah, it's true it's not good clojure code, but it's about learning. |
| 03:52 | TEttinger | but... learning bad ways is not good |
| 03:52 | qsys | allright... better than not learning at all? |
| 03:53 | owlbird | For my experience (a Java programmer) to learn Clojure, should get used to write little method, combining them with 'apply/map/reduce/filter...' |
| 03:53 | qsys | right - bad Java code is kind a commonplace (and accepted) |
| 03:54 | qsys | the thing is: if it's very different from what people know, most of them don't have the courage to continue the 'learning process' |
| 03:54 | TEttinger | I'd rather have java people program in java using clojure-like libs. https://github.com/rschmitt/dynamic-object and https://github.com/rschmitt/collider for example |
| 03:55 | qsys | Starting from what people know might help some people out |
| 03:55 | BRODUS | the clojure way kind of expects you to keep the java interop to a minimum. |
| 03:55 | TEttinger | those two libs might be a good starting point to introduce clojure syntax etc |
| 03:56 | owlbird | But Clojure is a little slower than java, and the tech leader has no reason to choose a worse performance language |
| 03:57 | TEttinger | it depends, it can be drastically faster to write |
| 03:57 | qsys | so, rather than starting 'java code in clojure', starting coding like clojure in java :p. Might be fun :) |
| 03:58 | BRODUS | i may be wrong but I think scala kind of expects you to use both scala and java |
| 03:58 | mpenet | owlbird: by that logic we'd all be doing assembly |
| 03:58 | qsys | well, little slower, don't know about that... might be, sometimes. I don't worry about that: bad java code might be much slower/less stable than good clojure code |
| 03:58 | owlbird | I saw a lot of performance comparison, if a Java programmer want a better language, why don't choose Scala or Nginx/luajit |
| 03:58 | TEttinger | because nginx isn't a language |
| 03:58 | owlbird | which is more practical |
| 03:58 | mpenet | owlbird: if it makes his team 10x more productive for 5% perfs hit (random value) he'd jump ship |
| 03:59 | owlbird | Nginx is not, bug openresty does |
| 03:59 | owlbird | but |
| 03:59 | qsys | I only know: I don't have the instability/performance problems many of my collegues have |
| 04:00 | qsys | I use clojure code (although I shouldn't, 'cause it's not allowed, since it's not Java, but so far, I could defend myself by saying I'm using 'Java technology', since it runs on the JVM) |
| 04:01 | qsys | Some wanted to learn clojure, but the moment I start talking about data structures, immutability, etc, most of them just see the point anymore - it's just too far from what they know to be 'true' |
| 04:03 | qsys | so I was planning to make a kind of crash course, but well, I can't jump in clojure like that... it should be 'from what they know up to clojure' |
| 04:04 | noncom|2 | BRODUS: no, scala does not actually... it can replace java |
| 04:04 | qsys | scala can replace Java, like Ceylon, or like Kotlin (which even has a 'java to kotlin converter' built-in) |
| 04:04 | algernon | qsys: I'd like to disagree. I held a two-day clojure crash course for C# developers last year, and started with data structures, clojure benefits, etc. So not with what they already knew and were familiar with. First day we did stuff the Clojure way only. Second day, we had some idiomatic C# -> idiomatic Clojure exercises. |
| 04:05 | algernon | qsys: it was a huge success, despite half of the team being very scpetic about clojure, lisp and the JVM up front. |
| 04:06 | qsys | allright... maybe it works in a crash course. I only know it doesn't work when I just have to explain 'on-the-fly'. So, well, I probably just have to try :p |
| 04:06 | algernon | qsys: if your developers are open to new ideas, starting at idiomatic clojure works suprisingly well. if they're not, well, it won't work either way :P |
| 04:06 | algernon | qsys: yeah, on the fly explanation is hard. never managed to sell clojure that way, either |
| 04:07 | qsys | well... there's a condition there :p. It's not only the devs - let's say about half of them is open to new ideas - but it's even more about tech leads, architects and well, managers, that are extremely afraid of 'new ideas' |
| 04:08 | mpenet | from my exp. they need to dig into a new project 100% in clojure, and build from there, trying to mix things up at the beginning is hard. |
| 04:08 | powered | java developers don't see the point of immutability? |
| 04:09 | qsys | Anyway, just giving it a try and jump right into clojure in a crash course might work. I'm curious how this will be... |
| 04:09 | mpenet | I mentored a team in a large company doing critical stuff (satellite related), they were producing quite good code after a dozen days or so, and were *very* impressed with the language. |
| 04:09 | algernon | perhaps I'm lucky, but I never found that to be a problem. showing big names recruiting clojure programmers convinced all managers I had to deal with. tech leads listened to reason, and to devs saying "we want to go with these stuff" |
| 04:09 | qsys | powered: well, some do, some don't, some others don't really know what you talk about. That's the bad thing these days: they learn 'frameworks', not coding, or paradigms, or ... |
| 04:10 | algernon | (that = tech leads, architects, managers) |
| 04:10 | noncom|2 | powered: it's not about immutability.. there comes the whole "another language" thing with "oh my it's lisp" thing |
| 04:11 | noncom|2 | and most programmers that i worked with were so brainwashed by oop that immutability was an almost unexisting concept for them |
| 04:11 | noncom|2 | coz objects have state, you know.. |
| 04:11 | qsys | true... |
| 04:11 | powered | the string type is immutable in java, so they should at least be familiar with the concept |
| 04:11 | qsys | noncom|2: that's the thing: they call Java oop, no mather how non-oop they are doing :p |
| 04:12 | noncom|2 | oh yeah :) and when trying to solve oop shortcommings, they just apply more oop |
| 04:12 | mpenet | functional programming/immutability isn't hard really. You just manage state differently but it's way easier to learn that how to do OOP in a not awful way |
| 04:12 | mpenet | base concepts are very simple |
| 04:12 | powered | it's all about applying them in the right way |
| 04:13 | qsys | mpenet: true, not difficult, but it is for people that are brainwashed. They only know 1 paradigm... and that is the only true one, for them. |
| 04:13 | noncom|2 | mpenet: it is, scientifically, but real world programmers are not always about science.. |
| 04:15 | mpenet | I am not sure, yes, it's different and requires to let some experience behind, but knowing oop doesn't make it much harder really. Programming is about knowing algos/ds and so on, not much about how to code in [insert language]. |
| 04:16 | noncom|2 | theoretically yes. in practice it comes down to neuroplasticity, bias, age, self, and other biological factors |
| 04:16 | mpenet | some people are a bit frustrated at the beginning because they're used to do it another way, but (from my exp), they get over it quickly |
| 04:17 | noncom|2 | well those are lucky who are open-minded :) |
| 04:18 | qsys | lucky, and well, sometimes unlucky ;) |
| 04:21 | abunuwas | ~@i-blis |
| 04:21 | clojurebot | Huh? |
| 04:23 | qsys | mpenet: to me, programming is about knowing as much paradigms as possible. The more you know, the better you can solve problems, the cleaner you right code... I personally don't care about language, or features. |
| 04:25 | qsys | anyway, I take it as a challenge to jump right into clojure for a clojure crash course :p |
| 04:28 | owlbird | programming is about earning money, which depends on business mostly, and a couple of languages, Java is more easy to learn and to hire a newbee ;) |
| 04:28 | owlbird | It's not fancy, but it works well |
| 04:30 | noncom|2 | yeah, to me commercial programming is often like coal mining |
| 04:32 | qsys | lol |
| 04:32 | BRODUS | noncom|2: you should say that to a coal miner |
| 04:34 | qsys | owlbird: I don't consider 'good' Java easy to learn, and even harder to learn to good clojure... probably because of all the Java-junk on the web, in books etc. But true, it's easy to hire a brainless Java-code-monkey, who lets his ide vomit code that's very susceptible to bad performance and instability :). |
| 04:38 | owlbird | qsys: There were too many java courses and frameworks, Spring / Play, even a people who don't know much about programming can do the works by watching samples. Yes, the performance is awful some times, but business is changing too fast. |
| 04:40 | mpenet | people were saying the same about c/c++ when java came out :) |
| 04:40 | owlbird | Sometimes, I think nginx, luajit is more suitable to build a prototype, which is also fast to develop and run. by building code into a yum package, it's also to maintain different versions. |
| 04:41 | qsys | yes, and that's the problem: when someting changes, it takes 'ages' to adopt. Real-life example: A few years ago, I got a request from another team to change something in their code. It was a translation into french, 1 sentence had to change somewhere in a properties file. The programmer that had to do that, estimated that it would take 1 day to do that. |
| 04:41 | mpenet | (or asp/php/perl for web thingies) |
| 04:43 | qsys | It took me about 1 hour to import the project, 25 seconds to change the sentence, 30 minutes to take out a few errors in the code and 25 minutes to rebuild the project :p - and it took another 3 weeks before it was released, due to the 'release cycle'. That's, sadly, the way things are programmed very often... |
| 04:43 | qsys | and that's the only truth for many. |
| 04:45 | qsys | ... but that's not about clojure, and since this is channel #clojure and not #whining, I'd better stop whining about it :p. |
| 04:46 | powered | 25 minutes to rebuild because it's so much code, or because people push code with compiler errors in it? |
| 04:47 | qsys | more about too much code: too much useless code, no errors, loads of warnings etc. |
| 04:48 | owlbird | I have seen enough stupid codes from another team, and the programmers are struggling everyday.... but their business is growing 300% every year, how can you blame them " What a stupid code"? TAT |
| 04:51 | qsys | owlbird: I agree with you... if they grow 300%/year, it's fine with me. I don't blame them (although I wouldn't be satisfied if the code is instable and not performant, but that's personnal). However, if they grow 300%, they might be able to grow 400%/year if the code would be less messy? |
| 04:52 | mpenet | It's all theorical bs really, I have seen "capable" outsourced teams of java devs kill a well funded project over time. |
| 04:53 | mpenet | it's very dependant on the context and many other factors |
| 04:56 | mpenet | Growing toxic code is never good. Can win you some time at the beginning but you almost always end up paying a high price |
| 04:59 | schmir | dammit. I've got 400k lines of toxic RosiSQL code that should be reimplemented. my life sucks. |
| 05:03 | qsys | schmir: ;) |
| 06:25 | ridcully_ | schmir: that's a whole lotta rosi |
| 06:41 | t0by | ridcully_ wins one internets |
| 06:43 | schmir | ridcully_: yes, but at least I'm using clojure for the new implementation |
| 08:22 | juanjo | yesterday i was able to compile clojure, thanks! |
| 08:22 | juanjo | how can i run the compiled version of it instead the system installed one? |
| 08:24 | juanjo | java -cp clojure-${VERSION}.jar clojure.main |
| 08:24 | juanjo | sorry, it was in the readme :/ |
| 09:26 | jsabeaudry | Can this be written better https://www.refheap.com/113414 ? |
| 09:34 | vijaykiran | jsabeaudry: what does sub return ? |
| 09:37 | jsabeaudry | vijaykiran, my guess would be the publication, let me check |
| 09:39 | jsabeaudry | vijaykiran, I was wrong, it returns the channel that was just subscribed |
| 10:10 | sdegutis_ | Hallo. |
| 10:18 | hiron | I'm having issues using with clojure.tools.namespace.repl/refresh. If I add a defn to my core.clj file and call refresh in my cider-repl, the new function is not available at the previously required namespace. Any thoughts? |
| 10:21 | sdegutis_ | justin_smith: how heavily are you using component? |
| 10:23 | favetelinguis | i have Java 8, latest stable clojure and leningen installed on my arch linux system but when im trying to use incanter charts only empty windows open up, what library do i need to install to get the plots working with incanter? |
| 10:24 | ridcully_ | that _could_ be a problem with your window manager |
| 10:26 | favetelinguis | i use xmonad |
| 10:27 | ridcully_ | have a websearch about "non reparenting wm java swing" - if this brings nothing up, i can put my script up on refheap |
| 10:27 | sdegutis_ | Lately I want to use i3, but that's probably because I'm just so dang tired of the plain-jane OS X UI... |
| 10:28 | ridcully_ | it basically to lie about the familiy of window manager you are using to make java render anything |
| 10:29 | Bronsa | ridcully_: FYI refheap is shutting down |
| 10:29 | Bronsa | might be read-only already |
| 10:29 | ridcully_ | yeah, heard about it here. thanks for the info |
| 10:29 | sdegutis_ | Bronsa: why? |
| 10:29 | sdegutis_ | Bronsa: I thought it was really cool |
| 10:31 | Bronsa | sdegutis_: people started uploading stolen credit card infos or something like that and Raynes doesn't have the time to deal with that IIRC |
| 10:31 | sdegutis_ | ahh yeah that'll do it |
| 10:48 | favetelinguis | ridcully_: seems to be a known issue with xmonad, thanks for the pointer |
| 10:51 | ridcully_ | favetelinguis: no only with xmonad. you found the workarounds? |
| 10:53 | favetelinguis | might, http://stackoverflow.com/questions/30742662/java-swing-gui-not-displaying-in-xmonad |
| 10:53 | engblom | ridcully_: Try 'export SAL_USE_VCLPLUGIN=gen' before using your JVM apps |
| 10:54 | engblom | ridcully_: Since adding that to my configuration I have never had any problem with xmonad |
| 10:55 | ridcully_ | engblom: i dont run xmonad - i use some script where the source is maybe burried in my git log. most likely wmname |
| 11:28 | TimMc | Bronsa: I talked with him and he said that it's not being taken down, just made read-only, which is great. |
| 11:28 | jsabeaudry | So if I understand correctly I can never put nil on a channel because consumer will think the channel is closed? |
| 11:29 | Bronsa | TimMc: ah, good |
| 11:35 | ridcully_ | jsabeaudry: yes. documented e.g. here https://clojure.github.io/core.async/#clojure.core.async/put! |
| 11:39 | jsabeaudry | ridcully_, ah, yes indeed! thanks! |
| 11:53 | domgetter | what's the reverse of mapcat? What will take a sequence and turn it into a sequence of subsequences? |
| 11:53 | justin_smith | domgetter: partition? partition-all? split-with? |
| 11:53 | domgetter | I'm trying to take a list of words and shove them into subsequences that represent rows of words when displayed |
| 11:54 | domgetter | I'll look into those three, thank you :) |
| 11:55 | domgetter | are any of those stateful with respect to the currect accumulating subsequence? |
| 11:55 | justin_smith | no |
| 11:56 | justin_smith | you can use reduce or loop for that though |
| 11:56 | domgetter | okay I'll just build my own then, thank you |
| 12:10 | domgetter | justin_smith: thanks for the advice. I got it up and running: https://gist.github.com/domgetter/2939fd3f5c45fd082a25 |
| 12:11 | justin_smith | domgetter: cool - it might be easier / more efficient if instead of repeatedly pop/conj acc if it's not full, you have a two collection accumulator |
| 12:11 | justin_smith | (defn rows [[full pending] word] ...) |
| 12:12 | justin_smith | so instead of of pop at each step, you can just conj to pending / or conj to full and pass [] as pending |
| 12:12 | domgetter | okay I think I understand. I'll go ruminate on it and see if I can come up with a result |
| 12:13 | justin_smith | domgetter: also, you use (last acc) and (pop acc) - if it's a vector always use pop, last is O(n), peek is much faster |
| 12:13 | justin_smith | err, always use peek too, that is |
| 12:13 | justin_smith | ,(peek [1 2 3]) |
| 12:13 | clojurebot | 3 |
| 12:14 | domgetter | ah okay. got it. obligatory "why don't they just make last efficient for vectors?" :P |
| 12:15 | justin_smith | domgetter: yeah, last uses the seq interface rather than having it's own interface |
| 12:15 | justin_smith | it would need its own interface for that to work |
| 12:17 | domgetter | Hmm, for the destructuring to work, "full" would have to be all the rows up to the last one, and pending would always be the last one. Is there a way to do a rest parameter that would work like butlast ? |
| 12:17 | justin_smith | domgetter: nope, that's why I suggested splitting it in two parts like that |
| 12:17 | domgetter | oh you mean maintaining it in that structure til the end manually? |
| 12:18 | domgetter | or did you mean have "pending" be its own vector just chilling until I shove it into full? |
| 12:18 | domgetter | that makes a lot more sense |
| 12:20 | justin_smith | (defn rows [[full pending] word] (if (> (apply + (count word) (map count pending)) 35) [(conj full pending) [word]] [full (conj pending word)])) |
| 12:21 | justin_smith | domgetter: right, maintaining that structure for every step - which means you need to do a conj at the end after reduce is done, or (apply conj (reduce ...)) |
| 12:21 | domgetter | awesome, thanks for the insight :) |
| 12:21 | justin_smith | domgetter: also see how I was able to combine your two sums into one apply + |
| 12:21 | sdegutis_ | What's the benefit of using type hints? What's the downside of not using them? When should they be used? |
| 12:22 | domgetter | yea I saw that, that makes more sense. I was being a lot more procedural |
| 12:22 | justin_smith | sdegutis_: 100x perf difference when they are needed is not unheard of |
| 12:22 | sdegutis_ | I've mostly been putting them in places to satisfy `lein check` but it feels a bit random and ad-hoc. |
| 12:22 | sdegutis_ | justin_smith: wow... |
| 12:22 | justin_smith | sdegutis_: clojure knows when compiling whether it's outputting expensive runtime reflection ops |
| 12:23 | justin_smith | sdegutis_: that's why lein check can warn you - it's a hook that tells you when that happens |
| 12:23 | justin_smith | sdegutis_: and the reflection is very expensive |
| 12:24 | justin_smith | sdegutis_: I've even seen differences more like 1000x (in cases that involve not only reflection but also numeric boxing...) |
| 12:26 | domgetter | justin_smith: the only "downside" is that I have to do a final conjoin after the reduce since I have a trailing pending vector |
| 12:26 | justin_smith | domgetter: right, like I said, (apply conj (reduce ...)) |
| 12:26 | domgetter | oh, you were one step ahead |
| 12:27 | justin_smith | domgetter: I've done this before :) |
| 12:30 | sdegutis_ | justin_smith: oh wow, then I'll definitely look for hot code paths in `lein check` and fix those |
| 12:31 | domgetter | justin_smith: much better! https://gist.github.com/domgetter/2939fd3f5c45fd082a25 |
| 12:31 | justin_smith | sdegutis_: best value is probably a combination of lein check to see where the reflection is happening, and a profiler so you know what the hot path is |
| 12:31 | sdegutis_ | justin_smith: hmm interesting concept |
| 12:32 | Bronsa | setting *unchecked-math* to :warn-on-boxed is also really useful |
| 12:32 | justin_smith | definitely |
| 12:33 | sdegutis_ | Nice, only 33 reflection warnings. And none of them in hot code paths. |
| 12:33 | sdegutis_ | Bronsa: whoa, definitely gonna set that one |
| 12:33 | Bronsa | although it doesn't catch all the boxing cases |
| 12:34 | justin_smith | Bronsa: is there a good guide to finding numeric boxing that *unchecked-math* :warn-on-boxed would not catch? |
| 12:34 | Bronsa | justin_smith: http://dev.clojure.org/jira/browse/CLJ-1585 this is the only case I'm aware of |
| 12:35 | Bronsa | I really dislike how clojure does automatic boxing/unboxing, I wish it didn't |
| 12:35 | Bronsa | I'd rather use (Integer. x) and (int x) |
| 12:36 | Bronsa | also sometimes type hints work for unboxing, sometimes they don't. I think they should never and the only way to unbox should be using the casting functions |
| 12:36 | Bronsa | but it's probably way too late to even propose such a change |
| 12:39 | sdegutis_ | It's never too late! |
| 12:40 | justin_smith | sdegutis_: clojure values back-compatibility, having to use (Integer. x) / (int x) explicitly would break so much code... |
| 12:44 | Bronsa | yeah like, 80% of code that uses interop |
| 12:45 | justin_smith | but oxlang could totally go that route |
| 12:46 | sdegutis_ | oxlang!? |
| 12:47 | sdegutis_ | arrdem: that looks fricken cool |
| 12:47 | sdegutis_ | arrdem: do you use it in production yet? |
| 13:04 | sdegutis_ | Why does clojure.data.csv take a writer rather than just returning a string? Or at least why doesn't it have a variant that just returns a string? |
| 13:05 | justin_smith | sdegutis_: returning a writer rather than a string is one of those marks of distinction that differentiates a gentleman api dev from the hoi paloi |
| 13:06 | justin_smith | sdegutis_: j/k I have no idea honestly |
| 13:06 | sdegutis_ | :D |
| 13:07 | justin_smith | sdegutis_: (java.io.StringWriter.) is simple enough to make at least, maybe they don't want to force the intermediate string form for csv's that are bigger than RAM |
| 13:07 | justin_smith | sdegutis_: actually, now that I think about it, it must be that case: a writer can handle a csv bigger than RAM, generating a string breaks well before RAM is even full |
| 13:07 | justin_smith | there's a max string size |
| 13:08 | sdegutis_ | Sure, but now I have a 3 line function in my codebase in its own util namespace whereas I could delete it if this lib came with the 3 line function itself. |
| 13:12 | justin_smith | sdegutis: something like (let [s (java.io.StringWriter.)] (read-csv file s) (str s)) ? |
| 13:12 | sdegutis | yeah that's what I have |
| 13:13 | sdegutis | well, close: (defn csv-to-string [csv & opts] (let [out (java.io.StringWriter.)] (apply write-csv out csv opts) (str out))) |
| 13:13 | sdegutis | the apply is cuz it takes pseudo-mappified opts |
| 14:22 | catern | how would I get an atomic set datastructure? |
| 14:22 | catern | just put it in an atom? |
| 14:22 | mikerod | catern: (atom #{}) |
| 14:22 | mikerod | I guess I don't know what you mean actually |
| 14:23 | mikerod | #{} is thread safe |
| 14:23 | mikerod | every modification just returns a new one, you don't affect the original |
| 14:23 | mikerod | if you want one though that multiple things refer to, then yes (atom {}) |
| 14:23 | mikerod | (atom #{}) |
| 14:24 | mikerod | with atomic update |
| 14:24 | catern | hmm |
| 14:25 | catern | what i really want is, I have some threads handling incoming data, and they check if a tag in the data is in a seen-set, and if it isn't in the seen-set they add it and start a new thread to start doing a thing |
| 14:25 | catern | is there a better way to do that than an atomic set? |
| 14:26 | catern | an (atom #{}) |
| 14:28 | justin_smith | catern: note that if you want only one thread to take the action, you can't just deref and swap as separate actions |
| 14:29 | mikerod | justin_smith: yes, I was thinking of that |
| 14:29 | mikerod | but if you are just conjoining some value to a set |
| 14:29 | justin_smith | catern: and swap! retries, which means you probably don't want to put the launch of that action into the swapping function |
| 14:29 | mikerod | and you aren't concerned about it being conjoined more than once |
| 14:29 | justin_smith | mikerod: sure |
| 14:30 | justin_smith | catern: how big a problem is it if accidentally more than one thread gets started? |
| 14:30 | mikerod | if you want to be able to see the set and conj to it atomically, you'd use some transaction based construcdt I guess |
| 14:30 | justin_smith | mikerod: or use something like an agent that synchronizes on its value (but runs async) |
| 14:30 | justin_smith | and thus does not swap |
| 14:30 | justin_smith | s/swap/retry |
| 14:31 | mikerod | sure, I really don't have a ton of real-world experience with these things - so I'm learning at this point on what is best for these situations |
| 14:32 | mikerod | I think the the (atom #{}) solution is nice if you aren't concerned with retries and don't mind if you are conj'ing a value that was already conj'ed there after you derefed it |
| 14:32 | catern | justin_smith: well, what will actually happen if it's not in the seen-set is a websocket will be opened corresponding to that tag, and then the data that comes in on that websocket will be put in a datastructure somewhere |
| 14:32 | catern | justin_smith: so I don't want to open that websocket twice or create that datastructure twice |
| 14:33 | justin_smith | catern: right |
| 14:33 | mikerod | now I think the (atom #{}) way isn't good then |
| 14:33 | justin_smith | catern: since agents don't retry, it might make sense to use an agent and send-off, then await the agent and see if you need to start your thread or not |
| 14:34 | justin_smith | or spawn the thread from inside the send-off actually (that would be best I think) |
| 14:34 | mikerod | it is weird to me you'd need to do something async for this |
| 14:34 | mikerod | not to say I know the best/better way |
| 14:35 | neoncontrails | I just realized, I still haven't contributed to an open source project yet. (Other than my own.) |
| 14:35 | neoncontrails | Is there a bulletin board somewhere of Clojure projects seeking volunteers? |
| 14:35 | catern | i have too much incoming data to do it synchronously |
| 14:35 | neoncontrails | Or is Git my best bet? |
| 14:35 | catern | the "threads handling incoming data and opening websockets" are actually polling an API, and each request is too slow for me to wait for it to complete before sending the next request |
| 14:36 | justin_smith | mikerod: it has to do with the semantics for atoms vs. agents - agent operations are async, atom operations are synchronous - I don't have a good summary for the reasons handy atm but there are good reasons |
| 14:36 | mikerod | justin_smith: I know that part |
| 14:36 | justin_smith | oh, OK |
| 14:37 | mikerod | I just thought there was something synchronous that allowed you to view a value + do something based on it + update it in one lock |
| 14:37 | mikerod | if that makes sense |
| 14:37 | catern | (oh, when you said do something async you were talking about the agent way rather than the atom way. nvm) |
| 14:37 | mikerod | catern: yes, sorry |
| 14:37 | justin_smith | mikerod: not without retries |
| 14:38 | mikerod | justin_smith: yeah, I meant to mention that one |
| 14:38 | mikerod | "do something side-effecty" |
| 14:38 | justin_smith | yeah |
| 14:38 | BRODUS | neoncontrails: i normally contribute to stuff organically. I end up using open source libraries or read open-source code while doing my projects and when I find something I can fix I do it. |
| 14:40 | neoncontrails | BRODUS: Hmm. There must be some resource besides git though, no? Or a way to browse git for repos actively seeking contributors? |
| 14:41 | BRODUS | neoncontrails: there was a link on HN recently you might like, i'll try and find it |
| 14:42 | neoncontrails | BRODUS: I do love HN. Thanks |
| 14:42 | catern | justin_smith: i'm worried about the send-off being delayed, though |
| 14:42 | catern | i want to create the websocket ASAP because data is being dropped on the floor as long as I don't have it open |
| 14:42 | justin_smith | neoncontrails: lein has issues that are marked as specifically good for newcomers to work on, and is very open to contributions |
| 14:42 | catern | (this is for a programming game) |
| 14:43 | BRODUS | neoncontrails: ah it was this http://up-for-grabs.net/#/ , no clojure projects though |
| 14:43 | justin_smith | catern: it will be delayed if another send-off is still running |
| 14:43 | neoncontrails | justin_smith: oh, wow. lein itself, eh? I'll look into it |
| 14:43 | catern | justin_smith: i mean, those are implementation details though |
| 14:43 | catern | it's not necessarily that I want to do it synchronously |
| 14:43 | catern | i just want to do it fast |
| 14:44 | justin_smith | neoncontrails: there's also crossclj.info that lets you see which projects are most visible/used by other projects, which has links to source etc. might be helpful for finding where to jump in |
| 14:44 | catern | scheduled immediately |
| 14:44 | catern | (in practice I'm sure it's fine for my application to just let it be scheduled "whenever" since "whenever" is probably very soon, but...) |
| 14:44 | justin_smith | catern: sure, then if your other send-off actions are things that return quickly it will be fine. All it does is check a key, conditionally conj and start a thread, right? |
| 14:45 | neoncontrails | BRODUS: still a nice list, thanks for sharing |
| 14:45 | justin_smith | catern: other than indeterminacy that would be the same as that effecting any new thread already, the only issue is other send-off events, and you have 100% control of how quickly those return |
| 14:45 | neoncontrails | justin_smith: also a great suggestion. Thanks for the help |
| 14:46 | justin_smith | catern: in fact you should only have one kind of send-off event, run as often as needed: check for key, if not present spawn thread and conj |
| 14:46 | justin_smith | if that sequence of actions is a bottleneck of any sort, you are writing some amazing high performance code I tell you hwat |
| 14:47 | catern | heh |
| 14:47 | catern | well, creating/opening the websocket might take a bit of time... |
| 14:47 | justin_smith | catern: right, do that in a new thread |
| 14:47 | justin_smith | not in the agent |
| 14:48 | catern | btw |
| 14:48 | catern | what should I use to make async HTTP requests in Clojure? and async websockets? |
| 14:48 | justin_smith | catern: I use http-kit, and the sente lib which maps websockets to core.async |
| 14:49 | catern | just clientside btw |
| 14:49 | justin_smith | I haven't tried http-kit for client-side websockets though |
| 14:49 | justin_smith | but iirc that exists, if not aleph can do it |
| 14:52 | catern | aleph? why not use sente? |
| 14:52 | justin_smith | catern: sente uses aleph or http-kit |
| 14:53 | justin_smith | aleph and http-kit do the websocket part, sente hooks it up nicely to core.async |
| 14:54 | justin_smith | ztellman has an alternative called manifold that does similar to sente (connecting websockets, vanilla tcp, input-streams, core.async in various configurations to one another) |
| 14:57 | catern | hmm, sente appears to assume you control both ends? |
| 14:57 | catern | server and client |
| 14:57 | justin_smith | catern: yeah, it's kind of frameworky |
| 14:57 | justin_smith | manifold is more flexible |
| 14:58 | catern | but aleph would be the part actually doing the websocket part |
| 14:58 | catern | afaics http-kit doesn't have websocket client support |
| 14:59 | justin_smith | 'k |
| 15:00 | justin_smith | yeah, looks like it only has server support, and lately I don't think it's as well maintained as aleph either |
| 15:01 | catern | aleph has http too |
| 15:01 | catern | so I guess I'll just use that for everything |
| 15:01 | catern | normal http* |
| 15:05 | catern | so, wait, I can't really tell |
| 15:05 | catern | http://ideolalia.com/aleph/literate.html#aleph.examples.http |
| 15:05 | catern | how do I get callback-style thing? |
| 15:05 | catern | get a* |
| 15:07 | justin_smith | catern: if you go down to the http/get examples, instead of specifying a callback, you chain operations on the dereferenced result |
| 15:07 | justin_smith | hmm... maybe there is a way to do a callback too though |
| 15:07 | catern | yeah, I saw that, but that's not what I want, I think |
| 15:08 | catern | since, well, right now my architecture is to fire off HTTP a bunch of requests every fraction of a second |
| 15:08 | catern | fire off a bunch of HTTP requests |
| 15:09 | justin_smith | catern: did you get down to the aleph.examples.websocket stuff at the bottom? |
| 15:09 | catern | i don't want to have to wait for any or all of them to complete before firing off the next |
| 15:10 | catern | justin_smith: yeah, I can't really grasp what's going on, but I can only assume that I can register some callbacks maybe |
| 15:11 | justin_smith | catern: I think bus/subscribe is the thing you want there, from skimming that code |
| 15:11 | justin_smith | catern: I'm interested myself as I may want to upgrade from http-kit/sente to aleph/manifold... |
| 15:16 | catern | this is quite complex |
| 15:17 | justin_smith | catern: might be easier to just use the direct socket with socket i/o, then upgrade if you need the features |
| 15:17 | justin_smith | catern: the more I work on my websocket connected app the more sense those features make... |
| 15:20 | catern | the direct websocket or TCP socket? |
| 15:20 | justin_smith | websocket |
| 15:21 | catern | i can't even tell what the features are here |
| 15:22 | catern | this doesn't look any better than wrapping synchronous actions in some async thing |
| 15:22 | catern | anyway, operating on the direct socket would be synchronous, right? |
| 15:23 | lokien | Hey, I'm processing a string with recursion. Each time I process a letter, I have to update a vector, based on that letter and last item on the vector. How do I do that? I'm struggling with immutability here |
| 15:23 | justin_smith | catern: depends, you could use nio |
| 15:23 | justin_smith | lokien: are you processing a sequence of some sort start to end? |
| 15:24 | lokien | justin_smith: yeah |
| 15:24 | justin_smith | if so, reduce |
| 15:24 | lokien | let me show you what'd be my input and desired output |
| 15:24 | justin_smith | ,(reduce (fn [letters letter] (update letters letter (fnil inc 0))) {} "hello") |
| 15:24 | clojurebot | {\h 1, \e 1, \l 2, \o 1} |
| 15:24 | lokien | "next prev next next" -> [0 1 0 1 2] |
| 15:25 | lokien | (vector is 0 initially) |
| 15:25 | lokien | "" -> [0] |
| 15:26 | catern | justin_smith: wait so is this websocket support all just borrowed from some java library? |
| 15:26 | ridcully_ | ,(frequencies "hello") |
| 15:26 | clojurebot | {\h 1, \e 1, \l 2, \o 1} |
| 15:27 | justin_smith | ridcully_: right :) just showing the general idea of how to do that with reduce |
| 15:27 | lokien | ridcully_: I know, but.. how does that help? |
| 15:28 | ridcully_ | lokien: that was to make justin_smith smile |
| 15:28 | lokien | ridcully_: oh, well, you're a nice person |
| 15:29 | TimMc | lokien: If I give you an accumulator [0 1] and an operation "next", how would you write (fn [accum operation] ...) to give me back [0 1 2]? |
| 15:29 | TimMc | besides (constantly [0 1 2]) ;-) |
| 15:29 | justin_smith | ,,(reduce (fn [moves word] (conj moves (({"next" inc "prev" dec} word) (peek moves)))) [0] (clojure.string/split "next prev next next" #" ")) |
| 15:29 | clojurebot | [0 1 0 1 2] |
| 15:31 | justin_smith | ,(reductions (fn [move word] (({"next" inc "prev" dec} word) move)) 0 (clojure.string/split "next prev next next" #" ")) |
| 15:31 | clojurebot | (0 1 0 1 2) |
| 15:31 | justin_smith | simpler, I think |
| 15:32 | lokien | I tried to do it with "loop" |
| 15:32 | lokien | but it was a nightmare |
| 15:33 | justin_smith | lokien: yeah - that's why my first question was "are you visiting items in order from some source" - reduce / reductions handle the defaults for that nicely |
| 15:34 | justin_smith | and unlike map / for, they carry state you can use at future steps |
| 15:34 | lokien | justin_smith: idiomatic clojure is so good, my clojure is awful tho |
| 15:34 | justin_smith | lokien: the solution is to write more clojure - and share your code with other clojure folks |
| 15:35 | sdegutis | the level of indirection in duct is really confusing me... https://github.com/weavejester/duct/blob/master/duct/src/duct/component/endpoint.clj |
| 15:35 | justin_smith | my clojure was terrible when I started, it's maybe acceptable now |
| 15:35 | lokien | justin_smith: primarily with you, I guess |
| 15:35 | lokien | acceptable? |
| 15:35 | lokien | writing code for entire irc? |
| 15:35 | lokien | are you serious? :D |
| 15:35 | justin_smith | heh, that's just one-liner examples, building real stuff is different |
| 15:36 | lokien | even more demanding? ygh |
| 15:37 | sdegutis | lol justin_smith "maybe acceptable" |
| 15:37 | justin_smith | lokien: the one liners and examples here are kind of like that forms in a martial art, or scales in music - they can help you understand something, but aren't much on their own, there's the actual craft side of it too, and I have far to go |
| 15:38 | lokien | even sdegutis says you're beyond "acceptable"! |
| 15:38 | justin_smith | like, I still have yet to hit the "build a useful lib that has nothing in it I am embarrassed of" landmark |
| 15:38 | sdegutis | lokien: "even sdegutis" lol |
| 15:38 | sdegutis | justin_smith: that goal is literally impossible due to the 6-months rule |
| 15:39 | lokien | justin_smith: for how long have you been in clojure family? |
| 15:39 | lokien | sdegutis: welp, you're good too |
| 15:39 | justin_smith | lokien: I've been using clojure for ... about 4 years? |
| 15:39 | sdegutis | hey me too! |
| 15:39 | justin_smith | sdegutis: OIC http://www.imdb.com/title/tt0865561/ |
| 15:39 | lokien | sdegutis: I saw you on hacker news, is paladin usable now? |
| 15:39 | sdegutis | lokien: wha? |
| 15:40 | sdegutis | lokien: i was on HN? |
| 15:40 | lokien | sdegutis: you were commenting |
| 15:40 | sdegutis | oh |
| 15:41 | lokien | justin_smith: that's not 20 years! |
| 15:41 | lokien | I mean, you don't have to have a killer app/lib yet |
| 15:41 | sdegutis | lokien: haha no paladin probably wont be usable until 2017 at this rate.. this is my first attempt at writing a bytecode-based vm and bytecode compiler |
| 15:41 | lokien | sdegutis: damn, I wanted to try it |
| 15:42 | sdegutis | lokien: haha get in line ;) |
| 15:42 | sdegutis | (aka: i wanna try it too!) |
| 15:43 | lokien | sdegutis: only if I could help |
| 15:43 | lokien | justin_smith: where would I use "loop" form then? |
| 15:44 | TEttinger | sdegutis: making a language eh? clojuresque? |
| 15:44 | justin_smith | lokien: where speed is your top priority, it can be faster |
| 15:45 | sdegutis | TEttinger: heh i wouldnt go so far as to say "making".. more like "dreaming of" at this rate lol |
| 15:45 | justin_smith | lokien: especially when your source of data is not a sequence, but maybe a channel or a socket etc. |
| 15:45 | justin_smith | sdegutis: you should just do a fork of oxcart |
| 15:45 | TEttinger | is that arrdem's? |
| 15:45 | sdegutis | TEttinger: but yeah im seein if i can make a bytecode based compiler and vm written in pure & portable c that has only immutable clojure-like values and clojure-like sytnax |
| 15:45 | justin_smith | yeah |
| 15:46 | lokien | justin_smith: thanks |
| 15:46 | TEttinger | ha, portable C |
| 15:46 | justin_smith | sdegutis: how many years do you have set aside to do hash-maps? |
| 15:46 | TEttinger | that one always makes me chuckle |
| 15:46 | sdegutis | justin_smith: haha wait i dont get it |
| 15:47 | justin_smith | sdegutis: I mean, do you plan to take 2 years implementing hash-maps, maybe 4 or 5? |
| 15:47 | TEttinger | "portable if you have a windows, mac, linux 32-bit, and linux 64-bit computer to compile on" |
| 15:47 | sdegutis | justin_smith: heh yeah i thought hash maps were simple until i started reading about how clojure implements them |
| 15:47 | sdegutis | justin_smith: so i guess 2017 is reasonable to have "efficient" hashmaps by :D |
| 15:47 | justin_smith | especially since you are also writing your own gc last I heard |
| 15:47 | TEttinger | there are HAMT implementations in C |
| 15:48 | TEttinger | CHAMP is optimized for the JVM |
| 15:48 | sdegutis | justin_smith: oh yeah the gc is the easy part afaiui |
| 15:48 | TEttinger | tell that to google |
| 15:48 | sdegutis | i didnt say efficient/fast gc lol |
| 15:48 | TEttinger | dalvik's GC is awful compared to hotspt |
| 15:49 | sdegutis | im not aiming to compete with the jvm, im just trying to get something that would be cool for command line scripts.. something like lua |
| 15:49 | TEttinger | ah cool |
| 15:49 | sdegutis | (in terms of performance) |
| 15:49 | TEttinger | yeah I had a similar goal with my attempt at a language |
| 15:49 | sdegutis | how did it go? |
| 15:49 | sdegutis | did you finish it? |
| 15:49 | TEttinger | it went pretty well, I did not finish it, luajit is a kickass thing to target |
| 15:50 | TEttinger | the bad parts were that I was doing a lot of stuff in a dumb way, so it lost a lot of potential improvement |
| 15:50 | lokien | eh, guys here are implementing languages |
| 15:50 | lokien | and I'm just sitting here, struggling with advent of code |
| 15:51 | TEttinger | I was trying to make a clojure-like lisp that, like yours, could start up quickly and run simple things |
| 15:52 | TEttinger | if I started over I would use https://github.com/franko/luajit-lang-toolkit , which is a bit heavy-duty but should result in damn good opts |
| 15:52 | sdegutis | lokien: youd be surprised how graspable implementing a basic language is, as long as you do it inefficiently :D |
| 15:52 | sdegutis | TEttinger: hmm interesting.. yeah for something that would compete with ruby&rails, luajit looks like a good vm to target |
| 15:53 | sdegutis | TEttinger: i think ruby rather shines at command line stuff, small programs that arent intended to be long-lived |
| 15:53 | lokien | sdegutis: I dream of a project like this :( |
| 15:53 | sdegutis | lokien: lol haha |
| 15:54 | TEttinger | ok, back to space filling curves... |
| 15:54 | lokien | sdegutis: I open up my vim, sit there staring at screen for like 20 minutes, and then go eat something |
| 15:55 | sdegutis | well theres your problem |
| 15:55 | lokien | sdegutis: and then I forget about clojure for the rest of the day |
| 15:55 | sdegutis | you're using vim! |
| 15:55 | sdegutis | haha |
| 15:55 | lokien | with emacs it was even worse |
| 15:55 | lokien | like "shit, how do I close this buffer? *pkill emacs* welp, all is gone, screw this" |
| 15:55 | engblom | I also prefer vim. fireplace is really making clojure development under vim pleasant |
| 15:56 | lokien | I can't connect to my repl with fireplace |
| 15:56 | lokien | few days ago, only :Console wasn't working |
| 15:56 | lokien | now I can't connect at all |
| 15:56 | lokien | :( |
| 15:57 | sdegutis | editor wars are, like, over, maaan.. the /true/ editor is whatever is in your heart |
| 15:58 | lokien | what if my heart is a cold place filled with void? |
| 15:59 | ridcully_ | have you changed anything? any plugins got autoupdated etc? |
| 15:59 | sdegutis | then the true editor for you is (void)0; |
| 15:59 | lokien | ridcully_: nothing! |
| 16:00 | ridcully_ | e.g. cider-nrepl was updated recently, or am i just sitting on an old version? |
| 16:00 | lokien | sdegutis: let's write it in clojure :^) |
| 16:00 | sdegutis | hahahhaa |
| 16:00 | sdegutis | (do nil) |
| 16:00 | sdegutis | done |
| 16:00 | sdegutis | ,(do nil) |
| 16:00 | lokien | Next Big Thing |
| 16:00 | clojurebot | nil |
| 16:01 | ridcully_ | lokien: are you using a pinned version for cider/cider-nrepl? |
| 16:01 | lokien | ridcully_: I'm using vim, darn |
| 16:01 | ridcully_ | me too |
| 16:02 | lokien | with cider? |
| 16:02 | ridcully_ | yet i have cider-nrepl for fireplace installed |
| 16:02 | lokien | I'm using vanilla fireplace |
| 16:02 | lokien | and salve |
| 16:02 | lokien | and things for highlighting |
| 16:13 | amandabb | hi |
| 16:14 | amandabb | so hash tables dont have guaranteed order, but assuming they dont change will accessing items by random index at least be consistently random? |
| 16:14 | sdegutis | oh right i forgot cider 0.10 was released woo time to upgrade |
| 16:15 | sobel | amandabb: i wouldn't count on it |
| 16:15 | amandabb | like if i have a hash table of 10 items and access by random index instead of key |
| 16:15 | amandabb | will any item be relatively equal likely to show itself given a large enough amount of attempts |
| 16:16 | amandabb | or will some items be more likely to keep reappearing |
| 16:16 | sobel | how do you index a hash table |
| 16:17 | amandabb | can you not? |
| 16:17 | amandabb | i just assumed you could |
| 16:17 | justin_smith | amandabb: (rand-nth (vals m)) |
| 16:17 | amandabb | sometimes i want to access by key but other times i just want a random item |
| 16:17 | amandabb | ooo |
| 16:17 | amandabb | thank you |
| 16:17 | justin_smith | amandabb: if you want key and value, (rand-nth (seq m)) |
| 16:17 | justin_smith | that will give you k/v as a two element vector |
| 16:17 | amandabb | gotcha thanks this is perfect |
| 16:23 | ridcully_ | lokien_: fired up a container, empty vim + pathogen + the four deps salve wants + lein. ran in tmux and ran :Console. cpp/Eval works |
| 16:24 | lokien_ | ridcully_: yeah, I'm hearing it for the second time |
| 16:24 | lokien_ | I guess my laptop is.. Special |
| 16:25 | lokien_ | sdegutis: do you use emacs? ;-; |
| 16:25 | sdegutis | lokien_: yep |
| 16:26 | lokien_ | sdegutis: with.. Emacs bindings? |
| 16:26 | sdegutis | lokien_: yep |
| 16:26 | ridcully_ | i added cider-nrepl for some reason (maybe mentioned in a ticket). so i wanted to see, if its important - but seems not |
| 16:26 | sdegutis | lokien_: well, kinda |
| 16:26 | ridcully_ | what errors do you get? |
| 16:26 | lokien_ | sdegutis: I'm telling your mother |
| 16:27 | sdegutis | lokien_: hahaha good luck |
| 16:28 | StevensMother | Hello sdegutis |
| 16:29 | StevensMother | I'm worried about your pinkies going sore from these bindings you're using |
| 16:29 | noncom|2 | did anyone use lein-externs ( https://github.com/ejlo/lein-externs ) for clojurescript to generate externs ? |
| 16:30 | sdegutis | lokien hah |
| 16:30 | StevensMother | It's your mom here |
| 16:30 | StevensMother | Please, please stop |
| 16:30 | sdegutis | op plz |
| 16:30 | sdegutis | haha lol |
| 16:30 | sdegutis | StevensMother: no this is patrick |
| 16:31 | StevensMother | Oh, you're no fun. :^( |
| 16:31 | ridcully_ | used some online service last time (most likely linked in the cljs wiki) last time i had to do it |
| 16:31 | sdegutis | lokien_: YOU MUST CONSTRUCT ADDITIONAL PYLONS |
| 16:31 | ridcully_ | noncom|2: but the js was very simple |
| 16:31 | noncom|2 | ridcully_: yeah, i remember you gave link to the service |
| 16:31 | sdegutis | lokien_: sorry i never learned how to interact with people on a normal level this is the best i can do |
| 16:31 | artosis | sdegutis: no I don't |
| 16:32 | sdegutis | hahah apparently neither have you, alright high five! |
| 16:32 | artosis | *high five of social awkwardness* |
| 16:32 | sdegutis | lokien so you learnin clojure as part of a high school course or just for fun on the side or what? |
| 16:33 | lokien_ | I'm in high school, it sucks, it's all hardware |
| 16:33 | lokien_ | I just want to write programs, they make me happy |
| 16:36 | lokien_ | sdegutis: also, I don't want to go to college, it sucks even more |
| 16:36 | sdegutis | lokien_: heh dont know what to tell ya bud sorry |
| 16:36 | sdegutis | bbl |
| 16:37 | lokien_ | sdegutis: why sorry? |
| 16:39 | lokien_ | sdegutis: going to sleep now, so.. have a nice day and everything :) |
| 16:51 | amandabb | hi can someone take a quick look at this go-block (couple lines) and explain why i'm getting the listed error? http://pastebin.com/j3W8xM3j |
| 16:51 | amandabb | tried using do blocks, doall, doseq.. hmm not sure why it's not working |
| 16:54 | neoncontrails | Alright I give up. Asking this n00b question. Using this library: |
| 16:54 | neoncontrails | https://github.com/wiseman/clj-pronouncing |
| 16:54 | neoncontrails | Very straightforward. Included the library under :dependencies in my project.clj |
| 16:54 | neoncontrails | Included the require statement. |
| 16:55 | neoncontrails | Cursive still can't find the library. What else is required? |
| 16:56 | neoncontrails | I rebooted the project as JDK1.6, juuust in case it was a versioning issue. No dice. |
| 16:56 | neoncontrails | I'm out of ideas. |
| 16:58 | cfleming | neoncontrails: Do you see the lib under External Libraries in the project view? |
| 16:58 | ridcully_ | mind to share that project.clj? or is this a cursive-only problem? |
| 16:59 | neoncontrails | cfleming: good question. I don't see it, no. |
| 16:59 | neoncontrails | ridculy_: it's dull I promise, but sure. One sec |
| 16:59 | cfleming | neoncontrails: Ok, open View->Tool Windows->Leiningen |
| 16:59 | cfleming | And hit the refresh button. |
| 17:00 | cfleming | That'll sync your dependencies from your project.clj to your Cursive project |
| 17:01 | neoncontrails | Got it. Trying now |
| 17:01 | neoncontrails | ridcully_: http://pastebin.com/X1kzkufG |
| 17:02 | noncom|2 | amandabb: something is undefined |
| 17:02 | amandabb | hmmmm |
| 17:02 | noncom|2 | it's clojurescript, so that means you are doing undefined.someMethod in js |
| 17:02 | amandabb | nothing is undefined in there though |
| 17:03 | amandabb | (def game-chan (chan)) is above it |
| 17:03 | amandabb | what other vars are there? when i remove that block of code it runs fine |
| 17:03 | noncom|2 | amandabb: are you sure? what if you console.log all of them: go, timeout, <!, >!, game-chan |
| 17:03 | amandabb | ooooooo |
| 17:03 | amandabb | it's not just vars |
| 17:04 | amandabb | i forgot about require |
| 17:04 | amandabb | thats probably it |
| 17:04 | noncom|2 | these are functions, right, but they should print out |
| 17:04 | amandabb | yeah didnt import timeout |
| 17:04 | amandabb | good call thanks |
| 17:04 | noncom|2 | ah, ok |
| 17:04 | neoncontrails | cfleming: so that worked great for loading the library into the current project. Now It's giving me a different error about unspecified modules when I try to run, but I may be able to tackle that one |
| 17:05 | neoncontrails | cfleming: appreciate it. I just upgraded from community edition, I don't recall these hoops |
| 17:07 | cfleming | neoncontrails: No worries, I have plans to make that easier/more intuitive |
| 17:07 | cfleming | (i.e. starting with actually telling you when you need to do it) |
| 17:08 | noncom|2 | amandabb: oh and as a second thought: all these: <!, >!, go, and other stuff are actually vars. it's one of the core features of a lisp - homoiconicity :) |
| 17:08 | amandabb | o right |
| 17:15 | neoncontrails | cfleming: hmm. I know that the 'module not specified' error is related, but I'm having trouble deciphering what the error means. It's not... really a module, is it? A module would be like a .jar? |
| 17:16 | cfleming | neoncontrails: Did you just upgrade IntelliJ? |
| 17:16 | neoncontrails | I did, yes |
| 17:16 | cfleming | Ok, there's a migration to the run configs which doesn't always work, and I haven't figured out why. |
| 17:17 | cfleming | Open your run config using Run->Edit Configurations |
| 17:17 | cfleming | Check that the specified module looks ok - you might need to re-select it and hit apply. |
| 17:18 | neoncontrails | Bingo! Man, I am glad you were here. |
| 17:19 | neoncontrails | I'm not sure I would've stumbled on the solution to that. |
| 17:26 | devth | how to get lein to output just the project version? |
| 17:31 | devth | looks like i'm gonna have to use lein-exec |
| 17:36 | justin_smith | devth_: hack way to do it (nth (read-string (slurp "project.clj")) 2) |
| 17:36 | justin_smith | if it's there on disk |
| 17:36 | justin_smith | I'm sure there's a right way that isn't that though |
| 17:37 | devth_ | ah, yeah |
| 17:37 | devth_ | could use that in combination with lein-exec |
| 17:38 | justin_smith | devth_: the good way to do it would be to make a simple lein plugin that gets that data from the project |
| 17:38 | justin_smith | that would be a very simple plugin |
| 17:38 | devth_ | true |
| 17:38 | devth_ | wonder if someone already has |
| 17:39 | devth_ | there's one that sets version :) |
| 17:39 | justin_smith | devth_: https://github.com/taoeffect/slothcfg |
| 17:39 | justin_smith | runtime access to project.clj data? |
| 17:43 | devth_ | hm, so i don't think lein-exec and another plugin can work together |
| 17:43 | devth_ | plugins run in a separate jvm or smth? |
| 17:43 | devth_ | tried: lein exec -e "(use 'cfg.current) (println (:version project))" |
| 17:44 | devth_ | but it can't find cfg.current |
| 17:45 | devth | ah, need -ep to eval in-project |
| 17:46 | devth | lein exec -ep "(use 'cfg.current) (println (:version @project))" |
| 17:47 | devth | lol. a bit heavy handed |
| 18:04 | justin_smith | (defn 😈 [& args] ...) <- what should go in there? |
| 18:08 | ystael | justin_smith: i dunno but it should probably consume all available file descriptors |
| 18:08 | MJB47 | (mapv #(println "i hate bytes") (range)) |
| 18:09 | justin_smith | MJB47: making them signed is the icing on the cake |
| 18:32 | yenda | Hi guys, do you have a better way to refactor cljs code than manual work ? |
| 18:38 | neoncontrails | yenda: I've had great results with IntelliJ/Clojure's refactor tool. I think emacs also has a respectable one, but it's a bit tricky to use |
| 18:39 | neoncontrails | yenda: if you decide to go with intelliJ though, make sure to get IDEA 14 (not 15, the most recent). Cursive, the Clojure plugin, hasn't been updated yet |
| 18:40 | BRODUS | neoncontrails: what refactoring tool do you use for emacs? |
| 18:40 | cfleming | neoncontrails: Cursive does work with v15 |
| 18:40 | BRODUS | i didn't know there waso ne |
| 18:40 | cfleming | BRODUS: clj-refactor |
| 18:40 | cfleming | (I don't use it, but that's what you want) |
| 18:40 | neoncontrails | cfleming: it does? Yess! I might get that right now then |
| 18:41 | BRODUS | ooo, thanks |
| 18:41 | noncom|2 | but it won't refactor clojurescript because it relies on a running jvm, no? |
| 18:41 | neoncontrails | BRODUS: uhh... I'll look up the name. It was the scary tool none of us understood at all in SICP |
| 18:41 | cfleming | @noncom|2 I believe that's the case, yes |
| 18:42 | BRODUS | there was emacs in SICP ? |
| 18:42 | cfleming | Cursive's does work with CLJS, but is currently more limited than clj-refactor |
| 18:42 | noncom|2 | cfleming: that might be interesting for yenda then |
| 18:42 | zms | I'm trting to launch a cljs repl with boot using cljs-repl task. I get "Implicit target dir is deprecated, please use the target task instead. Set BOOT_EMIT_TARGET=no to disable implicit target dir. |
| 18:42 | neoncontrails | yup. My university really threw us in the deep end of the pool there |
| 18:43 | BRODUS | yeah it took me 2-3 attempts over a couple years before I took to emacs, can't imagine having to learn it with an actual workload |
| 18:45 | zms | running with "BOOT_EMIT_TARGET=no boot cljs-repl" seems to indicate that an nrepl server was started but there's no repl." |
| 18:45 | neoncontrails | It wasn't pretty. I still managed to fall kind of in love with Scheme, but it definitely left a Pavlovian aversion in me to emacs itself |
| 18:47 | zms | Emacs CIDER also fails to connect to the reported port of the nrepl server.. :-( Any hints/guidance appreciated. |
| 18:48 | justin_smith | zms: is the cljs repl provided via a browser, or node, or? |
| 18:51 | turbofail | huh. i learned to love emacs in order to deal with my workload |
| 18:51 | zms | justin_smith: hmm, good point. i'm using https://github.com/adzerk-oss/boot-cljs-repl with weasel and piggieback.. so i guess it should be provided by browser. however, i want to use node. |
| 18:53 | justin_smith | zms: so you get a clojure repl, then eventually you call (start-repl) ? |
| 18:54 | justin_smith | (once the node process is running with that half of the piggieback/weasel stuff?) |
| 18:58 | zms | justin_smith: i guess i'm all confused. must have faulty mental model.. :-( what i would like: Emacs CIDER to be connected to a repl provided by node. |
| 18:58 | pilne | hrm... clojure + actors for a concurrent game engine.... |
| 18:59 | yenda | cfleming: clj-refactor doesn't work with cljs |
| 19:00 | justin_smith | zms: the way it works is that you have a clojure repl on a jvm, and you have a clojurescript process with a websocket. The websocket connection is used to send your compiled cljs and run it, and the results come back to your repl (which is still on top of the jvm) |
| 19:00 | justin_smith | you need the jvm because you are compiling new clojurescript code as you go in order to run the repl |
| 19:00 | yenda | neoncontrails: thanks, I prefer emacs though :/ |
| 19:00 | neoncontrails | turbofail: yeah that's one way of looking at it. I just remember one time being on a tight deadline, and hitting the wrong key combo, and suddenly everything I typed was wingbats |
| 19:01 | turbofail | lol |
| 19:01 | justin_smith | zms: so you need cljs code that opens up the websocket and is ready to eval your code, and then you bootstrap (piggyback) that on top of a regular clj nrepl process |
| 19:01 | neoncontrails | and I distinctly remember figuring out 10 minutes later that I was stuck in something called 'cuneiform mode' and kind of rage sobbing |
| 19:03 | neoncontrails | yenda: you are a much braver soul than I. :) Glad you found something |
| 19:03 | yenda | neoncontrails: for me the hardest par was not getting myself stucked in configuration mode, where I would end up configuring emacs for days |
| 19:03 | yenda | then I discovered spacemacs and barely felt the need to configure anything |
| 19:05 | zms | justin_smith: so i need 1) clojure repl on jvm (using boot repl), 2) clojurescript process with a websocket (using cljs-repl?), 3) CIDER connects to nrepl (which passes the code to cljs). did i get it right? |
| 19:05 | neoncontrails | yenda: yeah you make a good point though. I've been rocking Vim a bit lately, when constrained to a headless server, and I think it can be pretty tough to learn the keystrokes if you haven't directly participated in their making |
| 19:06 | justin_smith | zms: I'm not sure about "cljs-repl" but the rest sounds exactly right |
| 19:06 | justin_smith | the cljs process will be node loading the js that your cljsbuild outputs |
| 19:06 | justin_smith | and that js should make it open a websocket that talks to your repl, etc. |
| 19:07 | yenda | neoncontrails: that's why spacemacs is so awesome, it has all the nice tools to help you learn the keystrokes as you go |
| 19:07 | zms | justin_smith: so the missing piece is something that will start a process that will link node and clj repl over a websocket, right? |
| 19:07 | justin_smith | zms: yeah, this is what piggieback and weasel do together |
| 19:07 | justin_smith | their readme files should show you what to do |
| 19:08 | neoncontrails | yenda: yeah? Hmm. I'll keep that in mind. I will gladly accept offers of handholding when it comes to emacs config |
| 19:08 | zms | justin_smith: thank you for the clarity. be back in a few. :) |
| 19:08 | justin_smith | zms: I use figwheel via lein, which automates all this (but I still ended up needing to know the details because abstractions leak, of course) |
| 19:09 | yenda | neoncontrails: apparently there is no refactoring tool for cljs yet though :( |
| 19:09 | neoncontrails | Gotta say. I've never felt more like an old man than I have the past few weeks on Vim |
| 19:10 | zms | justin_smith: figwheel with browser or node? |
| 19:10 | neoncontrails | At first, I mean, it was understandable. I was just picking it up. I was just getting started. |
| 19:10 | justin_smith | zms: with browser, but with node wouldn't be a huge difference - either way they load up the js and try to connect to a websocket |
| 19:10 | zms | justin_smith: honestly, lein has me frustarted.. it seems magical. boot seems conceptually something i can understand. |
| 19:11 | justin_smith | zms: yeah, the classic declarative vs. procedural split |
| 19:12 | neoncontrails | Then a week went by. Then another week. and I'm still terrified to move the cursor, lest I lose my 300th ordinal position in whatever line I'm on |
| 19:12 | zms | justin_smith: which is which? :) |
| 19:13 | justin_smith | zms: lein is declarative (you use a data structure that describes your outcome and parameters), boot is procedural (code that does the steps you want performed) |
| 19:14 | BRODUS | im using cider to dynamically refer a namespaces vars in another if it isn't already. is there a way to check what has been required in the namespace? |
| 19:16 | justin_smith | BRODUS: ns-aliases shows you what has been aliased |
| 19:16 | amandabb | hmmmm |
| 19:16 | justin_smith | ns-refers shows you what has been used / referred |
| 19:16 | justin_smith | BRODUS: but really, running require twice is not an error, and without the :reload arg it doesn't do anything the second time |
| 19:17 | justin_smith | BRODUS: calling refer again isn't an error either, if you want to do it at that level |
| 19:17 | justin_smith | ,(doc refer) |
| 19:17 | clojurebot | "([ns-sym & filters]); refers to all public vars of ns, subject to filters. filters can include at most one each of: :exclude list-of-symbols :only list-of-symbols :rename map-of-fromsymbol-tosymbol For each public interned var in the namespace named by the symbol, adds a mapping from the name of the var to the var to the current namespace. Throws an exception if name is already mapped to somethin... |
| 19:17 | neoncontrails | three cheers for idempotency! *cheers seven times* |
| 19:17 | justin_smith | heh |
| 19:20 | justin_smith | ,(refer 'clojure.core) ; no error! |
| 19:20 | clojurebot | nil |
| 19:20 | justin_smith | it only errors if the new refer conflicts |
| 19:20 | BRODUS | justin_smith: thanks, i didn't realize require did nothing second time around |
| 19:20 | zms | justin_smith: i read those documents several times (piggieback, weasel, and others) but it began to make sense only once you spelt it out. so thanks for that. i have enough homework for now. :) |
| 19:22 | yenda | neoncontrails: you can play vim-adventures to learn faster |
| 19:24 | neoncontrails | yenda: ooh! I was seriously thinking, just the other night, I need to either make a game or find one, because I think the only way I'm going to learn that many keybindings is if I'm playing like... Bop It! or something |
| 19:25 | neoncontrails | But that might be kind of fun, actually. Delete it! Find it! Yank it! Yank it! |
| 19:26 | BRODUS | i liked this one: http://www.openvim.com/ |
| 19:26 | BRODUS | don't know if vim-adventures goes deeper without paying |
| 19:28 | neoncontrails | That's pretty cool too. I've talked myself into making Vim It! See ya, evening plans |
| 19:37 | BorisKourt | Does anyone use lentic here? |
| 19:38 | BorisKourt | (Better question might be, how do I search through all package commands in Spacemacs. It looks like the two commands Lentic uses are renamed.) |
| 19:39 | amandabb | is there any way to return a value from doseq? |
| 19:40 | amandabb | im trying to iterate through a 2d array and when two if's are true i want to return a value and exit out of the loop |
| 19:40 | amandabb | and then if it gets through both of them then to just return another value |
| 19:40 | turbofail | doseq never returns a value, it always returns nil |
| 19:41 | amandabb | so what else can i use? |
| 19:41 | amandabb | trying to do something like this: (doseq [x .. y ..] if#1 .. if #2 .. return a value! .. ... . . done looping through both so just return this value instead |
| 19:42 | devth | rewrite it using reduce |
| 19:42 | turbofail | maybe reduce |
| 19:42 | amandabb | nested reduces? |
| 19:43 | turbofail | you could do a nested reduce, or you could do (reduce (fn [[x y]] ...) (for [x ... y ...] [x y])) |
| 19:45 | amandabb | hmmm |
| 19:45 | amandabb | there's got to be a better way of doing this |
| 19:45 | amandabb | i guess ill just think on it for a while |
| 19:45 | turbofail | or actually you could do it without reduce just by using some |
| 19:46 | justin_smith | amandabb: you can use reduce with reduced |
| 19:46 | justin_smith | ,(doc reduced) |
| 19:46 | clojurebot | "([x]); Wraps x in a way such that a reduce will terminate with the value x" |
| 19:47 | amandabb | ok |
| 19:47 | amandabb | ill look in to reduced and some |
| 19:47 | amandabb | thanks |
| 19:47 | justin_smith | ,(reduce (fn [_ x] (when (even? x) (reduced x))) [1 3 5 8 1]) |
| 19:47 | clojurebot | 8 |
| 19:47 | amandabb | yeah it sounds about right |
| 19:47 | justin_smith | amandabb: you can use reduce to walk the result of for, and for has the same syntax as doseq |
| 19:48 | amandabb | ok |
| 19:49 | amandabb | im just not sure if reduce is right though |
| 19:49 | amandabb | i dont really have an accumulator value per-se.. |
| 19:49 | justin_smith | if all you are doing is checking for a specific value, use (some pred? (for ...)) |
| 19:50 | amandabb | yeah that might be it |
| 19:51 | turbofail | actually (first (for [x ...y ... :when (pred x y)] (foo x y))) would do it to |
| 19:51 | turbofail | s/to/too/ |
| 19:51 | justin_smith | oh yeah, :when is cool |
| 19:51 | amandabb | ohhh right first would cut it off right? thats a good point |
| 19:51 | turbofail | there's so many possibilities |
| 19:51 | amandabb | it wouldnt continue doing the calculation becuse it only needs one |
| 19:51 | turbofail | right |
| 19:51 | amandabb | ill look in to that too |
| 19:51 | justin_smith | first is not guaranteed to cut it off |
| 19:52 | amandabb | really? |
| 19:52 | justin_smith | if f has side effects that are important, don't do it that way |
| 19:52 | turbofail | well yeah there's like chunked sequences |
| 19:52 | justin_smith | amandabb: chunking |
| 19:52 | justin_smith | side effects and laziness are a bad mix |
| 19:52 | amandabb | theres no side effects in here |
| 19:52 | amandabb | im just checking for intersections in a grid |
| 19:52 | justin_smith | amandabb: I said "if f has side effects that are important" |
| 19:52 | justin_smith | amandabb: if it doesn't go right ahead and do it that way |
| 19:53 | amandabb | ok cool |
| 19:53 | justin_smith | ,(first (map print [1 2 3 4 5 6])) ; amandabb - example of the gotcha |
| 19:53 | clojurebot | 123456 |
| 19:53 | justin_smith | it printed all of them because chunking |
| 19:53 | amandabb | i dont quite understand |
| 19:54 | justin_smith | amandabb: map is lazy, but it still processed all the items even though we only asked for the first one |
| 19:54 | amandabb | yeah im saying why does it process all of them if it knows we just need one |
| 19:54 | justin_smith | amandabb: it doesn't |
| 19:54 | justin_smith | first knows, map doesn't |
| 19:55 | justin_smith | chunking |
| 19:55 | justin_smith | amandabb: basically, for efficiency reasons it processes 32 items at a time |
| 19:56 | amandabb | so first only stops map from processing more elements when it can guarantee the map function is pure? |
| 19:56 | justin_smith | well, if it can guarantee the map function is pure, it doesn't matter whether it stops it or not |
| 19:56 | justin_smith | (except for cpu cost of course) |
| 19:57 | amandabb | i guess what im failing to understand is that i was under the impression when first is paired with lazy sequences that it doesnt process the entire list |
| 19:57 | amandabb | that it only does as much as it needs to and is thus efficient |
| 19:57 | justin_smith | amandabb: yeah, it's not that deterministic - chunking every time is faster than taking only one item at a time because you might not need them all |
| 19:58 | amandabb | ohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh |
| 19:58 | amandabb | i get it now |
| 19:58 | justin_smith | amandabb: stupid analogy "I need a soda" - it's faster to get a six pack than tear one can out |
| 19:58 | justin_smith | especially when it's "I need n sodas" and you don't know until runtime - default to grabbing some cases |
| 19:58 | amandabb | so if a list is less than a certain size (say 100) it just runs through the whole thing because that would be faster than trying to get speed improvements with laziness |
| 19:59 | justin_smith | right - it turns out it chunks by groups of 32 iirc |
| 19:59 | amandabb | gotcha |
| 19:59 | amandabb | ok thats neato |
| 19:59 | amandabb | i have to go now thanks for the help |
| 19:59 | justin_smith | np |
| 20:12 | zms | justin_smith: yay! finally everything works (with lein and figwheel). for reference, this is what i followed: https://libraries.io/clojars/nrepl-figwheel-node%2Flein-template |
| 20:13 | zms | justin_smith: good night! |
| 20:16 | justin_smith | zms: you too, glad you figured it out |
| 22:04 | domgetter | If you pass a partialed function to reduce, does it remake it every iteration? ex: https://gist.github.com/domgetter/bb41ebb4056aff7804d7 |
| 22:14 | justin_smith | domgetter: reduce is not a macro, all its args including the function are evaluated when the form is compiled |
| 22:14 | justin_smith | domgetter: easy test... |
| 22:14 | domgetter | ah okay, and macros get evaluated at runtime? |
| 22:14 | justin_smith | ,(reduce (partial str (println "test")) [1 2 3]) |
| 22:14 | clojurebot | test\n"123" |
| 22:15 | domgetter | right, because that would've printed test three times if it was evaluating the partial every time |
| 22:15 | justin_smith | domgetter: macros can change how their args are evaluated - they can cause them to be evaluated at compile time, during some run-times, during every run-time, never.... |
| 22:15 | justin_smith | right |
| 22:15 | domgetter | Okay I'll keep that in mind, thank you |
| 22:20 | domgetter | justin_smith: one more question. are these delays superfluous or will clojure try to evaluate the let bindings? https://gist.github.com/domgetter/02fbe16020dd8b481d83 |
| 22:21 | domgetter | oh I guess I could do my own test with println |
| 22:26 | justin_smith | domgetter: yes, it will run all the clauses, so you can use delays if you want to only evaluate certain clauses |
| 22:27 | domgetter | yea, I just used the side-effect trick to convince myself that that's true :) |
| 22:27 | justin_smith | but here I think just the code is clearer than the delay / deref combo |
| 22:29 | justin_smith | yeah, println is a good way to test which things actually run |
| 22:30 | devth | println-driven-development |
| 22:46 | domgetter | println-driven-*understanding* |
| 22:54 | sdegutis | welp |
| 22:58 | justin_smith | sdegutis: whelps http://leerburg.com/Photos/whelp-1.jpg |
| 22:58 | sdegutis | haha lol |
| 22:58 | sdegutis | justin_smith: what new adventures in clojureland have you partaken in as of late old chap? |
| 23:26 | justin_smith | sdegutis: same old, working for a startup doing graph analysis |
| 23:27 | justin_smith | err, doing an app that does graph analysis |
| 23:27 | sdegutis | man that sounds so boring |
| 23:27 | sdegutis | is it fun? |
| 23:27 | justin_smith | it's actually pretty great, I've just been stuck with the generic stuff lately |
| 23:27 | justin_smith | the stuff that would just work out of the box with rails - login, settings, etc. |
| 23:28 | justin_smith | or at least the things I gather are much more cookie cutter there |
| 23:31 | sdegutis | hahaha yeah i know those feels |