#clojure log - Feb 04 2015

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:00 Lewix: i dont care about the type

0:00 julianleviston: Lewix: in fact they don’t even tell you the abstraction

0:00 Lewix: tell me what it returns in a way that dont confuse

0:00 me*

0:00 julianleviston: Lewix: that always depends on who is asking that question.

0:00 Lewix: anyways, thanks guys

0:00 I'm off

0:01 julianleviston: Lewix: 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.

0:01 Lewix: later

1:37 domokato: hi, anyone use neko?

2:30 * rpaulo updates leiningen in freebsd ports

2:30 rpaulo: only 26 days late.

4:04 l3dx: I don't get a repl buffer in cider. This is the case for both jack-in and "lein repl" + attach

4:04 suggestions?

4:05 can't seem to find any errors

4:07 ordnungswidrig: l3dx: no buffer created? what does the *Messages* buffer tell you?

4:07 hellofunk: l3dx: do you get any of the other nrepl buffers if you look at your full emacs buffer list?

4:34 l3dx: I get a nrepl-server and a nrepl-connection buffer

4:34 https://gist.github.com/tskardal/7ca53cbd58575e9275ef

4:34 relevant output from *Messages*

4:51 ordnungswidrig: l3dx: doesnt' your bufferlist contain a *cider-repl ...* buffer?

4:52 l3dx: nope

4:53 CookedGr1phon: domokato: yep, there's also a #clojure-android room if you're interested

4:54 domokato: CookedGr1phon: thanks, I found it :)

4:54 l3dx: ordnungswidrig: proof https://dl.dropboxusercontent.com/u/809432/emacs%20buffers.png

4:54 :P

4:59 michaelr`: hmm

5:01 ordnungswidrig: hmmm, which version of cider (emacs) and cider-nrepl (clojure) do you use?

5:02 what happens when you invoke `cider-switch-to-repl-buffer` (in core.clj, C-c C-z)?

5:03 cloudsaja: Hi 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 ?

5:03 hellofunk: l3dx: 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

5:04 julianleviston: cloudsaja: um… (:graph component) ?

5:05 cloudsaja: julianleviston .. I know that. but how can i get the component ? Where is stuartsierra.component stores its maps ?

5:05 hellofunk: l3dx: you can look directly inside the nrepl buffers for error messages

5:05 julianleviston: cloudsaja: I don’t follow your question. Apologies. It doesn’t work that way from memory.

5:06 cloudsaja: your system holds the components.

5:08 cloudsaja: julianleviston : 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.

5:12 julianleviston: cloudsaja: hang a sec I just have to remind myself how component works… it’s been a few months since I’ve used it.

5:13 ordnungswidrig: cloudsaja: 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

5:16 julianleviston: cloudsaja: ok… so where are you trying to access it from?

5:16 cloudsaja: or did ordnungswidrig’s response fix your issue?

5:16 cloudsaja: from repl

5:17 julianleviston: cloudsaja: ah… ok… so yeah… (-> system :database :graph) assumping your database component is databas?

5:18 *assuming your database is assoc’d on to the system as :databas

5:18 :database * (sigh)

5:19 cloudsaja: does that help / make sense?

5:21 cloudsaja: julianleviston : You are correct... saved my day. Thanks a lot. ordnungswidrig also.. thanks

5:21 julianleviston: cloudsaja: you can always type system at the repl and it’ll show you the map… tis not very conducive to reading, but yeah…

5:22 cloudsaja: I think last time I checked, stuart was interested in improving that but nothing had occurred to him yet.

5:22 cloudsaja: julianleviston : got it

5:22 julianleviston: cloudsaja: maybe prettyprinting it might help

5:22 TEttinger: (inc julianleviston)

5:22 lazybot ded

5:24 julianleviston: cloudsaja: 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.

5:28 cloudsaja: julianleviston : Okay... I will mention the context nextime.

5:40 hejki_: 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?

5:45 ordnungswidrig: hejki_: jfx was discussed on the clojureD conference. Seems hot to me.

5:47 hejki_: ordnungswidrig: http://www.bytebucket.org/splendid/jfx ?

5:48 googling "clojure jfx" provided results "all around", so it indeed is "hot" :P

5:59 julianleviston: I, for one, welcome our new fervently sardonic overlords.

6:04 zot1: i 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?

6:05 julianleviston: zot: how’s about a go block?

6:06 l3dx: hellofunk: thanks, I'll have a look. It used to work fine, but stopped yesterday

6:06 zot: julianleviston: core.async was my other consideration, but i wondered if lazy-seq would actually be simpler for my case

6:07 julianleviston: ,(source repeatedly)

6:07 clojurebot: Source not found\n

6:07 julianleviston: zot: looks pretty good to me, why not...

6:08 zot: ahhhh, i forgot about repeatedly. that's even better :)

6:08 julianleviston: zot: sweet :-)

6:08 zot: (inc julianleviston)

6:08 tnx!

6:09 frphank: julianleviston: core.async and lazy-seq don't normally compete

6:09 one is for I/O

6:09 the other for computation

6:09 julianleviston: frphank: depends what you’re trying to do I guess ;-)

6:10 frphank: yes, either you have I/O or you do not

6:10 what's the body of your "repeatedly"?

6:10 julianleviston: frphank: what if you want to compute many things at once? :-)

6:10 zot: for me, (repeatedly (partial recv-message this))

6:10 frphank: hm

6:11 zot: quite trivial

6:11 julianleviston: frphank: or split their functionality into delayed process that happens later? or… etc.

6:11 zot: excellent.

6:11 frphank: but thanks, I’ll keep that in mind.

6:11 frphank: zot: sorry I got confused, you are the one that wants to use repeatedly?

6:11 zot: recv-message is from what library?

6:11 zot: not, it's my own code in a component wrapping a kafka client

6:12 frphank: ok

6:12 it probably blocks?

6:12 zot: but needs to be substitutable with in memory and other forms for testing

6:12 julianleviston: frphank: I think he’s got his solution.

6:12 zot: yes it does

6:12 frphank: zot: yeah that's problematic

6:13 zot: you can't interrupt the thread for starters, or it will do funny things

6:13 julianleviston: frphank: unless receive message is an action, not a channel-like thing… :)

6:13 frphank: julianleviston: it only matters if it blocks or not

6:13 julianleviston: frphank: blocks intentionally or not?

6:13 frphank: zot: CLJ-1119 has a discussion on that

6:14 julianleviston: what's unintentional blocking??

6:14 julianleviston: frphank: what you think he’s doing?

6:14 frphank: all’s I’m saying is I don’t think we have enough info to make a recommendation about what to do yet.

6:14 frphank: julianleviston: zot said that recv-message blocks and that makes it unsuitable for repeatedly

6:15 zot: so if i understand, you believe that the thread termination may fail when wrapping this call in repeatedly?

6:15 frphank: zot: 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

6:15 zot: (to be clear, it blocks via Thread/sleep, spinning on an atom)

6:16 frphank: zot: 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

6:17 julianleviston: frphank: it *does* sound like core async is a better fit.

6:17 frphank: yeah

6:17 zot: in 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.

6:18 frphank: zot: in that case you might get away with it

6:18 zot: testing shortly to find out :)

7:02 rksm: Hello! 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

7:02 All I get back is {"failingTest":0,"message":"","error":null,"golfScore":"","golfChart":""}

7:02 Any idea?

7:07 justin_smith: rksm: have you tried it with curl?

7:07 rksm: Well with clj-http-lite and node.js, will give curl a try...

7:07 NewToClj: hi 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?

7:09 hyPiRion: NewToClj: Sure thing

7:09 NewToClj: the 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

7:10 justin_smith: "an error"

7:10 hyPiRion: NewToClj: could you post the project.clj to a pastebin, just so I could see?

7:10 we*

7:10 NewToClj: yes the error is: Unable to resolve symbol: make-oauth-creds , which is a symvol'/function of the lib

7:11 how can i check if the dependencies resolved correctly?

7:11 justin_smith: NewToClj: did you use require or use to load the dep?

7:11 NewToClj: justin_smith: (require 'tweedels-clj.core)

7:11 hyPiRion: NewToClj: If you managed to get into the repl itself, there should be no issues with the dependency handling.

7:11 justin_smith: NewToClj: if you do it that way, try tweedels-clj.core/make-oauth-creds

7:12 NewToClj: likely you want an :as in your require so you don't have to spell all that out

7:17 NewToClj: I listed project and the source file, nothing fancy, thats why im wondering what im doing wrong...

7:18 justin_smith: NewToClj: on line 14 you refer to a function that is not mapped to your ns

7:18 NewToClj: right so : make-oauth-creds should come from twitter.oath

7:18 justin_smith: NewToClj: change it to tiwtter.outh/make-oauth-creds or add an :as clause to the require and mutatis mutandis

7:19 NewToClj: justin_smith: but isn't the equire for this?

7:19 justin_smith: NewToClj: no

7:19 NewToClj: justin_smith: ah i see...

7:19 justin_smith: NewToClj: require makes it available, it does not map it directly to your namespace

7:19 hyPiRion: NewToClj: You don't import them to the namespace, but if you want to do that you could do (:require [twitter.oauth :refer :all])

7:19 It's generally not recommended though

7:20 justin_smith: or :refer [make-oauth-creds] even :)

7:20 NewToClj: ahh I see because of namespace shadowing, hm ok

7:20 justin_smith: NewToClj: not just shadowing - it makes editing things later much much easier when it's clear where things came from

7:20 NewToClj: or even reading the code

7:21 * justin_smith has flashbacks of trying to work on namespaces with 10 :use clauses and everything always breaking...

7:29 ro_st: i 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 ?

7:30 is this possible with core.async, or should i use setTimeout/clearTimeout? this is in cljs, obviously

7:30 justin_smith: ro_st: sounds like you want debouncing

7:30 ro_st: ah, is THAT what debouncing is :-)

7:31 https://gist.github.com/scttnlsn/9744501 ?

7:31 julianleviston: ro_st: I thought debouncing was stopping two requests registering when you only pressed once! :)

7:31 justin_smith: ro_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

7:31 julianleviston: justin_smith: handy!

7:31 justin_smith: julianleviston: same concept

7:31 NewToClj: justin_smith: thanks that helped now i'm a step further!

7:31 justin_smith: julianleviston: it comes from hardware / hardware switches

7:32 julianleviston: justin_smith: yeah, I knew it from keyboards.

7:32 justin_smith: julianleviston: in the hardware switch you would have a capacitor that needs to charge up, and any bounce / jiggle gets subsumed

7:32 ro_st: the gist link i pasted seems to do exactly that

7:32 justin_smith: julianleviston: same idea, different domain :) instead of capacitors we have timers

7:33 ro_st: yes, that looks like an acceptable version of debounce

7:33 it resets the timer if you get new events within the timout, othwerwise hits the timout and does the timout's thing

7:34 ro_st: thanks justin_smith!

7:34 justin_smith: ro_st: very useful in UI

7:34 ro_st: but that is probably exactly where you are using it

7:34 ro_st: hugely. i'm doing an autocompleter

7:34 julianleviston: justin_smith: I wanted something like this a few days ago...

7:34 justin_smith: I think...

7:35 ro_st: love core.async. literally just wrapped the arg where i pass in the channel

7:35 justin_smith: omg I can't believe I only just now got the 4clojure "fore" -> golf - code-golf pun

7:35 argh

7:35 ((juxt inc dec) amalloy)

7:36 ro_st: if your cljs app causes safari/mac to restart your mac, is it a bug or a feature?

7:36 julianleviston: justin_smith: i don’t get it… is it just fore/4 ?

7:37 justin_smith: julianleviston: right, and you shout "fore" before swinging in golf

7:37 ro_st: Fore is what they shout when you might just about to be brained by a golf ball

7:37 julianleviston: justin_smith: haha yep. That’s what I thought.

7:38 ah, I hate these “fill in the blanks” type coding things for learning...

7:38 clojure koans had me slapping my head at once stage...

7:39 they’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.

7:40 4clojure is much better than the koans

7:40 ro_st: did you learn a lot about clojure when trying to figure them out? -zen master-

7:40 michaelr`: what would be a good strategy to use liberator resources in a Componentized app?

7:40 justin_smith: julianleviston: won't they just accept any answer that returns the right result?

7:41 julianleviston: michaelr`: Can you rephrase?

7:41 justin_smith: something like that… which often doesn’t help one learn..

7:41 “What’s 1 + 1” doesn’t really help you understand addition.

7:43 justin_smith: julianleviston: it depends on your model of learning. In practice a combination of immersion and higher level reasoning tend to be most effective.

7:43 julianleviston: and immersion is often just "drilling the rote answers"

7:43 michaelr`: 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

7:43 the resource handler..

7:43 julianleviston: Dave 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.

7:43 justin_smith: though it can also include exposure - frequent reading of others code etc.

7:44 julianleviston: justin_smith: yeah, I think reading is excellent to do… more beginning devs should read more before they try to write, IMHO… study good code.

7:44 justin_smith: (myself included, no doubt)

7:45 rksm: [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

7:45 justin_smith: michaelr`: you could also make the function that creates the resource a partial function, or maybe as a macro that is to onerous

7:45 rksm: (http/post (str "http://www.4clojure.com/rest/problem/&quot; 1)

7:45 {:form-params {:code "true" :id 1}})

7:45 justin_smith: (partial function taking the db bindings at creation time)

7:45 rksm: is necessary

7:46 justin_smith: rksm: cool, glad you figured it out

7:47 michaelr`: yeah well, i was hoping for some way to create the liberator resources as part of the system (component) lifecycle

7:47 julianleviston: justin_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…

7:47 michaelr`: instead of passing it at runtime..

7:48 justin_smith: michaelr`: yeah, if it isn't going to change at runtime, why not bind it once

7:48 michaelr`: a similar solution is to use a promise that gets delivered to at init

7:49 "not going to change at runtime" here means that the component system will be restarted if you rebind the db settings, of course

7:53 michaelr`: 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..

7:54 in the sense of a closure..

7:54 julianleviston: michaelr`: yeah, but *your* code can do whatever you like, can’t it?

7:55 michaelr`: sure.. it's all my code :)

7:55 julianleviston: michaelr`: so… can’t you use a function that returns a function?

7:55 michaelr`: yes I can

7:55 julianleviston: michaelr`: I used that a lot in my component code.

7:55 alexyakushev: rksm: you can check how I did it here https://github.com/alexander-yakushev/foreclojure-android/blob/master/src/clojure/org/bytopia/foreclojure/api.clj

7:56 rksm: @alexyakushev cool, thanks!

7:58 justin_smith: michaelr`: 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

7:59 michaelr`: hmm

7:59 justin_smith: michaelr`: 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)

7:59 the vm can't optimize things that are last-minute paramaterized as nicely

8:00 (or the clj compiler can't compile them to as nice a form, etc.)

8:00 michaelr`: hmm

8:01 thinking of it I

8:03 I'm not sure I understand what you're suggesting me to do :)

8:04 justin_smith: michaelr`: does liberator have a function version of its route thing?

8:05 michaelr`: looking..

8:07 looks like there is some function which I could use

8:08 how would that help?

8:09 justin_smith: if 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

8:13 michaelr`: hmm

8:13 thanks justin

8:14 i can see a few ways to do that, i'll play with it a bit more to get a better insight

8:14 justin_smith: michaelr`: aha - it has the function called resource

8:14 http://clojure-liberator.github.io/liberator/doc/resource-definition.html

8:14 shown near the bottom of the page there

8:15 you should be able to craft a call to resource that captures the db in the definition

8:16 and (defresource foo ...) is the same as (def foo (resource ...))

8:17 michaelr`: how about referencing the system var and taking the db component from there? ;

8:17 ;)

8:17 justin_smith: michaelr`: that may be the more straightforward way to do it, actually

8:18 d'oh

8:18 michaelr`: on the other hand, but on the other i think it ruins the whole concept of components

8:19 i mean, the system then becomes a singleton

8:19 justin_smith: right

8:20 well, parameterizing the resource on the config data solves the singleton issue, at the cost of a slightly less straightforward impl

8:21 michaelr`: I thought of maybe defining the resources within the (start) method of a component

8:21 But then I'd have to create one component for each rest entity or put them all inside one component

8:22 either way looks bad

8:22 justin_smith: michaelr`: what about a hash-map to hold the resources, as created by resource

8:22 michaelr`: then that hash-map can be used by the component that creates the server

8:22 (and the middleware, presumably)

8:23 julianleviston: justin_smith: hey do you know… are xhr’s done on the main js thread in the browser?

8:23 justin_smith: julianleviston: I am actually not sure of that

8:23 hellofunk: julianleviston: they can be synchronous or asynch. if you use cljs-ajax they are asynx

8:23 julianleviston: justin_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?

8:24 hellofunk: I’m using the google closure one, I think.

8:24 hellofunk: let me check.

8:24 justin_smith: julianleviston: for cleanliness sake I think putting your logic in a go block rather than a callback tends to work

8:24 hellofunk: julianleviston: 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.

8:24 michaelr`: julianleviston: either way the callback code would be executed on the main js thread

8:24 julianleviston: justin_smith: I have the part of my code that writes the data it gets into an atom in there...

8:25 justin_smith: I just noticed that part of the code seems to take a while...

8:25 michaelr`: yeah? ok.

8:25 hellofunk: julianleviston: up to you whether you use a callback directly or use core.async as a handler.

8:25 julianleviston: hellofunk: I *think* it’s async… just curious.

8:26 hellofunk: well I’m doing a bit of both… but it seems to be blocking up the UI…

8:26 hellofunk: I’m probably doing something stupid tho :(

8:26 hellofunk: julianleviston: i'm a big fan of cljs-ajax and the author is quite opinionated about making sure synchronous activity is avoided

8:27 michaelr`: 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

8:27 julianleviston: hellofunk: 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"})))

8:28 michaelr`: hm… isn’t ajax async by default?

8:28 michaelr`: how can you have ajax if it’s not async?

8:28 michaelr`: isn’t that what the A stands for?

8:29 hellofunk: julianleviston: the question is about xhr and whether that is sync or async

8:29 julianleviston: hellofunk: it is.

8:29 hejki_: 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?

8:29 hellofunk: julianleviston: i mean, xhr can be either. but ajax is typically async xhr

8:29 Glenjamin: node+cljs is an option

8:29 justin_smith: hejki_: jvm is not the bottleneck

8:30 julianleviston: hellofunk: ype

8:30 hellofunk: yep.*

8:30 justin_smith: hejki_: but node+cljs / closure advanced compilation mode do lower the startup time

8:30 hejki_: 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

8:30 justin_smith: (we don't have an equivalent optimization in jvm clojure)

8:30 hejki_: the jvm starts fast

8:30 hejki_: it is clojure that starts slowly

8:31 hejki_: ok

8:31 and can it be made faster? :P

8:31 justin_smith: hejki_: you can avoid this by using cljs, which does not bundle the clojure compiler

8:31 hejki_: but then I lose some features

8:31 justin_smith: and which can be optimized with google closure

8:31 it's true!

8:31 julianleviston: Well I think (let [xhr (XhrIo.)]) that answers my q… Xhrlo is async…apparently?

8:31 justin_smith: hejki_: it's a hard tradeoff

8:31 hejki_: and actually important ones too :P

8:31 julianleviston: i’m pretty sure it’s async… anyway.

8:31 hejki_: clearly :P

8:32 justin_smith: hejki_: drip will not help at all though

8:32 hejki_: ok

8:32 julianleviston: it must just by my code doing some blocked up steff...

8:32 I wonder if I segment it and put it into go blocks if it’s make everything smoother.

8:32 justin_smith: hejki_: you could look at grenchman - one clj process with one set of deps, which runs your clj stuff for you via an ocaml client

8:33 hejki_: 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)

8:33 justin_smith: hejki_: the limitation there is all usages of grenchman must share the same deps

8:33 also, there are other lisps that are better for fast startup / short tasks (eg. racket scheme)

8:34 julianleviston: (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.

8:34 hejki_: justin_smith: well, grenchman could preload everything my cli tool uses and the tool just connects to that and runs stuff?

8:34 justin_smith: ocaml is pretty awesome in terms of startup time / low overhead if you might consider an ml, as well

8:34 hejki_: exactly

8:34 julianleviston: justin_smith: or maybe even Piumerta’s COLA!

8:34 justin_smith: hejki_: as long as all uses of grenchman are OK with using the same version of every lib, that will just work

8:35 hejki_: 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

8:36 justin_smith: hejki_: yeah, you could probably figure out a managed restart

8:36 hejki_: I can do that with the distribution package manager when new version of the cli tool gets installed

8:37 the nrepl could be ran as a service anyhow

8:37 justin_smith: thanks for this information. I'll look more deeply into grenchman and perhaps start porting the current tool soonish :)

8:38 justin_smith: hejki_: the other concern of course is to make sure you aren't relying on globals at all

8:38 hejki_: but clojure is very good with helping you with that sort of thing

8:38 hejki_: i think all global states are in filesystem in my case

8:38 justin_smith: hejki_: well, for example you would want no defs in namespaces that would be client specific

8:39 julianleviston: Ok 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?

8:39 justin_smith: but if it's all in files and can be per-execution local, then yeah, great

8:39 hejki_: that might require some redesigning

8:40 justin_smith: hejki_: a nice trick is replacing usage of vars (defs) with a map of bindings passed to your function in which you look things up

8:40 hejki_: suddenly nothing is global any more!

8:41 hejki_: justin_smith: only things currently global in the python tool are db connection and definitions (constants that i do not wish to hardcode)

8:41 justin_smith: what I mean by global is a bit more extensive than what python might mean

8:41 ie. no singletons are allowed

8:42 hejki_: hmm.. I do have user configurations that are 'singletons' (read: python package globals)

8:42 can't I bind them somehow?

8:42 justin_smith: pass them in a map to your executing function

8:42 and it can forward them down the call chain as needed

8:43 hejki_: hmm.. maybe I'll just read them whenever I need something from those config files

8:43 not all operations actually require anything from that global data (those are actually read lazily now in the python tool, too)

8:44 however the package global state makes the current implementation read that data only once per execution

8:55 justin_smith: hejki_: you mention user config - be aware that nrepl is not a good idea on true multi-user systems

8:56 it opens an http port on a local socket that executes arbitrary code (including shelling out) as the user who spawned it

8:56 with no auth

8:56 (and grench uses nrepl)

9:05 gfredericks: ~hi

9:05 clojurebot: No entiendo

9:06 justin_smith: nyello

9:10 gfredericks: after digging into using def inside a function, I'm surprised at how straightforward and harmless it is. It's just unidiomatic amirite?

9:11 not much worse than a global atom?

9:11 justin_smith: gfredericks: 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.

9:11 gfredericks: I replace def inside functions with (def foo (promise)) and then put (deliver foo x) inside a function

9:12 then of course I need to deref

9:12 gfredericks: justin_smith: your first question applies to a global atom as well?

9:12 justin_smith: but it leaves out the open questions that an atom would leave hanging

9:12 gfredericks: sure, initialization issues

9:12 but a promise just blocks until delivered

9:12 which avoids that (as long as someone plans on delivering...)

9:12 gfredericks: can anybody think of any uses for a validator on a var?

9:13 a normal var I mean

9:13 justin_smith: a "normal" var, I only define once

9:13 gfredericks: exactly

9:13 justin_smith: I mean a validator is a great idea for something that gets a lot of updates, potentially from clients you don't control...

9:14 gfredericks: I feel like the idiomatic use of vars is just don't programmatically redefine them

9:14 justin_smith: but you should not be letting clients def your vars...

9:14 gfredericks: perhaps validator on a dynamic var?

9:14 that kind of makes sense, if you tolerate dynamics

9:15 gfredericks: yeah that's a good point

9:15 maybe also for with-local-vars which who even uses that

9:15 it feels like an almost entirely different kind of thing

9:15 justin_smith: I mean seriously, yeah

9:15 would any of us even notice if with-local-vars just disappeared?

9:16 gfredericks: I once came up with a non-composable tactic for turning a non-dynamic var into a dynamic one

9:16 I think it might've or could've used with-local-vars in the impl

9:18 justin_smith: a SO question I provided an inadequate answer to yesterday led to an idea for a useful utility

9:18 someone wants a command line with a long running lein instance where they can type in lein commands to run them

9:19 gfredericks: a repl for lein?

9:19 justin_smith: it seems like you could do that with a shell script that loads the lein jar, and runs a custom interpreter loop

9:19 yeah

9:19 gfredericks: didn't it have that feature at some point?

9:19 `lein interactive`

9:19 hyPiRion: yes, we did

9:19 stuartsierra: I thought it still did.

9:19 justin_smith: I think there is an issue that lein has some stuff that just breaks in long running processes

9:20 but what if you (every time? occasionally?) restarted lein after the command to get a fresh start...

9:20 or, bigger task, fixed the weird stuff that happens when lein stays running

9:20 said weird stuff I would need to do some more research - I recall technomancy talking about this a while back

9:21 stuartsierra: I think lein interactive was discontinued with lein 2.x

9:21 stuartsierra: oh

9:21 justin_smith: "lein rewrite using component" - awesom gsoc proposal

9:22 jballanc: justin_smith: according to crossclj, no...nobody would miss with-local-vars: http://crossclj.info/fun/cljs.core/with-local-vars.html

9:22 justin_smith: (inc jballanc)

9:22 hyPiRion: lazybot is as dead as every

9:22 *ever

9:22 justin_smith: OK, this is getting way silly

9:23 yeah, I need to look into implementing "oh, I need to reconnect" logic in lazybot one of these days

9:23 if I wasn't behind on 3 different contracting jobs...

9:27 jballanc: ,(rip lazybot)

9:27 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: rip in this context, compiling:(NO_SOURCE_PATH:0:0)>

9:33 Bronsa: jballanc: I would https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader/impl/utils.clj#L74-L77

9:33 jballanc: ah, interesting!

9:33 justin_smith: Bronsa: ahh, I guess crossclj doesn't cross reference tools.reader

9:33 jballanc: reminds me that I need to spend more time with tools.reader

9:34 Bronsa: justin_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

9:35 jballanc: oh, whoops!

9:35 :-[

9:35 justin_smith: ahh, OK

9:37 jballanc: Bronsa: wait...looking at the source for `with-local-vars`, wouldn't it make more sense to just call `(.. clojure.lang.Var create setDynamic)` directly?

9:37 I mean, the whole thread context gets pushed and poped before you return `x`, so that doesn't really do anything for you, right?

9:38 ionthas: I 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?

9:38 justin_smith: ionthas: use an atom / agent / ref for the counter

9:38 tbaldridge: ionthas: kindof a odd use-case, but consider using agents

9:38 ,(doc agent)

9:38 clojurebot: "([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 ...

9:38 Bronsa: jballanc: yes, except with-local-vars is a public var, Var/create and Var/setDynamic are implementation details

9:39 jballanc: hmm...true

9:39 justin_smith: yeah, that is a good use case for agent

9:39 ionthas: ok, thanks. I will look at them.

9:39 Bronsa: jballanc: and since one of t.r promises is backcompatibility, I'd rather not rely on implementation details that might change in the future

9:40 jballanc: yeah, a laudable goal...still makes me think that the ability to create new dynamic vars should be promoted to public API

9:40 justin_smith: (let [a (agent 0)] (dotimes [i 10000] (send a inc)) @a)

9:41 ,(let [a (agent 0)] (dotimes [i 10000] (send a inc)) @a)

9:41 clojurebot: 0

9:41 justin_smith: haha

9:41 Bronsa: jballanc: agreed

9:42 justin_smith: ionthas: 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

9:42 Bronsa: ,(let [a (agent 0)] (dotimes [i 10000] (send a inc)) (await a) @a)

9:42 justin_smith: aha!

9:42 clojurebot: eval service is offline

9:42 Bronsa: well

9:42 ,(let [a (agent 0)] (dotimes [i 10] (send a inc)) (await a) @a)

9:42 whatever, that works.

9:42 clojurebot: eval service is offline

9:42 Bronsa: ,1

9:42 clojurebot: 1

9:42 hyPiRion: clojurebot doesn't like threads

9:42 Bronsa: clojurebot: you're a weirdo

9:42 clojurebot: Pardon?

9:43 justin_smith: (inc Bronsa)

9:43 I had forgotten about await

9:43 Bronsa: justin_smith: you are now my least favourite person, followed closely by lazybot

9:44 justin_smith: hehe

9:53 hejki_: 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

9:54 justin_smith: hejki_: OH, OK

9:54 haha, didn't mean to all caps that.

9:54 hejki_: 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)

9:55 has there been any work done to add local auth to nrepl?

9:56 hejki_: I do not think that is going to be a real problem

10:00 justin_smith: hejki_: yeah, it just reminded me of the general issue, which I think is still worth fixing

10:01 hejki_: 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:01 is anything ran in the repl session accessible via grench?

10:02 justin_smith: hejki_: well, how modified? the startup time issue is because of how clojure bootstraps itself

10:02 hejki_: grench is an nrepl client written in ocaml, it accesses a clojure process (and has full access to that process)

10:02 hejki_: 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:03 justin_smith: hejki_: yeah, you can access whatever you like in the clojure server process via grench

10:04 hejki_: so I could always (use "myglobals") when the REPL is started and those would then be accessable in the code ran using grench

10:04 ?

10:04 justin_smith: hejki_: not that exact syntax, but yeah

10:05 hejki_: well yes

10:05 :P

10:05 '

10:05 :)

10:05 would it be a bit too transparent for a developer? they should "just know" that some namespace is preloaded in the repl

10:05 justin_smith: hejki_: typically I would have an init function that binds a bunch of config.

10:06 hejki_: I think it could be set up such that you put them in a default ns when they connect

10:06 and you can use / require / bind whatever you need to in that ns

10:06 hejki_: that would be awesome :)

10:07 justin_smith: hejki_: but the way clojure namespaces work, if they create / switch to their own ns, from that point they are on their own

10:07 hejki_: 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:07 justin_smith: hejki_: there is no such thing as "globally using" for all namespaces

10:07 hejki_: good :)

10:07 I think I'll have to just install grench and do some experimentation

10:07 justin_smith: hejki_: you could define the ns in a normal clojure file, and just set it to be the repl default

10:07 hejki_: I just have boring work stuff I have finish first :P

10:08 justin_smith: hejki_: yeah, good plan

10:15 jackhill: Hi, can I get lein to communicate with nrepl over a unix domain socket instead of a network socket?

10:16 justin_smith: jackhill: the jvm can't do uds without a native lib

10:17 jackhill: 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:17 jackhill: justin_smith: I'm okay with using a native lib, or is that too hard?

10:17 justin_smith: ah, I'll continue digging

10:17 justin_smith: jackhill: 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:19 jackhill: justin_smith: okay thanks. Do you have pointers about where in nrepl I'd look to try to make it use that?

10:21 justin_smith: jackhill: 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:21 jackhill: if your uds replacement for the network socket has the same api as ServerSocket, then it should Just Work™

10:22 jackhill: it's a small enough function that you could copy/paste to make a uds using replacement even

10:23 jackhill: mutatis mutandis for client, of course :)

10:25 jackhill: justin_smith: great, I'll look into it :)

10:34 michaelr`: re

10:36 martinklepsch: best way to get random alpanumeric 10 character strings in clojure?

10:37 I guess cutting uuids isn't the right thing to do

10:37 llasram: martinklepsch: depends some on context. E.g, if for test.check tests then you should use appropriate generators :-)

10:38 noidi: ,(apply str (repeatedly 10 #(rand-nth "abcdefghijklmnopqrstuvwxyz0123456789")))

10:38 clojurebot: "m4uuvda17f"

10:38 hyPiRion: ^

10:39 martinklepsch: llasram: not for testing

10:41 llasram: ,(let [chars (->> (range 128) (filter #(or (Character/isAlphabetic (int %)) (Character/isDigit (int %)))) (map char) (into []))] (apply str (repeatedly 10 #(rand-nth chars))))

10:41 clojurebot: "OU7Ep7yHmK"

10:41 llasram: Look Ma, no magic strings! :-)

10:42 martinklepsch: I need these to be unique, can I rely on something as simple as rand-nth for that?

10:43 llasram: martinklepsch: uh. how unique?

10:43 martinklepsch: (should have mentioned that uniqueness requirement earlier, sorry)

10:43 hejki_: prng never provides unique enough ;>

10:43 Glenjamin: secure unique?

10:44 martinklepsch: Glenjamin: no

10:44 Glenjamin: i.e. I don't need proof that it's going to be unique

10:44 Glenjamin: can you say the use-case?

10:44 something like tiny-url?

10:45 martinklepsch: Glenjamin: yeah I guess that's similar

10:45 I feel evil mentioning the actual usecase: tagging browsers via cookies

10:45 Glenjamin: i think generally for that there's a number store internally, and a two-way mapping from number to string

10:45 llasram: martinklepsch: You've made this a very different problem. What you actually have are 10 digit base-36 numbers

10:46 Glenjamin: why not just use uuid ?

10:46 martinklepsch: Glenjamin: legacy

10:46 llasram: martinklepsch: What you actually want to to make sure you're generating a unique sequence of numbers

10:46 martinklepsch: Can you just e.g. use persistent state to generate integers in standard order?

10:47 Or you could generate randomly and ensure uniqueness in a transactional database

10:48 martinklepsch: llasram: 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:49 llasram: 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:49 llasram: martinklepsch: 10 base-36 digits gives you ~51.7 bits

10:50 martinklepsch: Yes, but they're very different ways of thinking of the problem

10:50 martinklepsch: llasram: ok, that's right

10:52 Glenjamin: 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:52 Glenjamin: eventually that stuff is all handled by Clojure and we can switch to something sane like UUIDs

10:52 llasram: martinklepsch: Can you just implement the same algorithm the PHP code uses? Then it won't be any worse

10:53 martinklepsch: llasram: I can but I don't want to really:

10:53 $hash = md5(mt_rand(1, 10000).microtime().getmypid().gethostname());

10:53 return str_pad(substr(base_convert($hash, 16, 36),0,10),10,"0");

10:53 julianleviston: martinklepsch: what time or space period do they have to be unique across?

10:53 martinklepsch: There must be a less weird way of doing it in clojure :D

10:54 julianleviston: martinklepsch: nevermind, you kind of answered my q with your php implementation paste.

10:54 martinklepsch: julianleviston: what did that paste tell you about your q?

10:55 julianleviston: I don't think the php implementation is ideal

10:55 julianleviston: martinklepsch: that you don’t care about total uniqunenss enough to be storing it in a db and checking previous ones or anything

10:55 llasram: martinklepsch: How many users do you have?

10:56 martinklepsch: But probably timestamp + some randomly-seeded randomness is the best you can do

10:57 julianleviston: martinklepsch: I don’t know what is wrong with uuid?

10:57 martinklepsch: julianleviston: it's 16 bytes vs 10

10:57 llasram: julianleviston: Because UUIDs are 128 bits and martinklepsch needs to fit this identifier into 51.7 bits

10:58 julianleviston: does this help? https://clojuredocs.org/clojure.core/rand-int

10:58 ie… the example on that page has a fn called “unique-randon-numbers”

11:00 martinklepsch: but that’s talking about uniquneness within itself… you want uniqueness outside of the numbers… sorry.

11:00 (ie no char repeated versus no repeated set of chars)

11:01 martinklepsch: can you use gensym?

11:01 martinklepsch: sorry I’ll be quiet :) I’m not helping.

11:03 martinklepsch: julianleviston: 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:03 julianleviston: martinklepsch: one more… this lib might be very helpful… https://github.com/maxcountryman/flake

11:03 clojurebot: Huh?

11:04 julianleviston: martinklepsch: (utils/base62-encode (flake/generate)) ; -> "8mwFA958SJ2CZVu9nk"

11:04 Decentralized, k-ordered unique ID generator

11:04 martinklepsch: julianleviston: what does this provide over UUIDs?

11:05 https://github.com/boundary/flake#frequently-asked-questions

11:05 nvm

11:05 julianleviston: guh… sorry. I didn’t see that it was 128bit only until too late. k. soz.

11:15 martinklepsch: julianleviston: interesting nontheless, thanks for the link, I noted it as UUID alternative

11:17 kodumulo: Is 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:17 sm0ke: is it possible to efficiently scan classpath for all implementation of a protocol?

11:17 julianleviston: kodumulo: the reader will do that...

11:18 kodumulo: julianleviston: not sure I understand what that mean

11:18 Bronsa: kodumulo: read-string

11:18 julianleviston: kodumulo: it’s how clojure reads source.

11:19 kodumulo: thnx

11:19 julianleviston: kodumulo: depending on your date literals, you might want to use something other than the reader… all depends on the format…

11:20 kodumulo: yeah its not working on these dates, oh well I'll think of something fancy for that. Thanks

11:21 julianleviston: kodumulo: this might help: https://github.com/clojurewerkz/serialism

11:21 Bronsa: kodumulo: also check out tagged literals

11:22 kodumulo: NumberFormatException Invalid number: 2015-01-06 clojure.lang.LispReader.readNumber (LispReader.java:256)

11:23 Bronsa: ,(read-string "#inst \"2015-01-06\"")

11:23 clojurebot: #<SecurityException java.lang.SecurityException: denied>

11:23 Bronsa: kodumulo: try that on your repl

11:23 julianleviston: kodumulo: it’s a tagged literal

11:23 kodumulo: I am reading from a file, I don't know before hand if its a date or not, this isn't clojure data

11:23 Bronsa: kodumulo: then read-string is not what you need

11:24 kodumulo: I'm discovering that ;)

11:24 julianleviston: kodumulo: that lib I linked you to probably does anything you want to throw at it.

11:24 kodumulo: julianleviston: nice thanks

11:24 julianleviston: gotta be specific as possible with your q’s. o-)

11:24 it’s hard.

11:27 sardinha_biba: What'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:27 tcrayford____: sardinha_biba: "arity" is the number of arguments a function can take

11:27 Bronsa: sardinha_biba: (fn ([] 0) ([x] 1))

11:28 sardinha_biba: that function can take either 0 or 1 args, those are those functions' arities

11:28 julianleviston: sardinha_biba: it’s not a normal english word. It’s a programming term.

11:28 justin_smith: julianleviston: also math / logic

11:29 julianleviston: justin_smith: too true! :)

11:29 justin_smith: but yeah, not conversational english at all

11:29 julianleviston: sardinha_biba: a quick google will find it for you BTW… http://en.wikipedia.org/wiki/Arity

11:29 sardinha_biba: so arity = number of arguments a function can take?

11:30 tcrayford____: yep

11:31 julianleviston: sardinha_biba: and arity overloading is when a function has different bodies, each of which correspond to a different number of arguments

11:31 nonrecursive: sardinha_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:31 kodumulo: in grammar it's called valency

11:31 julianleviston: kodumulo: oh wow… I did not know that…

11:32 kodumulo: and the function is a predicate, although in programming only some functions are predicates

11:32 sardinha_biba: its atarting to make sense now :)

11:32 thank you all for the clarifications

11:32 and the links :)

11:32 kodumulo: essentially in natural language all verbs return true (the basic idea behind lojban)

11:33 julianleviston: kodumulo: Ah… I didn’t know it because I’d primarily studied functional grammar

11:33 kodumulo: i mean all verbs return true or false

11:34 julianleviston: kodumulo: I need to study more :) http://en.wikipedia.org/wiki/Valency_(linguistics) this is cool. Thanks for that.

11:34 kodumulo: np

11:35 in lojban all verbs have a fixed valency/arity

11:35 julianleviston: kodumulo: hehe that’s a funny language… did you ever learn any esperanto?

11:36 kodumulo: Jes, mi povas paroli Esperanton tre bone

11:36 julianleviston: mi forgesis mia esperanton

11:36 kodumulo: Mia nomo estas Esperanta

11:37 julianleviston: I do like it, tho :)

11:37 dbronico: Hey, 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:39 julianleviston: kodumulo: ah… mi vidas… http://eo.wikipedia.org/wiki/Kodumulo

11:42 tbaldridge: sm0ke: if you just want to get all current impls of a protocol you can do this:

11:42 ,(:impls clojure.core.protocols/CollReduce)

11:42 clojurebot: {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:44 Bronsa: tbaldridge: i'm not sure that includes the inline impls

11:44 ,(deftype x [] clojure.core.protocols/CollReduce)

11:44 clojurebot: sandbox.x

11:44 Bronsa: ,((:impls clojure.core.protocols/CollReduce) sandbox.x)

11:45 clojurebot: nil

11:45 Bronsa: ,((:impls clojure.core.protocols/CollReduce) 'sandbox.x)

11:45 clojurebot: nil

11:45 Bronsa: yeah, no

11:45 julianleviston: ,(:impls clojure.core.protocols/CollReduce)

11:45 clojurebot: {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:46 julianleviston: ,(-> (:impls clojure.core.protocols/CollReduce) vals first (get 'sandbox.x))

11:46 clojurebot: nil

11:46 julianleviston: Bronsa: were they equiv?

11:47 Bronsa: what?

11:47 clojurebot: what can possibly go wrong

11:47 julianleviston: Bronsa: Ah soz… I didn’t realise what was going on :)

11:47 Bronsa: the initial key of nil threw me off.

11:49 ppppaul: is there a quick way to pretty print/beautify clojure/edn on the command line/lighttable/web ???

11:49 julianleviston: ppppaul: pprint

11:49 ppppaul: pprint means i am in a clojue env

11:50 which, i'm not (hence web/command line ref)

11:50 mdrogalis: ppppaul: Cljs doesn't have pprint yet.

11:50 I usually get around this by pprinting it on the server and sending it to JS. Sad face.

11:50 ppppaul: i know cljs doesn't have pprint... is there a web service that will pprint, or lighttable plugin (there is one for JS beautify)

11:51 i don't have the option to pprint on the server, as i don't have a server

11:51 my edn data is coming from mori, actually

11:52 mdrogalis: ppppaul: Not sure, sorry. :(

11:52 ppppaul: i have been converting my edn into JS and using jsbeautify

11:53 julianleviston: What’s this? http://crossclj.info/ns/org.clojure/clojurescript/latest/cljs.pprint.cljs.html

11:54 is it borked?

11:58 ppppaul: i feel borked

12:00 julianleviston: ppppaul: same…

12:00 but that might just be because it’s 4 am.

12:01 sardinha_biba: lies.. it's 17h

12:01 justin_smith: ~ugt

12:01 clojurebot: ugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html

12:02 sardinha_biba: :)

12:03 julianleviston: haha sorry :)

12:03 justin_smith: I 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 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:06 tcrayford____: {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 tcrayford____: You know, I don't really know. I don't see any reason to believe that it does, though.

12:07 tcrayford____: yea, oof :( File an issue I guess?

12:07 tbaldridge: depending 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:08 tbaldridge: what 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 So I don't think it's auto-pooling. =)

12:09 michaelr`: thank god for postgres ;)

12:09 {blake}: Looking at getDB, it's just "(.getDB conn name)", where conn is passed in.

12:09 uris77: is 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:09 michaelr`: 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:12 tcrayford____: uris77: yeah, look for "uberjar"

12:13 uris77: ah, 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 Aspect Oriented Progrmaming! =)

12:15 julianleviston: {blake}: couldn’t your stubbing include check and retry if not connected?

12:16 jcrossley3: gfredericks: i like your talk title :)

12:17 gfredericks: jcrossley3: 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:18 julianleviston: {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:20 thearthur: at the conj there was mention of a non-blocking put and take function for core.async, anyone remember what that was called?

12:20 julianleviston: {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:20 tbaldridge: thearthur: put! and take! are non-blocking

12:20 julianleviston: thearthur: put! take! right?

12:20 tbaldridge: oh too quick! :)

12:20 (inc tbaldridge)

12:21 thearthur: tbaldridge: julianleviston I guess i meant non-parking then

12:21 julianleviston: thearthur: 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:21 julianleviston: thearthur: they don’t park a go block, or block a thread, and they can be used in or out of go blocks

12:22 thearthur: so if the buffer is full they should return an error instead of parking the block until the buffer empties

12:22 tbaldridge: thearthur: yeah, I think Rich mentioned that. Don't think they are implemented yet.

12:22 whomp: how do i get the cursive ide? i can't find it in the list of plugins for intellij idea

12:23 julianleviston: whomp: you have to add a repo in intellij or d/l it from the site.. there are instructions on the site.

12:23 Bronsa: whomp: https://cursiveclojure.com/userguide/

12:23 whomp: thx :)

12:24 julianleviston: tbaldridge: really? so what do they do now? I thought they worked async… so they just buffered it or something?

12:24 tbaldridge: it *did* cross my mind as being curious a couple times, actually.

12:25 tbaldridge: julianleviston: 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:25 julianleviston: tbaldridge: i guess it probably spins up a go block that finishes when the put succeeds?

12:25 tbaldridge: Rich wants to add (poll c) where you either get nil or a value instantly, never a block and no callback required

12:26 julianleviston: tbaldridge: put! doesn’t require a callback… oh… so if it fails, it silently fails at the moment??

12:26 tbaldridge: why is this not in the documentation? :) :)

12:26 raspasov: tbaldridge: can you achieve something like that with alts!! and using the :default?

12:27 tbaldridge: julianleviston: here's the bit of Rich's talk about it: http://youtu.be/4KqUvG8HPYo?t=50m28s

12:27 raspasov: tbaldrige: (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:28 julianleviston: tbaldridge: ;ian. byt O

12:28 tbaldridge: 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:29 raspasov: julianleviston: if you put too many you'll start getting exceptions I believe

12:29 using put!

12:29 julianleviston: raspasov: yeah, 1024.

12:29 tbaldridge: julianleviston: 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:29 julianleviston: raspasov: assuming a standard (chan)…

12:30 tbaldridge: julianleviston: 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:30 *pending puts and takes

12:30 julianleviston: tbaldridge: 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:30 julianleviston: tbaldridge: interesting. I wish this was written down somewhere

12:30 tbaldridge: sure, thats changing the size of the buffer, not the size of the pending (blocking) puts and takes

12:31 julianleviston: {blake}: lol… nice.

12:31 thearthur: julianleviston: that alts method shows promise as a workaround

12:31 julianleviston: thearthur: it does? how’s that?

12:32 thearthur: the goal is to get all the messages currently avaiable now, consolidate them into a collection and then move on

12:32 tbaldridge: raspasov: 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:32 julianleviston: tbaldridge: 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:32 thearthur: is there a better way of going about that?

12:33 gfredericks: fun fact: NPEs have null messages

12:33 tbaldridge: thearthur: yeah, with the API as it is today, I'd just do alts+:default

12:33 raspasov: tbaldridge: you mean garbage in terms of GC/objects or just ugly code?

12:33 danielglauser: gfredericks: niiiice

12:34 julianleviston: gfredericks: what’s an NPE?

12:34 tcrayford____: nullpointerexception

12:34 tbaldridge: raspasov: 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:35 gfredericks: I would demo it but I don't think the bots let you catch things

12:35 julianleviston: oh … right.

12:36 whomp: how do i create a new clojure project with resources/, src/, etc. from intellij cursive?

12:36 julianleviston: whomp: I think you have to do it in lein...

12:36 whomp: but don’t quote me on that

12:37 I 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:37 whomp: thx julian

12:38 justin_smith: julianleviston: I like promises for values that only get delivered once, but not right away. Not for threading complex logic via callbacks though.

12:38 julianleviston: justin_smith: yeah, it’s more about delivery than program data flow...

12:38 justin_smith: whomp: I think File -> New Project should set things up, no?

12:39 julianleviston: right, I don't think promises are good for program flow

12:39 whomp: justin_smith, not really

12:39 justin_smith: julianleviston: but they are better than using an atom that only gets set once

12:40 whomp: oh, yeah, julianleviston was right https://cursiveclojure.com/userguide/leiningen.html

12:40 * julianleviston falls over

12:40 justin_smith: haha

12:41 julianleviston: should have seen the mess I had to write in Ember in order to do a recursive tree structure clone… GUH

12:41 raspasov: tbaldridge: cool, thanks for clarification!

12:41 julianleviston: like 70 lines of coffeescript and many hours of my life

12:41 ugly ugly ugly

12:42 amusingly to do that in clojure is like… almost 0 lines of code.

12:42 {blake}: (For large values of "0")

12:42 julianleviston: {blake}: well… how do you clone a large map? You don’t need to… right? :)

12:43 {blake}: (assoc m :id new-id) ; <- something like that, if I want to change the id.

12:43 justin_smith: ,(let [m' m] m') - done

12:43 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: m in this context, compiling:(NO_SOURCE_PATH:0:0)>

12:43 julianleviston: justin_smith: lol :)

12:43 {blake}: Hah!

12:43 justin_smith: why did I use ,? my brain is missing

12:44 julianleviston: justin_smith: because I’m tired, and I infected you :)

12:44 justin_smith: ok I gotta go sleep… :) was lovely talking to all of you today!

12:44 laters

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:21 justin_smith: {blake}: on the other hand, vars automatically call their dereffed value in the calling position

13:21 ,(#'+ 1 1)

13:21 clojurebot: 2

13:24 hyPiRion: {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:24 if that variable was a function

13:30 justin_smith: another option would be to always deref

13:31 the source of the data can deside on what kind of dereffable thing they should provide

13:31 *decide

13:32 it could be an atom, a delay, whatever

13:32 a deftype that calls a function when you deref

13:32 whatever evil thing you like

13:32 hyPiRion: call-by-deref

13:32 justin_smith: right

13:32 probably the right way to do UAP in clojure, but UAP isn't a very good idea in clojure

13:35 hyPiRion: ,(proxy [clojure.lang.IDeref] [] (deref [] (prn "hi")))

13:35 clojurebot: "hi"\n#<Object$IDeref$e595a7c1@7cec352a: nil>

13:36 justin_smith: why did it get dereffed?

13:36 or is that not what happened?

13:36 hyPiRion: it was printed

13:36 justin_smith: ahh

13:36 hyPiRion: ,(do @(proxy [clojure.lang.IDeref] [] (deref [] (prn "hi"))) nil)

13:36 clojurebot: "hi"\n

13:36 hyPiRion: ,(do (proxy [clojure.lang.IDeref] [] (deref [] (prn "hi"))) nil)

13:36 clojurebot: nil

13:36 justin_smith: cool

13:37 so, it's value is nil, but it prints "hi" whenever you access the value

13:37 hyPiRion: yup

13:37 justin_smith: well that's that, we have implemented the important features of ruby in clojure, we're done now

13:39 hyPiRion: oh hey

13:39 ,(alter-var-root #'clojure.core/unquote (constantly deref))

13:39 clojurebot: #<core$deref clojure.core$deref@6f1792ce>

13:39 hyPiRion: ,~(atom 10)

13:39 clojurebot: 10

13:39 justin_smith: oh no

13:42 gfredericks: hey unary

13:42 ,(alter-var-root #'clojure.core/unquote (constantly inc))

13:42 clojurebot: #<core$inc clojure.core$inc@61a36d43>

13:42 gfredericks: ,~~~~~~~~~~~~~~~~~~~~~~~~~0

13:42 clojurebot: 25

13:42 gfredericks: the idris people will love it

13:43 hyPiRion: woah

13:43 tomjack: only if it compiles down to primitive arithmetic

13:43 :P

13:43 gfredericks: downside is it's probably stackful

13:43 so you can't make big numbers

13:43 justin_smith: now figure out how to access alter-var-root etc. from swearjure, and you can start doing some insanity

13:43 gfredericks: ,(alter-var-root #'clojure.core/unquote-splicing (constantly #(* % %)))

13:43 clojurebot: #<sandbox$eval203$fn__204 sandbox$eval203$fn__204@f8913dd>

13:44 gfredericks: ,~~~~~~~~@~~~~~@~~~~@~~~~~~~~0

13:44 clojurebot: 20187056

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:44 justin_smith: gfredericks: omfg

13:44 gfredericks: how 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:44 TimMc: justin_smith: I don't think we'll be able to break out of the swearjure prison unless we can like... glitch the JVM.

13:44 gfredericks: probably not very

13:45 {blake}: justin_smith: I'm trying to parse that.

13:45 justin_smith: {blake}: parse which?

13:46 {blake}: justin_smith: "on the other hand, vars automatically call their dereffed value in the calling position"

13:46 hyPiRion: TimMc: perhaps if there are bugs with the new conditional form, #?

13:46 gfredericks: ,(alter-var-root #'clojure.core/unquote (constantly #(* 2 %)))

13:46 hyPiRion: or the #?@ version

13:46 clojurebot: #<sandbox$eval26$fn__27 sandbox$eval26$fn__27@51993720>

13:46 gfredericks: ,(alter-var-root #'clojure.core/unquote-splicing (constantly #(inc (* 2 %))))

13:46 clojurebot: #<sandbox$eval53$fn__54 sandbox$eval53$fn__54@7bb0d860>

13:46 justin_smith: ,(type #'+) ; {blake}

13:46 clojurebot: clojure.lang.Var

13:47 gfredericks: ^ that should give an efficient representation though

13:47 justin_smith: {blake}: so that's a var

13:47 gfredericks: ,~~~~~~@0

13:47 clojurebot: 32

13:47 justin_smith: ,(#'+ 1 1) ; it auto-derefs and calls

13:47 clojurebot: 2

13:47 {blake}: justin_smith: The plus sign is a var? Pointing to the plus function?

13:47 gfredericks: ,~@~~~~~~@0

13:47 clojurebot: 65

13:47 justin_smith: {blake}: no #'+ is a var

13:47 {blake}: justin_smith: So...lemme think how I can apply that.

13:48 pound quote plus? =P Hang on...

13:48 hyPiRion: {blake}: so #'+ is not +, but @#'+ is the same as +

13:48 TimMc: hyPiRion: Oh man, I haven't looked at the conditional stuff yet!

13:48 justin_smith: and furthermore, #'+ when used as a function looks up + and calls it for you

13:48 aperiodic: ,(= #'+ (var +))

13:48 clojurebot: true

13:49 hyPiRion: TimMc: It doesn't seem useful yet, but if there are bugs in it we might get a chance

13:49 Oh right

13:49 TimMc: There could be bugs anywhere already.

13:49 hyPiRion: {blake}: #'x is just sugar for (var x)

13:49 ,'#'x

13:49 clojurebot: (var x)

13:49 TimMc: Maybe we need to add metadata to just the right thing or something.

13:49 or a parser bug somewhere

13:49 hyPiRion: yeah

13:50 How should we go forward though? Make fuzzy tests or something?

13:51 maybe we can use this

13:51 ,(-> + #'foo)

13:51 clojurebot: #'clojure.core/+

13:53 krat0sprakhar: hi everyone

13:53 i've been trying to wrack my brains on problem 132 on 4clojure

13:53 my solution is passing all but the last test case - https://www.refheap.com/96906

13:53 any idea whats wrong?

13:56 my hunch is that my solutions uses reduce with iterate

13:56 ,(take 10 (->> (iterate inc 10) (reduce +)))

13:56 will fail

13:56 clojurebot: Execution Timed Out

13:58 justin_smith: krat0sprakhar: the last case returns an infinite series

13:58 krat0sprakhar: so your function needs to be lazy

13:58 krat0sprakhar: yeah..

13:59 but i cant do that with reduce right?

13:59 justin_smith: krat0sprakhar: no, you can't

13:59 krat0sprakhar: so i need to find another way that doesn't rely on reduce?

13:59 justin_smith: krat0sprakhar: 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:59 krat0sprakhar: yeah

14:00 krat0sprakhar: try it with lazy-seq directly - that's the more tedious but more informative way as a beginner I think :)

14:00 it's basically just going to look like a recursive function

14:00 krat0sprakhar: haha.. i'm having a hard time understanding the lazy-seq macro

14:00 can i use loop / recur?

14:01 or will that fail as well

14:01 gfredericks: lazy-seq is normally used with normal recursion

14:01 justin_smith: yeah - you want laziness with dumb recursion

14:01 ie. calling the same function, not using recur

14:01 krat0sprakhar: ah ok

14:02 justin_smith: krat0sprakhar: 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:02 krat0sprakhar: so using let bindings i can get the first part of the collection, then conj it with a lazy seq - calling the function recursively?

14:02 justin_smith: right

14:02 and because lazy-seq thunkifies things, you won't blow the stack

14:03 gfredericks: ~lazy-seq |thunkifies| things

14:03 clojurebot: You don't have to tell me twice.

14:03 {blake}: Ahhh...I'm getting "var" and "def" mixed up.

14:03 krat0sprakhar: justin_smith: thanks! i'll give that a shot

14:03 justin_smith: weee got that thunk, got to have that thunk

14:03 krat0sprakhar: will come back to you if i'm not able to solve it :P

14:03 hope thats okay

14:03 justin_smith: https://www.youtube.com/watch?v=l4nOHdUntyM

14:04 {blake}: Wait, they are the same thing, sorta.

14:04 justin_smith: {blake}: def creates vars

14:04 (var x) gets the thing def created

14:04 using the symbol x looks up that def's value

14:04 krat0sprakhar: justin_smith: this is groovy .. thanks! :D

14:04 justin_smith: gotta have that thunk

14:04 krat0sprakhar: LOL :D

14:05 {blake}: justin_smith: Right.

14:05 justin_smith: http://en.wikipedia.org/wiki/Thunk in case you didn't know

14:05 it's how laziness is done

14:06 krat0sprakhar: wow! so *thunk* is really a word :D

14:06 i had no clue

14:07 ,(def my-msg "thunk")

14:07 clojurebot: #'sandbox/my-msg

14:07 krat0sprakhar: ,(count my-msg)

14:07 clojurebot: 5

14:07 krat0sprakhar: wow

14:07 you know, this clojurebot is much more awesome than tryclj.com

14:07 justin_smith: also, you can access clojurebot via /msg

14:07 krat0sprakhar: the repl there is quite buggy as anthony as longer working on it..

14:08 and boy is clojurebot fast!

14:08 justin_smith: Raynes has been far from the clojure fold

14:08 krat0sprakhar: why so

14:08 ?

14:08 justin_smith: he is doing other langs for work now

14:08 krat0sprakhar: haskell? i remember seeing a post on his blog

14:10 anyone with cursive got a clue what does the error msg - "no nREPL ack recieved mean"?

14:10 after that outofmemory error it doesnt seem to recover.. tried restarting intellij as well

14:10 justin_smith: either nrepl did not start, or it did not reply quickly enough

14:11 hmm, yeah out of memory - is that because your machine is low on memory, or maybe you could raise the limit above the default?

14:12 krat0sprakhar: hmm everythign else to be running fine

14:12 justin_smith: I think nrepl ends up in its own vm

14:13 TimMc: hyPiRion: I'm thinking of course of the Pokemon glitch that allowed a team to program tetris inside of pokemon just using controller inputs.

14:13 hyPiRion: oh, of course

14:13 krat0sprakhar: if i rm -rf target folder and run lein repl will that help?

14:13 cant do lein repl from the command line also

14:13 REPL server launch timed out

14:14 justin_smith: krat0sprakhar: OK, what about lein :trampoline repl

14:14 krat0sprakhar: trying..

14:14 justin_smith: (there are some other things we can try if that fails too)

14:14 krat0sprakhar: ':trampoline' is not a task.

14:14 hyPiRion: remove the colon

14:14 justin_smith: oh, oops, my bad

14:14 krat0sprakhar: sorry :P

14:15 justin_smith: no, it's my fault

14:15 hyPiRion: TimMc: did we get any way with #= ?

14:16 TimMc: If we can find a symbol form for first we can do stuff like

14:16 ,(#=(first #'+) -)

14:16 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

14:16 krat0sprakhar: justin_smith: got any more recommendations for some programming music like the clinton one? :D

14:16 hyPiRion: ahhh

14:17 ,(binding [*read-eval* true] (#=(first #'+) -))

14:17 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

14:17 hyPiRion: :(

14:17 krat0sprakhar: :D

14:17 justin_smith: krat0sprakhar: mostly meant that as a pun on "thunk" but now I am playlisting james brown / george clinton

14:17 krat0sprakhar: so did the trampoline repl help?

14:18 krat0sprakhar: fetching dependancies

14:18 not on a good connection.. sorry.. taking some time

14:18 shouldn't rm -rf target folder bring everything back to initial state?

14:18 TimMc: ,(alter-var-root #'clojure.core/*read-eval* (constantly true))

14:18 clojurebot: true

14:18 krat0sprakhar: (just guessing here)

14:18 TimMc: ,(#=(first #'+) -)

14:18 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

14:19 hyPiRion: ,(set! *read-eval*)

14:19 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Malformed assignment, expecting (set! target val), compiling:(NO_SOURCE_PATH:0:0)>

14:20 TimMc: It's bound in the scope of the reader, and our binding doesn't take effect until after reading.

14:21 justin_smith: krat0sprakhar: target just has your compiled output, not deps

14:21 krat0sprakhar: and lein should usually handle the compiled output smartly, most of the time

14:21 hyPiRion: ,(binding [*read-eval* true] (eval (read-string "#=(+ 1 2)")))

14:21 clojurebot: 3

14:21 hyPiRion: hurray

14:21 krat0sprakhar: ok.. is there any way i can set the project state back to the intial state?

14:22 i cant do lein repl only inside taht folder

14:22 its working everywhere else

14:22 TimMc: ,(alter-var-root #'clojure.core/read (constantly (let [r @#'read] #(binding [*read-eval* true] (apply r %&)))))

14:22 clojurebot: #<sandbox$eval233$fn__234 sandbox$eval233$fn__234@7061ce7d>

14:22 krat0sprakhar: trampoline still installing

14:22 TimMc: ,(#=(first #'+) -)

14:22 clojurebot: #<RuntimeException java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>

14:22 TimMc: ah well

14:23 justin_smith: krat0sprakhar: that makes me think the timeout from cursive's connect was because the downloads were happening in the background

14:23 hyPiRion: I think it's read-string

14:23 krat0sprakhar: i started the downloads

14:23 just now

14:23 justin_smith: krat0sprakhar: recall I said either it did not start, or did not reply in time

14:23 right

14:23 krat0sprakhar: the download doesnt happen everytime right?

14:23 just the first time the proejct is set up..

14:23 justin_smith: krat0sprakhar: but if it loaded them before, it wouldn't be happening this time

14:24 krat0sprakhar: right

14:24 so it had..

14:24 justin_smith: krat0sprakhar: the first time any of your projects uses a dep

14:24 krat0sprakhar: after i went crazy with iterate and reduce

14:24 it screwed up

14:24 TimMc: hyPiRion: #= requires literal symbols and only resolves the top level expression.

14:24 justin_smith: krat0sprakhar: going crazy with iterate and reduce should not be able to mess up your local dep repo state

14:25 TimMc: ,(binding [*read-eval* true] (eval (read-string "#=(class hi)")))

14:25 clojurebot: clojure.lang.Symbol

14:25 hyPiRion: yeah. So I was kind of hoping it could be used to something

14:25 krat0sprakhar: hehe.. apologies for rambling :D

14:25 my project has no external deps.. so lein repl should work

14:25 hyPiRion: ,(binding [*read-eval* true] (eval (read-string "(quote #=(first #'+))")))

14:25 krat0sprakhar: its working on all other projecs

14:25 clojurebot: var

14:25 krat0sprakhar: *projects

14:27 hyPiRion: ,(defn sharp-eval [s] (binding [*read-eval* true] (eval (read-string s))))

14:27 clojurebot: #'sandbox/sharp-eval

14:27 hyPiRion: ,(sharp-eval "(quote #=(first `[~@[]]))")

14:27 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: sharp-eval in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:27 hyPiRion: argh

14:27 TimMc: reset?

14:27 hyPiRion: well, that gives me apply

14:27 ,(defn sharp-eval [s] (binding [*read-eval* true] (eval (read-string s))))

14:27 clojurebot: #'sandbox/sharp-eval

14:27 hyPiRion: ,(sharp-eval "(quote #=(first `[~@[]]))")

14:27 clojurebot: clojure.core/apply

14:27 krat0sprakhar: ,(let [[a b c *xs] '( 1 2 3 4 5 6 7)] xs)

14:27 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: xs in this context, compiling:(NO_SOURCE_PATH:0:0)>

14:28 krat0sprakhar: why is this wrong?

14:28 ,(let [[a b c *xs] '( 1 2 3 4 5 6 7)] (+ a b c )

14:28 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

14:28 TimMc: hyPiRion: But you can get the ssymbol 'apply without #=.

14:28 krat0sprakhar: ,(let [[a b c *xs] '( 1 2 3 4 5 6 7)] (+ a b c ))

14:28 clojurebot: 6

14:28 hyPiRion: TimMc: Aw, righto. I thought it actually was the function :(

14:29 TimMc: krat0sprakhar: Because this isn't Python, if I read your intent correctly.

14:29 krat0sprakhar: hmm.. so how can I get the rest of the list ?

14:29 TimMc: krat0sprakhar: [a b c & xs]

14:30 krat0sprakhar: oh crap.. sorry!

14:31 justin_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:31 it works now.. thanks for the help

14:34 justin_smith: krat0sprakhar: ahh - yeah, in general side effects on the top level of a namespace are a bad idea

14:34 so of course it times out, because it wants to evaluate the namespace before giving you your prompt

14:34 lesson learned, we can hope

14:34 krat0sprakhar: time to finally give 132 a try :P

14:34 definitely :D

14:34 git checkout to the rescue

14:35 justin_smith: krat0sprakhar: 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:35 krat0sprakhar: got it!

14:41 justin_smith: all lazy-seq examples follow the pattern (cons x (lazy-seq ..))

14:41 can I do (conj (lazy-seq ..) a b)

14:41 instead?

14:41 justin_smith: krat0sprakhar: sure, but conj ends up doing cons on a lazy seq input

14:41 err... wait

14:41 no, use cons

14:41 because conj messes with the laziness

14:41 krat0sprakhar: but i want to add more than one elem into teh seq

14:42 (conj [] a b)

14:42 justin_smith: amalloy_ is better than me at explaining this stuff

14:42 krat0sprakhar: check out concat

14:42 ,(concat [:a :b] (lazy-seq))

14:42 clojurebot: (:a :b)

14:43 justin_smith: concat is alsy lazy

14:43 ,(type (concat [:a :b] (lazy-seq)))

14:43 clojurebot: clojure.lang.LazySeq

14:43 justin_smith: haha, alsy

14:43 krat0sprakhar: :D

14:44 ok.. let me give that a shot

14:59 justin_smith: got it! used mapcat to solve it :D

14:59 justin_smith: nice

15:00 krat0sprakhar: thanks a lot

15:16 auser: hello all… anyone here use figwheel/chestnut?

15:17 hellofunk: ~anyone

15:17 clojurebot: Just 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:18 krat0sprakhar: clojurebot _/\_

15:19 auser: Great… I’m trying out chestnut for the first time and am running into the message “nREPL: No response handler with id nil found “

15:19 Leaving me a bit stumped

15:20 dnolen: auser: you might want to ask in #clojurescript

15:20 auser: good idea dnolen

15:20 hellofunk: auser: i think there is an open issue for that on github, you might want to search there

15:20 dnolen: auser: it's a dedicated channel with helpful people

15:21 Lewix: yo

15:21 auser: good idea hellofunk + dnolen

15:21 krat0sprakhar: hola dnolen

15:21 always wanted to say hi :P

15:23 dnolen: krat0sprakhar: hello!

15:26 mmitchell: i'm using clojure.tools.logging + log4j2. Anyone know how to simply configure the log level at runtime?

15:26 in clojure/repl that is

15:27 justin_smith: mmitchell: clj-logging-config and timbre are two options for that

15:28 mmitchell: there may or may not be something simpler...

15:29 mmitchell: justin_smith: oh! I thought timbre was a pure clojure logging thing, with no support for log4j

15:35 justin_smith: mmitchell: yeah, timbre is a wrapper for java logging, the main thing is allowing runtime reconfig

15:37 mmitchell: justin_smith: perfect - will check it out now. Thanks!

15:38 amalloy: justin_smith: rather than (concat [a b] xs), (list* a b xs)

15:39 krat0sprakhar: amalloy: whats the difference?

15:40 amalloy: krat0sprakhar: well, they both do the same thing, but (concat [a b] xs) does it in a roundabout and slightly more expensive way

15:40 krat0sprakhar: oh ok.. thanks!

15:40 amalloy: (list* a b xs) is the same as (cons a (cons b xs)), which is the most obvious solution to your problem

15:40 krat0sprakhar: one more quick question - the common pattern for lazy-seq is (cons x (lazy-seq ...))

15:40 amalloy: using concat and a vector gets a lot more machinery involved

15:41 krat0sprakhar: can I do (conj (lazy-seq ..) a b )

15:41 ?

15:41 amalloy: you can, but don't

15:42 like, 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:42 justin_smith: krat0sprakhar: remember, I mentioned earlier that it isn't as lazy as it should be

15:42 krat0sprakhar: as lazy as it should be meaning?

15:42 isnt it either lazy or not lazy?

15:44 mmitchell: justin_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:45 justin_smith: mmitchell: I don't really know, I haven't tried that

15:45 mmitchell: ok np, thanks

15:45 justin_smith: krat0sprakhar: it can force results it shouldn't need to

15:46 krat0sprakhar: oh hmm.. i don't quite understand most of it. but i'll try to use the common pattern more often

16:26 cfleming_: krat0sprakhar: I haven't read the whole thread here, did you get your nREPL ack problem sorted?

16:29 justin_smith: cfleming_: he has an infinite loop at the top level of his main ns

16:29 which would kind of prevent an ack from coming back in time :)

16:29 cfleming: justin_smith: That would do it, yes :)

16:30 justin_smith: I was going to suggest increasing his timeout, but I don't think the field accepts +Infinity

16:30 justin_smith: heh

16:32 irctc: hey, does someone know how I can hide the 0, 1, 2 at the bottom of an Incanter boxplot?

16:32 cfleming: whomp: 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:32 irctc: http://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:33 llasram: {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:33 imanc_: are syntax quotes ` and normal quotes ' interchangeable?

16:34 irctc: I 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:34 llasram: {blake}: Ah, then no :-)

16:35 irctc: (Again, I'm trying to remove the 0,1,2 from charts like this http://incanter.org/images/examples/newtheme/box-gamma.png)

16:35 llasram: {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:35 irctc: Probably no one here right now uses incanter

16:35 irctc: llasram: oh ok

16:35 {blake}: llasram: So, refer has some additional capability, and use is just baggage.

16:35 llasram: {blake}: right

16:36 {blake}: llasram: Groovy. Thanks!

16:36 (inc llasram)

16:36 (inc has-been-less-meaningful-than-usual)

16:37 llasram: Alas, poor lazybot

16:37 {blake}: He's gotten REALLY lazy!

16:39 amalloy: man, lazybot has been getting disconnected like every day all week

16:39 he 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:42 amalloy: (inc llasram)

16:42 lazybot: ⇒ 48

16:43 {blake}: (inc lazybot)

16:43 lazybot: ⇒ 37

16:43 justin_smith: (inc Bronsa)

16:43 lazybot: ⇒ 90

16:44 amalloy: (inc inc inc)

16:44 lazybot: ⇒ 1

16:44 {blake}: (inc inc)

16:44 lazybot: ⇒ 12

16:44 amalloy: SNIPED

16:44 {blake}: damn

16:45 justin_smith: (identity inc inc)

16:45 lazybot: inc inc has karma 1.

16:47 {blake}: (inc Spaces are no barrier to karma.)

16:47 lazybot: ⇒ 1

16:47 {blake}: (identity Spaces are no barrier to karma.)

16:47 lazybot: Spaces are no barrier to karma. has karma 1.

16:47 SagiCZ: lol

16:57 ordnungswidrig: (identity 1 karma)

16:57 lazybot: 1 karma has karma 0.

16:57 ordnungswidrig: (identity 1 karma)

16:57 lazybot: 1 karma has karma 0.

16:57 ordnungswidrig: (inc 1 karma)

16:57 lazybot: ⇒ 1

16:57 ordnungswidrig: (identity 1 karma)

16:57 lazybot: 1 karma has karma 1.

16:58 * ordnungswidrig loves symmetrie

17:06 justin_smith: (inc ordnunswidrig symmetrischennehcsirtemmys giridiwsnundro nci)

17:06 lazybot: ⇒ 1

17:06 jballanc: hey! lazybot's back

17:07 sobel: i assumed german but had to check whether symmetrie wasn't also a clojure lib ;)

17:08 justin_smith: haha

17:08 jballanc: hmm...

17:08 (inc 1 amrak sah)

17:08 lazybot: ⇒ 1

17:09 jballanc: (identity 1 amrak sah)

17:09 lazybot: 1 amrak sah has karma 1.

17:09 jballanc: better

17:18 whomp: how 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:18 SagiCZ: whomp: depends on what you mean by "litte window"

17:18 if you are running REPL it should print out to the repl output

17:18 whomp: SagiCZ, the window that pops up when i hit "run"

17:19 SagiCZ: that should work too.. it has to be the Console window

17:19 whomp: SagiCZ, 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:19 imanc_: ,(take 10 (iterate inc 1))

17:19 whomp: Process finished with exit code 0

17:19 oh man, sorry guys :)

17:19 clojurebot: (1 2 3 4 5 ...)

17:19 bodie_: anyone using IDEA Cursive?

17:19 SagiCZ: whomp: well then your code is wrong or you are executing a different file then you want to

17:19 bodie_: yeas

17:20 *yes

17:20 imanc_: bodie_: trying to - still need to work on it.

17:20 SagiCZ: i have been using it for months.. its amazing

17:20 bodie_: nice

17:20 imanc_: i hear the debugger rocks

17:21 bodie_: IDEA 14 isn't letting me update or install it, not sure why

17:21 SagiCZ: imanc_: its ok but i debug clojure much less than java

17:21 bodie_: you have to specify new plugin repository acording to the guide

17:22 bodie_: I probably shouldn't be asking nooby questions like this in here ;P

17:22 SagiCZ: bodie_: this is totally the place for noob question.. as long as tbaldridge isnt around

17:22 bodie_: but the plugin install button does nothing after I add the repo... just wondered if anyone else had had that issue

17:22 SagiCZ, usually I keep my noob questions to overly convoluted ways to do simple things that functions or macros are already defined for

17:23 sobel: SagiCZ: would you say you debug less clojure because your clojure code is less error prone?

17:23 mfikes: bodie_: 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:24 SagiCZ: sobel: 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:24 sobel: SagiCZ: gotcha

17:25 bodie_: mfikes, thanks. exactly what I needed to know. I'll give the archive version a shot

17:27 SagiCZ: sobel: 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:30 tehgeekmeister: i'm running into some really weird issues with some io redirection using future and io/copy

17:31 have two instances of basically this running in parallel: (future (clojure.java.io/copy (:err results) *out* :buffer-size 1))

17:31 ending up with output like this on *some* lines eetcchhoe d 'Fetched mmoodduulleess..'

17:31 but then it goes back to normal

17:31 also, it truncates the output mid line after a certain point

17:31 so, seems like race conditions plus timeouts, probably

17:31 anyone have insight that could help?

17:37 cfleming: mfikes: Ugh, no, I got distracted.

17:37 gfredericks: Hypirion: who is "a friend of Gary Fredericks"?

17:37 cfleming: bodie_: Try downloading and manually installing, see https://cursiveclojure.com/userguide/ under Manually installing

17:38 hyPiRion: gfredericks: There was some Clojure meetup you attended, where you said someone came up with (->> foo #())

17:38 cfleming: bodie_: Sorry for the hassle, for some reason the initial install is difficult sometimes.

17:40 sdegutis: tbaldrid_: what's your language called again?

17:40 cfleming: sdegutis: Pixie

17:40 sdegutis: Cool, thanks.

17:41 ibash: Going to leave this question here while I grab a coffee

17:41 what 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:41 ibash: Any good examples of medium size public clojure apps I can explore?

17:41 sdegutis: ibash: it's basically good for anything you'd use Java or Ruby for

17:42 ibash: 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:42 sdegutis: ibash: but some of us use it in place of Rails

17:43 hiredman_: {blake}: they are not

17:43 ,#(#"/bword/b")

17:43 clojurebot: #<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 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:47 amalloy: {blake}: ##(doc re-pattern)

17:47 lazybot: ⇒ "([s]); Returns an instance of java.util.regex.Pattern, for use, e.g. in re-matcher."

17:47 whomp: intellij cursive won't let me type out parentheses when it thinks there's an incorrect arity issue. how can i avoid this?

17:47 amalloy: &(re-pattern (str "a" "b"))

17:47 lazybot: ⇒ #"ab"

17:47 {blake}: whomp: Turn off structural editing.

17:48 amalloy: Seems like a lot for a single "find this word in a string" issue.

17:48 amalloy: well, 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:49 gfredericks: hyPiRion: I'm convinced you're making this up, but hey who knows

17:49 amalloy: it'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:50 hyPiRion: {blake}: ##(.matches "foooo" "^fo*$")

17:50 lazybot: ⇒ true

17:50 {blake}: ##(.matches "anteater,aardvark,antelop" "/bant/b")

17:50 lazybot: ⇒ false

17:50 {blake}: ##(.matches "anteater,aardvark,antelop" "/bantelope/b")

17:50 lazybot: ⇒ false

17:50 {blake}: :-/

17:51 ##(.matches "anteater,aardvark,antelope" "/bantelope/b")

17:51 lazybot: ⇒ false

17:51 {blake}: ##(.matches "anteater,aardvark,antelope" "ant")

17:51 lazybot: ⇒ false

17:51 amalloy: matches expects an exact match

17:51 {blake}: ##(.matches "anteater,aardvark,antelope" "antelope")

17:51 lazybot: ⇒ false

17:52 hyPiRion: gfredericks: 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 ##(.contains "anteater,aardvark,antelope" "antelope")

17:52 lazybot: ⇒ true

17:52 {blake}: ##(.contains "anteater,aardvark,antelope" "ant")

17:52 lazybot: ⇒ true

17:52 {blake}: so close

17:52 hyPiRion: {blake}: I thought you meant begin and end of string boundaries, soz.

17:52 amalloy: really like, clojure's regex facilities are really nice, you have re-seq and whatever

17:53 gfredericks: ~you |have| re-seq and whatever

17:53 clojurebot: In Ordnung

17:53 amalloy: and you're spending a bunch of effort because (re-pattern a b) is unacceptable compared to your desired notation of #(str a b)

17:53 re-pattern is just The Way To Do It

17:56 {blake}: ,(re-find (re-pattern (str "\\b" "antelope" "\\b")) "aardvark,anteater,antelope")

17:56 clojurebot: "antelope"

17:56 {blake}: Good enough.

17:56 (inc re-pattern)

17:56 lazybot: ⇒ 1

17:57 amalloy: {blake}: note that if you tire of double-escaping, you can use (str #"\b" "antelope" #"\b")

17:57 since 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 Reader macros are the theme of the day.

18:00 ibash: sdegutis: tell me more about using it for large streaming data

18:00 we have some streams right now using node.js and highland

18:00 they’re okay — but they’re may come a time where we rebuild our data import pipeline

18:01 sdegutis: ibash: gtg

18:01 sorry

18:04 cfleming: whomp: The arity issue doesn't affect parens, that's structural editing (paredit), see: https://cursiveclojure.com/userguide/paredit.html

18:05 whomp: cfleming {blake}, ty :)

18:09 tehgeekmeister: do futures timeout?

18:10 like, if nothing's happening in the thread, does it just get killed?

18:10 will the main thread only wait so long?

18:10 amalloy: what do you mean, nothing is happening?

18:10 tehgeekmeister: that is a good question! my thinking was unclear there.

18:13 say i (future (something)), and then there's nothing else in the program

18:13 does the parent thread wait on that thread until it finishes executing, or what?

18:14 amalloy: the jvm shuts down when there are no more threads running (actually no non-daemon threads, but that's not really relevant here)

18:14 whomp: how do i reference the current function i'm in from within it? i want to make a recursive call

18:15 amalloy: whomp: http://stackoverflow.com/q/5626641/625403

18:15 tehgeekmeister: 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:15 whomp: amalloy, ty

18:16 tehgeekmeister: yeah, i'm kinda at a dead end here unless i run this on linux and strace this

18:17 not 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:17 when the buffer size is smaller than the size of the string

18:19 hiredman_: tehgeekmeister: I think you mentioned running two threads?

18:19 tehgeekmeister: three, yeah

18:19 hiredman_: is one of them closing *out* ?

18:19 tehgeekmeister: main, copier for stdout, and copier for stderr

18:19 good point!

18:19 the main one might

18:19 so i should wait for those threads

18:20 i'll try

18:20 hiredman_: just never close *out*

18:20 tehgeekmeister: it's not explicitly doing so

18:20 so unless it happens implicitly, it's not happening

18:20 hiredman_: ok, that is what I meant

18:22 TimMc: hyPiRion, 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:24 hyPiRion: hrm, perhaps I'm mixing you two up. It's been some time since it happened.

18:38 tehgeekmeister: so, based on the syscalls it's making, it seems like it's doing a nonblocking check of a thread's status

18:38 and then checking if a a time's been hit

18:39 lots of lines like this: 67796/0x41532c: psynch_cvwait(0x7F863BF25668, 0x100000100, 0x0) = -1 Err#316

18:39 67796/0x41532c: gettimeofday(0x1279BFC90, 0x0, 0x0) = 1423092974 0

18:39 Anyone have some clues based on that?

18:43 hiredman_: just to be clear, you meant i'm good if i don't explicitly close it, right?

18:44 amalloy: tehgeekmeister: 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:44 tehgeekmeister: amalloy: might be. i'm better at that approach. i'll give the alternate one a try.

18:44 thanks for calling it out.

18:44 pdlug_: 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:45 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:49 justin_smith: pdlug_: what do you mean by leave out nil values? - is it a function that doesn't handle nil?

18:49 or are you just looking to remove nils from the map?

18:50 pdlug_: More for cleaner output, so, optional assoc

18:50 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:51 gist I posted above leaves them in if nil, but also just doesn't "look right"

18:51 tehgeekmeister: amalloy: any preferred paste mechanism here?

18:51 i have a repro case that's small

18:51 amalloy: ~paste

18:51 clojurebot: paste is https://refheap.com/

18:52 justin_smith: you 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:52 tehgeekmeister: it has an ssl warning right now?

18:52 nbd for what i'm posting, but not awesome

18:52 amalloy: oh, interseting. that's new

18:52 justin_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:52 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

18:52 amalloy: Raynes: refheap's ssl cert is expired

18:52 justin_smith: err

18:52 ,(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:52 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: map-kv in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:53 tehgeekmeister: https://www.refheap.com/96919 <== this stops early

18:53 and then hangs

18:53 for me it stopped at zygot

18:53 amalloy: oh, interesting. www.refheap.com is fine, but refheap.com isn't. good to know

18:53 justin_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:53 clojurebot: {:a 0, :c 1, :e 2}

18:53 justin_smith: pdlug_: ^

18:53 tehgeekmeister: notably, when i interrupted it, it flushed all the rest of the stream

18:53 amalloy: why are you setting the buffer size at all, tehgeekmeister?

18:54 10 seems ludicrously small

18:54 tehgeekmeister: 1024 was chunking weirdly

18:54 i really want line buffering

18:54 but i'm trying to get this part done quickly

18:54 amalloy: well you have two different threads writing to the same output stream at the same time

18:54 tehgeekmeister: this is redirecting the real time output of a shell command, so partial lines are painful

18:54 yep, i know

18:54 amalloy: you are gonna get crappy-looking interleaved output regardless of buffer size

18:55 tehgeekmeister: the interleaving i can deal with for the moment

18:55 pdlug_: 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:55 tehgeekmeister: i could also live with the delay, i guess, too

18:55 i'm probably off track. this was a nice to have addition i started on at like 7 last night. =P

18:56 justin_smith: pdlug_: yeah, that would work too

18:56 amalloy: delay? i don't really understand; you said it was blocking indefinitely, i thought

18:56 tehgeekmeister: well, if there's say 1050 lines of output

18:56 and then a big pause

18:56 err, bytes, sorry

18:57 then the 26 bytes (assuming the default 1024 buffer) at the beginning of the buffer could take a long time to get through

18:58 would 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:58 justin_smith: tehgeekmeister: sounds like you need to go into host interop land and control the mode of the pipe or something

18:58 tehgeekmeister: justin_smith: can you provide a bit more context about why you think that?

18:58 amalloy: mmm, 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:59 tehgeekmeister: i'm moving a crappy shell script to clojure, bit by bit

18:59 core goal is to have a good wrapper for packer based build processes

18:59 so, yeah, this is complicated, i agree

19:00 justin_smith: tehgeekmeister: 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:00 tehgeekmeister: but 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:00 justin_smith: didn't know line buffering was an os level option. you mean stdlib or syscall?

19:01 i can assume nix, this will only run on osx/linux (at least in the near term, for my company)

19:01 justin_smith: tehgeekmeister: http://www.pixelbeat.org/programming/stdio_buffering/

19:01 this looks like a decent intro ^

19:01 tehgeekmeister: thanks!

19:02 so, looks like setting buffer size to 0 doesn't do anything special.

19:02 yay no special values!

19:03 justin_smith: tehgeekmeister: the c syscall in question is setbuf http://man7.org/linux/man-pages/man3/setbuf.3.html

19:03 tehgeekmeister: awesome! i had not heard of that one.

19:03 also the guide you sent won't load, but the man page will

19:04 justin_smith: heh, OK

19:04 tehgeekmeister: yeah, worth noting that conch returns a buffered stream

19:04 justin_smith: tehgeekmeister: oh, I was just reminded from that man page "stderr is always unbuffered by default"

19:04 tehgeekmeister: so there are multiple layers here

19:04 justin_smith: tehgeekmeister: oh, is this Process streams?

19:05 tehgeekmeister: yeah, i'm using the conch library

19:05 justin_smith: java.io.Process has options, including "join stout and stderr into one stream" if conch doesn't allow access to that, ditch conch

19:05 err, not io.Process

19:05 lang.Process

19:05 tehgeekmeister: yeah, ideally i'd like to keep them separate for semantics, but i still want to print them joined right

19:05 justin_smith: ahh

19:05 that's trickier

19:06 tehgeekmeister: but for short term, i can be lenient about that

19:06 time to finally really read the conch docs in depth, i guess

19:06 amalloy: me.raynes.conch.low-level/proc gives you direct access to gives you access to the ProcessBuilder constructor directly

19:06 wei: lein uberjar is trying to run my app instead of just compiling it. any ideas on how to troubleshoot this?

19:06 amalloy: and has a :redirect-err option

19:06 justin_smith: wei: don't do anything with side effects at the top level of your ns

19:06 wei: that's always the reason

19:07 wei: if you can't run your ns file without running your app, redesign your ns

19:07 tehgeekmeister: yeah, i'm using low-level too

19:07 hiredman_: 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:07 amalloy: it looks like me.raynes.conch/run-command accepts :redirect-err as well

19:07 justin_smith: amalloy: cool

19:07 clojurebot: Titim gan éirí ort.

19:07 hiredman_: wei: you should put things in functions, and then call those functions from your main function

19:08 tehgeekmeister: wait, i can provide it an output it looks like

19:08 crap

19:08 that's a lot simpler

19:08 i can just have it forward directly on to the parent streams

19:08 * tehgeekmeister shakes head

19:09 amalloy: clojurebot: conch is pretty cool in general

19:09 clojurebot: You don't have to tell me twice.

19:10 hiredman_: clojurebot: conch |does| stream fusion

19:10 clojurebot: Roger.

19:10 wei: hiredman_ , justin_smith: I don’t appear to have any side-effect code, but guess I need to digging around to do

19:10 does defining a handler count as a side effect?

19:11 amalloy: wei: you probably do something like (def app (run-jetty ...))

19:11 hiredman_: wei: are you starting jetty in a top level form?

19:11 tehgeekmeister: actually, i misread

19:11 wei: http-kit, and I’m starting it from a -main function

19:11 tehgeekmeister: but i'm on a good path now

19:11 thanks so much everyone

19:12 hiredman_: what do you mean by running your app then?

19:12 wei: when I try to build a jar, it’s initiating a postgres connection and failing to find the database

19:13 hiredman_: are you using korma?

19:13 wei: no

19:13 hiredman_: the stacktrace should tell you the file and line where the connection is happening

19:14 maybe you are configuring a connection pool or something

19:15 tehgeekmeister: ah, but ProcessBuilder *does* support setting a file for each of stdout and stderr, and redirecting stderr to stdout

19:15 how easy would it be for me to run a fork of conch while I work on getting an improvement like that merged in?

19:15 I don't know leiningen well yet.

19:17 wei: hiredman_: at xb.helpers$loading__4958__auto__.invoke(helpers.clj:1)

19:17 does this mean I have side-effect code that’s running as it’s loading the namespace? the line number isn’t helping, unfortunately

19:17 hiredman_: wei: :/ some file helpers.clj is loading is doing it

19:18 amalloy: wei: that's not a stacktrace, it's one line of a stacktrace

19:18 hiredman_: 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:19 wei: the rest of the stacktrace isn’t from my app: https://gist.github.com/yayitswei/e8fc479fc414157d9199

19:20 hiredman_: wei: I would change the ns form in helpers.clj to include :load-verbosely (a flag on :require, if I recall)

19:21 it will print out every file it loads, the last one printed before the error should be the problem

19:21 amalloy: resources.clj:23

19:21 is where the database call is

19:22 tehgeekmeister: is the lein-git-deps plugin pretty commonly used, or a bad practice, or what?

19:22 justin_smith: probably a top level def of the db connection or something

19:22 tehgeekmeister: i see it hasn't been updated in a long time

19:22 amalloy: tehgeekmeister: don't use it

19:22 hiredman_: I guess the ns thing got fixed?

19:22 tehgeekmeister: amalloy: should i just make changes locally and install locally?

19:23 justin_smith: tehgeekmeister: you can use lein checkouts, or you can clone / lein install locally

19:23 lein checkouts start with a clone + lein install step :)

19:23 tehgeekmeister: i'll look into that, thanks

19:23 amalloy: if 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:23 and using checkouts simplifies the install-locally process

19:23 justin_smith: shouldn't need to install

19:24 justin_smith: amalloy: checkouts don't work unless you run lein install first

19:24 amalloy: or so I heard

19:24 unless maybe you already have an artifact with that version string maybe

19:24 amalloy: right

19:24 and 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:25 tehgeekmeister: yeah, my intent would totally be to get it merged back in

19:25 justin_smith: indeed, but I find habits like that can lead to terrible bugs and confusion :)

19:25 tehgeekmeister: just trying to figure out how to point to a fork in the mean time

19:25 justin_smith: or maybe I am too scatterbrained for such schemes and others can handle it

19:25 tehgeekmeister: justin_smith: nah, i think you're right, such approaches are scary

19:26 justin_smith: when my local artifact of a given group / version / project is not the global one, and I forget that fact...

19:26 so I tend to defensively alter versions right off the bat

19:29 tehgeekmeister: looks like checkouts work for development

19:29 not for deploy

19:29 well, not cleanly for deploy

19:29 i guess a fork on clojars is the cleanest answer for until a pull is merged

19:29 aight

19:30 justin_smith: tehgeekmeister: you can deploy, a checkout is just a symlink to the real project dir

19:30 tehgeekmeister: on the project dir side, it has no way to know it is even a checkout

19:30 (since symlinks are one way)

19:30 tehgeekmeister: i may not understand the deploy process well enough to know how that works out

19:30 in fact, i certainly don't

19:31 lots to learn right now

19:31 justin_smith: tehgeekmeister: if you are in the dir of the checked out project, you are no longer strictly in a subdir of the other project

19:31 tehgeekmeister: yes, i mean if i want to package up this whole thing

19:31 and use it on a server

19:31 in production

19:31 justin_smith: tehgeekmeister: then yeah, you deploy each checkout as a separate project

19:31 tehgeekmeister: i see

19:31 justin_smith: tehgeekmeister: or make an uberjar of the top level one

19:31 tehgeekmeister: k

19:32 cool

19:32 this is a good enough path

19:32 justin_smith: tehgeekmeister: unless you need the libs to be published...

19:32 the uberjar will pull in the stuff from the subdirs

19:32 tehgeekmeister: it'll be published later

19:32 for now, just working is sufficient

19:33 wei: found 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:34 justin_smith: wei: was it creating a db connection as a top level def?

19:40 wei: justin_smith: I was preloading some system accounts into a map. forgot about that :P

19:40 justin_smith: aha, that would do it

19:40 wei: my solution was just to wrap it in delay

19:40 justin_smith: wei: and easy fix for that is a delay

19:40 haha

19:41 wei: at some point i want to check out the component framework, but it looks heavyweight for my needs at the moment

19:57 julianleviston: I 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:57 hiredman_: apply is not a fold

19:58 julianleviston: hiredman_: but are they sematically equivalent?

19:58 wei: is there any way to get the current stacktrace without throwing an error?

19:58 amalloy: julianleviston: they are totally different; for some functions, such as +, they happen to do the same thing

19:58 hiredman_: julianleviston: no reduce is a fold

19:58 amalloy: http://stackoverflow.com/q/3153396/625403

19:58 tehgeekmeister: how do i require part of a library from lein repl inside that library, when I'm editing it?

19:58 hiredman_: ,(reduce cons nil (range 10))

19:58 julianleviston: hiredman_: could you rephrase that?

19:58 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long>

19:58 tehgeekmeister: can't get this to work in general

19:58 sometimes by luck

19:58 but not in general

19:58 hiredman_: ,(reduce conj nil (range 10))

19:58 clojurebot: (9 8 7 6 5 ...)

19:58 hiredman_: blarge

19:58 ,(apply conj nil (range 10))

19:58 clojurebot: (9 8 7 6 5 ...)

19:58 hiredman_: damn it clojure

19:59 amalloy: *chuckle*

19:59 hiredman_: ,(reduce (fn [a b] (cons b a)) nil (range 10))

19:59 clojurebot: (9 8 7 6 5 ...)

19:59 hiredman_: ,(apply (fn [a b] (cons b a)) nil (range 10))

19:59 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (11) passed to: sandbox/eval123/fn--124>

19:59 julianleviston: amalloy: thanks… I’m just trying to work out if I can change my apply to a reduce….

20:00 hiredman_: apply applies a function to a list of arguments, reduce folds a function over an accumulator and each value from a collection

20:00 julianleviston: I have this: (apply merge-with (partial merge-with min) (map some-function somecoll) someothercoll)

20:00 amalloy: julianleviston: if you have an apply that's working, there's no reason to change it to a reduce

20:01 julianleviston: (with some more parens on the end ;-))

20:01 amolloy well I have a feeling it’s slowing things by consuming too much stack space

20:01 amalloy: julianleviston: your feeling is nonsense

20:01 don't worry about that

20:01 julianleviston: amalloy: oh ok good :)

20:02 amalloy: 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:02 and the apply doesn’t feel right to me.

20:04 amalloy: (apply merge-with m ms) is a pretty common thing

20:04 i expect it's implemented as a reduce under the hood, so the difference really is just a single function call

20:04 julianleviston: amalloy: cool beans :)

20:05 amalloy: merge is, yeah.

20:05 (when (some identity maps) (reduce1 #(conj (or %1 {}) %2) maps))

20:29 justin_smith: julianleviston: ##((fnil conj {}) nil {:a 0})

20:29 lazybot: ⇒ {:a 0}

20:34 julianleviston: justin_smith: what does ## do?

20:35 gfredericks: it triggers ##'lazybot

20:35 lazybot: ⇒ lazybot

20:36 julianleviston: ah… inline lazybot! huzzah :)

20:36 gfredericks: ###'first

20:36 lazybot: ⇒ #'clojure.core/first

20:36 julianleviston: I wonder if it’s ##’just for this form or the rest of the sentence?

20:36 (sigh curly quotes)

20:36 gfredericks: haha

20:38 julianleviston: stupid mac. Apparently I don’t have control over that in this IRC client. LOL fail.

20:38 oh well

20:39 i wonder if ##`it is one form only

20:39 lazybot: ⇒ clojure.core/it

20:39 julianleviston: ok cool.

20:39 gfredericks: ,(read-string "hey okay")

20:39 clojurebot: hey

20:40 julianleviston: justin_smith: how come you were telling me that form?

20:40 dah: brew install irssi # ;)

20:54 julianleviston: is this a terrible way to result in a vector of items none of which are nil? (filter (complement nil?) (flatten [(association-kwd item)]))

20:55 should I just be using (remove nil? (concat … or something?

20:55 ticking: remove nil? would probablu be more idiomatic

20:55 amalloy: i don't understand the goal, but that is a terrible way to do it, yeah

20:55 association-kwd returns...what? a seq of things?

20:56 julianleviston: amalloy: (association-kwd item) returns a coll of integers.

20:56 tehgeekmeister: if i'm in a scope where I can reference ProcessBuilder directly, how do I refer to ProcessBuilder.Redirect (a nested class) in clojure?

20:56 amalloy: import ProcessBuilder$Redirect

20:56 ticking: julianleviston: then why would you flatten it?

20:56 tehgeekmeister: amalloy: have to import, can't just reference it directly somehow?

20:56 I only need it in one place

20:57 amalloy: tehgeekmeister: sure, you can. foo.bar.whatever.ProcessBuilder$Redirect

20:57 it's just an ordinary class with a funny-looking name

20:57 tehgeekmeister: cool, thanks!

20:57 amalloy: yeah, it sounds like you just want (remove nil? (association-kwd ...))

20:57 julianleviston: ticking: good question… it might also return a single integer sorry

20:57 ticking: julianleviston: so it might return a single integer or a collection?

20:57 julianleviston: ticking: association-kwd can return an int, or a vec of ints.

20:57 ticking: apologies, yes.

20:57 ticking: julianleviston: did you write it?

20:58 julianleviston: ticking: sadly, yes. :)

20:58 amalloy: julianleviston: change it to always return a vec of ints

20:58 it's pretty gross to return one or the other, because it makes the client code do stupid stuff, as you're now discovering

20:58 ticking: yeah I would agree with amalloy on that

20:58 julianleviston: amalloy: erm… it’s not one thing, tho...

20:58 ticking: julianleviston: how so?

20:58 julianleviston: amalloy: association-kwd might be “block_id” or it might be “block_ids"

20:59 ticking: it’s looking up data in a map… some of which is has-many, some of which is belongs-to relationship data

21:00 amalloy: so…. belongs-to [5] wouldn’t make sense.

21:00 ticking: julianleviston: how is that determinded?

21:00 julianleviston: ticking: I don’t follow, sorry…

21:00 ticking: wether or not it is block-id or block-ids?

21:01 julianleviston: it’s depetrmined by the nature of the relationship of other data to that map.

21:01 ticking: like?

21:01 julianleviston: this fn maps over all the relevant relationship association data and gets it.

21:01 and collects it into a single seq

21:01 and then goes off and calls an API requesting it

21:02 {:a_id 5 :b_ids [10 9 8] :c_id nil} … run fn on it… -> [5 10 9 8]

21:03 ticking: is the first thing really a map?

21:03 because it has duplicate keys

21:04 ah no sorry

21:04 julianleviston: ticking: huh?

21:04 ticking: I misread

21:04 julianleviston: k

21:04 ticking: how is that map generated?

21:04 tehgeekmeister: is there a way to get at the underlying files behind *out* etc?

21:04 julianleviston: ticking: I don’t know how that’s relevant

21:04 tehgeekmeister: turns out they're PrintWriters

21:04 I need a file subclass

21:04 and PrintWriter doesn't let you get the file it's attached to

21:05 ticking: julianleviston: I'm trying to figure out it you can fix this abomination of a datastructure ;P

21:05 tehgeekmeister: oh, i bet java can do this

21:06 julianleviston: ticking: i’m not too sure the data structure is the problem ;-)

21:06 amalloy: tehgeekmeister: they might not be attached to a file at all

21:06 ticking: julianleviston: (remove nil? (flatten (keys that-horrible-list-thing))) is how I would do it when I couldn't change the data

21:06 amalloy: printwriters in general, that is

21:06 tehgeekmeister: yeah, seems like System.out is a stream, it looks like

21:06 julianleviston: ticking: I just want a function that will take a collection, or item… and filter out nils and always return a collection.

21:07 ticking: which is what I have.

21:07 tehgeekmeister: Basically, there is no easy and great way to do this, it seems. But there are acceptable ways, at least.

21:07 ticking: ,(remove nil? (flatten (keys {:a_id 5 :b_ids [10 9 8] :c_id nil})))

21:07 clojurebot: (:c_id :b_ids :a_id)

21:07 ticking: ,(remove nil? (flatten (vals {:a_id 5 :b_ids [10 9 8] :c_id nil})))

21:07 julianleviston: ticking: 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:07 clojurebot: (10 9 8 5)

21:08 ticking: julianleviston: yeah exactly

21:08 julianleviston: I'd fix that

21:08 julianleviston: ticking: yeah, I already have code that works… I just wanted to know if there was a better way to do it…

21:08 ticking: which is impossible to fix. :P

21:08 ticking: julianleviston: yeah fix that map and make it always return vectors

21:08 julianleviston: ticking: its very nature is that I’m trying to collate a disparate set of data.

21:08 ticking: but vectors make no sense for some keys.

21:09 ticking: it’s like this: {:cat-names [“fred”] :eye-color “blue”} … now… I want a coll of cat names and their eye colours...

21:10 ticking: “Just change eye colour so it’s a collection”

21:10 ticking: see what I mean?

21:10 ticking: julianleviston: 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:11 julianleviston: as you want them in a single collection afterwards they are obviously the samee thing

21:11 julianleviston: ticking: 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:11 ticking: because a seq of ("fred" blue) makes no sense

21:11 julianleviston: ticking: THIS function is the exception, not the other way round. :)

21:12 ticking: julianleviston: still looks broken to me though

21:13 julianleviston: ticking: 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:14 the only thing with this fn is, I can’t work out why it’s taking so long.

21:15 430 ms in some invocations in cljs for a few hundred items.

21:17 ticking: thanks for your attention, tho.

21:18 ticking: is association-kwd a keyword or a fn?

21:18 performance prblem could be in there

21:19 julianleviston: it’s a keyword

21:19 ticking: flatten is not the fastest fn though

21:20 is 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:20 julianleviston: I’m doing (apply (merge-with (partial merge-with min) (map (reduce (….))))

21:20 ticking: that looks expensive

21:20 julianleviston: ticking: yeah!

21:21 ticking: how does (apply (merge-with (partial merge-with min) (map (reduce (….)))) and (complement nil?) (flatten [(association-kwd item)])) interplay?

21:21 julianleviston: ticking: 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:22 ticking: the latter is inside the inner reduce

21:22 ticking: so the entire code is

21:22 (apply (merge-with (partial merge-with min) (map (reduce (filter (complement nil?) (flatten [(association-kwd item)]))))))?

21:22 julianleviston: ticking: erm… I can’t paste it here coz it’s too big. It has a 10 line let block inside it (…)

21:23 tehgeekmeister: found the potential answer to my questions here! https://clojuredocs.org/clojure.core/future

21:23 ticking: julianleviston: tbh this sounds horribly broken

21:23 julianleviston: ticking: 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:24 ticking: julianleviston: can you post the code in a gist

21:24 julianleviston: or describe what you're trying to achieve

21:24 julianleviston: the data that goes in and the data that's supposed to come out is probably the most helpfull

21:25 julianleviston: ticking: yeah, the context… the only thing is it’s quite varied and complex but I’ll post the code in a bin

21:25 ticking: here y’are: https://gist.github.com/JulianLeviston/f5d26f6ec4a3c4813131

21:26 whomp: can i give a transient a starting capacity, so that it doesn't have to keep growing?

21:26 julianleviston: ticking: i’ll try to get you some data for it, too...

21:27 amalloy: whomp: no, just trust in the holy wisdom of rich that transients will perform well

21:27 ticking: whomp: I don't thin so, a transient should still be a trie that just gets updated in place

21:27 julianleviston: ticking: actually, it’s too hard because there are two or three chunks of data I’d have to post…

21:27 ticking: I realise that’s no help…

21:29 whomp: thx guys, sorry rich

21:29 julianleviston: ticking: 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:29 ticking: julianleviston: can there both be an :id and :ids at the same time?

21:29 julianleviston: ticking: depending on where you mean… yes.

21:29 ticking: and no.

21:30 association-kwd will only be gathering either an id or a coll of ids. Never both.

21:30 ticking: I was thinking always doing (conj (:id item) (:ids item))

21:31 julianleviston: ticking: conj takes a coll first doesn’t it?

21:31 ticking: hm.

21:31 ,(conj 1 [500])

21:31 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IPersistentCollection>

21:31 julianleviston: ,(conj [500] 1)

21:31 clojurebot: [500 1]

21:31 ticking: uh yeah sorry

21:31 clojurebot: Huh?

21:31 julianleviston: ticking: that’s a bit disturbing.

21:32 ticking: sorry it's 3:30 am over here

21:32 julianleviston: ticking: all good.

21:37 ticking: julianleviston: (or coll {}) is not needed btw

21:38 ,(assoc (or nil {}) :a 1)

21:38 clojurebot: {:a 1}

21:38 ticking: ,(assoc nil :a 1)

21:38 clojurebot: {:a 1}

21:38 julianleviston: ticking: nice. Thanks.

21:41 ticking: julianleviston: what does calculate depth do?

21:41 sdegutis: Are there any plans to separate the ClojureScript compiler from the JVM?

21:41 julianleviston: ticking: 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:41 ticking: julianleviston: you could probably put the mergin into the reduce step

21:42 julianleviston: ticking: 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:43 ticking: by reducing the ints.. until they get to 0.

21:43 ticking: julianleviston: the main problem seems to be many iterations, so I'd try to do as much of that in a tight loop

21:43 julianleviston: hrm

21:43 julianleviston: It's really hard to visualize what it all does

21:44 julianleviston: ticking: I know, isn’t it! :)

21:44 ticking: it’s hard enough even for me, with the data...

21:44 ticking: it seems overcomplicated though :/

21:44 julianleviston: ticking: it took me about 30 mins to write that function.

21:44 ticking: I agree

21:45 ticking: it doesn't have to be that complicated though

21:45 for example calculate-depth returns a tuple as it seems

21:45 justin_smith: oh, 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:45 lazybot: ⇒ {:e 2, :g 3, :c 1, :a 0}

21:46 julianleviston: ticking: actually, calculate-depth returns a map

21:46 ticking: julianleviston: does it have side effects? it looks like it doesn't really return a depth

21:47 julianleviston: but that would do (assoc coll {:foo :bar})

21:48 justin_smith: conj would make sense there, or merge

21:50 julianleviston: ticking: haha sorry… yeah, calculate-depth returns a seq of ids interleaved with depth ints

21:51 ticking: so… (103 5 203 5 999 2) etc

21:51 ticking: ah

21:51 julianleviston: ticking: it looks like I need to pull it apart and simplify it, I think…

21:51 ticking: julianleviston: returning a map would make more sense

21:51 julianleviston: ticking: if I can’t even reason about it myself easily, something’s wrong, huh.

21:52 ticking: then you could do (update-in coll [item-model-coll-kwd] merge (calculate-depth foo))

21:52 julianleviston: ticking: even though I’m calling (apply assoc coll return-value-from-calculate-depth) ?

21:52 ticking: oh neat.

21:53 ticking: will behave slightly different though when overriding keys

21:54 the above will actually keep existing keys instead of overriding them

21:56 dweave: how do i eval with clojurebot

21:56 julianleviston: ticking: shouldn’t I use conj then?

21:57 d4gg4d: ##”you can do this”

21:57 d4gg4d: ##`(lol)

21:57 lazybot: ⇒ (clojure.core/lol)

21:57 julianleviston: ,(quote or this)

21:57 clojurebot: or

21:57 ticking: julianleviston: if you return a map and want to add all keys to the old one you have to use merge

21:58 but merge will override left to right

21:58 right gets kept

21:58 julianleviston: ticking: yeah, I know

21:59 dweave: ##`(+ 1 1)

21:59 lazybot: ⇒ (clojure.core/+ 1 1)

21:59 julianleviston: ##(+ 1 1)

21:59 lazybot: ⇒ 2

21:59 dweave: ##(+ 1 1)

21:59 lazybot: ⇒ 2

22:00 julianleviston: ,(:or {:this :works :too :or :hooray!})

22:00 clojurebot: #<RuntimeException java.lang.RuntimeException: Map literal must contain an even number of forms>

22:00 julianleviston: fail

22:00 ticking: yeah, that didn’t work too well…

22:06 dweave: how are other commands run against lazybot?

22:06 such as “wiki”

22:08 amalloy: $wiki clojure

22:08 lazybot: [Clojure - Wikipedia, the free encyclopedia] http://en.wikipedia.org/wiki/Clojure

22:08 dweave: ahaa

22:08 Lewix: questions: 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:09 julianleviston: Lewix: lein has try

22:09 Lewix: and :reload can be given to require

22:10 Lewix: you can call clojure jars like ordinary java ones, assuming you’ve built one, too.

22:42 Lewix: julianleviston: I didn't get it but thanks. I'll figure later

22:43 amalloy: 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:45 amalloy: Lewix: i mean, you can try it yourself, by taking that function definition and replacing (first args) with (first vec args)

22:45 er, (first (vec args))

22:45 if 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:54 Lewix: amalloy: 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:55 amalloy: Lewix: well, fair enough

22:57 Lewix: vectors are concrete, eager, and finite

22:57 so you can't have an infinite arglist if you use vectors

22:57 if you only require a seq, you can use anything seqable as an arglist, including an infinite lazy seq

23:00 Lewix: amalloy: thank you. It makes sense

23:00 amalloy: is an ArraySeq an infinite lazsy seq?

23:01 amalloy: no, it's a seq wrapper around a java array

23:02 if you call a function "explicitly" like (f x), your args will generally be an ArraySeq

23:02 but if you apply it to some other seq, like (apply f xs), then your args will be whatever that other seq was

23:03 ,(map (partial apply (fn [& args] (class args))) [[1] (range 2) '(a b) '{a b}])

23:03 clojurebot: (clojure.lang.PersistentVector$ChunkedSeq clojure.lang.ChunkedCons clojure.lang.PersistentList clojure.lang.PersistentArrayMap$Seq)

23:03 Lewix: ,(type ((fn [& args] args) 1 2))

23:03 clojurebot: clojure.lang.ArraySeq

23:05 Lewix: amalloy: I have a hard time understanding why it's an ArraySeq and yet we cannot use a finite seq such as vectors

23:05 (I should probably read more on the topic)

23:06 amalloy: Lewix: 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:06 it's fine to use any specific concrete type as the arglist to a function, including vectors

23:06 what's not fine is *requiring* that be the only type, by guaranteeing that function args are always a vector

23:07 in real life, args often are ArraySeq, but that's not guaranteed; they can be something else instead

23:10 Lewix: amalloy: ok thanks. I'll think about all that - it's helpful

Logging service provided by n01se.net