#clojure logs

2015-02-04

00:00Lewixi dont care about the type
00:00julianlevistonLewix: in fact they don’t even tell you the abstraction
00:00Lewixtell me what it returns in a way that dont confuse
00:00Lewixme*
00:00julianlevistonLewix: that always depends on who is asking that question.
00:00Lewixanyways, thanks guys
00:00LewixI'm off
00:01julianlevistonLewix: I guarantee you a 6 year old would have trouble no matter what, because they don’t know what / means… but a math professor proll wouldn’t.
00:01julianlevistonLewix: later
01:37domokatohi, anyone use neko?
02:30rpauloonly 26 days late.
04:04l3dxI don't get a repl buffer in cider. This is the case for both jack-in and "lein repl" + attach
04:04l3dxsuggestions?
04:05l3dxcan't seem to find any errors
04:07ordnungswidrigl3dx: no buffer created? what does the *Messages* buffer tell you?
04:07hellofunkl3dx: do you get any of the other nrepl buffers if you look at your full emacs buffer list?
04:34l3dxI get a nrepl-server and a nrepl-connection buffer
04:34l3dxhttps://gist.github.com/tskardal/7ca53cbd58575e9275ef
04:34l3dxrelevant output from *Messages*
04:51ordnungswidrigl3dx: doesnt' your bufferlist contain a *cider-repl ...* buffer?
04:52l3dxnope
04:53CookedGr1phondomokato: yep, there's also a #clojure-android room if you're interested
04:54domokatoCookedGr1phon: thanks, I found it :)
04:54l3dxordnungswidrig: proof https://dl.dropboxusercontent.com/u/809432/emacs%20buffers.png
04:54l3dx:P
04:59michaelr`hmm
05:01ordnungswidrighmmm, which version of cider (emacs) and cider-nrepl (clojure) do you use?
05:02ordnungswidrigwhat happens when you invoke `cider-switch-to-repl-buffer` (in core.clj, C-c C-z)?
05:03cloudsajaHi guys. Im using com.stuartsierra.component ... in (start [component] i did (assoc componenet :graph graph). ... My question is, how do I get the :graph from the component after it started ?
05:03hellofunkl3dx: i recently had this setup to make it easier to see a proper cider setup: https://github.com/clojure-emacs/example-config up to you if you want to take a look at it, or you can, as i do, just use it as a starting point for your own config
05:04julianlevistoncloudsaja: um… (:graph component) ?
05:05cloudsajajulianleviston .. I know that. but how can i get the component ? Where is stuartsierra.component stores its maps ?
05:05hellofunkl3dx: you can look directly inside the nrepl buffers for error messages
05:05julianlevistoncloudsaja: I don’t follow your question. Apologies. It doesn’t work that way from memory.
05:06julianlevistoncloudsaja: your system holds the components.
05:08cloudsajajulianleviston : Okay... let me reconstruct my question... http://pastebin.com/uLWjCvDH ... in line 17, I associated the newly created graph into my component map.... later, when the database component starts, I want to access to the map but I dont know how to obtain the map in the stuartsiera component.
05:12julianlevistoncloudsaja: hang a sec I just have to remind myself how component works… it’s been a few months since I’ve used it.
05:13ordnungswidrigcloudsaja: your component is a record and after assoc'ing the graph under :graph, you can access it with :graph: (-> (databse config) (start) :graph) give's you the graph
05:16julianlevistoncloudsaja: ok… so where are you trying to access it from?
05:16julianlevistoncloudsaja: or did ordnungswidrig’s response fix your issue?
05:16cloudsajafrom repl
05:17julianlevistoncloudsaja: ah… ok… so yeah… (-> system :database :graph) assumping your database component is databas?
05:18julianleviston*assuming your database is assoc’d on to the system as :databas
05:18julianleviston:database * (sigh)
05:19julianlevistoncloudsaja: does that help / make sense?
05:21cloudsajajulianleviston : You are correct... saved my day. Thanks a lot. ordnungswidrig also.. thanks
05:21julianlevistoncloudsaja: you can always type system at the repl and it’ll show you the map… tis not very conducive to reading, but yeah…
05:22julianlevistoncloudsaja: I think last time I checked, stuart was interested in improving that but nothing had occurred to him yet.
05:22cloudsajajulianleviston : got it
05:22julianlevistoncloudsaja: maybe prettyprinting it might help
05:22TEttinger(inc julianleviston)
05:22TEttingerlazybot ded
05:24julianlevistoncloudsaja: for future reference, context is really useful to have. We didn’t know it was the REPL, or that you’d started your system already, or what the component or system were called. Just FYI.
05:28cloudsajajulianleviston : Okay... I will mention the context nextime.
05:40hejki_ohai. if I were to make a multiplatform gui client with clojure, should I just go with seesaw or are there other alternatives to consider?
05:45ordnungswidrighejki_: jfx was discussed on the clojureD conference. Seems hot to me.
05:47hejki_ordnungswidrig: http://www.bytebucket.org/splendid/jfx ?
05:48hejki_googling "clojure jfx" provided results "all around", so it indeed is "hot" :P
05:59julianlevistonI, for one, welcome our new fervently sardonic overlords.
06:04zot1i have a "receive-message" function which blocks, waiting for a message to arrive. is lazy-seq the best way to wrap an infinite number of calls into a sequence?
06:05julianlevistonzot: how’s about a go block?
06:06l3dxhellofunk: thanks, I'll have a look. It used to work fine, but stopped yesterday
06:06zotjulianleviston: core.async was my other consideration, but i wondered if lazy-seq would actually be simpler for my case
06:07julianleviston,(source repeatedly)
06:07clojurebotSource not found\n
06:07julianlevistonzot: looks pretty good to me, why not...
06:08zotahhhh, i forgot about repeatedly. that's even better :)
06:08julianlevistonzot: sweet :-)
06:08zot(inc julianleviston)
06:08zottnx!
06:09frphankjulianleviston: core.async and lazy-seq don't normally compete
06:09frphankone is for I/O
06:09frphankthe other for computation
06:09julianlevistonfrphank: depends what you’re trying to do I guess ;-)
06:10frphankyes, either you have I/O or you do not
06:10frphankwhat's the body of your "repeatedly"?
06:10julianlevistonfrphank: what if you want to compute many things at once? :-)
06:10zotfor me, (repeatedly (partial recv-message this))
06:10frphankhm
06:11zotquite trivial
06:11julianlevistonfrphank: or split their functionality into delayed process that happens later? or… etc.
06:11julianlevistonzot: excellent.
06:11julianlevistonfrphank: but thanks, I’ll keep that in mind.
06:11frphankzot: sorry I got confused, you are the one that wants to use repeatedly?
06:11frphankzot: recv-message is from what library?
06:11zotnot, it's my own code in a component wrapping a kafka client
06:12frphankok
06:12frphankit probably blocks?
06:12zotbut needs to be substitutable with in memory and other forms for testing
06:12julianlevistonfrphank: I think he’s got his solution.
06:12zotyes it does
06:12frphankzot: yeah that's problematic
06:13frphankzot: you can't interrupt the thread for starters, or it will do funny things
06:13julianlevistonfrphank: unless receive message is an action, not a channel-like thing… :)
06:13frphankjulianleviston: it only matters if it blocks or not
06:13julianlevistonfrphank: blocks intentionally or not?
06:13frphankzot: CLJ-1119 has a discussion on that
06:14frphankjulianleviston: what's unintentional blocking??
06:14julianlevistonfrphank: what you think he’s doing?
06:14julianlevistonfrphank: all’s I’m saying is I don’t think we have enough info to make a recommendation about what to do yet.
06:14frphankjulianleviston: zot said that recv-message blocks and that makes it unsuitable for repeatedly
06:15zotso if i understand, you believe that the thread termination may fail when wrapping this call in repeatedly?
06:15frphankzot: there are more problems e.g. when the lazy-seq produced gets consumed by more than one reader. the semantics of lazy-seq assume quick realization
06:15zot(to be clear, it blocks via Thread/sleep, spinning on an atom)
06:16frphankzot: no the thread will terminate properly, but it will end the production of the sequence. you won't be able to restart it later. it's basically a mutation which is a no-no
06:17julianlevistonfrphank: it *does* sound like core async is a better fit.
06:17frphankyeah
06:17zotin my case, that's acceptable; this variation is strictly test code, with only a single reader. core.async might be a better fit though; but the first half was already written, so i was hoping for a trivial wrapper, a la repeatedly.
06:18frphankzot: in that case you might get away with it
06:18zottesting shortly to find out :)
07:02rksmHello! I'm trying to POSTing solutions to the 4clojure server, to www.4clojure.com/rest/problem/:id as specified in https://github.com/4clojure/4clojure/blob/develop/src/foreclojure/problems.clj
07:02rksmAll I get back is {"failingTest":0,"message":"","error":null,"golfScore":"","golfChart":""}
07:02rksmAny idea?
07:07justin_smithrksm: have you tried it with curl?
07:07rksmWell with clj-http-lite and node.js, will give curl a try...
07:07NewToCljhi there, i'm new to clojure and having some problems creating a first toy project with lein, where i fail to depend on a library, can anyone help me with that?
07:09hyPiRionNewToClj: Sure thing
07:09NewToCljthe library i'm trying to include is : https://github.com/adamwynne/twitter-api I have included there version in my project.clj but when i load up : lein repl I get an error
07:10justin_smith"an error"
07:10hyPiRionNewToClj: could you post the project.clj to a pastebin, just so I could see?
07:10hyPiRionwe*
07:10NewToCljyes the error is: Unable to resolve symbol: make-oauth-creds , which is a symvol'/function of the lib
07:11NewToCljhow can i check if the dependencies resolved correctly?
07:11justin_smithNewToClj: did you use require or use to load the dep?
07:11NewToCljjustin_smith: (require 'tweedels-clj.core)
07:11hyPiRionNewToClj: If you managed to get into the repl itself, there should be no issues with the dependency handling.
07:11justin_smithNewToClj: if you do it that way, try tweedels-clj.core/make-oauth-creds
07:12justin_smithNewToClj: likely you want an :as in your require so you don't have to spell all that out
07:17NewToCljI listed project and the source file, nothing fancy, thats why im wondering what im doing wrong...
07:18justin_smithNewToClj: on line 14 you refer to a function that is not mapped to your ns
07:18NewToCljright so : make-oauth-creds should come from twitter.oath
07:18justin_smithNewToClj: change it to tiwtter.outh/make-oauth-creds or add an :as clause to the require and mutatis mutandis
07:19NewToCljjustin_smith: but isn't the equire for this?
07:19justin_smithNewToClj: no
07:19NewToCljjustin_smith: ah i see...
07:19justin_smithNewToClj: require makes it available, it does not map it directly to your namespace
07:19hyPiRionNewToClj: You don't import them to the namespace, but if you want to do that you could do (:require [twitter.oauth :refer :all])
07:19hyPiRionIt's generally not recommended though
07:20justin_smithor :refer [make-oauth-creds] even :)
07:20NewToCljahh I see because of namespace shadowing, hm ok
07:20justin_smithNewToClj: not just shadowing - it makes editing things later much much easier when it's clear where things came from
07:20justin_smithNewToClj: or even reading the code
07:29ro_sti know that i can have either an action or a timeout occur within <timeout> time with core.async. how do i ensure that something happens only after <timeout> time after the last of any number of input messages - e.g. only issue a network request once the user stops typing for 1000ms ?
07:30ro_stis this possible with core.async, or should i use setTimeout/clearTimeout? this is in cljs, obviously
07:30justin_smithro_st: sounds like you want debouncing
07:30ro_stah, is THAT what debouncing is :-)
07:31ro_sthttps://gist.github.com/scttnlsn/9744501 ?
07:31julianlevistonro_st: I thought debouncing was stopping two requests registering when you only pressed once! :)
07:31justin_smithro_st: general idea is you have a timer, every action of the user restarts the timer from 0, when the timer finally hits the end, then you do your thing
07:31julianlevistonjustin_smith: handy!
07:31justin_smithjulianleviston: same concept
07:31NewToCljjustin_smith: thanks that helped now i'm a step further!
07:31justin_smithjulianleviston: it comes from hardware / hardware switches
07:32julianlevistonjustin_smith: yeah, I knew it from keyboards.
07:32justin_smithjulianleviston: in the hardware switch you would have a capacitor that needs to charge up, and any bounce / jiggle gets subsumed
07:32ro_stthe gist link i pasted seems to do exactly that
07:32justin_smithjulianleviston: same idea, different domain :) instead of capacitors we have timers
07:33justin_smithro_st: yes, that looks like an acceptable version of debounce
07:33justin_smithit resets the timer if you get new events within the timout, othwerwise hits the timout and does the timout's thing
07:34ro_stthanks justin_smith!
07:34justin_smithro_st: very useful in UI
07:34justin_smithro_st: but that is probably exactly where you are using it
07:34ro_sthugely. i'm doing an autocompleter
07:34julianlevistonjustin_smith: I wanted something like this a few days ago...
07:34julianlevistonjustin_smith: I think...
07:35ro_stlove core.async. literally just wrapped the arg where i pass in the channel
07:35justin_smithomg I can't believe I only just now got the 4clojure "fore" -> golf - code-golf pun
07:35justin_smithargh
07:35justin_smith((juxt inc dec) amalloy)
07:36ro_stif your cljs app causes safari/mac to restart your mac, is it a bug or a feature?
07:36julianlevistonjustin_smith: i don’t get it… is it just fore/4 ?
07:37justin_smithjulianleviston: right, and you shout "fore" before swinging in golf
07:37ro_stFore is what they shout when you might just about to be brained by a golf ball
07:37julianlevistonjustin_smith: haha yep. That’s what I thought.
07:38julianlevistonah, I hate these “fill in the blanks” type coding things for learning...
07:38julianlevistonclojure koans had me slapping my head at once stage...
07:39julianlevistonthey’d be fine if the creators didn’t try to be arcane… and also if they only had one or two acceptable answers, but they’re usually kind of bad.
07:40julianleviston4clojure is much better than the koans
07:40ro_stdid you learn a lot about clojure when trying to figure them out? -zen master-
07:40michaelr`what would be a good strategy to use liberator resources in a Componentized app?
07:40justin_smithjulianleviston: won't they just accept any answer that returns the right result?
07:41julianlevistonmichaelr`: Can you rephrase?
07:41julianlevistonjustin_smith: something like that… which often doesn’t help one learn..
07:41julianleviston“What’s 1 + 1” doesn’t really help you understand addition.
07:43justin_smithjulianleviston: it depends on your model of learning. In practice a combination of immersion and higher level reasoning tend to be most effective.
07:43justin_smithjulianleviston: and immersion is often just "drilling the rote answers"
07:43michaelr`julianleviston: A liberator (defresource) needs to access a database. The database connection is wrapped in a Component. So I wonder what would be a good way to define the resources in such way that they would have a reference to the database dependency component. One way which I've used in the past is to wrap the resource in a handler function which in turn associates the dependencies to the request map which is passed at runtime to
07:43michaelr`the resource handler..
07:43julianlevistonDave Thomas is a big advocate of exercises… that he calls Kata… but that’s really not what Kata are. Kata are doing solutions that are GOOD solutions over and over as drills.
07:43justin_smiththough it can also include exposure - frequent reading of others code etc.
07:44julianlevistonjustin_smith: yeah, I think reading is excellent to do… more beginning devs should read more before they try to write, IMHO… study good code.
07:44julianlevistonjustin_smith: (myself included, no doubt)
07:45rksm[POST to 4clojure] debugged the emacs plugin that worked. seems that the compojure handler only accepts form data, no json body. so in order to post to /rest/problem/:1 something like
07:45justin_smithmichaelr`: you could also make the function that creates the resource a partial function, or maybe as a macro that is to onerous
07:45rksm(http/post (str "http://www.4clojure.com/rest/problem/&quot; 1)
07:45rksm {:form-params {:code "true" :id 1}})
07:45justin_smith(partial function taking the db bindings at creation time)
07:45rksmis necessary
07:46justin_smithrksm: cool, glad you figured it out
07:47michaelr`yeah well, i was hoping for some way to create the liberator resources as part of the system (component) lifecycle
07:47julianlevistonjustin_smith: I actually think the best way to learn is to have have a real or very real-like context… if it’s controlled or overseen, by a teacher or mentor, even better…
07:47michaelr`instead of passing it at runtime..
07:48justin_smithmichaelr`: yeah, if it isn't going to change at runtime, why not bind it once
07:48justin_smithmichaelr`: a similar solution is to use a promise that gets delivered to at init
07:49justin_smith"not going to change at runtime" here means that the component system will be restarted if you rebind the db settings, of course
07:53michaelr`not sure what you mean.. but sounds a bit hacky. the way I think of it is the (defresource) macro defines a ring handler function. So in order for the code in that function to have a reference to the db connection, the reference either has to be passed to the function as a parameter or it has to be enclosed in the function's scope at definition time..
07:54michaelr`in the sense of a closure..
07:54julianlevistonmichaelr`: yeah, but *your* code can do whatever you like, can’t it?
07:55michaelr`sure.. it's all my code :)
07:55julianlevistonmichaelr`: so… can’t you use a function that returns a function?
07:55michaelr`yes I can
07:55julianlevistonmichaelr`: I used that a lot in my component code.
07:55alexyakushevrksm: you can check how I did it here https://github.com/alexander-yakushev/foreclojure-android/blob/master/src/clojure/org/bytopia/foreclojure/api.clj
07:56rksm@alexyakushev cool, thanks!
07:58justin_smithmichaelr`: yes, I was suggesting that passing the db at creation time would be an option, though "def-foo" macros tend to make this harder to do
07:59michaelr`hmm
07:59justin_smithmichaelr`: of course anything you like can be passed in with the request, but my general rule of thumb is to fix things if they are fixable (this tends to help things like hotspot optimizations)
07:59justin_smiththe vm can't optimize things that are last-minute paramaterized as nicely
08:00justin_smith(or the clj compiler can't compile them to as nice a form, etc.)
08:00michaelr`hmm
08:01michaelr`thinking of it I
08:03michaelr`I'm not sure I understand what you're suggesting me to do :)
08:04justin_smithmichaelr`: does liberator have a function version of its route thing?
08:05michaelr`looking..
08:07michaelr`looks like there is some function which I could use
08:08michaelr`how would that help?
08:09justin_smithif it has a function, you can make a function that, given a db connection (and perhaps other data that would come in from component) would create a set of routes
08:13michaelr`hmm
08:13michaelr`thanks justin
08:14michaelr`i can see a few ways to do that, i'll play with it a bit more to get a better insight
08:14justin_smithmichaelr`: aha - it has the function called resource
08:14justin_smithhttp://clojure-liberator.github.io/liberator/doc/resource-definition.html
08:14justin_smithshown near the bottom of the page there
08:15justin_smithyou should be able to craft a call to resource that captures the db in the definition
08:16justin_smithand (defresource foo ...) is the same as (def foo (resource ...))
08:17michaelr`how about referencing the system var and taking the db component from there? ;
08:17michaelr`;)
08:17justin_smithmichaelr`: that may be the more straightforward way to do it, actually
08:18justin_smithd'oh
08:18michaelr`on the other hand, but on the other i think it ruins the whole concept of components
08:19michaelr`i mean, the system then becomes a singleton
08:19justin_smithright
08:20justin_smithwell, parameterizing the resource on the config data solves the singleton issue, at the cost of a slightly less straightforward impl
08:21michaelr`I thought of maybe defining the resources within the (start) method of a component
08:21michaelr`But then I'd have to create one component for each rest entity or put them all inside one component
08:22michaelr`either way looks bad
08:22justin_smithmichaelr`: what about a hash-map to hold the resources, as created by resource
08:22justin_smithmichaelr`: then that hash-map can be used by the component that creates the server
08:22justin_smith(and the middleware, presumably)
08:23julianlevistonjustin_smith: hey do you know… are xhr’s done on the main js thread in the browser?
08:23justin_smithjulianleviston: I am actually not sure of that
08:23hellofunkjulianleviston: they can be synchronous or asynch. if you use cljs-ajax they are asynx
08:23julianlevistonjustin_smith: am I better off not putting too much code in the callback handler of an xhr and actually putting it into a channel instead?
08:24julianlevistonhellofunk: I’m using the google closure one, I think.
08:24julianlevistonhellofunk: let me check.
08:24justin_smithjulianleviston: for cleanliness sake I think putting your logic in a go block rather than a callback tends to work
08:24hellofunkjulianleviston: haven't used closure directly but cljs-ajax wraps it. if closure exposes synchronous xhr, then i know it is optional. cljs-ajax uses async only.
08:24michaelr`julianleviston: either way the callback code would be executed on the main js thread
08:24julianlevistonjustin_smith: I have the part of my code that writes the data it gets into an atom in there...
08:25julianlevistonjustin_smith: I just noticed that part of the code seems to take a while...
08:25julianlevistonmichaelr`: yeah? ok.
08:25hellofunkjulianleviston: up to you whether you use a callback directly or use core.async as a handler.
08:25julianlevistonhellofunk: I *think* it’s async… just curious.
08:26julianlevistonhellofunk: well I’m doing a bit of both… but it seems to be blocking up the UI…
08:26julianlevistonhellofunk: I’m probably doing something stupid tho :(
08:26hellofunkjulianleviston: i'm a big fan of cljs-ajax and the author is quite opinionated about making sure synchronous activity is avoided
08:27michaelr`julianleviston: if the ajax is sync then your code would block until the request is finished, if it's async then your code would continue to run and then would be interupted as with a timer when the request calls the callback function
08:27julianlevistonhellofunk: this is my call… (. xhr (send url (meths method) (transit/write json-writer (walk/stringify-keys data)) (clj->js {"Content-Type" "application/json" "Accept" "application/json"})))
08:28julianlevistonmichaelr`: hm… isn’t ajax async by default?
08:28julianlevistonmichaelr`: how can you have ajax if it’s not async?
08:28julianlevistonmichaelr`: isn’t that what the A stands for?
08:29hellofunkjulianleviston: the question is about xhr and whether that is sync or async
08:29julianlevistonhellofunk: it is.
08:29hejki_if I were to make a CLI tool using clojure, would there be any additional trickery to eliminate the slowness of JVM start/cleanup apart from drip?
08:29hellofunkjulianleviston: i mean, xhr can be either. but ajax is typically async xhr
08:29Glenjaminnode+cljs is an option
08:29justin_smithhejki_: jvm is not the bottleneck
08:30julianlevistonhellofunk: ype
08:30julianlevistonhellofunk: yep.*
08:30justin_smithhejki_: but node+cljs / closure advanced compilation mode do lower the startup time
08:30hejki_justin_smith: really, i thought the startup and teardown times are not really fun when you have a cli tool that is constantly used for operations that take up quite short time themselves
08:30justin_smith(we don't have an equivalent optimization in jvm clojure)
08:30justin_smithhejki_: the jvm starts fast
08:30justin_smithhejki_: it is clojure that starts slowly
08:31hejki_ok
08:31hejki_and can it be made faster? :P
08:31justin_smithhejki_: you can avoid this by using cljs, which does not bundle the clojure compiler
08:31hejki_but then I lose some features
08:31justin_smithand which can be optimized with google closure
08:31justin_smithit's true!
08:31julianlevistonWell I think (let [xhr (XhrIo.)]) that answers my q… Xhrlo is async…apparently?
08:31justin_smithhejki_: it's a hard tradeoff
08:31hejki_and actually important ones too :P
08:31julianlevistoni’m pretty sure it’s async… anyway.
08:31hejki_clearly :P
08:32justin_smithhejki_: drip will not help at all though
08:32hejki_ok
08:32julianlevistonit must just by my code doing some blocked up steff...
08:32julianlevistonI wonder if I segment it and put it into go blocks if it’s make everything smoother.
08:32justin_smithhejki_: you could look at grenchman - one clj process with one set of deps, which runs your clj stuff for you via an ocaml client
08:33hejki_justin_smith: thanks for the information, I'll look into other potential alternatives then. the tool is currently written in python, that has decent performance for smaller operations, but it chugs badly on more cpu intensive ones (also, no actual threading)
08:33justin_smithhejki_: the limitation there is all usages of grenchman must share the same deps
08:33justin_smithalso, there are other lisps that are better for fast startup / short tasks (eg. racket scheme)
08:34julianleviston(ie instead of (doseq [thing all-the-work-things] (do the work on each)) maybe I should map it all into chans and that might make things smoother. <sigh> I just don’t know.
08:34hejki_justin_smith: well, grenchman could preload everything my cli tool uses and the tool just connects to that and runs stuff?
08:34justin_smithocaml is pretty awesome in terms of startup time / low overhead if you might consider an ml, as well
08:34justin_smithhejki_: exactly
08:34julianlevistonjustin_smith: or maybe even Piumerta’s COLA!
08:34justin_smithhejki_: as long as all uses of grenchman are OK with using the same version of every lib, that will just work
08:35hejki_justin_smith: I think that is not going to be a problem. I'll just have to think how the users will migrate their grenchman when the tool has changes in dependencies
08:36justin_smithhejki_: yeah, you could probably figure out a managed restart
08:36hejki_I can do that with the distribution package manager when new version of the cli tool gets installed
08:37hejki_the nrepl could be ran as a service anyhow
08:37hejki_justin_smith: thanks for this information. I'll look more deeply into grenchman and perhaps start porting the current tool soonish :)
08:38justin_smithhejki_: the other concern of course is to make sure you aren't relying on globals at all
08:38justin_smithhejki_: but clojure is very good with helping you with that sort of thing
08:38hejki_i think all global states are in filesystem in my case
08:38justin_smithhejki_: well, for example you would want no defs in namespaces that would be client specific
08:39julianlevistonOk next question… if I do 10 async xhrs… are they all on separate threads each or is that an implementation detail up to the browser?
08:39justin_smithbut if it's all in files and can be per-execution local, then yeah, great
08:39hejki_that might require some redesigning
08:40justin_smithhejki_: a nice trick is replacing usage of vars (defs) with a map of bindings passed to your function in which you look things up
08:40justin_smithhejki_: suddenly nothing is global any more!
08:41hejki_justin_smith: only things currently global in the python tool are db connection and definitions (constants that i do not wish to hardcode)
08:41justin_smithwhat I mean by global is a bit more extensive than what python might mean
08:41justin_smithie. no singletons are allowed
08:42hejki_hmm.. I do have user configurations that are 'singletons' (read: python package globals)
08:42hejki_can't I bind them somehow?
08:42justin_smithpass them in a map to your executing function
08:42justin_smithand it can forward them down the call chain as needed
08:43hejki_hmm.. maybe I'll just read them whenever I need something from those config files
08:43hejki_not all operations actually require anything from that global data (those are actually read lazily now in the python tool, too)
08:44hejki_however the package global state makes the current implementation read that data only once per execution
08:55justin_smithhejki_: you mention user config - be aware that nrepl is not a good idea on true multi-user systems
08:56justin_smithit opens an http port on a local socket that executes arbitrary code (including shelling out) as the user who spawned it
08:56justin_smithwith no auth
08:56justin_smith(and grench uses nrepl)
09:05gfredericks~hi
09:05clojurebotNo entiendo
09:06justin_smithnyello
09:10gfredericksafter digging into using def inside a function, I'm surprised at how straightforward and harmless it is. It's just unidiomatic amirite?
09:11gfredericksnot much worse than a global atom?
09:11justin_smithgfredericks: the problem is - what if you try to use the thing defined before the function is called - do you expect the function to get called more than once? etc.
09:11justin_smithgfredericks: I replace def inside functions with (def foo (promise)) and then put (deliver foo x) inside a function
09:12justin_smiththen of course I need to deref
09:12gfredericksjustin_smith: your first question applies to a global atom as well?
09:12justin_smithbut it leaves out the open questions that an atom would leave hanging
09:12justin_smithgfredericks: sure, initialization issues
09:12justin_smithbut a promise just blocks until delivered
09:12justin_smithwhich avoids that (as long as someone plans on delivering...)
09:12gfrederickscan anybody think of any uses for a validator on a var?
09:13gfredericksa normal var I mean
09:13justin_smitha "normal" var, I only define once
09:13gfredericksexactly
09:13justin_smithI mean a validator is a great idea for something that gets a lot of updates, potentially from clients you don't control...
09:14gfredericksI feel like the idiomatic use of vars is just don't programmatically redefine them
09:14justin_smithbut you should not be letting clients def your vars...
09:14justin_smithgfredericks: perhaps validator on a dynamic var?
09:14justin_smiththat kind of makes sense, if you tolerate dynamics
09:15gfredericksyeah that's a good point
09:15gfredericksmaybe also for with-local-vars which who even uses that
09:15gfredericksit feels like an almost entirely different kind of thing
09:15justin_smithI mean seriously, yeah
09:15justin_smithwould any of us even notice if with-local-vars just disappeared?
09:16gfredericksI once came up with a non-composable tactic for turning a non-dynamic var into a dynamic one
09:16gfredericksI think it might've or could've used with-local-vars in the impl
09:18justin_smitha SO question I provided an inadequate answer to yesterday led to an idea for a useful utility
09:18justin_smithsomeone wants a command line with a long running lein instance where they can type in lein commands to run them
09:19gfredericksa repl for lein?
09:19justin_smithit seems like you could do that with a shell script that loads the lein jar, and runs a custom interpreter loop
09:19justin_smithyeah
09:19gfredericksdidn't it have that feature at some point?
09:19gfredericks`lein interactive`
09:19hyPiRionyes, we did
09:19stuartsierraI thought it still did.
09:19justin_smithI think there is an issue that lein has some stuff that just breaks in long running processes
09:20justin_smithbut what if you (every time? occasionally?) restarted lein after the command to get a fresh start...
09:20justin_smithor, bigger task, fixed the weird stuff that happens when lein stays running
09:20justin_smithsaid weird stuff I would need to do some more research - I recall technomancy talking about this a while back
09:21justin_smithstuartsierra: I think lein interactive was discontinued with lein 2.x
09:21stuartsierraoh
09:21justin_smith"lein rewrite using component" - awesom gsoc proposal
09:22jballancjustin_smith: according to crossclj, no...nobody would miss with-local-vars: http://crossclj.info/fun/cljs.core/with-local-vars.html
09:22justin_smith(inc jballanc)
09:22hyPiRionlazybot is as dead as every
09:22hyPiRion*ever
09:22justin_smithOK, this is getting way silly
09:23justin_smithyeah, I need to look into implementing "oh, I need to reconnect" logic in lazybot one of these days
09:23justin_smithif I wasn't behind on 3 different contracting jobs...
09:27jballanc,(rip lazybot)
09:27clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: rip in this context, compiling:(NO_SOURCE_PATH:0:0)>
09:33Bronsajballanc: I would https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader/impl/utils.clj#L74-L77
09:33jballancah, interesting!
09:33justin_smithBronsa: ahh, I guess crossclj doesn't cross reference tools.reader
09:33jballancreminds me that I need to spend more time with tools.reader
09:34Bronsajustin_smith: no just jballanc linked cljs.core/with-local-vars rather than clojure.core/with-local-vars http://crossclj.info/fun/clojure.core/with-local-vars.html
09:35jballancoh, whoops!
09:35jballanc:-[
09:35justin_smithahh, OK
09:37jballancBronsa: wait...looking at the source for `with-local-vars`, wouldn't it make more sense to just call `(.. clojure.lang.Var create setDynamic)` directly?
09:37jballancI mean, the whole thread context gets pushed and poped before you return `x`, so that doesn't really do anything for you, right?
09:38ionthasI have an infinite loop in a future, right now is only a counter. How can I get the current number of the future in my main thread? deref hangs up because the future it's still running.... any ideas?
09:38justin_smithionthas: use an atom / agent / ref for the counter
09:38tbaldridgeionthas: kindof a odd use-case, but consider using agents
09:38tbaldridge,(doc agent)
09:38clojurebot"([state & options]); Creates and returns an agent with an initial value of state and zero or more options (in any order): :meta metadata-map :validator validate-fn :error-handler handler-fn :error-mode mode-keyword If metadata-map is supplied, it will become the metadata on the agent. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on ...
09:38Bronsajballanc: yes, except with-local-vars is a public var, Var/create and Var/setDynamic are implementation details
09:39jballanchmm...true
09:39justin_smithyeah, that is a good use case for agent
09:39ionthasok, thanks. I will look at them.
09:39Bronsajballanc: and since one of t.r promises is backcompatibility, I'd rather not rely on implementation details that might change in the future
09:40jballancyeah, a laudable goal...still makes me think that the ability to create new dynamic vars should be promoted to public API
09:40justin_smith(let [a (agent 0)] (dotimes [i 10000] (send a inc)) @a)
09:41justin_smith,(let [a (agent 0)] (dotimes [i 10000] (send a inc)) @a)
09:41clojurebot0
09:41justin_smithhaha
09:41Bronsajballanc: agreed
09:42justin_smithionthas: in one's own repl, you'll notice you get numbers in the 8k to 10k range, but if there were even a short wait before the deref at the end you would consistently see 10k
09:42Bronsa,(let [a (agent 0)] (dotimes [i 10000] (send a inc)) (await a) @a)
09:42justin_smithaha!
09:42clojureboteval service is offline
09:42Bronsawell
09:42Bronsa,(let [a (agent 0)] (dotimes [i 10] (send a inc)) (await a) @a)
09:42Bronsawhatever, that works.
09:42clojureboteval service is offline
09:42Bronsa,1
09:42clojurebot1
09:42hyPiRionclojurebot doesn't like threads
09:42Bronsaclojurebot: you're a weirdo
09:42clojurebotPardon?
09:43justin_smith(inc Bronsa)
09:43justin_smithI had forgotten about await
09:43Bronsajustin_smith: you are now my least favourite person, followed closely by lazybot
09:44justin_smithhehe
09:53hejki_justin_smith: user config is just per user per computer data (i.e. user preferences), not something where multiple users concurrently access the same system
09:54justin_smithhejki_: OH, OK
09:54justin_smithhaha, didn't mean to all caps that.
09:54justin_smithhejki_: but there is still the concern that any process that can use loopback network can get the user's privs (but that's a smaller problem, of course)
09:55justin_smithhas there been any work done to add local auth to nrepl?
09:56hejki_I do not think that is going to be a real problem
10:00justin_smithhejki_: yeah, it just reminded me of the general issue, which I think is still worth fixing
10:01hejki_btw, could I launch up a modified nREPL that contains all the user "globals" I wish, rest of the code would be executed via grench
10:01hejki_is anything ran in the repl session accessible via grench?
10:02justin_smithhejki_: well, how modified? the startup time issue is because of how clojure bootstraps itself
10:02justin_smithhejki_: grench is an nrepl client written in ocaml, it accesses a clojure process (and has full access to that process)
10:02hejki_well, I would like to read some data whenever the REPL is launched, and then that data could be referred in the code I run using grench in that REPL
10:03justin_smithhejki_: yeah, you can access whatever you like in the clojure server process via grench
10:04hejki_so I could always (use "myglobals") when the REPL is started and those would then be accessable in the code ran using grench
10:04hejki_?
10:04justin_smithhejki_: not that exact syntax, but yeah
10:05hejki_well yes
10:05hejki_:P
10:05hejki_'
10:05hejki_:)
10:05hejki_would it be a bit too transparent for a developer? they should "just know" that some namespace is preloaded in the repl
10:05justin_smithhejki_: typically I would have an init function that binds a bunch of config.
10:06justin_smithhejki_: I think it could be set up such that you put them in a default ns when they connect
10:06justin_smithand you can use / require / bind whatever you need to in that ns
10:06hejki_that would be awesome :)
10:07justin_smithhejki_: but the way clojure namespaces work, if they create / switch to their own ns, from that point they are on their own
10:07hejki_wouldn't that be just defining a namespace in the REPL startup and then using that namespace like any other namespace from the actual code?
10:07justin_smithhejki_: there is no such thing as "globally using" for all namespaces
10:07hejki_good :)
10:07hejki_I think I'll have to just install grench and do some experimentation
10:07justin_smithhejki_: you could define the ns in a normal clojure file, and just set it to be the repl default
10:07hejki_I just have boring work stuff I have finish first :P
10:08justin_smithhejki_: yeah, good plan
10:15jackhillHi, can I get lein to communicate with nrepl over a unix domain socket instead of a network socket?
10:16justin_smithjackhill: the jvm can't do uds without a native lib
10:17justin_smithjackhill: that said, I don't know how hard it would be to make nrepl use that instead of a network socket (and I think doing so would be a great idea)
10:17jackhilljustin_smith: I'm okay with using a native lib, or is that too hard?
10:17jackhilljustin_smith: ah, I'll continue digging
10:17justin_smithjackhill: junixsocket might be worth trying out, I haven't had great luck with native libs but it could be I was trying to use a bad lib
10:19jackhilljustin_smith: okay thanks. Do you have pointers about where in nrepl I'd look to try to make it use that?
10:21justin_smithjackhill: I think you would want to parameterize or replace start-server https://github.com/clojure/tools.nrepl/blob/master/src/main/clojure/clojure/tools/nrepl/server.clj#L121
10:21justin_smithjackhill: if your uds replacement for the network socket has the same api as ServerSocket, then it should Just Work™
10:22justin_smithjackhill: it's a small enough function that you could copy/paste to make a uds using replacement even
10:23justin_smithjackhill: mutatis mutandis for client, of course :)
10:25jackhilljustin_smith: great, I'll look into it :)
10:34michaelr`re
10:36martinklepschbest way to get random alpanumeric 10 character strings in clojure?
10:37martinklepschI guess cutting uuids isn't the right thing to do
10:37llasrammartinklepsch: depends some on context. E.g, if for test.check tests then you should use appropriate generators :-)
10:38noidi,(apply str (repeatedly 10 #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789")))
10:38clojurebot"m4uuvda17f"
10:38hyPiRion^
10:39martinklepschllasram: not for testing
10:41llasram,(let [chars (->> (range 128) (filter #(or (Character/isAlphabetic (int %)) (Character/isDigit (int %)))) (map char) (into []))] (apply str (repeatedly 10 #(rand-nth chars))))
10:41clojurebot"OU7Ep7yHmK"
10:41llasramLook Ma, no magic strings! :-)
10:42martinklepschI need these to be unique, can I rely on something as simple as rand-nth for that?
10:43llasrammartinklepsch: uh. how unique?
10:43martinklepsch(should have mentioned that uniqueness requirement earlier, sorry)
10:43hejki_prng never provides unique enough ;>
10:43Glenjaminsecure unique?
10:44martinklepschGlenjamin: no
10:44martinklepschGlenjamin: i.e. I don't need proof that it's going to be unique
10:44Glenjamincan you say the use-case?
10:44Glenjaminsomething like tiny-url?
10:45martinklepschGlenjamin: yeah I guess that's similar
10:45martinklepschI feel evil mentioning the actual usecase: tagging browsers via cookies
10:45Glenjamini think generally for that there's a number store internally, and a two-way mapping from number to string
10:45llasrammartinklepsch: You've made this a very different problem. What you actually have are 10 digit base-36 numbers
10:46Glenjaminwhy not just use uuid ?
10:46martinklepschGlenjamin: legacy
10:46llasrammartinklepsch: What you actually want to to make sure you're generating a unique sequence of numbers
10:46llasrammartinklepsch: Can you just e.g. use persistent state to generate integers in standard order?
10:47llasramOr you could generate randomly and ensure uniqueness in a transactional database
10:48martinklepschllasram: theoretically that'd be possible I guess however that's not how the system currently works and it would complicate things when things are distributed
10:49martinklepschllasram: isn't this: (apply str (repeatedly 10 #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789"))) the same as this basically: "What you actually have are 10 digit base-36 numbers"?
10:49llasrammartinklepsch: 10 base-36 digits gives you ~51.7 bits
10:50llasrammartinklepsch: Yes, but they're very different ways of thinking of the problem
10:50martinklepschllasram: ok, that's right
10:52martinklepschGlenjamin: sorry if my "legacy" reply earlier was a little minimal. I'm migrating a PHP system to clojure. PHP generates this kind of token, now I need to do the same thing in Clojure.
10:52martinklepschGlenjamin: eventually that stuff is all handled by Clojure and we can switch to something sane like UUIDs
10:52llasrammartinklepsch: Can you just implement the same algorithm the PHP code uses? Then it won't be any worse
10:53martinklepschllasram: I can but I don't want to really:
10:53martinklepsch $hash = md5(mt_rand(1, 10000).microtime().getmypid().gethostname());
10:53martinklepsch return str_pad(substr(base_convert($hash, 16, 36),0,10),10,"0");
10:53julianlevistonmartinklepsch: what time or space period do they have to be unique across?
10:53martinklepschThere must be a less weird way of doing it in clojure :D
10:54julianlevistonmartinklepsch: nevermind, you kind of answered my q with your php implementation paste.
10:54martinklepschjulianleviston: what did that paste tell you about your q?
10:55martinklepschjulianleviston: I don't think the php implementation is ideal
10:55julianlevistonmartinklepsch: that you don’t care about total uniqunenss enough to be storing it in a db and checking previous ones or anything
10:55llasrammartinklepsch: How many users do you have?
10:56llasrammartinklepsch: But probably timestamp + some randomly-seeded randomness is the best you can do
10:57julianlevistonmartinklepsch: I don’t know what is wrong with uuid?
10:57martinklepschjulianleviston: it's 16 bytes vs 10
10:57llasramjulianleviston: Because UUIDs are 128 bits and martinklepsch needs to fit this identifier into 51.7 bits
10:58julianlevistondoes this help? https://clojuredocs.org/clojure.core/rand-int
10:58julianlevistonie… the example on that page has a fn called “unique-randon-numbers”
11:00julianlevistonmartinklepsch: but that’s talking about uniquneness within itself… you want uniqueness outside of the numbers… sorry.
11:00julianleviston(ie no char repeated versus no repeated set of chars)
11:01julianlevistonmartinklepsch: can you use gensym?
11:01julianlevistonmartinklepsch: sorry I’ll be quiet :) I’m not helping.
11:03martinklepschjulianleviston: nah, it's appreciated :) but I just figure I'm just gonna do some randomness like (apply str (repeatedly 10 #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789"))) for now and lobby to make the switch to UUIDs before anything goes live
11:03julianlevistonmartinklepsch: one more… this lib might be very helpful… https://github.com/maxcountryman/flake
11:03clojurebotHuh?
11:04julianlevistonmartinklepsch: (utils/base62-encode (flake/generate)) ; -> "8mwFA958SJ2CZVu9nk"
11:04julianlevistonDecentralized, k-ordered unique ID generator
11:04martinklepschjulianleviston: what does this provide over UUIDs?
11:05martinklepschhttps://github.com/boundary/flake#frequently-asked-questions
11:05martinklepschnvm
11:05julianlevistonguh… sorry. I didn’t see that it was 128bit only until too late. k. soz.
11:15martinklepschjulianleviston: interesting nontheless, thanks for the link, I noted it as UUID alternative
11:17kodumuloIs there a way to detect datatypes from strings? Like lets say i have a vector of strings, the first element is a normal string of characters, the second one is a string of numbers and the third one is a date. Is there a function I can map over them to convert them to string,number,date respectively?
11:17sm0keis it possible to efficiently scan classpath for all implementation of a protocol?
11:17julianlevistonkodumulo: the reader will do that...
11:18kodumulojulianleviston: not sure I understand what that mean
11:18Bronsakodumulo: read-string
11:18julianlevistonkodumulo: it’s how clojure reads source.
11:19kodumulothnx
11:19julianlevistonkodumulo: depending on your date literals, you might want to use something other than the reader… all depends on the format…
11:20kodumuloyeah its not working on these dates, oh well I'll think of something fancy for that. Thanks
11:21julianlevistonkodumulo: this might help: https://github.com/clojurewerkz/serialism
11:21Bronsakodumulo: also check out tagged literals
11:22kodumuloNumberFormatException Invalid number: 2015-01-06 clojure.lang.LispReader.readNumber (LispReader.java:256)
11:23Bronsa,(read-string "#inst \"2015-01-06\"")
11:23clojurebot#<SecurityException java.lang.SecurityException: denied>
11:23Bronsakodumulo: try that on your repl
11:23julianlevistonkodumulo: it’s a tagged literal
11:23kodumuloI am reading from a file, I don't know before hand if its a date or not, this isn't clojure data
11:23Bronsakodumulo: then read-string is not what you need
11:24kodumuloI'm discovering that ;)
11:24julianlevistonkodumulo: that lib I linked you to probably does anything you want to throw at it.
11:24kodumulojulianleviston: nice thanks
11:24julianlevistongotta be specific as possible with your q’s. o-)
11:24julianlevistonit’s hard.
11:27sardinha_bibaWhat's the meaning of arity in this expression please? "Functions can also be overloaded by arity." I'm not a native english speaker and i'm having some difficulty understanding it.
11:27tcrayford____sardinha_biba: "arity" is the number of arguments a function can take
11:27Bronsasardinha_biba: (fn ([] 0) ([x] 1))
11:28Bronsasardinha_biba: that function can take either 0 or 1 args, those are those functions' arities
11:28julianlevistonsardinha_biba: it’s not a normal english word. It’s a programming term.
11:28justin_smithjulianleviston: also math / logic
11:29julianlevistonjustin_smith: too true! :)
11:29justin_smithbut yeah, not conversational english at all
11:29julianlevistonsardinha_biba: a quick google will find it for you BTW… http://en.wikipedia.org/wiki/Arity
11:29sardinha_bibaso arity = number of arguments a function can take?
11:30tcrayford____yep
11:31julianlevistonsardinha_biba: and arity overloading is when a function has different bodies, each of which correspond to a different number of arguments
11:31nonrecursivesardinha_biba: also, http://en.wikipedia.org/wiki/Function_overloading “Function overloading or method overloading is the ability to create multiple methods of the same name with different implementations”
11:31kodumuloin grammar it's called valency
11:31julianlevistonkodumulo: oh wow… I did not know that…
11:32kodumuloand the function is a predicate, although in programming only some functions are predicates
11:32sardinha_bibaits atarting to make sense now :)
11:32sardinha_bibathank you all for the clarifications
11:32sardinha_bibaand the links :)
11:32kodumuloessentially in natural language all verbs return true (the basic idea behind lojban)
11:33julianlevistonkodumulo: Ah… I didn’t know it because I’d primarily studied functional grammar
11:33kodumuloi mean all verbs return true or false
11:34julianlevistonkodumulo: I need to study more :) http://en.wikipedia.org/wiki/Valency_(linguistics) this is cool. Thanks for that.
11:34kodumulonp
11:35kodumuloin lojban all verbs have a fixed valency/arity
11:35julianlevistonkodumulo: hehe that’s a funny language… did you ever learn any esperanto?
11:36kodumuloJes, mi povas paroli Esperanton tre bone
11:36julianlevistonmi forgesis mia esperanton
11:36kodumuloMia nomo estas Esperanta
11:37julianlevistonI do like it, tho :)
11:37dbronicoHey, guys. I've got a question regarding calling an external program (not caring about the results). I started with clojure.java.shell/sh, but I think it's 1., the wrong place to use it, and 2., it wouldn't pass all of the arguments correctly. So I looked at calling Java's 'exec' through java.util.Runtime, but the program terminates before the exec call is finished. Wrapping it with 'waitFor' caused it to hang. Any suggestions?
11:39julianlevistonkodumulo: ah… mi vidas… http://eo.wikipedia.org/wiki/Kodumulo
11:42tbaldridgesm0ke: if you just want to get all current impls of a protocol you can do this:
11:42tbaldridge,(:impls clojure.core.protocols/CollReduce)
11:42clojurebot{nil {:coll-reduce #<protocols$fn__6424 clojure.core.protocols$fn__6424@400bbd0b>}, java.lang.Object {:coll-reduce #<protocols$fn__6422 clojure.core.protocols$fn__6422@33801e1a>}, clojure.lang.IReduce {:coll-reduce #<protocols$fn__6420 clojure.core.protocols$fn__6420@52f07026>}, clojure.lang.ASeq {:coll-reduce #<protocols$fn__6418 clojure.core.protocols$fn__6418@386f0df7>}, clojure.lang.LazySeq {:...
11:44Bronsatbaldridge: i'm not sure that includes the inline impls
11:44Bronsa,(deftype x [] clojure.core.protocols/CollReduce)
11:44clojurebotsandbox.x
11:44Bronsa,((:impls clojure.core.protocols/CollReduce) sandbox.x)
11:45clojurebotnil
11:45Bronsa,((:impls clojure.core.protocols/CollReduce) 'sandbox.x)
11:45clojurebotnil
11:45Bronsayeah, no
11:45julianleviston,(:impls clojure.core.protocols/CollReduce)
11:45clojurebot{nil {:coll-reduce #<protocols$fn__6424 clojure.core.protocols$fn__6424@400bbd0b>}, java.lang.Object {:coll-reduce #<protocols$fn__6422 clojure.core.protocols$fn__6422@33801e1a>}, clojure.lang.IReduce {:coll-reduce #<protocols$fn__6420 clojure.core.protocols$fn__6420@52f07026>}, clojure.lang.ASeq {:coll-reduce #<protocols$fn__6418 clojure.core.protocols$fn__6418@386f0df7>}, clojure.lang.LazySeq {:...
11:46julianleviston,(-> (:impls clojure.core.protocols/CollReduce) vals first (get 'sandbox.x))
11:46clojurebotnil
11:46julianlevistonBronsa: were they equiv?
11:47Bronsawhat?
11:47clojurebotwhat can possibly go wrong
11:47julianlevistonBronsa: Ah soz… I didn’t realise what was going on :)
11:47julianlevistonBronsa: the initial key of nil threw me off.
11:49ppppaulis there a quick way to pretty print/beautify clojure/edn on the command line/lighttable/web ???
11:49julianlevistonppppaul: pprint
11:49ppppaulpprint means i am in a clojue env
11:50ppppaulwhich, i'm not (hence web/command line ref)
11:50mdrogalisppppaul: Cljs doesn't have pprint yet.
11:50mdrogalisI usually get around this by pprinting it on the server and sending it to JS. Sad face.
11:50ppppauli know cljs doesn't have pprint... is there a web service that will pprint, or lighttable plugin (there is one for JS beautify)
11:51ppppauli don't have the option to pprint on the server, as i don't have a server
11:51ppppaulmy edn data is coming from mori, actually
11:52mdrogalisppppaul: Not sure, sorry. :(
11:52ppppauli have been converting my edn into JS and using jsbeautify
11:53julianlevistonWhat’s this? http://crossclj.info/ns/org.clojure/clojurescript/latest/cljs.pprint.cljs.html
11:54julianlevistonis it borked?
11:58ppppauli feel borked
12:00julianlevistonppppaul: same…
12:00julianlevistonbut that might just be because it’s 4 am.
12:01sardinha_bibalies.. it's 17h
12:01justin_smith~ugt
12:01clojurebotugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html
12:02sardinha_biba:)
12:03julianlevistonhaha sorry :)
12:03justin_smithI think referencing your local time is fine
12:05{blake}OK, so, I've got this ns my co-worker wrote for accessing MongoDB, wherein every call starts by opening a connection to the DB (which is never closed =P).
12:06{blake}I'm looking at how to fix. There doesn't seem to be a "Is this connection good?" pingy kind of thing in Monger.
12:06tcrayford____{blake}: doesn't Monger's underlying driver just handle busted connections by default? It should :/
12:07{blake}One problem that recurs under other languages with DB access is the wrapping of everything in exception handling/error checking, but that's kind of weak.
12:07{blake}tcrayford____: You know, I don't really know. I don't see any reason to believe that it does, though.
12:07tcrayford____yea, oof :( File an issue I guess?
12:07tbaldridgedepending on your client library, it might also be doing connection pooling/reuse
12:07{blake}If you connect, you get a connection...string?...back.
12:08tbaldridgewhat are you using to talk to Mongo?
12:08{blake}tbaldridge: Monger. And I discovered the problem when I killed my local app (just me testing) and watched MongoDB close about 2,000 live connections. =P
12:08{blake}So I don't think it's auto-pooling. =)
12:09michaelr`thank god for postgres ;)
12:09{blake}Looking at getDB, it's just "(.getDB conn name)", where conn is passed in.
12:09uris77is there a way to create a deployable jar for ring apps, similar to the way it is done with spring boot and dropwizard?
12:09{blake}michaelr`: Pretty sure we could screw this up with Postgres, too. Heh.
12:09michaelr`jk
12:12{blake}So, I'm thinking, maybe I stub out our little connection call so that it returns whatever the connection is. This will work as long as the connection remains unbroken.
12:12tcrayford____uris77: yeah, look for "uberjar"
12:13uris77ah, thank you tcrayford____
12:13{blake}Doing that, though, do I also wrap the other routines in such a way that a failure checks for bad connection, and retries to connect? And if so, how?
12:14{blake}Aspect Oriented Progrmaming! =)
12:15julianleviston{blake}: couldn’t your stubbing include check and retry if not connected?
12:16jcrossley3gfredericks: i like your talk title :)
12:17gfredericksjcrossley3: heythanks!
12:17{blake}julianleviston: It could! If I had any way to check! I thought about reauthenticating on every request as a test, but that seems somewhat excessive. (Less so than opening a new connection every time, though, I must admit.)
12:18julianleviston{blake}: it really gives you no way to determine if you’re connected?
12:19{blake}julianleviston: Not that I see, and I'm perusing the code for likely candidate. Though if I can find such a utility in MongoDB itself, I could probably use that.
12:20thearthurat the conj there was mention of a non-blocking put and take function for core.async, anyone remember what that was called?
12:20julianleviston{blake}: what happens if you issue a command and it’s not connected? You could use that as your verification… I guess this is why you were talking about wrappering all your queries
12:20tbaldridgethearthur: put! and take! are non-blocking
12:20julianlevistonthearthur: put! take! right?
12:20julianlevistontbaldridge: oh too quick! :)
12:20julianleviston(inc tbaldridge)
12:21thearthurtbaldridge: julianleviston I guess i meant non-parking then
12:21julianlevistonthearthur: yes. that is what they are.
12:21{blake}julianleviston: Exactly. And it's the sort of problem that comes up in DB programming all the time. So, if I have to do it, I wanna do it in a non-sucky way.
12:21julianlevistonthearthur: they don’t park a go block, or block a thread, and they can be used in or out of go blocks
12:22thearthurso if the buffer is full they should return an error instead of parking the block until the buffer empties
12:22tbaldridgethearthur: yeah, I think Rich mentioned that. Don't think they are implemented yet.
12:22whomphow do i get the cursive ide? i can't find it in the list of plugins for intellij idea
12:23julianlevistonwhomp: you have to add a repo in intellij or d/l it from the site.. there are instructions on the site.
12:23Bronsawhomp: https://cursiveclojure.com/userguide/
12:23whompthx :)
12:24julianlevistontbaldridge: really? so what do they do now? I thought they worked async… so they just buffered it or something?
12:24julianlevistontbaldridge: it *did* cross my mind as being curious a couple times, actually.
12:25tbaldridgejulianleviston: no, Rich mentioned at the conj that he wants to add something like non-blocking deref for channels. take! and put! require a callback
12:25julianlevistontbaldridge: i guess it probably spins up a go block that finishes when the put succeeds?
12:25tbaldridgeRich wants to add (poll c) where you either get nil or a value instantly, never a block and no callback required
12:26julianlevistontbaldridge: put! doesn’t require a callback… oh… so if it fails, it silently fails at the moment??
12:26julianlevistontbaldridge: why is this not in the documentation? :) :)
12:26raspasovtbaldridge: can you achieve something like that with alts!! and using the :default?
12:27tbaldridgejulianleviston: here's the bit of Rich's talk about it: http://youtu.be/4KqUvG8HPYo?t=50m28s
12:27raspasovtbaldrige: (alts!! [my-chan] :default :nothing-immediately-in-chan)
12:27{blake}I love when things are marked as deprecated with no suggestion of what their functionality is being replaced by.
12:28julianlevistontbaldridge: ;ian. byt O
12:28julianlevistontbaldridge: yeah but I’m just curious about if I do a put! outside of a go block into a chan right now that is full, what is supposed to happen?
12:29raspasovjulianleviston: if you put too many you'll start getting exceptions I believe
12:29raspasovusing put!
12:29julianlevistonraspasov: yeah, 1024.
12:29tbaldridgejulianleviston: if you provide a callback, the callback will not be run until the buffer has room for the put. If you try to do too many puts, eventually you will get an exception.
12:29julianlevistonraspasov: assuming a standard (chan)…
12:30tbaldridgejulianleviston: that 1024 limit is hard-coded, there is no config for it. Channels consist of 3 "queues" the puts, takes and the buffer. Puts and takes have a hard limit of 1024
12:30tbaldridge*pending puts and takes
12:30julianlevistontbaldridge: oh really? I thought I’d managed to have a (chan 2048) in my code...
12:30{blake}1K ought to be enough for anybody.
12:30julianlevistontbaldridge: interesting. I wish this was written down somewhere
12:30tbaldridgesure, thats changing the size of the buffer, not the size of the pending (blocking) puts and takes
12:31julianleviston{blake}: lol… nice.
12:31thearthurjulianleviston: that alts method shows promise as a workaround
12:31julianlevistonthearthur: it does? how’s that?
12:32thearthurthe goal is to get all the messages currently avaiable now, consolidate them into a collection and then move on
12:32tbaldridgeraspasov: yeah, you can do the same thing with alts! and :default, but that method creates a fair amount of garbage and bookkeeping, it's probably possible to do it in a much more efficient way.
12:32julianlevistontbaldridge: the annoying thing in my program is I’m using one main channel to handle all my events. I guess this answers the question “should I have more than 1 main channel”… I added two more and kept the main one as a handler that hands off calls to 3 other ones the other day… quite helpful...
12:32thearthuris there a better way of going about that?
12:33gfredericksfun fact: NPEs have null messages
12:33tbaldridgethearthur: yeah, with the API as it is today, I'd just do alts+:default
12:33raspasovtbaldridge: you mean garbage in terms of GC/objects or just ugly code?
12:33danielglausergfredericks: niiiice
12:34julianlevistongfredericks: what’s an NPE?
12:34tcrayford____nullpointerexception
12:34tbaldridgeraspasov: yeah, it creates about 3-4 objects, plus it creates a "slot" in the channel that is canceled right away. I don't know how Rich wants to go about implementing offer! and poll! but they could be done with very little (no?) garbage creation
12:35gfredericksI would demo it but I don't think the bots let you catch things
12:35julianlevistonoh … right.
12:36whomphow do i create a new clojure project with resources/, src/, etc. from intellij cursive?
12:36julianlevistonwhomp: I think you have to do it in lein...
12:36julianlevistonwhomp: but don’t quote me on that
12:37julianlevistonI don’t like promises… I think that might be because I wrote a lot of RSVP ones when I wrote my app in Ember… and it was so hard to think about. With channels it might be much easier to think about.
12:37whompthx julian
12:38justin_smithjulianleviston: I like promises for values that only get delivered once, but not right away. Not for threading complex logic via callbacks though.
12:38julianlevistonjustin_smith: yeah, it’s more about delivery than program data flow...
12:38justin_smithwhomp: I think File -> New Project should set things up, no?
12:39justin_smithjulianleviston: right, I don't think promises are good for program flow
12:39whompjustin_smith, not really
12:39justin_smithjulianleviston: but they are better than using an atom that only gets set once
12:40justin_smithwhomp: oh, yeah, julianleviston was right https://cursiveclojure.com/userguide/leiningen.html
12:40justin_smithhaha
12:41julianlevistonshould have seen the mess I had to write in Ember in order to do a recursive tree structure clone… GUH
12:41raspasovtbaldridge: cool, thanks for clarification!
12:41julianlevistonlike 70 lines of coffeescript and many hours of my life
12:41julianlevistonugly ugly ugly
12:42julianlevistonamusingly to do that in clojure is like… almost 0 lines of code.
12:42{blake}(For large values of "0")
12:42julianleviston{blake}: well… how do you clone a large map? You don’t need to… right? :)
12:43julianleviston{blake}: (assoc m :id new-id) ; <- something like that, if I want to change the id.
12:43justin_smith,(let [m' m] m') - done
12:43clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: m in this context, compiling:(NO_SOURCE_PATH:0:0)>
12:43julianlevistonjustin_smith: lol :)
12:43{blake}Hah!
12:43justin_smithwhy did I use ,? my brain is missing
12:44julianlevistonjustin_smith: because I’m tired, and I infected you :)
12:44julianlevistonjustin_smith: ok I gotta go sleep… :) was lovely talking to all of you today!
12:44julianlevistonlaters
13:14{blake}Interesting. Coming from languages where variables were indistinct from functions (in terms of calling conventions), I could replace any variable access with a function call transparently. Can't do that en Clojure.
13:21justin_smith{blake}: on the other hand, vars automatically call their dereffed value in the calling position
13:21justin_smith,(#'+ 1 1)
13:21clojurebot2
13:24hyPiRion{blake}: huh. Then if you have a variable, how would you say I want to return it? You can just call it then, right?
13:24hyPiRionif that variable was a function
13:30justin_smithanother option would be to always deref
13:31justin_smiththe source of the data can deside on what kind of dereffable thing they should provide
13:31justin_smith*decide
13:32justin_smithit could be an atom, a delay, whatever
13:32justin_smitha deftype that calls a function when you deref
13:32justin_smithwhatever evil thing you like
13:32hyPiRioncall-by-deref
13:32justin_smithright
13:32justin_smithprobably the right way to do UAP in clojure, but UAP isn't a very good idea in clojure
13:35hyPiRion,(proxy [clojure.lang.IDeref] [] (deref [] (prn "hi")))
13:35clojurebot"hi"\n#<Object$IDeref$e595a7c1@7cec352a: nil>
13:36justin_smithwhy did it get dereffed?
13:36justin_smithor is that not what happened?
13:36hyPiRionit was printed
13:36justin_smithahh
13:36hyPiRion,(do @(proxy [clojure.lang.IDeref] [] (deref [] (prn "hi"))) nil)
13:36clojurebot"hi"\n
13:36hyPiRion,(do (proxy [clojure.lang.IDeref] [] (deref [] (prn "hi"))) nil)
13:36clojurebotnil
13:36justin_smithcool
13:37justin_smithso, it's value is nil, but it prints "hi" whenever you access the value
13:37hyPiRionyup
13:37justin_smithwell that's that, we have implemented the important features of ruby in clojure, we're done now
13:39hyPiRionoh hey
13:39hyPiRion,(alter-var-root #'clojure.core/unquote (constantly deref))
13:39clojurebot#<core$deref clojure.core$deref@6f1792ce>
13:39hyPiRion,~(atom 10)
13:39clojurebot10
13:39justin_smithoh no
13:42gfrederickshey unary
13:42gfredericks,(alter-var-root #'clojure.core/unquote (constantly inc))
13:42clojurebot#<core$inc clojure.core$inc@61a36d43>
13:42gfredericks,~~~~~~~~~~~~~~~~~~~~~~~~~0
13:42clojurebot25
13:42gfredericksthe idris people will love it
13:43hyPiRionwoah
13:43tomjackonly if it compiles down to primitive arithmetic
13:43tomjack:P
13:43gfredericksdownside is it's probably stackful
13:43gfredericksso you can't make big numbers
13:43justin_smithnow figure out how to access alter-var-root etc. from swearjure, and you can start doing some insanity
13:43gfredericks,(alter-var-root #'clojure.core/unquote-splicing (constantly #(* % %)))
13:43clojurebot#<sandbox$eval203$fn__204 sandbox$eval203$fn__204@f8913dd>
13:44gfredericks,~~~~~~~~@~~~~~@~~~~@~~~~~~~~0
13:44clojurebot20187056
13:44{blake}hyPiRion: Well, you're not calling it, right? 'cause it's not a function. But from the programmer's standpoint "val = something + 1" doesn't change if something is a var or a fn.
13:44justin_smithgfredericks: omfg
13:44gfrederickshow efficient of a representation is just incing and squaring?
13:44{blake}hyPiRion: And, in some cases, you can even say "val = something + 1" and it won't matter if =val= is a variable or function.
13:44TimMcjustin_smith: I don't think we'll be able to break out of the swearjure prison unless we can like... glitch the JVM.
13:44gfredericksprobably not very
13:45{blake}justin_smith: I'm trying to parse that.
13:45justin_smith{blake}: parse which?
13:46{blake}justin_smith: "on the other hand, vars automatically call their dereffed value in the calling position"
13:46hyPiRionTimMc: perhaps if there are bugs with the new conditional form, #?
13:46gfredericks,(alter-var-root #'clojure.core/unquote (constantly #(* 2 %)))
13:46hyPiRionor the #?@ version
13:46clojurebot#<sandbox$eval26$fn__27 sandbox$eval26$fn__27@51993720>
13:46gfredericks,(alter-var-root #'clojure.core/unquote-splicing (constantly #(inc (* 2 %))))
13:46clojurebot#<sandbox$eval53$fn__54 sandbox$eval53$fn__54@7bb0d860>
13:46justin_smith,(type #'+) ; {blake}
13:46clojurebotclojure.lang.Var
13:47gfredericks^ that should give an efficient representation though
13:47justin_smith{blake}: so that's a var
13:47gfredericks,~~~~~~@0
13:47clojurebot32
13:47justin_smith,(#'+ 1 1) ; it auto-derefs and calls
13:47clojurebot2
13:47{blake}justin_smith: The plus sign is a var? Pointing to the plus function?
13:47gfredericks,~@~~~~~~@0
13:47clojurebot65
13:47justin_smith{blake}: no #'+ is a var
13:47{blake}justin_smith: So...lemme think how I can apply that.
13:48{blake}pound quote plus? =P Hang on...
13:48hyPiRion{blake}: so #'+ is not +, but @#'+ is the same as +
13:48TimMchyPiRion: Oh man, I haven't looked at the conditional stuff yet!
13:48justin_smithand furthermore, #'+ when used as a function looks up + and calls it for you
13:48aperiodic,(= #'+ (var +))
13:48clojurebottrue
13:49hyPiRionTimMc: It doesn't seem useful yet, but if there are bugs in it we might get a chance
13:49hyPiRionOh right
13:49TimMcThere could be bugs anywhere already.
13:49hyPiRion{blake}: #'x is just sugar for (var x)
13:49hyPiRion,'#'x
13:49clojurebot(var x)
13:49TimMcMaybe we need to add metadata to just the right thing or something.
13:49TimMcor a parser bug somewhere
13:49hyPiRionyeah
13:50hyPiRionHow should we go forward though? Make fuzzy tests or something?
13:51hyPiRionmaybe we can use this
13:51hyPiRion,(-> + #'foo)
13:51clojurebot#'clojure.core/+
13:53krat0sprakharhi everyone
13:53krat0sprakhari've been trying to wrack my brains on problem 132 on 4clojure
13:53krat0sprakharmy solution is passing all but the last test case - https://www.refheap.com/96906
13:53krat0sprakharany idea whats wrong?
13:56krat0sprakharmy hunch is that my solutions uses reduce with iterate
13:56krat0sprakhar,(take 10 (->> (iterate inc 10) (reduce +)))
13:56krat0sprakharwill fail
13:56clojurebotExecution Timed Out
13:58justin_smithkrat0sprakhar: the last case returns an infinite series
13:58justin_smithkrat0sprakhar: so your function needs to be lazy
13:58krat0sprakharyeah..
13:59krat0sprakharbut i cant do that with reduce right?
13:59justin_smithkrat0sprakhar: no, you can't
13:59krat0sprakharso i need to find another way that doesn't rely on reduce?
13:59justin_smithkrat0sprakhar: it's good to know how to use lazy-seq (or you can even use concat in a recursive function for this particular case)
13:59justin_smithkrat0sprakhar: yeah
14:00justin_smithkrat0sprakhar: try it with lazy-seq directly - that's the more tedious but more informative way as a beginner I think :)
14:00justin_smithit's basically just going to look like a recursive function
14:00krat0sprakharhaha.. i'm having a hard time understanding the lazy-seq macro
14:00krat0sprakharcan i use loop / recur?
14:01krat0sprakharor will that fail as well
14:01gfrederickslazy-seq is normally used with normal recursion
14:01justin_smithyeah - you want laziness with dumb recursion
14:01justin_smithie. calling the same function, not using recur
14:01krat0sprakharah ok
14:02justin_smithkrat0sprakhar: conj.io has good examples of stuff http://conj.io/store/v0/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/lazy-seq/
14:02krat0sprakharso using let bindings i can get the first part of the collection, then conj it with a lazy seq - calling the function recursively?
14:02justin_smithright
14:02justin_smithand because lazy-seq thunkifies things, you won't blow the stack
14:03gfredericks~lazy-seq |thunkifies| things
14:03clojurebotYou don't have to tell me twice.
14:03{blake}Ahhh...I'm getting "var" and "def" mixed up.
14:03krat0sprakharjustin_smith: thanks! i'll give that a shot
14:03justin_smithweee got that thunk, got to have that thunk
14:03krat0sprakharwill come back to you if i'm not able to solve it :P
14:03krat0sprakharhope thats okay
14:03justin_smithhttps://www.youtube.com/watch?v=l4nOHdUntyM
14:04{blake}Wait, they are the same thing, sorta.
14:04justin_smith{blake}: def creates vars
14:04justin_smith(var x) gets the thing def created
14:04justin_smithusing the symbol x looks up that def's value
14:04krat0sprakharjustin_smith: this is groovy .. thanks! :D
14:04justin_smithgotta have that thunk
14:04krat0sprakharLOL :D
14:05{blake}justin_smith: Right.
14:05justin_smithhttp://en.wikipedia.org/wiki/Thunk in case you didn't know
14:05justin_smithit's how laziness is done
14:06krat0sprakharwow! so *thunk* is really a word :D
14:06krat0sprakhari had no clue
14:07krat0sprakhar,(def my-msg "thunk")
14:07clojurebot#'sandbox/my-msg
14:07krat0sprakhar,(count my-msg)
14:07clojurebot5
14:07krat0sprakharwow
14:07krat0sprakharyou know, this clojurebot is much more awesome than tryclj.com
14:07justin_smithalso, you can access clojurebot via /msg
14:07krat0sprakharthe repl there is quite buggy as anthony as longer working on it..
14:08krat0sprakharand boy is clojurebot fast!
14:08justin_smithRaynes has been far from the clojure fold
14:08krat0sprakharwhy so
14:08krat0sprakhar?
14:08justin_smithhe is doing other langs for work now
14:08krat0sprakharhaskell? i remember seeing a post on his blog
14:10krat0sprakharanyone with cursive got a clue what does the error msg - "no nREPL ack recieved mean"?
14:10krat0sprakharafter that outofmemory error it doesnt seem to recover.. tried restarting intellij as well
14:10justin_smitheither nrepl did not start, or it did not reply quickly enough
14:11justin_smithhmm, yeah out of memory - is that because your machine is low on memory, or maybe you could raise the limit above the default?
14:12krat0sprakharhmm everythign else to be running fine
14:12justin_smithI think nrepl ends up in its own vm
14:13TimMchyPiRion: I'm thinking of course of the Pokemon glitch that allowed a team to program tetris inside of pokemon just using controller inputs.
14:13hyPiRionoh, of course
14:13krat0sprakharif i rm -rf target folder and run lein repl will that help?
14:13krat0sprakharcant do lein repl from the command line also
14:13krat0sprakharREPL server launch timed out
14:14justin_smithkrat0sprakhar: OK, what about lein :trampoline repl
14:14krat0sprakhartrying..
14:14justin_smith(there are some other things we can try if that fails too)
14:14krat0sprakhar':trampoline' is not a task.
14:14hyPiRionremove the colon
14:14justin_smithoh, oops, my bad
14:14krat0sprakharsorry :P
14:15justin_smithno, it's my fault
14:15hyPiRionTimMc: did we get any way with #= ?
14:16hyPiRionTimMc: If we can find a symbol form for first we can do stuff like
14:16hyPiRion,(#=(first #'+) -)
14:16clojurebot#<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
14:16krat0sprakharjustin_smith: got any more recommendations for some programming music like the clinton one? :D
14:16hyPiRionahhh
14:17hyPiRion,(binding [*read-eval* true] (#=(first #'+) -))
14:17clojurebot#<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
14:17hyPiRion:(
14:17krat0sprakhar:D
14:17justin_smithkrat0sprakhar: mostly meant that as a pun on "thunk" but now I am playlisting james brown / george clinton
14:17justin_smithkrat0sprakhar: so did the trampoline repl help?
14:18krat0sprakharfetching dependancies
14:18krat0sprakharnot on a good connection.. sorry.. taking some time
14:18krat0sprakharshouldn't rm -rf target folder bring everything back to initial state?
14:18TimMc,(alter-var-root #'clojure.core/*read-eval* (constantly true))
14:18clojurebottrue
14:18krat0sprakhar(just guessing here)
14:18TimMc,(#=(first #'+) -)
14:18clojurebot#<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
14:19hyPiRion,(set! *read-eval*)
14:19clojurebot#<CompilerException java.lang.IllegalArgumentException: Malformed assignment, expecting (set! target val), compiling:(NO_SOURCE_PATH:0:0)>
14:20TimMcIt's bound in the scope of the reader, and our binding doesn't take effect until after reading.
14:21justin_smithkrat0sprakhar: target just has your compiled output, not deps
14:21justin_smithkrat0sprakhar: and lein should usually handle the compiled output smartly, most of the time
14:21hyPiRion,(binding [*read-eval* true] (eval (read-string "#=(+ 1 2)")))
14:21clojurebot3
14:21hyPiRionhurray
14:21krat0sprakharok.. is there any way i can set the project state back to the intial state?
14:22krat0sprakhari cant do lein repl only inside taht folder
14:22krat0sprakharits working everywhere else
14:22TimMc,(alter-var-root #'clojure.core/read (constantly (let [r @#'read] #(binding [*read-eval* true] (apply r %&)))))
14:22clojurebot#<sandbox$eval233$fn__234 sandbox$eval233$fn__234@7061ce7d>
14:22krat0sprakhartrampoline still installing
14:22TimMc,(#=(first #'+) -)
14:22clojurebot#<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
14:22TimMcah well
14:23justin_smithkrat0sprakhar: that makes me think the timeout from cursive's connect was because the downloads were happening in the background
14:23hyPiRionI think it's read-string
14:23krat0sprakhari started the downloads
14:23krat0sprakharjust now
14:23justin_smithkrat0sprakhar: recall I said either it did not start, or did not reply in time
14:23justin_smithright
14:23krat0sprakharthe download doesnt happen everytime right?
14:23krat0sprakharjust the first time the proejct is set up..
14:23justin_smithkrat0sprakhar: but if it loaded them before, it wouldn't be happening this time
14:24krat0sprakharright
14:24krat0sprakharso it had..
14:24justin_smithkrat0sprakhar: the first time any of your projects uses a dep
14:24krat0sprakharafter i went crazy with iterate and reduce
14:24krat0sprakharit screwed up
14:24TimMchyPiRion: #= requires literal symbols and only resolves the top level expression.
14:24justin_smithkrat0sprakhar: going crazy with iterate and reduce should not be able to mess up your local dep repo state
14:25TimMc,(binding [*read-eval* true] (eval (read-string "#=(class hi)")))
14:25clojurebotclojure.lang.Symbol
14:25hyPiRionyeah. So I was kind of hoping it could be used to something
14:25krat0sprakharhehe.. apologies for rambling :D
14:25krat0sprakharmy project has no external deps.. so lein repl should work
14:25hyPiRion,(binding [*read-eval* true] (eval (read-string "(quote #=(first #'+))")))
14:25krat0sprakharits working on all other projecs
14:25clojurebotvar
14:25krat0sprakhar*projects
14:27hyPiRion,(defn sharp-eval [s] (binding [*read-eval* true] (eval (read-string s))))
14:27clojurebot#'sandbox/sharp-eval
14:27hyPiRion,(sharp-eval "(quote #=(first `[~@[]]))")
14:27clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sharp-eval in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:27hyPiRionargh
14:27TimMcreset?
14:27hyPiRionwell, that gives me apply
14:27hyPiRion,(defn sharp-eval [s] (binding [*read-eval* true] (eval (read-string s))))
14:27clojurebot#'sandbox/sharp-eval
14:27hyPiRion,(sharp-eval "(quote #=(first `[~@[]]))")
14:27clojurebotclojure.core/apply
14:27krat0sprakhar,(let [[a b c *xs] '( 1 2 3 4 5 6 7)] xs)
14:27clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: xs in this context, compiling:(NO_SOURCE_PATH:0:0)>
14:28krat0sprakharwhy is this wrong?
14:28krat0sprakhar,(let [[a b c *xs] '( 1 2 3 4 5 6 7)] (+ a b c )
14:28clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
14:28TimMchyPiRion: But you can get the ssymbol 'apply without #=.
14:28krat0sprakhar,(let [[a b c *xs] '( 1 2 3 4 5 6 7)] (+ a b c ))
14:28clojurebot6
14:28hyPiRionTimMc: Aw, righto. I thought it actually was the function :(
14:29TimMckrat0sprakhar: Because this isn't Python, if I read your intent correctly.
14:29krat0sprakharhmm.. so how can I get the rest of the list ?
14:29TimMckrat0sprakhar: [a b c & xs]
14:30krat0sprakharoh crap.. sorry!
14:31krat0sprakharjustin_smith: i had the iterate + reduce code in the core.clj file because of which teh repl timed out whenever it tried to restart.. stupid me :| ..
14:31krat0sprakharit works now.. thanks for the help
14:34justin_smithkrat0sprakhar: ahh - yeah, in general side effects on the top level of a namespace are a bad idea
14:34justin_smithso of course it times out, because it wants to evaluate the namespace before giving you your prompt
14:34justin_smithlesson learned, we can hope
14:34krat0sprakhartime to finally give 132 a try :P
14:34krat0sprakhardefinitely :D
14:34krat0sprakhargit checkout to the rescue
14:35justin_smithkrat0sprakhar: the general idea is you can put anything with side effects into a function or a delay, so that just loading the file doesn't make <whatever> happen every time you load it
14:35krat0sprakhargot it!
14:41krat0sprakharjustin_smith: all lazy-seq examples follow the pattern (cons x (lazy-seq ..))
14:41krat0sprakharcan I do (conj (lazy-seq ..) a b)
14:41krat0sprakharinstead?
14:41justin_smithkrat0sprakhar: sure, but conj ends up doing cons on a lazy seq input
14:41justin_smitherr... wait
14:41justin_smithno, use cons
14:41justin_smithbecause conj messes with the laziness
14:41krat0sprakharbut i want to add more than one elem into teh seq
14:42krat0sprakhar(conj [] a b)
14:42justin_smithamalloy_ is better than me at explaining this stuff
14:42justin_smithkrat0sprakhar: check out concat
14:42justin_smith,(concat [:a :b] (lazy-seq))
14:42clojurebot(:a :b)
14:43justin_smithconcat is alsy lazy
14:43justin_smith,(type (concat [:a :b] (lazy-seq)))
14:43clojurebotclojure.lang.LazySeq
14:43justin_smithhaha, alsy
14:43krat0sprakhar:D
14:44krat0sprakharok.. let me give that a shot
14:59krat0sprakharjustin_smith: got it! used mapcat to solve it :D
14:59justin_smithnice
15:00krat0sprakharthanks a lot
15:16auserhello all… anyone here use figwheel/chestnut?
15:17hellofunk~anyone
15:17clojurebotJust a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..."
15:18krat0sprakharclojurebot _/\_
15:19auserGreat… I’m trying out chestnut for the first time and am running into the message “nREPL: No response handler with id nil found “
15:19auserLeaving me a bit stumped
15:20dnolenauser: you might want to ask in #clojurescript
15:20ausergood idea dnolen
15:20hellofunkauser: i think there is an open issue for that on github, you might want to search there
15:20dnolenauser: it's a dedicated channel with helpful people
15:21Lewixyo
15:21ausergood idea hellofunk + dnolen
15:21krat0sprakharhola dnolen
15:21krat0sprakharalways wanted to say hi :P
15:23dnolenkrat0sprakhar: hello!
15:26mmitchelli'm using clojure.tools.logging + log4j2. Anyone know how to simply configure the log level at runtime?
15:26mmitchellin clojure/repl that is
15:27justin_smithmmitchell: clj-logging-config and timbre are two options for that
15:28justin_smithmmitchell: there may or may not be something simpler...
15:29mmitchelljustin_smith: oh! I thought timbre was a pure clojure logging thing, with no support for log4j
15:35justin_smithmmitchell: yeah, timbre is a wrapper for java logging, the main thing is allowing runtime reconfig
15:37mmitchelljustin_smith: perfect - will check it out now. Thanks!
15:38amalloyjustin_smith: rather than (concat [a b] xs), (list* a b xs)
15:39krat0sprakharamalloy: whats the difference?
15:40amalloykrat0sprakhar: well, they both do the same thing, but (concat [a b] xs) does it in a roundabout and slightly more expensive way
15:40krat0sprakharoh ok.. thanks!
15:40amalloy(list* a b xs) is the same as (cons a (cons b xs)), which is the most obvious solution to your problem
15:40krat0sprakharone more quick question - the common pattern for lazy-seq is (cons x (lazy-seq ...))
15:40amalloyusing concat and a vector gets a lot more machinery involved
15:41krat0sprakharcan I do (conj (lazy-seq ..) a b )
15:41krat0sprakhar?
15:41amalloyyou can, but don't
15:42amalloylike, obviously that is a thing that is possible to do; you can see that by trying it in your repl. it just doesn't produce results that will make you happy
15:42justin_smithkrat0sprakhar: remember, I mentioned earlier that it isn't as lazy as it should be
15:42krat0sprakharas lazy as it should be meaning?
15:42krat0sprakharisnt it either lazy or not lazy?
15:44mmitchelljustin_smith: do you know if it's possible for timbre to use an existing log4j config file? That probably sounds strange, but we have common log4j config files shared across many different java projects, this is the only clojure one.
15:45justin_smithmmitchell: I don't really know, I haven't tried that
15:45mmitchellok np, thanks
15:45justin_smithkrat0sprakhar: it can force results it shouldn't need to
15:46krat0sprakharoh hmm.. i don't quite understand most of it. but i'll try to use the common pattern more often
16:26cfleming_krat0sprakhar: I haven't read the whole thread here, did you get your nREPL ack problem sorted?
16:29justin_smithcfleming_: he has an infinite loop at the top level of his main ns
16:29justin_smithwhich would kind of prevent an ack from coming back in time :)
16:29cflemingjustin_smith: That would do it, yes :)
16:30cflemingjustin_smith: I was going to suggest increasing his timeout, but I don't think the field accepts +Infinity
16:30justin_smithheh
16:32irctchey, does someone know how I can hide the 0, 1, 2 at the bottom of an Incanter boxplot?
16:32cflemingwhomp: Yes, unfortunately the best way to create a project right now if you want to use lein is on the command line, then import into Cursive
16:32irctchttp://incanter.org/images/examples/newtheme/box-gamma.png
16:32{blake}Is there a practical difference between (use 'ns) and (require '[ns :refer :all])?
16:33llasram{blake}: No, in that you should never do either (except maybe in a REPL)
16:33{blake}llasram: I am, in fact, doing it in a REPL. =P
16:33imanc_are syntax quotes ` and normal quotes ' interchangeable?
16:34irctcI can hide the 0, 1, 2 using java interop, (.setVisible (.getDomainAxis (.getPlot aprv)) false), but I lose my x axis labels too
16:34{blake}llasram: Though my colleague wrote some code that does a "(use [ns :only [...])". I'm somewhat confused because I've heard here that use is disparaged, if not excactly deprecated.
16:34llasram{blake}: Ah, then no :-)
16:35irctc(Again, I'm trying to remove the 0,1,2 from charts like this http://incanter.org/images/examples/newtheme/box-gamma.png)
16:35llasram{blake}: Yeah -- just now that `require` has `:refer` it can do everything `use` can, so there's no reason to have yet another form
16:35llasramirctc: Probably no one here right now uses incanter
16:35irctcllasram: oh ok
16:35{blake}llasram: So, refer has some additional capability, and use is just baggage.
16:35llasram{blake}: right
16:36{blake}llasram: Groovy. Thanks!
16:36{blake}(inc llasram)
16:36{blake}(inc has-been-less-meaningful-than-usual)
16:37llasramAlas, poor lazybot
16:37{blake}He's gotten REALLY lazy!
16:39amalloyman, lazybot has been getting disconnected like every day all week
16:39amalloyhe has always been broken, but recently he seems more broken
16:39{blake}Has someone tried talking to him? Maybe he's having trouble at home.
16:42amalloy(inc llasram)
16:42lazybot⇒ 48
16:43{blake}(inc lazybot)
16:43lazybot⇒ 37
16:43justin_smith(inc Bronsa)
16:43lazybot⇒ 90
16:44amalloy(inc inc inc)
16:44lazybot⇒ 1
16:44{blake}(inc inc)
16:44lazybot⇒ 12
16:44amalloySNIPED
16:44{blake}damn
16:45justin_smith(identity inc inc)
16:45lazybotinc inc has karma 1.
16:47{blake}(inc Spaces are no barrier to karma.)
16:47lazybot⇒ 1
16:47{blake}(identity Spaces are no barrier to karma.)
16:47lazybotSpaces are no barrier to karma. has karma 1.
16:47SagiCZlol
16:57ordnungswidrig(identity 1 karma)
16:57lazybot1 karma has karma 0.
16:57ordnungswidrig(identity 1 karma)
16:57lazybot1 karma has karma 0.
16:57ordnungswidrig(inc 1 karma)
16:57lazybot⇒ 1
16:57ordnungswidrig(identity 1 karma)
16:57lazybot1 karma has karma 1.
17:06justin_smith(inc ordnunswidrig symmetrischennehcsirtemmys giridiwsnundro nci)
17:06lazybot⇒ 1
17:06jballanchey! lazybot's back
17:07sobeli assumed german but had to check whether symmetrie wasn't also a clojure lib ;)
17:08justin_smithhaha
17:08jballanchmm...
17:08jballanc(inc 1 amrak sah)
17:08lazybot⇒ 1
17:09jballanc(identity 1 amrak sah)
17:09lazybot1 amrak sah has karma 1.
17:09jballancbetter
17:18whomphow do i get intellij idea to print out stdout to the little window? i have it running (println "Hello world"), but it doesn't display
17:18SagiCZwhomp: depends on what you mean by "litte window"
17:18SagiCZif you are running REPL it should print out to the repl output
17:18whompSagiCZ, the window that pops up when i hit "run"
17:19SagiCZthat should work too.. it has to be the Console window
17:19whompSagiCZ, currently it says this: /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/bin/java -Didea.launcher.port=7534 "-Didea.launcher.bin.path=/Applications/IntelliJ IDEA 14 CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_0
17:19imanc_,(take 10 (iterate inc 1))
17:19whompProcess finished with exit code 0
17:19whompoh man, sorry guys :)
17:19clojurebot(1 2 3 4 5 ...)
17:19bodie_anyone using IDEA Cursive?
17:19SagiCZwhomp: well then your code is wrong or you are executing a different file then you want to
17:19SagiCZbodie_: yeas
17:20SagiCZ*yes
17:20imanc_bodie_: trying to - still need to work on it.
17:20SagiCZi have been using it for months.. its amazing
17:20bodie_nice
17:20imanc_i hear the debugger rocks
17:21bodie_IDEA 14 isn't letting me update or install it, not sure why
17:21SagiCZimanc_: its ok but i debug clojure much less than java
17:21SagiCZbodie_: you have to specify new plugin repository acording to the guide
17:22bodie_I probably shouldn't be asking nooby questions like this in here ;P
17:22SagiCZbodie_: this is totally the place for noob question.. as long as tbaldridge isnt around
17:22bodie_but the plugin install button does nothing after I add the repo... just wondered if anyone else had had that issue
17:22bodie_SagiCZ, usually I keep my noob questions to overly convoluted ways to do simple things that functions or macros are already defined for
17:23sobelSagiCZ: would you say you debug less clojure because your clojure code is less error prone?
17:23mfikesbodie_: Don't know if cfleming has the Cursive mailing archive set up completely yet. There was a rash of emails on what appears to be the same subject recently.
17:24SagiCZsobel: i wouldnt say less error prone.. but i just know whats happening easily.. there is always a very clear path of execution in clojure.. if you write idiomatic clojure.. no need to step through and check the state of every object
17:24sobelSagiCZ: gotcha
17:25bodie_mfikes, thanks. exactly what I needed to know. I'll give the archive version a shot
17:27SagiCZsobel: on the other hand i must note that the stack traces in clojure tend to be rather cryptic.. but thats what you get for dynamic types and laziness
17:30tehgeekmeisteri'm running into some really weird issues with some io redirection using future and io/copy
17:31tehgeekmeisterhave two instances of basically this running in parallel: (future (clojure.java.io/copy (:err results) *out* :buffer-size 1))
17:31tehgeekmeisterending up with output like this on *some* lines eetcchhoe d 'Fetched mmoodduulleess..'
17:31tehgeekmeisterbut then it goes back to normal
17:31tehgeekmeisteralso, it truncates the output mid line after a certain point
17:31tehgeekmeisterso, seems like race conditions plus timeouts, probably
17:31tehgeekmeisteranyone have insight that could help?
17:37cflemingmfikes: Ugh, no, I got distracted.
17:37gfredericksHypirion: who is "a friend of Gary Fredericks"?
17:37cflemingbodie_: Try downloading and manually installing, see https://cursiveclojure.com/userguide/ under Manually installing
17:38hyPiRiongfredericks: There was some Clojure meetup you attended, where you said someone came up with (->> foo #())
17:38cflemingbodie_: Sorry for the hassle, for some reason the initial install is difficult sometimes.
17:40sdegutistbaldrid_: what's your language called again?
17:40cflemingsdegutis: Pixie
17:40sdegutisCool, thanks.
17:41ibashGoing to leave this question here while I grab a coffee
17:41ibashwhat use cases is clojure good for and what use cases would it not be recommended for?
17:41{blake}So, RegEx patterns are...functions?
17:41ibashAny good examples of medium size public clojure apps I can explore?
17:41sdegutisibash: it's basically good for anything you'd use Java or Ruby for
17:42sdegutisibash: it's especially good at consumption of large steaming data
17:42{blake}I ask because I put a #"/bword/b" in my code and got a "nested function literal" error.
17:42sdegutisibash: but some of us use it in place of Rails
17:43hiredman_{blake}: they are not
17:43hiredman_,#(#"/bword/b")
17:43clojurebot#<sandbox$eval25$fn__26 sandbox$eval25$fn__26@61b2c9b6>
17:43{blake}hiredman_: OK, I've just screwed something else up then. Thanks!
17:45{blake}Ah, I see my problem. How to construct a string for it. You use # to indicate the pattern, but if you need a concatenation of strings, you can't say #(str...) 'cause...well...
17:47amalloy{blake}: ##(doc re-pattern)
17:47lazybot⇒ "([s]); Returns an instance of java.util.regex.Pattern, for use, e.g. in re-matcher."
17:47whompintellij cursive won't let me type out parentheses when it thinks there's an incorrect arity issue. how can i avoid this?
17:47amalloy&(re-pattern (str "a" "b"))
17:47lazybot⇒ #"ab"
17:47{blake}whomp: Turn off structural editing.
17:48{blake}amalloy: Seems like a lot for a single "find this word in a string" issue.
17:48amalloywell, feel free to write java.util.regex.Pattern.compile("a" + "b"); instead
17:49{blake}I could use .contains, I guess, but that won't do boundaries.
17:49gfrederickshyPiRion: I'm convinced you're making this up, but hey who knows
17:49amalloyit's literally just one function to turn a string into a pattern
17:49{blake}java.util.regex.Pattern.compile(word-known-only-at-runtinme)?
17:50hyPiRion{blake}: ##(.matches "foooo" "^fo*$")
17:50lazybot⇒ true
17:50{blake}##(.matches "anteater,aardvark,antelop" "/bant/b")
17:50lazybot⇒ false
17:50{blake}##(.matches "anteater,aardvark,antelop" "/bantelope/b")
17:50lazybot⇒ false
17:50{blake}:-/
17:51{blake}##(.matches "anteater,aardvark,antelope" "/bantelope/b")
17:51lazybot⇒ false
17:51{blake}##(.matches "anteater,aardvark,antelope" "ant")
17:51lazybot⇒ false
17:51amalloymatches expects an exact match
17:51{blake}##(.matches "anteater,aardvark,antelope" "antelope")
17:51lazybot⇒ false
17:52hyPiRiongfredericks: I may very well be. I remember something about on tooter though, but can't find it. (and afaik TimMc isn't on tooter)
17:52{blake}amalloy: Ah. Yeah. I got a list.
17:52{blake}##(.contains "anteater,aardvark,antelope" "antelope")
17:52lazybot⇒ true
17:52{blake}##(.contains "anteater,aardvark,antelope" "ant")
17:52lazybot⇒ true
17:52{blake}so close
17:52hyPiRion{blake}: I thought you meant begin and end of string boundaries, soz.
17:52amalloyreally like, clojure's regex facilities are really nice, you have re-seq and whatever
17:53gfredericks~you |have| re-seq and whatever
17:53clojurebotIn Ordnung
17:53amalloyand you're spending a bunch of effort because (re-pattern a b) is unacceptable compared to your desired notation of #(str a b)
17:53amalloyre-pattern is just The Way To Do It
17:56{blake},(re-find (re-pattern (str "\\b" "antelope" "\\b")) "aardvark,anteater,antelope")
17:56clojurebot"antelope"
17:56{blake}Good enough.
17:56{blake}(inc re-pattern)
17:56lazybot⇒ 1
17:57amalloy{blake}: note that if you tire of double-escaping, you can use (str #"\b" "antelope" #"\b")
17:57amalloysince Pattern/toString returns the string you would have used to construct the pattern
17:57{blake}amalloy: Thanks. Simple situation here but I'm sure it'll re-emerge in the future.
17:58{blake}Reader macros are the theme of the day.
18:00ibashsdegutis: tell me more about using it for large streaming data
18:00ibashwe have some streams right now using node.js and highland
18:00ibashthey’re okay — but they’re may come a time where we rebuild our data import pipeline
18:01sdegutisibash: gtg
18:01sdegutissorry
18:04cflemingwhomp: The arity issue doesn't affect parens, that's structural editing (paredit), see: https://cursiveclojure.com/userguide/paredit.html
18:05whompcfleming {blake}, ty :)
18:09tehgeekmeisterdo futures timeout?
18:10tehgeekmeisterlike, if nothing's happening in the thread, does it just get killed?
18:10tehgeekmeisterwill the main thread only wait so long?
18:10amalloywhat do you mean, nothing is happening?
18:10tehgeekmeisterthat is a good question! my thinking was unclear there.
18:13tehgeekmeistersay i (future (something)), and then there's nothing else in the program
18:13tehgeekmeisterdoes the parent thread wait on that thread until it finishes executing, or what?
18:14amalloythe jvm shuts down when there are no more threads running (actually no non-daemon threads, but that's not really relevant here)
18:14whomphow do i reference the current function i'm in from within it? i want to make a recursive call
18:15amalloywhomp: http://stackoverflow.com/q/5626641/625403
18:15amalloytehgeekmeister: clojure complicates things slightly because futures and agents use a thread pool, and its threads sorta sit around for a while after being "done", unless you explicitly close them by calling (shutdown-agents)
18:15whompamalloy, ty
18:16tehgeekmeisteryeah, i'm kinda at a dead end here unless i run this on linux and strace this
18:17tehgeekmeisternot sure what's happening. i run a command, run a copy of stderr/stdout in separate threads, and then the output stops half way through a line i know is printed in a single syscall
18:17tehgeekmeisterwhen the buffer size is smaller than the size of the string
18:19hiredman_tehgeekmeister: I think you mentioned running two threads?
18:19tehgeekmeisterthree, yeah
18:19hiredman_is one of them closing *out* ?
18:19tehgeekmeistermain, copier for stdout, and copier for stderr
18:19tehgeekmeistergood point!
18:19tehgeekmeisterthe main one might
18:19tehgeekmeisterso i should wait for those threads
18:20tehgeekmeisteri'll try
18:20hiredman_just never close *out*
18:20tehgeekmeisterit's not explicitly doing so
18:20tehgeekmeisterso unless it happens implicitly, it's not happening
18:20hiredman_ok, that is what I meant
18:22TimMchyPiRion, gfredericks: No, I am not on the Site of Birds. My only contribution was realizing that you could give names to anonymous fns -- the arglists were new to me.
18:24hyPiRionhrm, perhaps I'm mixing you two up. It's been some time since it happened.
18:38tehgeekmeisterso, based on the syscalls it's making, it seems like it's doing a nonblocking check of a thread's status
18:38tehgeekmeisterand then checking if a a time's been hit
18:39tehgeekmeisterlots of lines like this: 67796/0x41532c: psynch_cvwait(0x7F863BF25668, 0x100000100, 0x0) = -1 Err#316
18:39tehgeekmeister67796/0x41532c: gettimeofday(0x1279BFC90, 0x0, 0x0) = 1423092974 0
18:39tehgeekmeisterAnyone have some clues based on that?
18:43tehgeekmeisterhiredman_: just to be clear, you meant i'm good if i don't explicitly close it, right?
18:44amalloytehgeekmeister: i think you are diving too deep too soon into systrace debugging, instead of just like...looking at and/or sharing the code, trying to simplify your program to the smallest possible failing case
18:44tehgeekmeisteramalloy: might be. i'm better at that approach. i'll give the alternate one a try.
18:44tehgeekmeisterthanks for calling it out.
18:44pdlug_Hi, I'm looking for some feedback on a more idiomatic clojure approach to building up maps, sample code here: https://gist.github.com/pdlug/ec2c6eef8fc51f6b6e40
18:45pdlug_What's the best way to move from a multiline map to iteratively building up the map without a bunch of if-let's to leave out nil values?
18:49justin_smithpdlug_: what do you mean by leave out nil values? - is it a function that doesn't handle nil?
18:49justin_smithor are you just looking to remove nils from the map?
18:50pdlug_More for cleaner output, so, optional assoc
18:50pdlug_I have a bunch of functions to extract values from XML doc, most are optional, I want to iterate over them, build up a map containing the keys and values from the XML, leaving out the key if nil
18:51pdlug_gist I posted above leaves them in if nil, but also just doesn't "look right"
18:51tehgeekmeisteramalloy: any preferred paste mechanism here?
18:51tehgeekmeisteri have a repro case that's small
18:51amalloy~paste
18:51clojurebotpaste is https://refheap.com/
18:52justin_smithyou can remove nils from any map with ##(into {} (map-kv (fn [m k v] (if v (assoc m k v) m)) {} {:a 0 :b nil :c 1 :d nil :e 2}) ; pdlug_
18:52tehgeekmeisterit has an ssl warning right now?
18:52tehgeekmeisternbd for what i'm posting, but not awesome
18:52amalloyoh, interseting. that's new
18:52justin_smith,(into {} (map-kv (fn [m k v] (if v (assoc m k v) m)) {} {:a 0 :b nil :c 1 :d nil :e 2}) ; pdlug_
18:52clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
18:52amalloyRaynes: refheap's ssl cert is expired
18:52justin_smitherr
18:52justin_smith,(into {} (map-kv (fn [m k v] (if v (assoc m k v) m)) {} {:a 0 :b nil :c 1 :d nil :e 2}))
18:52clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: map-kv in this context, compiling:(NO_SOURCE_PATH:0:0)>
18:53tehgeekmeisterhttps://www.refheap.com/96919 <== this stops early
18:53tehgeekmeisterand then hangs
18:53tehgeekmeisterfor me it stopped at zygot
18:53amalloyoh, interesting. www.refheap.com is fine, but refheap.com isn't. good to know
18:53justin_smith,(into {} (reduce-kv (fn [m k v] (if v (assoc m k v) m)) {} {:a 0 :b nil :c 1 :d nil :e 2})) ; doh
18:53clojurebot{:a 0, :c 1, :e 2}
18:53justin_smithpdlug_: ^
18:53tehgeekmeisternotably, when i interrupted it, it flushed all the rest of the stream
18:53amalloywhy are you setting the buffer size at all, tehgeekmeister?
18:54amalloy10 seems ludicrously small
18:54tehgeekmeister1024 was chunking weirdly
18:54tehgeekmeisteri really want line buffering
18:54tehgeekmeisterbut i'm trying to get this part done quickly
18:54amalloywell you have two different threads writing to the same output stream at the same time
18:54tehgeekmeisterthis is redirecting the real time output of a shell command, so partial lines are painful
18:54tehgeekmeisteryep, i know
18:54amalloyyou are gonna get crappy-looking interleaved output regardless of buffer size
18:55tehgeekmeisterthe interleaving i can deal with for the moment
18:55pdlug_justin_smith: thanks, I also came up with defining a function "assoc-if" that I used with -> to build up the map without nils
18:55tehgeekmeisteri could also live with the delay, i guess, too
18:55tehgeekmeisteri'm probably off track. this was a nice to have addition i started on at like 7 last night. =P
18:56justin_smithpdlug_: yeah, that would work too
18:56amalloydelay? i don't really understand; you said it was blocking indefinitely, i thought
18:56tehgeekmeisterwell, if there's say 1050 lines of output
18:56tehgeekmeisterand then a big pause
18:56tehgeekmeistererr, bytes, sorry
18:57tehgeekmeisterthen the 26 bytes (assuming the default 1024 buffer) at the beginning of the buffer could take a long time to get through
18:58tehgeekmeisterwould probably be better to use core.async and wait for new input on either stream, copy *all of that* over, and then go back to waiting for any new input
18:58justin_smithtehgeekmeister: sounds like you need to go into host interop land and control the mode of the pipe or something
18:58tehgeekmeisterjustin_smith: can you provide a bit more context about why you think that?
18:58amalloymmm, indeed. and what about just doing this in not-clojure? like, `cat /usr/share/dict/words 2>&1` is a lot simpler than this
18:59tehgeekmeisteri'm moving a crappy shell script to clojure, bit by bit
18:59tehgeekmeistercore goal is to have a good wrapper for packer based build processes
18:59tehgeekmeisterso, yeah, this is complicated, i agree
19:00justin_smithtehgeekmeister: on the OS level, at least in *nix, you can control flushing and buffering, including things like no buffering (which is super bad for perf, but low worst case latency) or line buffering where it's flushed on newline or whatever
19:00tehgeekmeisterbut i want a number of benefits from clojure for the higher level stuff, and i'm going to have to shell out to packer at the least, no matter what
19:00tehgeekmeisterjustin_smith: didn't know line buffering was an os level option. you mean stdlib or syscall?
19:01tehgeekmeisteri can assume nix, this will only run on osx/linux (at least in the near term, for my company)
19:01justin_smithtehgeekmeister: http://www.pixelbeat.org/programming/stdio_buffering/
19:01justin_smiththis looks like a decent intro ^
19:01tehgeekmeisterthanks!
19:02tehgeekmeisterso, looks like setting buffer size to 0 doesn't do anything special.
19:02tehgeekmeisteryay no special values!
19:03justin_smithtehgeekmeister: the c syscall in question is setbuf http://man7.org/linux/man-pages/man3/setbuf.3.html
19:03tehgeekmeisterawesome! i had not heard of that one.
19:03tehgeekmeisteralso the guide you sent won't load, but the man page will
19:04justin_smithheh, OK
19:04tehgeekmeisteryeah, worth noting that conch returns a buffered stream
19:04justin_smithtehgeekmeister: oh, I was just reminded from that man page "stderr is always unbuffered by default"
19:04tehgeekmeisterso there are multiple layers here
19:04justin_smithtehgeekmeister: oh, is this Process streams?
19:05tehgeekmeisteryeah, i'm using the conch library
19:05justin_smithjava.io.Process has options, including "join stout and stderr into one stream" if conch doesn't allow access to that, ditch conch
19:05justin_smitherr, not io.Process
19:05justin_smithlang.Process
19:05tehgeekmeisteryeah, ideally i'd like to keep them separate for semantics, but i still want to print them joined right
19:05justin_smithahh
19:05justin_smiththat's trickier
19:06tehgeekmeisterbut for short term, i can be lenient about that
19:06tehgeekmeistertime to finally really read the conch docs in depth, i guess
19:06amalloyme.raynes.conch.low-level/proc gives you direct access to gives you access to the ProcessBuilder constructor directly
19:06weilein uberjar is trying to run my app instead of just compiling it. any ideas on how to troubleshoot this?
19:06amalloyand has a :redirect-err option
19:06justin_smithwei: don't do anything with side effects at the top level of your ns
19:06justin_smithwei: that's always the reason
19:07justin_smithwei: if you can't run your ns file without running your app, redesign your ns
19:07tehgeekmeisteryeah, i'm using low-level too
19:07hiredman_wei: clojure runs code as it is loaded, so if you have side effects in top level forms, they will run when you load the code
19:07amalloyit looks like me.raynes.conch/run-command accepts :redirect-err as well
19:07justin_smithamalloy: cool
19:07clojurebotTitim gan éirí ort.
19:07hiredman_wei: you should put things in functions, and then call those functions from your main function
19:08tehgeekmeisterwait, i can provide it an output it looks like
19:08tehgeekmeistercrap
19:08tehgeekmeisterthat's a lot simpler
19:08tehgeekmeisteri can just have it forward directly on to the parent streams
19:09amalloyclojurebot: conch is pretty cool in general
19:09clojurebotYou don't have to tell me twice.
19:10hiredman_clojurebot: conch |does| stream fusion
19:10clojurebotRoger.
19:10weihiredman_ , justin_smith: I don’t appear to have any side-effect code, but guess I need to digging around to do
19:10weidoes defining a handler count as a side effect?
19:11amalloywei: you probably do something like (def app (run-jetty ...))
19:11hiredman_wei: are you starting jetty in a top level form?
19:11tehgeekmeisteractually, i misread
19:11weihttp-kit, and I’m starting it from a -main function
19:11tehgeekmeisterbut i'm on a good path now
19:11tehgeekmeisterthanks so much everyone
19:12hiredman_what do you mean by running your app then?
19:12weiwhen I try to build a jar, it’s initiating a postgres connection and failing to find the database
19:13hiredman_are you using korma?
19:13weino
19:13hiredman_the stacktrace should tell you the file and line where the connection is happening
19:14hiredman_maybe you are configuring a connection pool or something
19:15tehgeekmeisterah, but ProcessBuilder *does* support setting a file for each of stdout and stderr, and redirecting stderr to stdout
19:15tehgeekmeisterhow easy would it be for me to run a fork of conch while I work on getting an improvement like that merged in?
19:15tehgeekmeisterI don't know leiningen well yet.
19:17weihiredman_: at xb.helpers$loading__4958__auto__.invoke(helpers.clj:1)
19:17weidoes this mean I have side-effect code that’s running as it’s loading the namespace? the line number isn’t helping, unfortunately
19:17hiredman_wei: :/ some file helpers.clj is loading is doing it
19:18amalloywei: that's not a stacktrace, it's one line of a stacktrace
19:18hiredman_when a file throws an exception on load the stacktraces are not super helpful if I recall, they just point to the (ns ...) form that tried to load the failing file
19:19weithe rest of the stacktrace isn’t from my app: https://gist.github.com/yayitswei/e8fc479fc414157d9199
19:20hiredman_wei: I would change the ns form in helpers.clj to include :load-verbosely (a flag on :require, if I recall)
19:21hiredman_it will print out every file it loads, the last one printed before the error should be the problem
19:21amalloyresources.clj:23
19:21amalloyis where the database call is
19:22tehgeekmeisteris the lein-git-deps plugin pretty commonly used, or a bad practice, or what?
19:22justin_smithprobably a top level def of the db connection or something
19:22tehgeekmeisteri see it hasn't been updated in a long time
19:22amalloytehgeekmeister: don't use it
19:22hiredman_I guess the ns thing got fixed?
19:22tehgeekmeisteramalloy: should i just make changes locally and install locally?
19:23justin_smithtehgeekmeister: you can use lein checkouts, or you can clone / lein install locally
19:23justin_smithlein checkouts start with a clone + lein install step :)
19:23tehgeekmeisteri'll look into that, thanks
19:23amalloyif you want to use a local fork of a lib, you can edit it and publish to clojars (or just install locally) under a different groupid, like com.tehgeekmeister/conch or whatever
19:23amalloyand using checkouts simplifies the install-locally process
19:23amalloyjustin_smith: shouldn't need to install
19:24justin_smithamalloy: checkouts don't work unless you run lein install first
19:24justin_smithamalloy: or so I heard
19:24justin_smithunless maybe you already have an artifact with that version string maybe
19:24amalloyright
19:24amalloyand like, if you just want to hack on conch, you can just have a local install with the same version string but different code
19:25tehgeekmeisteryeah, my intent would totally be to get it merged back in
19:25justin_smithindeed, but I find habits like that can lead to terrible bugs and confusion :)
19:25tehgeekmeisterjust trying to figure out how to point to a fork in the mean time
19:25justin_smithor maybe I am too scatterbrained for such schemes and others can handle it
19:25tehgeekmeisterjustin_smith: nah, i think you're right, such approaches are scary
19:26justin_smithwhen my local artifact of a given group / version / project is not the global one, and I forget that fact...
19:26justin_smithso I tend to defensively alter versions right off the bat
19:29tehgeekmeisterlooks like checkouts work for development
19:29tehgeekmeisternot for deploy
19:29tehgeekmeisterwell, not cleanly for deploy
19:29tehgeekmeisteri guess a fork on clojars is the cleanest answer for until a pull is merged
19:29tehgeekmeisteraight
19:30justin_smithtehgeekmeister: you can deploy, a checkout is just a symlink to the real project dir
19:30justin_smithtehgeekmeister: on the project dir side, it has no way to know it is even a checkout
19:30justin_smith(since symlinks are one way)
19:30tehgeekmeisteri may not understand the deploy process well enough to know how that works out
19:30tehgeekmeisterin fact, i certainly don't
19:31tehgeekmeisterlots to learn right now
19:31justin_smithtehgeekmeister: if you are in the dir of the checked out project, you are no longer strictly in a subdir of the other project
19:31tehgeekmeisteryes, i mean if i want to package up this whole thing
19:31tehgeekmeisterand use it on a server
19:31tehgeekmeisterin production
19:31justin_smithtehgeekmeister: then yeah, you deploy each checkout as a separate project
19:31tehgeekmeisteri see
19:31justin_smithtehgeekmeister: or make an uberjar of the top level one
19:31tehgeekmeisterk
19:32tehgeekmeistercool
19:32tehgeekmeisterthis is a good enough path
19:32justin_smithtehgeekmeister: unless you need the libs to be published...
19:32justin_smiththe uberjar will pull in the stuff from the subdirs
19:32tehgeekmeisterit'll be published later
19:32tehgeekmeisterfor now, just working is sufficient
19:33weifound it! turns out the side-effect code was on line 23, just as it says in the second line of the stacktrace. thanks for your help hiredman_ justin_smith amalloy
19:34justin_smithwei: was it creating a db connection as a top level def?
19:40weijustin_smith: I was preloading some system accounts into a map. forgot about that :P
19:40justin_smithaha, that would do it
19:40weimy solution was just to wrap it in delay
19:40justin_smithwei: and easy fix for that is a delay
19:40justin_smithhaha
19:41weiat some point i want to check out the component framework, but it looks heavyweight for my needs at the moment
19:57julianlevistonI have a question about the nature of apply and reduce… are they semantically identical, but does apply consume stack space whereas reduce does not?
19:57hiredman_apply is not a fold
19:58julianlevistonhiredman_: but are they sematically equivalent?
19:58weiis there any way to get the current stacktrace without throwing an error?
19:58amalloyjulianleviston: they are totally different; for some functions, such as +, they happen to do the same thing
19:58hiredman_julianleviston: no reduce is a fold
19:58amalloyhttp://stackoverflow.com/q/3153396/625403
19:58tehgeekmeisterhow do i require part of a library from lein repl inside that library, when I'm editing it?
19:58hiredman_,(reduce cons nil (range 10))
19:58julianlevistonhiredman_: could you rephrase that?
19:58clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>
19:58tehgeekmeistercan't get this to work in general
19:58tehgeekmeistersometimes by luck
19:58tehgeekmeisterbut not in general
19:58hiredman_,(reduce conj nil (range 10))
19:58clojurebot(9 8 7 6 5 ...)
19:58hiredman_blarge
19:58hiredman_,(apply conj nil (range 10))
19:58clojurebot(9 8 7 6 5 ...)
19:58hiredman_damn it clojure
19:59amalloy*chuckle*
19:59hiredman_,(reduce (fn [a b] (cons b a)) nil (range 10))
19:59clojurebot(9 8 7 6 5 ...)
19:59hiredman_,(apply (fn [a b] (cons b a)) nil (range 10))
19:59clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (11) passed to: sandbox/eval123/fn--124>
19:59julianlevistonamalloy: thanks… I’m just trying to work out if I can change my apply to a reduce….
20:00hiredman_apply applies a function to a list of arguments, reduce folds a function over an accumulator and each value from a collection
20:00julianlevistonI have this: (apply merge-with (partial merge-with min) (map some-function somecoll) someothercoll)
20:00amalloyjulianleviston: if you have an apply that's working, there's no reason to change it to a reduce
20:01julianleviston(with some more parens on the end ;-))
20:01julianlevistonamolloy well I have a feeling it’s slowing things by consuming too much stack space
20:01amalloyjulianleviston: your feeling is nonsense
20:01amalloydon't worry about that
20:01julianlevistonamalloy: oh ok good :)
20:02julianlevistonamalloy: I need to time it again… I had a few redundant bits of code that I removed but I haven’t timed it since.
20:02julianlevistonand the apply doesn’t feel right to me.
20:04amalloy(apply merge-with m ms) is a pretty common thing
20:04amalloyi expect it's implemented as a reduce under the hood, so the difference really is just a single function call
20:04julianlevistonamalloy: cool beans :)
20:05julianlevistonamalloy: merge is, yeah.
20:05julianleviston (when (some identity maps) (reduce1 #(conj (or %1 {}) %2) maps))
20:29justin_smithjulianleviston: ##((fnil conj {}) nil {:a 0})
20:29lazybot⇒ {:a 0}
20:34julianlevistonjustin_smith: what does ## do?
20:35gfredericksit triggers ##'lazybot
20:35lazybot⇒ lazybot
20:36julianlevistonah… inline lazybot! huzzah :)
20:36gfredericks###'first
20:36lazybot⇒ #'clojure.core/first
20:36julianlevistonI wonder if it’s ##’just for this form or the rest of the sentence?
20:36julianleviston(sigh curly quotes)
20:36gfrederickshaha
20:38julianlevistonstupid mac. Apparently I don’t have control over that in this IRC client. LOL fail.
20:38julianlevistonoh well
20:39julianlevistoni wonder if ##`it is one form only
20:39lazybot⇒ clojure.core/it
20:39julianlevistonok cool.
20:39gfredericks,(read-string "hey okay")
20:39clojurebothey
20:40julianlevistonjustin_smith: how come you were telling me that form?
20:40dahbrew install irssi # ;)
20:54julianlevistonis this a terrible way to result in a vector of items none of which are nil? (filter (complement nil?) (flatten [(association-kwd item)]))
20:55julianlevistonshould I just be using (remove nil? (concat … or something?
20:55tickingremove nil? would probablu be more idiomatic
20:55amalloyi don't understand the goal, but that is a terrible way to do it, yeah
20:55amalloyassociation-kwd returns...what? a seq of things?
20:56julianlevistonamalloy: (association-kwd item) returns a coll of integers.
20:56tehgeekmeisterif i'm in a scope where I can reference ProcessBuilder directly, how do I refer to ProcessBuilder.Redirect (a nested class) in clojure?
20:56amalloyimport ProcessBuilder$Redirect
20:56tickingjulianleviston: then why would you flatten it?
20:56tehgeekmeisteramalloy: have to import, can't just reference it directly somehow?
20:56tehgeekmeisterI only need it in one place
20:57amalloytehgeekmeister: sure, you can. foo.bar.whatever.ProcessBuilder$Redirect
20:57amalloyit's just an ordinary class with a funny-looking name
20:57tehgeekmeistercool, thanks!
20:57amalloyyeah, it sounds like you just want (remove nil? (association-kwd ...))
20:57julianlevistonticking: good question… it might also return a single integer sorry
20:57tickingjulianleviston: so it might return a single integer or a collection?
20:57julianlevistonticking: association-kwd can return an int, or a vec of ints.
20:57julianlevistonticking: apologies, yes.
20:57tickingjulianleviston: did you write it?
20:58julianlevistonticking: sadly, yes. :)
20:58amalloyjulianleviston: change it to always return a vec of ints
20:58amalloyit's pretty gross to return one or the other, because it makes the client code do stupid stuff, as you're now discovering
20:58tickingyeah I would agree with amalloy on that
20:58julianlevistonamalloy: erm… it’s not one thing, tho...
20:58tickingjulianleviston: how so?
20:58julianlevistonamalloy: association-kwd might be “block_id” or it might be “block_ids"
20:59julianlevistonticking: it’s looking up data in a map… some of which is has-many, some of which is belongs-to relationship data
21:00julianlevistonamalloy: so…. belongs-to [5] wouldn’t make sense.
21:00tickingjulianleviston: how is that determinded?
21:00julianlevistonticking: I don’t follow, sorry…
21:00tickingwether or not it is block-id or block-ids?
21:01julianlevistonit’s depetrmined by the nature of the relationship of other data to that map.
21:01tickinglike?
21:01julianlevistonthis fn maps over all the relevant relationship association data and gets it.
21:01julianlevistonand collects it into a single seq
21:01julianlevistonand then goes off and calls an API requesting it
21:02julianleviston{:a_id 5 :b_ids [10 9 8] :c_id nil} … run fn on it… -> [5 10 9 8]
21:03tickingis the first thing really a map?
21:03tickingbecause it has duplicate keys
21:04tickingah no sorry
21:04julianlevistonticking: huh?
21:04tickingI misread
21:04julianlevistonk
21:04tickinghow is that map generated?
21:04tehgeekmeisteris there a way to get at the underlying files behind *out* etc?
21:04julianlevistonticking: I don’t know how that’s relevant
21:04tehgeekmeisterturns out they're PrintWriters
21:04tehgeekmeisterI need a file subclass
21:04tehgeekmeisterand PrintWriter doesn't let you get the file it's attached to
21:05tickingjulianleviston: I'm trying to figure out it you can fix this abomination of a datastructure ;P
21:05tehgeekmeisteroh, i bet java can do this
21:06julianlevistonticking: i’m not too sure the data structure is the problem ;-)
21:06amalloytehgeekmeister: they might not be attached to a file at all
21:06tickingjulianleviston: (remove nil? (flatten (keys that-horrible-list-thing))) is how I would do it when I couldn't change the data
21:06amalloyprintwriters in general, that is
21:06tehgeekmeisteryeah, seems like System.out is a stream, it looks like
21:06julianlevistonticking: I just want a function that will take a collection, or item… and filter out nils and always return a collection.
21:07julianlevistonticking: which is what I have.
21:07tehgeekmeisterBasically, there is no easy and great way to do this, it seems. But there are acceptable ways, at least.
21:07ticking,(remove nil? (flatten (keys {:a_id 5 :b_ids [10 9 8] :c_id nil})))
21:07clojurebot(:c_id :b_ids :a_id)
21:07ticking,(remove nil? (flatten (vals {:a_id 5 :b_ids [10 9 8] :c_id nil})))
21:07julianlevistonticking: erm… it’s not a horrible thing. It’s just a map… which I’m calling a key on… the only “horrible” thing is that the function doesn’t know if the return val of calling the key will be a coll or an item
21:07clojurebot(10 9 8 5)
21:08tickingjulianleviston: yeah exactly
21:08tickingjulianleviston: I'd fix that
21:08julianlevistonticking: yeah, I already have code that works… I just wanted to know if there was a better way to do it…
21:08julianlevistonticking: which is impossible to fix. :P
21:08tickingjulianleviston: yeah fix that map and make it always return vectors
21:08julianlevistonticking: its very nature is that I’m trying to collate a disparate set of data.
21:08julianlevistonticking: but vectors make no sense for some keys.
21:09julianlevistonticking: it’s like this: {:cat-names [“fred”] :eye-color “blue”} … now… I want a coll of cat names and their eye colours...
21:10julianlevistonticking: “Just change eye colour so it’s a collection”
21:10julianlevistonticking: see what I mean?
21:10tickingjulianleviston: no because I'd argue that an entity with a single id is just the :ids [id] special case for the true multi :ids case.
21:11tickingjulianleviston: as you want them in a single collection afterwards they are obviously the samee thing
21:11julianlevistonticking: if I did that, I’ve have to rearchitect pretty much every function that deals with single ids… which isn’t good. Trust me, I know what I’m doing.
21:11tickingbecause a seq of ("fred" blue) makes no sense
21:11julianlevistonticking: THIS function is the exception, not the other way round. :)
21:12tickingjulianleviston: still looks broken to me though
21:13julianlevistonticking: this data comes from a REST endpoint… and it doesn’t look broken to me… standard has-many and belongs-to relationship data as far as I can see
21:14julianlevistonthe only thing with this fn is, I can’t work out why it’s taking so long.
21:15julianleviston430 ms in some invocations in cljs for a few hundred items.
21:17julianlevistonticking: thanks for your attention, tho.
21:18tickingis association-kwd a keyword or a fn?
21:18tickingperformance prblem could be in there
21:19julianlevistonit’s a keyword
21:19tickingflatten is not the fastest fn though
21:20tickingis your collection of the form you posted above ({:a_id 5 :b_ids [10 9 8] :c_id nil}) or a collection of maps
21:20julianlevistonI’m doing (apply (merge-with (partial merge-with min) (map (reduce (….))))
21:20tickingthat looks expensive
21:20julianlevistonticking: yeah!
21:21tickinghow does (apply (merge-with (partial merge-with min) (map (reduce (….)))) and (complement nil?) (flatten [(association-kwd item)])) interplay?
21:21julianlevistonticking: the map is of the form I posted for the inner reduce that has that call to (remove nil? (flatten [(association-kwd item]))… (the bit I was asking about)
21:22julianlevistonticking: the latter is inside the inner reduce
21:22tickingso the entire code is
21:22ticking(apply (merge-with (partial merge-with min) (map (reduce (filter (complement nil?) (flatten [(association-kwd item)]))))))?
21:22julianlevistonticking: erm… I can’t paste it here coz it’s too big. It has a 10 line let block inside it (…)
21:23tehgeekmeisterfound the potential answer to my questions here! https://clojuredocs.org/clojure.core/future
21:23tickingjulianleviston: tbh this sounds horribly broken
21:23julianlevistonticking: while that’s an analysis I can appreciate and possibly even agree with, I’m not sure how it helps me to improve its quality. :)
21:24tickingjulianleviston: can you post the code in a gist
21:24tickingjulianleviston: or describe what you're trying to achieve
21:24tickingjulianleviston: the data that goes in and the data that's supposed to come out is probably the most helpfull
21:25julianlevistonticking: yeah, the context… the only thing is it’s quite varied and complex but I’ll post the code in a bin
21:25julianlevistonticking: here y’are: https://gist.github.com/JulianLeviston/f5d26f6ec4a3c4813131
21:26whompcan i give a transient a starting capacity, so that it doesn't have to keep growing?
21:26julianlevistonticking: i’ll try to get you some data for it, too...
21:27amalloywhomp: no, just trust in the holy wisdom of rich that transients will perform well
21:27tickingwhomp: I don't thin so, a transient should still be a trie that just gets updated in place
21:27julianlevistonticking: actually, it’s too hard because there are two or three chunks of data I’d have to post…
21:27julianlevistonticking: I realise that’s no help…
21:29whompthx guys, sorry rich
21:29julianlevistonticking: what it does *is* quite complicated… it is gathering a set of ids to retrieve from the API endpoint… based on a set of associations and a set of depth maps… which are arbitrarily described… (ie how deep I want it to automatically load the data).
21:29tickingjulianleviston: can there both be an :id and :ids at the same time?
21:29julianlevistonticking: depending on where you mean… yes.
21:29julianlevistonticking: and no.
21:30julianlevistonassociation-kwd will only be gathering either an id or a coll of ids. Never both.
21:30tickingI was thinking always doing (conj (:id item) (:ids item))
21:31julianlevistonticking: conj takes a coll first doesn’t it?
21:31julianlevistonticking: hm.
21:31julianleviston,(conj 1 [500])
21:31clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IPersistentCollection>
21:31julianleviston,(conj [500] 1)
21:31clojurebot[500 1]
21:31tickinguh yeah sorry
21:31clojurebotHuh?
21:31julianlevistonticking: that’s a bit disturbing.
21:32tickingsorry it's 3:30 am over here
21:32julianlevistonticking: all good.
21:37tickingjulianleviston: (or coll {}) is not needed btw
21:38ticking,(assoc (or nil {}) :a 1)
21:38clojurebot{:a 1}
21:38ticking,(assoc nil :a 1)
21:38clojurebot{:a 1}
21:38julianlevistonticking: nice. Thanks.
21:41tickingjulianleviston: what does calculate depth do?
21:41sdegutisAre there any plans to separate the ClojureScript compiler from the JVM?
21:41julianlevistonticking: I think I’ll go for one of the larger bottlenecks instead. Shaving 1 second off the request isn’t going to help THAT much.
21:41tickingjulianleviston: you could probably put the mergin into the reduce step
21:42julianlevistonticking: calculate depth works on a depth map, which is pairs of model-collection-kwds and ints representing how deep the current step of loading is at...
21:43julianlevistonticking: by reducing the ints.. until they get to 0.
21:43tickingjulianleviston: the main problem seems to be many iterations, so I'd try to do as much of that in a tight loop
21:43tickingjulianleviston: hrm
21:43tickingjulianleviston: It's really hard to visualize what it all does
21:44julianlevistonticking: I know, isn’t it! :)
21:44julianlevistonticking: it’s hard enough even for me, with the data...
21:44tickingit seems overcomplicated though :/
21:44julianlevistonticking: it took me about 30 mins to write that function.
21:44julianlevistonticking: I agree
21:45tickingit doesn't have to be that complicated though
21:45tickingfor example calculate-depth returns a tuple as it seems
21:45justin_smithoh, someone was asking about removing keys for nil vals, and I just realized this is much better: ##(into {} (filter second {:a 0 :b nil :c 1 :d nil :e 2 :f nil :g 3}))
21:45lazybot⇒ {:e 2, :g 3, :c 1, :a 0}
21:46julianlevistonticking: actually, calculate-depth returns a map
21:46tickingjulianleviston: does it have side effects? it looks like it doesn't really return a depth
21:47tickingjulianleviston: but that would do (assoc coll {:foo :bar})
21:48justin_smithconj would make sense there, or merge
21:50julianlevistonticking: haha sorry… yeah, calculate-depth returns a seq of ids interleaved with depth ints
21:51julianlevistonticking: so… (103 5 203 5 999 2) etc
21:51tickingah
21:51julianlevistonticking: it looks like I need to pull it apart and simplify it, I think…
21:51tickingjulianleviston: returning a map would make more sense
21:51julianlevistonticking: if I can’t even reason about it myself easily, something’s wrong, huh.
21:52tickingthen you could do (update-in coll [item-model-coll-kwd] merge (calculate-depth foo))
21:52julianlevistonticking: even though I’m calling (apply assoc coll return-value-from-calculate-depth) ?
21:52julianlevistonticking: oh neat.
21:53tickingwill behave slightly different though when overriding keys
21:54tickingthe above will actually keep existing keys instead of overriding them
21:56dweavehow do i eval with clojurebot
21:56julianlevistonticking: shouldn’t I use conj then?
21:57julianlevistond4gg4d: ##”you can do this”
21:57julianlevistond4gg4d: ##`(lol)
21:57lazybot⇒ (clojure.core/lol)
21:57julianleviston,(quote or this)
21:57clojurebotor
21:57tickingjulianleviston: if you return a map and want to add all keys to the old one you have to use merge
21:58tickingbut merge will override left to right
21:58tickingright gets kept
21:58julianlevistonticking: yeah, I know
21:59dweave##`(+ 1 1)
21:59lazybot⇒ (clojure.core/+ 1 1)
21:59julianleviston##(+ 1 1)
21:59lazybot⇒ 2
21:59dweave##(+ 1 1)
21:59lazybot⇒ 2
22:00julianleviston,(:or {:this :works :too :or :hooray!})
22:00clojurebot#<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>
22:00julianlevistonfail
22:00julianlevistonticking: yeah, that didn’t work too well…
22:06dweavehow are other commands run against lazybot?
22:06dweavesuch as “wiki”
22:08amalloy$wiki clojure
22:08lazybot[Clojure - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Clojure
22:08dweaveahaa
22:08Lewixquestions: How to load file in the repl and refresh it as needed (load-file path seems to run once). How to run a particular file from the command line without having to use project.clj
22:09julianlevistonLewix: lein has try
22:09julianlevistonLewix: and :reload can be given to require
22:10julianlevistonLewix: you can call clojure jars like ordinary java ones, assuming you’ve built one, too.
22:42Lewixjulianleviston: I didn't get it but thanks. I'll figure later
22:43Lewixamalloy: http://stackoverflow.com/questions/8205209/why-argument-list-as-arrayseq - I don't understand your answer, can you please elaborate. why would it be impossible if & args were required to be a vector
22:45amalloyLewix: i mean, you can try it yourself, by taking that function definition and replacing (first args) with (first vec args)
22:45amalloyer, (first (vec args))
22:45amalloyif you still need further clarification after that, please ask on SO, not in IRC: if one of my answers is not clear enough, i'd rather it be fixed for everyone and not just you
22:54Lewixamalloy: I thought that's what i was doing by asking in the public channel of irc and not in private. Also, making a SO account just for that is overkill but thank you
22:55amalloyLewix: well, fair enough
22:57amalloyLewix: vectors are concrete, eager, and finite
22:57amalloyso you can't have an infinite arglist if you use vectors
22:57amalloyif you only require a seq, you can use anything seqable as an arglist, including an infinite lazy seq
23:00Lewixamalloy: thank you. It makes sense
23:00Lewixamalloy: is an ArraySeq an infinite lazsy seq?
23:01amalloyno, it's a seq wrapper around a java array
23:02amalloyif you call a function "explicitly" like (f x), your args will generally be an ArraySeq
23:02amalloybut if you apply it to some other seq, like (apply f xs), then your args will be whatever that other seq was
23:03amalloy,(map (partial apply (fn [& args] (class args))) [[1] (range 2) '(a b) '{a b}])
23:03clojurebot(clojure.lang.PersistentVector$ChunkedSeq clojure.lang.ChunkedCons clojure.lang.PersistentList clojure.lang.PersistentArrayMap$Seq)
23:03Lewix,(type ((fn [& args] args) 1 2))
23:03clojurebotclojure.lang.ArraySeq
23:05Lewixamalloy: I have a hard time understanding why it's an ArraySeq and yet we cannot use a finite seq such as vectors
23:05Lewix(I should probably read more on the topic)
23:06amalloyLewix: this is the same basic problem as what you were talking about the other day, why things require just seqs instead of requiring a specific seq type, such as a list
23:06amalloyit's fine to use any specific concrete type as the arglist to a function, including vectors
23:06amalloywhat's not fine is *requiring* that be the only type, by guaranteeing that function args are always a vector
23:07amalloyin real life, args often are ArraySeq, but that's not guaranteed; they can be something else instead
23:10Lewixamalloy: ok thanks. I'll think about all that - it's helpful