#clojure logs

2016-01-06

00:15sdegutisDo any of yall use components for /everything/ in your system?
02:59BRODUSanyone 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:21owlbirdwhich web server has a better performance, I tried ring-jetty-adapter, but it was worse than Tomcat/Java.
03:42kungiowlbird: there is a clojure web server benchmark here: https://github.com/ptaoussanis/clojure-web-server-benchmarks
03:49qsysabout 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:50qsysStart from 'do it the Java-way in Clojure' and simplify it by introducing clojure concepts step by step?
03:50TEttingerqsys, good in principle, but bad for making good clojure code
03:51TEttingeryou can use amap in place of map when using arrays instead of vectors, but... it will be uglier
03:51TEttingerclojure the clojure way tends to be vastly shorter than clojure the java way or java the java way
03:51qsysYeah, it's true it's not good clojure code, but it's about learning.
03:52TEttingerbut... learning bad ways is not good
03:52qsysallright... better than not learning at all?
03:53owlbirdFor my experience (a Java programmer) to learn Clojure, should get used to write little method, combining them with 'apply/map/reduce/filter...'
03:53qsysright - bad Java code is kind a commonplace (and accepted)
03:54qsysthe 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:54TEttingerI'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:55qsysStarting from what people know might help some people out
03:55BRODUSthe clojure way kind of expects you to keep the java interop to a minimum.
03:55TEttingerthose two libs might be a good starting point to introduce clojure syntax etc
03:56owlbirdBut Clojure is a little slower than java, and the tech leader has no reason to choose a worse performance language
03:57TEttingerit depends, it can be drastically faster to write
03:57qsysso, rather than starting 'java code in clojure', starting coding like clojure in java :p. Might be fun :)
03:58BRODUSi may be wrong but I think scala kind of expects you to use both scala and java
03:58mpenetowlbird: by that logic we'd all be doing assembly
03:58qsyswell, 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:58owlbirdI saw a lot of performance comparison, if a Java programmer want a better language, why don't choose Scala or Nginx/luajit
03:58TEttingerbecause nginx isn't a language
03:58owlbirdwhich is more practical
03:58mpenetowlbird: if it makes his team 10x more productive for 5% perfs hit (random value) he'd jump ship
03:59owlbirdNginx is not, bug openresty does
03:59owlbirdbut
03:59qsysI only know: I don't have the instability/performance problems many of my collegues have
04:00qsysI 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:01qsysSome 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:03qsysso 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:04noncom|2BRODUS: no, scala does not actually... it can replace java
04:04qsysscala can replace Java, like Ceylon, or like Kotlin (which even has a 'java to kotlin converter' built-in)
04:04algernonqsys: 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:05algernonqsys: it was a huge success, despite half of the team being very scpetic about clojure, lisp and the JVM up front.
04:06qsysallright... 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:06algernonqsys: 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:06algernonqsys: yeah, on the fly explanation is hard. never managed to sell clojure that way, either
04:07qsyswell... 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:08mpenetfrom 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:08powered java developers don't see the point of immutability?
04:09qsysAnyway, just giving it a try and jump right into clojure in a crash course might work. I'm curious how this will be...
04:09mpenetI 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:09algernonperhaps 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:09qsyspowered: 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:10algernon(that = tech leads, architects, managers)
04:10noncom|2powered: it's not about immutability.. there comes the whole "another language" thing with "oh my it's lisp" thing
04:11noncom|2and most programmers that i worked with were so brainwashed by oop that immutability was an almost unexisting concept for them
04:11noncom|2coz objects have state, you know..
04:11qsystrue...
04:11poweredthe string type is immutable in java, so they should at least be familiar with the concept
04:11qsysnoncom|2: that's the thing: they call Java oop, no mather how non-oop they are doing :p
04:12noncom|2oh yeah :) and when trying to solve oop shortcommings, they just apply more oop
04:12mpenetfunctional 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:12mpenetbase concepts are very simple
04:12poweredit's all about applying them in the right way
04:13qsysmpenet: 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:13noncom|2mpenet: it is, scientifically, but real world programmers are not always about science..
04:15mpenetI 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:16noncom|2theoretically yes. in practice it comes down to neuroplasticity, bias, age, self, and other biological factors
04:16mpenetsome 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:17noncom|2well those are lucky who are open-minded :)
04:18qsyslucky, and well, sometimes unlucky ;)
04:21abunuwas~@i-blis
04:21clojurebotHuh?
04:23qsysmpenet: 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:25qsysanyway, I take it as a challenge to jump right into clojure for a clojure crash course :p
04:28owlbirdprogramming 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:28owlbirdIt's not fancy, but it works well
04:30noncom|2yeah, to me commercial programming is often like coal mining
04:32qsyslol
04:32BRODUSnoncom|2: you should say that to a coal miner
04:34qsysowlbird: 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:38owlbirdqsys: 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:40mpenetpeople were saying the same about c/c++ when java came out :)
04:40owlbirdSometimes, 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:41qsysyes, 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:41mpenet(or asp/php/perl for web thingies)
04:43qsysIt 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:43qsysand that's the only truth for many.
04:45qsys... but that's not about clojure, and since this is channel #clojure and not #whining, I'd better stop whining about it :p.
04:46powered25 minutes to rebuild because it's so much code, or because people push code with compiler errors in it?
04:47qsysmore about too much code: too much useless code, no errors, loads of warnings etc.
04:48owlbirdI 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:51qsysowlbird: 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:52mpenetIt's all theorical bs really, I have seen "capable" outsourced teams of java devs kill a well funded project over time.
04:53mpenetit's very dependant on the context and many other factors
04:56mpenetGrowing toxic code is never good. Can win you some time at the beginning but you almost always end up paying a high price
04:59schmirdammit. I've got 400k lines of toxic RosiSQL code that should be reimplemented. my life sucks.
05:03qsysschmir: ;)
06:25ridcully_schmir: that's a whole lotta rosi
06:41t0byridcully_ wins one internets
06:43schmirridcully_: yes, but at least I'm using clojure for the new implementation
08:22juanjoyesterday i was able to compile clojure, thanks!
08:22juanjohow can i run the compiled version of it instead the system installed one?
08:24juanjojava -cp clojure-${VERSION}.jar clojure.main
08:24juanjosorry, it was in the readme :/
09:26jsabeaudryCan this be written better https://www.refheap.com/113414 ?
09:34vijaykiranjsabeaudry: what does sub return ?
09:37jsabeaudryvijaykiran, my guess would be the publication, let me check
09:39jsabeaudryvijaykiran, I was wrong, it returns the channel that was just subscribed
10:10sdegutis_Hallo.
10:18hironI'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:21sdegutis_justin_smith: how heavily are you using component?
10:23favetelinguisi 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:24ridcully_that _could_ be a problem with your window manager
10:26favetelinguisi use xmonad
10:27ridcully_have a websearch about "non reparenting wm java swing" - if this brings nothing up, i can put my script up on refheap
10:27sdegutis_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:28ridcully_it basically to lie about the familiy of window manager you are using to make java render anything
10:29Bronsaridcully_: FYI refheap is shutting down
10:29Bronsamight be read-only already
10:29ridcully_yeah, heard about it here. thanks for the info
10:29sdegutis_Bronsa: why?
10:29sdegutis_Bronsa: I thought it was really cool
10:31Bronsasdegutis_: people started uploading stolen credit card infos or something like that and Raynes doesn't have the time to deal with that IIRC
10:31sdegutis_ahh yeah that'll do it
10:48favetelinguisridcully_: seems to be a known issue with xmonad, thanks for the pointer
10:51ridcully_favetelinguis: no only with xmonad. you found the workarounds?
10:53favetelinguismight, http://stackoverflow.com/questions/30742662/java-swing-gui-not-displaying-in-xmonad
10:53engblomridcully_: Try 'export SAL_USE_VCLPLUGIN=gen' before using your JVM apps
10:54engblomridcully_: Since adding that to my configuration I have never had any problem with xmonad
10:55ridcully_engblom: i dont run xmonad - i use some script where the source is maybe burried in my git log. most likely wmname
11:28TimMcBronsa: I talked with him and he said that it's not being taken down, just made read-only, which is great.
11:28jsabeaudrySo if I understand correctly I can never put nil on a channel because consumer will think the channel is closed?
11:29BronsaTimMc: ah, good
11:35ridcully_jsabeaudry: yes. documented e.g. here https://clojure.github.io/core.async/#clojure.core.async/put!
11:39jsabeaudryridcully_, ah, yes indeed! thanks!
11:53domgetterwhat's the reverse of mapcat? What will take a sequence and turn it into a sequence of subsequences?
11:53justin_smithdomgetter: partition? partition-all? split-with?
11:53domgetterI'm trying to take a list of words and shove them into subsequences that represent rows of words when displayed
11:54domgetterI'll look into those three, thank you :)
11:55domgetterare any of those stateful with respect to the currect accumulating subsequence?
11:55justin_smithno
11:56justin_smithyou can use reduce or loop for that though
11:56domgetterokay I'll just build my own then, thank you
12:10domgetterjustin_smith: thanks for the advice. I got it up and running: https://gist.github.com/domgetter/2939fd3f5c45fd082a25
12:11justin_smithdomgetter: 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:11justin_smith(defn rows [[full pending] word] ...)
12:12justin_smithso instead of of pop at each step, you can just conj to pending / or conj to full and pass [] as pending
12:12domgetterokay I think I understand. I'll go ruminate on it and see if I can come up with a result
12:13justin_smithdomgetter: 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:13justin_smitherr, always use peek too, that is
12:13justin_smith,(peek [1 2 3])
12:13clojurebot3
12:14domgetterah okay. got it. obligatory "why don't they just make last efficient for vectors?" :P
12:15justin_smithdomgetter: yeah, last uses the seq interface rather than having it's own interface
12:15justin_smithit would need its own interface for that to work
12:17domgetterHmm, 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:17justin_smithdomgetter: nope, that's why I suggested splitting it in two parts like that
12:17domgetteroh you mean maintaining it in that structure til the end manually?
12:18domgetteror did you mean have "pending" be its own vector just chilling until I shove it into full?
12:18domgetterthat makes a lot more sense
12:20justin_smith(defn rows [[full pending] word] (if (> (apply + (count word) (map count pending)) 35) [(conj full pending) [word]] [full (conj pending word)]))
12:21justin_smithdomgetter: 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:21domgetterawesome, thanks for the insight :)
12:21justin_smithdomgetter: also see how I was able to combine your two sums into one apply +
12:21sdegutis_What's the benefit of using type hints? What's the downside of not using them? When should they be used?
12:22domgetteryea I saw that, that makes more sense. I was being a lot more procedural
12:22justin_smithsdegutis_: 100x perf difference when they are needed is not unheard of
12:22sdegutis_I've mostly been putting them in places to satisfy `lein check` but it feels a bit random and ad-hoc.
12:22sdegutis_justin_smith: wow...
12:22justin_smithsdegutis_: clojure knows when compiling whether it's outputting expensive runtime reflection ops
12:23justin_smithsdegutis_: that's why lein check can warn you - it's a hook that tells you when that happens
12:23justin_smithsdegutis_: and the reflection is very expensive
12:24justin_smithsdegutis_: I've even seen differences more like 1000x (in cases that involve not only reflection but also numeric boxing...)
12:26domgetterjustin_smith: the only "downside" is that I have to do a final conjoin after the reduce since I have a trailing pending vector
12:26justin_smithdomgetter: right, like I said, (apply conj (reduce ...))
12:26domgetteroh, you were one step ahead
12:27justin_smithdomgetter: I've done this before :)
12:30sdegutis_justin_smith: oh wow, then I'll definitely look for hot code paths in `lein check` and fix those
12:31domgetterjustin_smith: much better! https://gist.github.com/domgetter/2939fd3f5c45fd082a25
12:31justin_smithsdegutis_: 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:31sdegutis_justin_smith: hmm interesting concept
12:32Bronsasetting *unchecked-math* to :warn-on-boxed is also really useful
12:32justin_smithdefinitely
12:33sdegutis_Nice, only 33 reflection warnings. And none of them in hot code paths.
12:33sdegutis_Bronsa: whoa, definitely gonna set that one
12:33Bronsaalthough it doesn't catch all the boxing cases
12:34justin_smithBronsa: is there a good guide to finding numeric boxing that *unchecked-math* :warn-on-boxed would not catch?
12:34Bronsajustin_smith: http://dev.clojure.org/jira/browse/CLJ-1585 this is the only case I'm aware of
12:35BronsaI really dislike how clojure does automatic boxing/unboxing, I wish it didn't
12:35BronsaI'd rather use (Integer. x) and (int x)
12:36Bronsaalso 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:36Bronsabut it's probably way too late to even propose such a change
12:39sdegutis_It's never too late!
12:40justin_smithsdegutis_: clojure values back-compatibility, having to use (Integer. x) / (int x) explicitly would break so much code...
12:44Bronsayeah like, 80% of code that uses interop
12:45justin_smithbut oxlang could totally go that route
12:46sdegutis_oxlang!?
12:47sdegutis_arrdem: that looks fricken cool
12:47sdegutis_arrdem: do you use it in production yet?
13:04sdegutis_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:05justin_smithsdegutis_: 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:06justin_smithsdegutis_: j/k I have no idea honestly
13:06sdegutis_:D
13:07justin_smithsdegutis_: (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:07justin_smithsdegutis_: 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:07justin_smiththere's a max string size
13:08sdegutis_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:12justin_smithsdegutis: something like (let [s (java.io.StringWriter.)] (read-csv file s) (str s)) ?
13:12sdegutisyeah that's what I have
13:13sdegutiswell, close: (defn csv-to-string [csv & opts] (let [out (java.io.StringWriter.)] (apply write-csv out csv opts) (str out)))
13:13sdegutisthe apply is cuz it takes pseudo-mappified opts
14:22caternhow would I get an atomic set datastructure?
14:22caternjust put it in an atom?
14:22mikerodcatern: (atom #{})
14:22mikerodI guess I don't know what you mean actually
14:23mikerod#{} is thread safe
14:23mikerodevery modification just returns a new one, you don't affect the original
14:23mikerodif you want one though that multiple things refer to, then yes (atom {})
14:23mikerod(atom #{})
14:24mikerodwith atomic update
14:24caternhmm
14:25caternwhat 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:25caternis there a better way to do that than an atomic set?
14:26caternan (atom #{})
14:28justin_smithcatern: note that if you want only one thread to take the action, you can't just deref and swap as separate actions
14:29mikerodjustin_smith: yes, I was thinking of that
14:29mikerodbut if you are just conjoining some value to a set
14:29justin_smithcatern: and swap! retries, which means you probably don't want to put the launch of that action into the swapping function
14:29mikerodand you aren't concerned about it being conjoined more than once
14:29justin_smithmikerod: sure
14:30justin_smithcatern: how big a problem is it if accidentally more than one thread gets started?
14:30mikerodif you want to be able to see the set and conj to it atomically, you'd use some transaction based construcdt I guess
14:30justin_smithmikerod: or use something like an agent that synchronizes on its value (but runs async)
14:30justin_smithand thus does not swap
14:30justin_smiths/swap/retry
14:31mikerodsure, 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:32mikerodI 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:32caternjustin_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:32caternjustin_smith: so I don't want to open that websocket twice or create that datastructure twice
14:33justin_smithcatern: right
14:33mikerodnow I think the (atom #{}) way isn't good then
14:33justin_smithcatern: 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:34justin_smithor spawn the thread from inside the send-off actually (that would be best I think)
14:34mikerodit is weird to me you'd need to do something async for this
14:34mikerodnot to say I know the best/better way
14:35neoncontrailsI just realized, I still haven't contributed to an open source project yet. (Other than my own.)
14:35neoncontrailsIs there a bulletin board somewhere of Clojure projects seeking volunteers?
14:35caterni have too much incoming data to do it synchronously
14:35neoncontrailsOr is Git my best bet?
14:35caternthe "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:36justin_smithmikerod: 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:36mikerodjustin_smith: I know that part
14:36justin_smithoh, OK
14:37mikerodI just thought there was something synchronous that allowed you to view a value + do something based on it + update it in one lock
14:37mikerodif that makes sense
14:37catern(oh, when you said do something async you were talking about the agent way rather than the atom way. nvm)
14:37mikerodcatern: yes, sorry
14:37justin_smithmikerod: not without retries
14:38mikerodjustin_smith: yeah, I meant to mention that one
14:38mikerod"do something side-effecty"
14:38justin_smithyeah
14:38BRODUSneoncontrails: 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:40neoncontrailsBRODUS: Hmm. There must be some resource besides git though, no? Or a way to browse git for repos actively seeking contributors?
14:41BRODUSneoncontrails: there was a link on HN recently you might like, i'll try and find it
14:42neoncontrailsBRODUS: I do love HN. Thanks
14:42caternjustin_smith: i'm worried about the send-off being delayed, though
14:42caterni want to create the websocket ASAP because data is being dropped on the floor as long as I don't have it open
14:42justin_smithneoncontrails: lein has issues that are marked as specifically good for newcomers to work on, and is very open to contributions
14:42catern(this is for a programming game)
14:43BRODUSneoncontrails: ah it was this http://up-for-grabs.net/#/ , no clojure projects though
14:43justin_smithcatern: it will be delayed if another send-off is still running
14:43neoncontrailsjustin_smith: oh, wow. lein itself, eh? I'll look into it
14:43caternjustin_smith: i mean, those are implementation details though
14:43caternit's not necessarily that I want to do it synchronously
14:43caterni just want to do it fast
14:44justin_smithneoncontrails: 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:44caternscheduled immediately
14:44catern(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:44justin_smithcatern: 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:45neoncontrailsBRODUS: still a nice list, thanks for sharing
14:45justin_smithcatern: 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:45neoncontrailsjustin_smith: also a great suggestion. Thanks for the help
14:46justin_smithcatern: 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:46justin_smithif that sequence of actions is a bottleneck of any sort, you are writing some amazing high performance code I tell you hwat
14:47caternheh
14:47caternwell, creating/opening the websocket might take a bit of time...
14:47justin_smithcatern: right, do that in a new thread
14:47justin_smithnot in the agent
14:48caternbtw
14:48caternwhat should I use to make async HTTP requests in Clojure? and async websockets?
14:48justin_smithcatern: I use http-kit, and the sente lib which maps websockets to core.async
14:49caternjust clientside btw
14:49justin_smithI haven't tried http-kit for client-side websockets though
14:49justin_smithbut iirc that exists, if not aleph can do it
14:52caternaleph? why not use sente?
14:52justin_smithcatern: sente uses aleph or http-kit
14:53justin_smithaleph and http-kit do the websocket part, sente hooks it up nicely to core.async
14:54justin_smithztellman 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:57caternhmm, sente appears to assume you control both ends?
14:57caternserver and client
14:57justin_smithcatern: yeah, it's kind of frameworky
14:57justin_smithmanifold is more flexible
14:58caternbut aleph would be the part actually doing the websocket part
14:58caternafaics http-kit doesn't have websocket client support
14:59justin_smith'k
15:00justin_smithyeah, looks like it only has server support, and lately I don't think it's as well maintained as aleph either
15:01caternaleph has http too
15:01caternso I guess I'll just use that for everything
15:01caternnormal http*
15:05caternso, wait, I can't really tell
15:05caternhttp://ideolalia.com/aleph/literate.html#aleph.examples.http
15:05caternhow do I get callback-style thing?
15:05caternget a*
15:07justin_smithcatern: if you go down to the http/get examples, instead of specifying a callback, you chain operations on the dereferenced result
15:07justin_smithhmm... maybe there is a way to do a callback too though
15:07caternyeah, I saw that, but that's not what I want, I think
15:08caternsince, well, right now my architecture is to fire off HTTP a bunch of requests every fraction of a second
15:08caternfire off a bunch of HTTP requests
15:09justin_smithcatern: did you get down to the aleph.examples.websocket stuff at the bottom?
15:09caterni don't want to have to wait for any or all of them to complete before firing off the next
15:10caternjustin_smith: yeah, I can't really grasp what's going on, but I can only assume that I can register some callbacks maybe
15:11justin_smithcatern: I think bus/subscribe is the thing you want there, from skimming that code
15:11justin_smithcatern: I'm interested myself as I may want to upgrade from http-kit/sente to aleph/manifold...
15:16caternthis is quite complex
15:17justin_smithcatern: might be easier to just use the direct socket with socket i/o, then upgrade if you need the features
15:17justin_smithcatern: the more I work on my websocket connected app the more sense those features make...
15:20caternthe direct websocket or TCP socket?
15:20justin_smithwebsocket
15:21caterni can't even tell what the features are here
15:22caternthis doesn't look any better than wrapping synchronous actions in some async thing
15:22caternanyway, operating on the direct socket would be synchronous, right?
15:23lokienHey, 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:23justin_smithcatern: depends, you could use nio
15:23justin_smithlokien: are you processing a sequence of some sort start to end?
15:24lokienjustin_smith: yeah
15:24justin_smithif so, reduce
15:24lokienlet me show you what'd be my input and desired output
15:24justin_smith,(reduce (fn [letters letter] (update letters letter (fnil inc 0))) {} "hello")
15:24clojurebot{\h 1, \e 1, \l 2, \o 1}
15:24lokien"next prev next next" -> [0 1 0 1 2]
15:25lokien(vector is 0 initially)
15:25lokien"" -> [0]
15:26caternjustin_smith: wait so is this websocket support all just borrowed from some java library?
15:26ridcully_,(frequencies "hello")
15:26clojurebot{\h 1, \e 1, \l 2, \o 1}
15:27justin_smithridcully_: right :) just showing the general idea of how to do that with reduce
15:27lokienridcully_: I know, but.. how does that help?
15:28ridcully_lokien: that was to make justin_smith smile
15:28lokienridcully_: oh, well, you're a nice person
15:29TimMclokien: 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:29TimMcbesides (constantly [0 1 2]) ;-)
15:29justin_smith,,(reduce (fn [moves word] (conj moves (({"next" inc "prev" dec} word) (peek moves)))) [0] (clojure.string/split "next prev next next" #" "))
15:29clojurebot[0 1 0 1 2]
15:31justin_smith,(reductions (fn [move word] (({"next" inc "prev" dec} word) move)) 0 (clojure.string/split "next prev next next" #" "))
15:31clojurebot(0 1 0 1 2)
15:31justin_smithsimpler, I think
15:32lokienI tried to do it with "loop"
15:32lokienbut it was a nightmare
15:33justin_smithlokien: 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:34justin_smithand unlike map / for, they carry state you can use at future steps
15:34lokienjustin_smith: idiomatic clojure is so good, my clojure is awful tho
15:34justin_smithlokien: the solution is to write more clojure - and share your code with other clojure folks
15:35sdegutisthe level of indirection in duct is really confusing me... https://github.com/weavejester/duct/blob/master/duct/src/duct/component/endpoint.clj
15:35justin_smithmy clojure was terrible when I started, it's maybe acceptable now
15:35lokienjustin_smith: primarily with you, I guess
15:35lokienacceptable?
15:35lokienwriting code for entire irc?
15:35lokienare you serious? :D
15:35justin_smithheh, that's just one-liner examples, building real stuff is different
15:36lokieneven more demanding? ygh
15:37sdegutislol justin_smith "maybe acceptable"
15:37justin_smithlokien: 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:38lokieneven sdegutis says you're beyond "acceptable"!
15:38justin_smithlike, I still have yet to hit the "build a useful lib that has nothing in it I am embarrassed of" landmark
15:38sdegutislokien: "even sdegutis" lol
15:38sdegutisjustin_smith: that goal is literally impossible due to the 6-months rule
15:39lokienjustin_smith: for how long have you been in clojure family?
15:39lokiensdegutis: welp, you're good too
15:39justin_smithlokien: I've been using clojure for ... about 4 years?
15:39sdegutishey me too!
15:39justin_smithsdegutis: OIC http://www.imdb.com/title/tt0865561/
15:39lokiensdegutis: I saw you on hacker news, is paladin usable now?
15:39sdegutislokien: wha?
15:40sdegutislokien: i was on HN?
15:40lokiensdegutis: you were commenting
15:40sdegutisoh
15:41lokienjustin_smith: that's not 20 years!
15:41lokienI mean, you don't have to have a killer app/lib yet
15:41sdegutislokien: 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:41lokiensdegutis: damn, I wanted to try it
15:42sdegutislokien: haha get in line ;)
15:42sdegutis(aka: i wanna try it too!)
15:43lokiensdegutis: only if I could help
15:43lokienjustin_smith: where would I use "loop" form then?
15:44TEttingersdegutis: making a language eh? clojuresque?
15:44justin_smithlokien: where speed is your top priority, it can be faster
15:45sdegutisTEttinger: heh i wouldnt go so far as to say "making".. more like "dreaming of" at this rate lol
15:45justin_smithlokien: especially when your source of data is not a sequence, but maybe a channel or a socket etc.
15:45justin_smithsdegutis: you should just do a fork of oxcart
15:45TEttingeris that arrdem's?
15:45sdegutisTEttinger: 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:45justin_smithyeah
15:46lokienjustin_smith: thanks
15:46TEttingerha, portable C
15:46justin_smithsdegutis: how many years do you have set aside to do hash-maps?
15:46TEttingerthat one always makes me chuckle
15:46sdegutisjustin_smith: haha wait i dont get it
15:47justin_smithsdegutis: I mean, do you plan to take 2 years implementing hash-maps, maybe 4 or 5?
15:47TEttinger"portable if you have a windows, mac, linux 32-bit, and linux 64-bit computer to compile on"
15:47sdegutisjustin_smith: heh yeah i thought hash maps were simple until i started reading about how clojure implements them
15:47sdegutisjustin_smith: so i guess 2017 is reasonable to have "efficient" hashmaps by :D
15:47justin_smithespecially since you are also writing your own gc last I heard
15:47TEttingerthere are HAMT implementations in C
15:48TEttingerCHAMP is optimized for the JVM
15:48sdegutisjustin_smith: oh yeah the gc is the easy part afaiui
15:48TEttingertell that to google
15:48sdegutisi didnt say efficient/fast gc lol
15:48TEttingerdalvik's GC is awful compared to hotspt
15:49sdegutisim 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:49TEttingerah cool
15:49sdegutis(in terms of performance)
15:49TEttingeryeah I had a similar goal with my attempt at a language
15:49sdegutishow did it go?
15:49sdegutisdid you finish it?
15:49TEttingerit went pretty well, I did not finish it, luajit is a kickass thing to target
15:50TEttingerthe bad parts were that I was doing a lot of stuff in a dumb way, so it lost a lot of potential improvement
15:50lokieneh, guys here are implementing languages
15:50lokienand I'm just sitting here, struggling with advent of code
15:51TEttingerI was trying to make a clojure-like lisp that, like yours, could start up quickly and run simple things
15:52TEttingerif 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:52sdegutislokien: youd be surprised how graspable implementing a basic language is, as long as you do it inefficiently :D
15:52sdegutisTEttinger: hmm interesting.. yeah for something that would compete with ruby&rails, luajit looks like a good vm to target
15:53sdegutisTEttinger: i think ruby rather shines at command line stuff, small programs that arent intended to be long-lived
15:53lokiensdegutis: I dream of a project like this :(
15:53sdegutislokien: lol haha
15:54TEttingerok, back to space filling curves...
15:54lokiensdegutis: I open up my vim, sit there staring at screen for like 20 minutes, and then go eat something
15:55sdegutiswell theres your problem
15:55lokiensdegutis: and then I forget about clojure for the rest of the day
15:55sdegutisyou're using vim!
15:55sdegutishaha
15:55lokienwith emacs it was even worse
15:55lokienlike "shit, how do I close this buffer? *pkill emacs* welp, all is gone, screw this"
15:55engblomI also prefer vim. fireplace is really making clojure development under vim pleasant
15:56lokienI can't connect to my repl with fireplace
15:56lokienfew days ago, only :Console wasn't working
15:56lokiennow I can't connect at all
15:56lokien:(
15:57sdegutiseditor wars are, like, over, maaan.. the /true/ editor is whatever is in your heart
15:58lokienwhat if my heart is a cold place filled with void?
15:59ridcully_have you changed anything? any plugins got autoupdated etc?
15:59sdegutisthen the true editor for you is (void)0;
15:59lokienridcully_: nothing!
16:00ridcully_e.g. cider-nrepl was updated recently, or am i just sitting on an old version?
16:00lokiensdegutis: let's write it in clojure :^)
16:00sdegutishahahhaa
16:00sdegutis(do nil)
16:00sdegutisdone
16:00sdegutis,(do nil)
16:00lokienNext Big Thing
16:00clojurebotnil
16:01ridcully_lokien: are you using a pinned version for cider/cider-nrepl?
16:01lokienridcully_: I'm using vim, darn
16:01ridcully_me too
16:02lokienwith cider?
16:02ridcully_yet i have cider-nrepl for fireplace installed
16:02lokienI'm using vanilla fireplace
16:02lokienand salve
16:02lokienand things for highlighting
16:13amandabbhi
16:14amandabbso hash tables dont have guaranteed order, but assuming they dont change will accessing items by random index at least be consistently random?
16:14sdegutisoh right i forgot cider 0.10 was released woo time to upgrade
16:15sobelamandabb: i wouldn't count on it
16:15amandabblike if i have a hash table of 10 items and access by random index instead of key
16:15amandabbwill any item be relatively equal likely to show itself given a large enough amount of attempts
16:16amandabbor will some items be more likely to keep reappearing
16:16sobelhow do you index a hash table
16:17amandabbcan you not?
16:17amandabbi just assumed you could
16:17justin_smithamandabb: (rand-nth (vals m))
16:17amandabbsometimes i want to access by key but other times i just want a random item
16:17amandabbooo
16:17amandabbthank you
16:17justin_smithamandabb: if you want key and value, (rand-nth (seq m))
16:17justin_smiththat will give you k/v as a two element vector
16:17amandabbgotcha thanks this is perfect
16:23ridcully_lokien_: fired up a container, empty vim + pathogen + the four deps salve wants + lein. ran in tmux and ran :Console. cpp/Eval works
16:24lokien_ridcully_: yeah, I'm hearing it for the second time
16:24lokien_I guess my laptop is.. Special
16:25lokien_sdegutis: do you use emacs? ;-;
16:25sdegutislokien_: yep
16:26lokien_sdegutis: with.. Emacs bindings?
16:26sdegutislokien_: yep
16:26ridcully_i added cider-nrepl for some reason (maybe mentioned in a ticket). so i wanted to see, if its important - but seems not
16:26sdegutislokien_: well, kinda
16:26ridcully_what errors do you get?
16:26lokien_sdegutis: I'm telling your mother
16:27sdegutislokien_: hahaha good luck
16:28StevensMotherHello sdegutis
16:29StevensMotherI'm worried about your pinkies going sore from these bindings you're using
16:29noncom|2did anyone use lein-externs ( https://github.com/ejlo/lein-externs ) for clojurescript to generate externs ?
16:30sdegutislokien hah
16:30StevensMotherIt's your mom here
16:30StevensMotherPlease, please stop
16:30sdegutisop plz
16:30sdegutishaha lol
16:30sdegutisStevensMother: no this is patrick
16:31StevensMotherOh, you're no fun. :^(
16:31ridcully_used some online service last time (most likely linked in the cljs wiki) last time i had to do it
16:31sdegutislokien_: YOU MUST CONSTRUCT ADDITIONAL PYLONS
16:31ridcully_noncom|2: but the js was very simple
16:31noncom|2ridcully_: yeah, i remember you gave link to the service
16:31sdegutislokien_: sorry i never learned how to interact with people on a normal level this is the best i can do
16:31artosissdegutis: no I don't
16:32sdegutishahah apparently neither have you, alright high five!
16:32artosis*high five of social awkwardness*
16:32sdegutislokien so you learnin clojure as part of a high school course or just for fun on the side or what?
16:33lokien_I'm in high school, it sucks, it's all hardware
16:33lokien_I just want to write programs, they make me happy
16:36lokien_sdegutis: also, I don't want to go to college, it sucks even more
16:36sdegutislokien_: heh dont know what to tell ya bud sorry
16:36sdegutisbbl
16:37lokien_sdegutis: why sorry?
16:39lokien_sdegutis: going to sleep now, so.. have a nice day and everything :)
16:51amandabbhi 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:51amandabbtried using do blocks, doall, doseq.. hmm not sure why it's not working
16:54neoncontrailsAlright I give up. Asking this n00b question. Using this library:
16:54neoncontrailshttps://github.com/wiseman/clj-pronouncing
16:54neoncontrailsVery straightforward. Included the library under :dependencies in my project.clj
16:54neoncontrailsIncluded the require statement.
16:55neoncontrailsCursive still can't find the library. What else is required?
16:56neoncontrailsI rebooted the project as JDK1.6, juuust in case it was a versioning issue. No dice.
16:56neoncontrailsI'm out of ideas.
16:58cflemingneoncontrails: Do you see the lib under External Libraries in the project view?
16:58ridcully_mind to share that project.clj? or is this a cursive-only problem?
16:59neoncontrailscfleming: good question. I don't see it, no.
16:59neoncontrailsridculy_: it's dull I promise, but sure. One sec
16:59cflemingneoncontrails: Ok, open View->Tool Windows->Leiningen
16:59cflemingAnd hit the refresh button.
17:00cflemingThat'll sync your dependencies from your project.clj to your Cursive project
17:01neoncontrailsGot it. Trying now
17:01neoncontrailsridcully_: http://pastebin.com/X1kzkufG
17:02noncom|2amandabb: something is undefined
17:02amandabbhmmmm
17:02noncom|2it's clojurescript, so that means you are doing undefined.someMethod in js
17:02amandabbnothing is undefined in there though
17:03amandabb(def game-chan (chan)) is above it
17:03amandabbwhat other vars are there? when i remove that block of code it runs fine
17:03noncom|2amandabb: are you sure? what if you console.log all of them: go, timeout, <!, >!, game-chan
17:03amandabbooooooo
17:03amandabbit's not just vars
17:04amandabbi forgot about require
17:04amandabbthats probably it
17:04noncom|2these are functions, right, but they should print out
17:04amandabbyeah didnt import timeout
17:04amandabbgood call thanks
17:04noncom|2ah, ok
17:04neoncontrailscfleming: 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:05neoncontrailscfleming: appreciate it. I just upgraded from community edition, I don't recall these hoops
17:07cflemingneoncontrails: No worries, I have plans to make that easier/more intuitive
17:07cfleming(i.e. starting with actually telling you when you need to do it)
17:08noncom|2amandabb: 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:08amandabbo right
17:15neoncontrailscfleming: 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:16cflemingneoncontrails: Did you just upgrade IntelliJ?
17:16neoncontrailsI did, yes
17:16cflemingOk, there's a migration to the run configs which doesn't always work, and I haven't figured out why.
17:17cflemingOpen your run config using Run->Edit Configurations
17:17cflemingCheck that the specified module looks ok - you might need to re-select it and hit apply.
17:18neoncontrailsBingo! Man, I am glad you were here.
17:19neoncontrailsI'm not sure I would've stumbled on the solution to that.
17:26devthhow to get lein to output just the project version?
17:31devthlooks like i'm gonna have to use lein-exec
17:36justin_smithdevth_: hack way to do it (nth (read-string (slurp "project.clj")) 2)
17:36justin_smithif it's there on disk
17:36justin_smithI'm sure there's a right way that isn't that though
17:37devth_ah, yeah
17:37devth_could use that in combination with lein-exec
17:38justin_smithdevth_: the good way to do it would be to make a simple lein plugin that gets that data from the project
17:38justin_smiththat would be a very simple plugin
17:38devth_true
17:38devth_wonder if someone already has
17:39devth_there's one that sets version :)
17:39justin_smithdevth_: https://github.com/taoeffect/slothcfg
17:39justin_smithruntime access to project.clj data?
17:43devth_hm, so i don't think lein-exec and another plugin can work together
17:43devth_plugins run in a separate jvm or smth?
17:43devth_tried: lein exec -e "(use 'cfg.current) (println (:version project))"
17:44devth_but it can't find cfg.current
17:45devthah, need -ep to eval in-project
17:46devthlein exec -ep "(use 'cfg.current) (println (:version @project))"
17:47devthlol. a bit heavy handed
18:04justin_smith(defn 😈 [& args] ...) <- what should go in there?
18:08ystaeljustin_smith: i dunno but it should probably consume all available file descriptors
18:08MJB47(mapv #(println "i hate bytes") (range))
18:09justin_smithMJB47: making them signed is the icing on the cake
18:32yendaHi guys, do you have a better way to refactor cljs code than manual work ?
18:38neoncontrailsyenda: 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:39neoncontrailsyenda: 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:40BRODUSneoncontrails: what refactoring tool do you use for emacs?
18:40cflemingneoncontrails: Cursive does work with v15
18:40BRODUSi didn't know there waso ne
18:40cflemingBRODUS: clj-refactor
18:40cfleming(I don't use it, but that's what you want)
18:40neoncontrailscfleming: it does? Yess! I might get that right now then
18:41BRODUSooo, thanks
18:41noncom|2but it won't refactor clojurescript because it relies on a running jvm, no?
18:41neoncontrailsBRODUS: uhh... I'll look up the name. It was the scary tool none of us understood at all in SICP
18:41cfleming@noncom|2 I believe that's the case, yes
18:42BRODUSthere was emacs in SICP ?
18:42cflemingCursive's does work with CLJS, but is currently more limited than clj-refactor
18:42noncom|2cfleming: that might be interesting for yenda then
18:42zmsI'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:42neoncontrailsyup. My university really threw us in the deep end of the pool there
18:43BRODUSyeah 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:45zmsrunning with "BOOT_EMIT_TARGET=no boot cljs-repl" seems to indicate that an nrepl server was started but there's no repl."
18:45neoncontrailsIt 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:47zmsEmacs CIDER also fails to connect to the reported port of the nrepl server.. :-( Any hints/guidance appreciated.
18:48justin_smithzms: is the cljs repl provided via a browser, or node, or?
18:51turbofailhuh. i learned to love emacs in order to deal with my workload
18:51zmsjustin_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:53justin_smithzms: so you get a clojure repl, then eventually you call (start-repl) ?
18:54justin_smith(once the node process is running with that half of the piggieback/weasel stuff?)
18:58zmsjustin_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:58pilnehrm... clojure + actors for a concurrent game engine....
18:59yendacfleming: clj-refactor doesn't work with cljs
19:00justin_smithzms: 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:00justin_smithyou need the jvm because you are compiling new clojurescript code as you go in order to run the repl
19:00yendaneoncontrails: thanks, I prefer emacs though :/
19:00neoncontrailsturbofail: 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:01turbofaillol
19:01justin_smithzms: 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:01neoncontrailsand I distinctly remember figuring out 10 minutes later that I was stuck in something called 'cuneiform mode' and kind of rage sobbing
19:03neoncontrailsyenda: you are a much braver soul than I. :) Glad you found something
19:03yendaneoncontrails: for me the hardest par was not getting myself stucked in configuration mode, where I would end up configuring emacs for days
19:03yendathen I discovered spacemacs and barely felt the need to configure anything
19:05zmsjustin_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:05neoncontrailsyenda: 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:06justin_smithzms: I'm not sure about "cljs-repl" but the rest sounds exactly right
19:06justin_smiththe cljs process will be node loading the js that your cljsbuild outputs
19:06justin_smithand that js should make it open a websocket that talks to your repl, etc.
19:07yendaneoncontrails: that's why spacemacs is so awesome, it has all the nice tools to help you learn the keystrokes as you go
19:07zmsjustin_smith: so the missing piece is something that will start a process that will link node and clj repl over a websocket, right?
19:07justin_smithzms: yeah, this is what piggieback and weasel do together
19:07justin_smiththeir readme files should show you what to do
19:08neoncontrailsyenda: yeah? Hmm. I'll keep that in mind. I will gladly accept offers of handholding when it comes to emacs config
19:08zmsjustin_smith: thank you for the clarity. be back in a few. :)
19:08justin_smithzms: 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:09yendaneoncontrails: apparently there is no refactoring tool for cljs yet though :(
19:09neoncontrailsGotta say. I've never felt more like an old man than I have the past few weeks on Vim
19:10zmsjustin_smith: figwheel with browser or node?
19:10neoncontrailsAt first, I mean, it was understandable. I was just picking it up. I was just getting started.
19:10justin_smithzms: 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:10zmsjustin_smith: honestly, lein has me frustarted.. it seems magical. boot seems conceptually something i can understand.
19:11justin_smithzms: yeah, the classic declarative vs. procedural split
19:12neoncontrailsThen 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:12zmsjustin_smith: which is which? :)
19:13justin_smithzms: 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:14BRODUSim 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:16justin_smithBRODUS: ns-aliases shows you what has been aliased
19:16amandabbhmmmm
19:16justin_smithns-refers shows you what has been used / referred
19:16justin_smithBRODUS: but really, running require twice is not an error, and without the :reload arg it doesn't do anything the second time
19:17justin_smithBRODUS: calling refer again isn't an error either, if you want to do it at that level
19:17justin_smith,(doc refer)
19:17clojurebot"([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:17neoncontrailsthree cheers for idempotency! *cheers seven times*
19:17justin_smithheh
19:20justin_smith,(refer 'clojure.core) ; no error!
19:20clojurebotnil
19:20justin_smithit only errors if the new refer conflicts
19:20BRODUSjustin_smith: thanks, i didn't realize require did nothing second time around
19:20zmsjustin_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:22yendaneoncontrails: you can play vim-adventures to learn faster
19:24neoncontrailsyenda: 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:25neoncontrailsBut that might be kind of fun, actually. Delete it! Find it! Yank it! Yank it!
19:26BRODUSi liked this one: http://www.openvim.com/
19:26BRODUSdon't know if vim-adventures goes deeper without paying
19:28neoncontrailsThat's pretty cool too. I've talked myself into making Vim It! See ya, evening plans
19:37BorisKourtDoes anyone use lentic here?
19:38BorisKourt(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:39amandabbis there any way to return a value from doseq?
19:40amandabbim 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:40amandabband then if it gets through both of them then to just return another value
19:40turbofaildoseq never returns a value, it always returns nil
19:41amandabbso what else can i use?
19:41amandabbtrying 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:42devthrewrite it using reduce
19:42turbofailmaybe reduce
19:42amandabbnested reduces?
19:43turbofailyou could do a nested reduce, or you could do (reduce (fn [[x y]] ...) (for [x ... y ...] [x y]))
19:45amandabbhmmm
19:45amandabbthere's got to be a better way of doing this
19:45amandabbi guess ill just think on it for a while
19:45turbofailor actually you could do it without reduce just by using some
19:46justin_smithamandabb: you can use reduce with reduced
19:46justin_smith,(doc reduced)
19:46clojurebot"([x]); Wraps x in a way such that a reduce will terminate with the value x"
19:47amandabbok
19:47amandabbill look in to reduced and some
19:47amandabbthanks
19:47justin_smith,(reduce (fn [_ x] (when (even? x) (reduced x))) [1 3 5 8 1])
19:47clojurebot8
19:47amandabbyeah it sounds about right
19:47justin_smithamandabb: you can use reduce to walk the result of for, and for has the same syntax as doseq
19:48amandabbok
19:49amandabbim just not sure if reduce is right though
19:49amandabbi dont really have an accumulator value per-se..
19:49justin_smithif all you are doing is checking for a specific value, use (some pred? (for ...))
19:50amandabbyeah that might be it
19:51turbofailactually (first (for [x ...y ... :when (pred x y)] (foo x y))) would do it to
19:51turbofails/to/too/
19:51justin_smithoh yeah, :when is cool
19:51amandabbohhh right first would cut it off right? thats a good point
19:51turbofailthere's so many possibilities
19:51amandabbit wouldnt continue doing the calculation becuse it only needs one
19:51turbofailright
19:51amandabbill look in to that too
19:51justin_smithfirst is not guaranteed to cut it off
19:52amandabbreally?
19:52justin_smithif f has side effects that are important, don't do it that way
19:52turbofailwell yeah there's like chunked sequences
19:52justin_smithamandabb: chunking
19:52justin_smithside effects and laziness are a bad mix
19:52amandabbtheres no side effects in here
19:52amandabbim just checking for intersections in a grid
19:52justin_smithamandabb: I said "if f has side effects that are important"
19:52justin_smithamandabb: if it doesn't go right ahead and do it that way
19:53amandabbok cool
19:53justin_smith,(first (map print [1 2 3 4 5 6])) ; amandabb - example of the gotcha
19:53clojurebot123456
19:53justin_smithit printed all of them because chunking
19:53amandabbi dont quite understand
19:54justin_smithamandabb: map is lazy, but it still processed all the items even though we only asked for the first one
19:54amandabbyeah im saying why does it process all of them if it knows we just need one
19:54justin_smithamandabb: it doesn't
19:54justin_smithfirst knows, map doesn't
19:55justin_smithchunking
19:55justin_smithamandabb: basically, for efficiency reasons it processes 32 items at a time
19:56amandabbso first only stops map from processing more elements when it can guarantee the map function is pure?
19:56justin_smithwell, if it can guarantee the map function is pure, it doesn't matter whether it stops it or not
19:56justin_smith(except for cpu cost of course)
19:57amandabbi 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:57amandabbthat it only does as much as it needs to and is thus efficient
19:57justin_smithamandabb: 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:58amandabbohhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
19:58amandabbi get it now
19:58justin_smithamandabb: stupid analogy "I need a soda" - it's faster to get a six pack than tear one can out
19:58justin_smithespecially when it's "I need n sodas" and you don't know until runtime - default to grabbing some cases
19:58amandabbso 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:59justin_smithright - it turns out it chunks by groups of 32 iirc
19:59amandabbgotcha
19:59amandabbok thats neato
19:59amandabbi have to go now thanks for the help
19:59justin_smithnp
20:12zmsjustin_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:13zmsjustin_smith: good night!
20:16justin_smithzms: you too, glad you figured it out
22:04domgetterIf you pass a partialed function to reduce, does it remake it every iteration? ex: https://gist.github.com/domgetter/bb41ebb4056aff7804d7
22:14justin_smithdomgetter: reduce is not a macro, all its args including the function are evaluated when the form is compiled
22:14justin_smithdomgetter: easy test...
22:14domgetterah okay, and macros get evaluated at runtime?
22:14justin_smith,(reduce (partial str (println "test")) [1 2 3])
22:14clojurebottest\n"123"
22:15domgetterright, because that would've printed test three times if it was evaluating the partial every time
22:15justin_smithdomgetter: 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:15justin_smithright
22:15domgetterOkay I'll keep that in mind, thank you
22:20domgetterjustin_smith: one more question. are these delays superfluous or will clojure try to evaluate the let bindings? https://gist.github.com/domgetter/02fbe16020dd8b481d83
22:21domgetteroh I guess I could do my own test with println
22:26justin_smithdomgetter: yes, it will run all the clauses, so you can use delays if you want to only evaluate certain clauses
22:27domgetteryea, I just used the side-effect trick to convince myself that that's true :)
22:27justin_smithbut here I think just the code is clearer than the delay / deref combo
22:29justin_smithyeah, println is a good way to test which things actually run
22:30devthprintln-driven-development
22:46domgetterprintln-driven-*understanding*
22:54sdegutiswelp
22:58justin_smithsdegutis: whelps http://leerburg.com/Photos/whelp-1.jpg
22:58sdegutishaha lol
22:58sdegutisjustin_smith: what new adventures in clojureland have you partaken in as of late old chap?
23:26justin_smithsdegutis: same old, working for a startup doing graph analysis
23:27justin_smitherr, doing an app that does graph analysis
23:27sdegutisman that sounds so boring
23:27sdegutisis it fun?
23:27justin_smithit's actually pretty great, I've just been stuck with the generic stuff lately
23:27justin_smiththe stuff that would just work out of the box with rails - login, settings, etc.
23:28justin_smithor at least the things I gather are much more cookie cutter there
23:31sdegutishahaha yeah i know those feels