2015-02-04
| 00:00 | Lewix | i dont care about the type |
| 00:00 | julianleviston | Lewix: in fact they don’t even tell you the abstraction |
| 00:00 | Lewix | tell me what it returns in a way that dont confuse |
| 00:00 | Lewix | me* |
| 00:00 | julianleviston | Lewix: that always depends on who is asking that question. |
| 00:00 | Lewix | anyways, thanks guys |
| 00:00 | Lewix | I'm off |
| 00: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. |
| 00:01 | julianleviston | Lewix: later |
| 01:37 | domokato | hi, anyone use neko? |
| 02:30 | rpaulo | only 26 days late. |
| 04:04 | l3dx | I don't get a repl buffer in cider. This is the case for both jack-in and "lein repl" + attach |
| 04:04 | l3dx | suggestions? |
| 04:05 | l3dx | can't seem to find any errors |
| 04:07 | ordnungswidrig | l3dx: no buffer created? what does the *Messages* buffer tell you? |
| 04:07 | hellofunk | l3dx: do you get any of the other nrepl buffers if you look at your full emacs buffer list? |
| 04:34 | l3dx | I get a nrepl-server and a nrepl-connection buffer |
| 04:34 | l3dx | https://gist.github.com/tskardal/7ca53cbd58575e9275ef |
| 04:34 | l3dx | relevant output from *Messages* |
| 04:51 | ordnungswidrig | l3dx: doesnt' your bufferlist contain a *cider-repl ...* buffer? |
| 04:52 | l3dx | nope |
| 04:53 | CookedGr1phon | domokato: yep, there's also a #clojure-android room if you're interested |
| 04:54 | domokato | CookedGr1phon: thanks, I found it :) |
| 04:54 | l3dx | ordnungswidrig: proof https://dl.dropboxusercontent.com/u/809432/emacs%20buffers.png |
| 04:54 | l3dx | :P |
| 04:59 | michaelr` | hmm |
| 05:01 | ordnungswidrig | hmmm, which version of cider (emacs) and cider-nrepl (clojure) do you use? |
| 05:02 | ordnungswidrig | what happens when you invoke `cider-switch-to-repl-buffer` (in core.clj, C-c C-z)? |
| 05: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 ? |
| 05: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 |
| 05:04 | julianleviston | cloudsaja: um… (:graph component) ? |
| 05:05 | cloudsaja | julianleviston .. I know that. but how can i get the component ? Where is stuartsierra.component stores its maps ? |
| 05:05 | hellofunk | l3dx: you can look directly inside the nrepl buffers for error messages |
| 05:05 | julianleviston | cloudsaja: I don’t follow your question. Apologies. It doesn’t work that way from memory. |
| 05:06 | julianleviston | cloudsaja: your system holds the components. |
| 05: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. |
| 05: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. |
| 05: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 |
| 05:16 | julianleviston | cloudsaja: ok… so where are you trying to access it from? |
| 05:16 | julianleviston | cloudsaja: or did ordnungswidrig’s response fix your issue? |
| 05:16 | cloudsaja | from repl |
| 05:17 | julianleviston | cloudsaja: ah… ok… so yeah… (-> system :database :graph) assumping your database component is databas? |
| 05:18 | julianleviston | *assuming your database is assoc’d on to the system as :databas |
| 05:18 | julianleviston | :database * (sigh) |
| 05:19 | julianleviston | cloudsaja: does that help / make sense? |
| 05:21 | cloudsaja | julianleviston : You are correct... saved my day. Thanks a lot. ordnungswidrig also.. thanks |
| 05: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… |
| 05:22 | julianleviston | cloudsaja: I think last time I checked, stuart was interested in improving that but nothing had occurred to him yet. |
| 05:22 | cloudsaja | julianleviston : got it |
| 05:22 | julianleviston | cloudsaja: maybe prettyprinting it might help |
| 05:22 | TEttinger | (inc julianleviston) |
| 05:22 | TEttinger | lazybot ded |
| 05: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. |
| 05:28 | cloudsaja | julianleviston : Okay... I will mention the context nextime. |
| 05: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? |
| 05:45 | ordnungswidrig | hejki_: jfx was discussed on the clojureD conference. Seems hot to me. |
| 05:47 | hejki_ | ordnungswidrig: http://www.bytebucket.org/splendid/jfx ? |
| 05:48 | hejki_ | googling "clojure jfx" provided results "all around", so it indeed is "hot" :P |
| 05:59 | julianleviston | I, for one, welcome our new fervently sardonic overlords. |
| 06: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? |
| 06:05 | julianleviston | zot: how’s about a go block? |
| 06:06 | l3dx | hellofunk: thanks, I'll have a look. It used to work fine, but stopped yesterday |
| 06:06 | zot | julianleviston: core.async was my other consideration, but i wondered if lazy-seq would actually be simpler for my case |
| 06:07 | julianleviston | ,(source repeatedly) |
| 06:07 | clojurebot | Source not found\n |
| 06:07 | julianleviston | zot: looks pretty good to me, why not... |
| 06:08 | zot | ahhhh, i forgot about repeatedly. that's even better :) |
| 06:08 | julianleviston | zot: sweet :-) |
| 06:08 | zot | (inc julianleviston) |
| 06:08 | zot | tnx! |
| 06:09 | frphank | julianleviston: core.async and lazy-seq don't normally compete |
| 06:09 | frphank | one is for I/O |
| 06:09 | frphank | the other for computation |
| 06:09 | julianleviston | frphank: depends what you’re trying to do I guess ;-) |
| 06:10 | frphank | yes, either you have I/O or you do not |
| 06:10 | frphank | what's the body of your "repeatedly"? |
| 06:10 | julianleviston | frphank: what if you want to compute many things at once? :-) |
| 06:10 | zot | for me, (repeatedly (partial recv-message this)) |
| 06:10 | frphank | hm |
| 06:11 | zot | quite trivial |
| 06:11 | julianleviston | frphank: or split their functionality into delayed process that happens later? or… etc. |
| 06:11 | julianleviston | zot: excellent. |
| 06:11 | julianleviston | frphank: but thanks, I’ll keep that in mind. |
| 06:11 | frphank | zot: sorry I got confused, you are the one that wants to use repeatedly? |
| 06:11 | frphank | zot: recv-message is from what library? |
| 06:11 | zot | not, it's my own code in a component wrapping a kafka client |
| 06:12 | frphank | ok |
| 06:12 | frphank | it probably blocks? |
| 06:12 | zot | but needs to be substitutable with in memory and other forms for testing |
| 06:12 | julianleviston | frphank: I think he’s got his solution. |
| 06:12 | zot | yes it does |
| 06:12 | frphank | zot: yeah that's problematic |
| 06:13 | frphank | zot: you can't interrupt the thread for starters, or it will do funny things |
| 06:13 | julianleviston | frphank: unless receive message is an action, not a channel-like thing… :) |
| 06:13 | frphank | julianleviston: it only matters if it blocks or not |
| 06:13 | julianleviston | frphank: blocks intentionally or not? |
| 06:13 | frphank | zot: CLJ-1119 has a discussion on that |
| 06:14 | frphank | julianleviston: what's unintentional blocking?? |
| 06:14 | julianleviston | frphank: what you think he’s doing? |
| 06:14 | julianleviston | frphank: all’s I’m saying is I don’t think we have enough info to make a recommendation about what to do yet. |
| 06:14 | frphank | julianleviston: zot said that recv-message blocks and that makes it unsuitable for repeatedly |
| 06:15 | zot | so if i understand, you believe that the thread termination may fail when wrapping this call in repeatedly? |
| 06: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 |
| 06:15 | zot | (to be clear, it blocks via Thread/sleep, spinning on an atom) |
| 06: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 |
| 06:17 | julianleviston | frphank: it *does* sound like core async is a better fit. |
| 06:17 | frphank | yeah |
| 06: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. |
| 06:18 | frphank | zot: in that case you might get away with it |
| 06:18 | zot | testing shortly to find out :) |
| 07: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 |
| 07:02 | rksm | All I get back is {"failingTest":0,"message":"","error":null,"golfScore":"","golfChart":""} |
| 07:02 | rksm | Any idea? |
| 07:07 | justin_smith | rksm: have you tried it with curl? |
| 07:07 | rksm | Well with clj-http-lite and node.js, will give curl a try... |
| 07: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? |
| 07:09 | hyPiRion | NewToClj: Sure thing |
| 07: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 |
| 07:10 | justin_smith | "an error" |
| 07:10 | hyPiRion | NewToClj: could you post the project.clj to a pastebin, just so I could see? |
| 07:10 | hyPiRion | we* |
| 07:10 | NewToClj | yes the error is: Unable to resolve symbol: make-oauth-creds , which is a symvol'/function of the lib |
| 07:11 | NewToClj | how can i check if the dependencies resolved correctly? |
| 07:11 | justin_smith | NewToClj: did you use require or use to load the dep? |
| 07:11 | NewToClj | justin_smith: (require 'tweedels-clj.core) |
| 07:11 | hyPiRion | NewToClj: If you managed to get into the repl itself, there should be no issues with the dependency handling. |
| 07:11 | justin_smith | NewToClj: if you do it that way, try tweedels-clj.core/make-oauth-creds |
| 07:12 | justin_smith | NewToClj: likely you want an :as in your require so you don't have to spell all that out |
| 07:17 | NewToClj | I listed project and the source file, nothing fancy, thats why im wondering what im doing wrong... |
| 07:18 | justin_smith | NewToClj: on line 14 you refer to a function that is not mapped to your ns |
| 07:18 | NewToClj | right so : make-oauth-creds should come from twitter.oath |
| 07:18 | justin_smith | NewToClj: change it to tiwtter.outh/make-oauth-creds or add an :as clause to the require and mutatis mutandis |
| 07:19 | NewToClj | justin_smith: but isn't the equire for this? |
| 07:19 | justin_smith | NewToClj: no |
| 07:19 | NewToClj | justin_smith: ah i see... |
| 07:19 | justin_smith | NewToClj: require makes it available, it does not map it directly to your namespace |
| 07: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]) |
| 07:19 | hyPiRion | It's generally not recommended though |
| 07:20 | justin_smith | or :refer [make-oauth-creds] even :) |
| 07:20 | NewToClj | ahh I see because of namespace shadowing, hm ok |
| 07:20 | justin_smith | NewToClj: not just shadowing - it makes editing things later much much easier when it's clear where things came from |
| 07:20 | justin_smith | NewToClj: or even reading the code |
| 07: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 ? |
| 07:30 | ro_st | is this possible with core.async, or should i use setTimeout/clearTimeout? this is in cljs, obviously |
| 07:30 | justin_smith | ro_st: sounds like you want debouncing |
| 07:30 | ro_st | ah, is THAT what debouncing is :-) |
| 07:31 | ro_st | https://gist.github.com/scttnlsn/9744501 ? |
| 07:31 | julianleviston | ro_st: I thought debouncing was stopping two requests registering when you only pressed once! :) |
| 07: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 |
| 07:31 | julianleviston | justin_smith: handy! |
| 07:31 | justin_smith | julianleviston: same concept |
| 07:31 | NewToClj | justin_smith: thanks that helped now i'm a step further! |
| 07:31 | justin_smith | julianleviston: it comes from hardware / hardware switches |
| 07:32 | julianleviston | justin_smith: yeah, I knew it from keyboards. |
| 07:32 | justin_smith | julianleviston: in the hardware switch you would have a capacitor that needs to charge up, and any bounce / jiggle gets subsumed |
| 07:32 | ro_st | the gist link i pasted seems to do exactly that |
| 07:32 | justin_smith | julianleviston: same idea, different domain :) instead of capacitors we have timers |
| 07:33 | justin_smith | ro_st: yes, that looks like an acceptable version of debounce |
| 07:33 | justin_smith | it resets the timer if you get new events within the timout, othwerwise hits the timout and does the timout's thing |
| 07:34 | ro_st | thanks justin_smith! |
| 07:34 | justin_smith | ro_st: very useful in UI |
| 07:34 | justin_smith | ro_st: but that is probably exactly where you are using it |
| 07:34 | ro_st | hugely. i'm doing an autocompleter |
| 07:34 | julianleviston | justin_smith: I wanted something like this a few days ago... |
| 07:34 | julianleviston | justin_smith: I think... |
| 07:35 | ro_st | love core.async. literally just wrapped the arg where i pass in the channel |
| 07:35 | justin_smith | omg I can't believe I only just now got the 4clojure "fore" -> golf - code-golf pun |
| 07:35 | justin_smith | argh |
| 07:35 | justin_smith | ((juxt inc dec) amalloy) |
| 07:36 | ro_st | if your cljs app causes safari/mac to restart your mac, is it a bug or a feature? |
| 07:36 | julianleviston | justin_smith: i don’t get it… is it just fore/4 ? |
| 07:37 | justin_smith | julianleviston: right, and you shout "fore" before swinging in golf |
| 07:37 | ro_st | Fore is what they shout when you might just about to be brained by a golf ball |
| 07:37 | julianleviston | justin_smith: haha yep. That’s what I thought. |
| 07:38 | julianleviston | ah, I hate these “fill in the blanks” type coding things for learning... |
| 07:38 | julianleviston | clojure koans had me slapping my head at once stage... |
| 07:39 | julianleviston | 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. |
| 07:40 | julianleviston | 4clojure is much better than the koans |
| 07:40 | ro_st | did you learn a lot about clojure when trying to figure them out? -zen master- |
| 07:40 | michaelr` | what would be a good strategy to use liberator resources in a Componentized app? |
| 07:40 | justin_smith | julianleviston: won't they just accept any answer that returns the right result? |
| 07:41 | julianleviston | michaelr`: Can you rephrase? |
| 07:41 | julianleviston | justin_smith: something like that… which often doesn’t help one learn.. |
| 07:41 | julianleviston | “What’s 1 + 1” doesn’t really help you understand addition. |
| 07: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. |
| 07:43 | justin_smith | julianleviston: and immersion is often just "drilling the rote answers" |
| 07: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 |
| 07:43 | michaelr` | the resource handler.. |
| 07: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. |
| 07:43 | justin_smith | though it can also include exposure - frequent reading of others code etc. |
| 07: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. |
| 07:44 | julianleviston | justin_smith: (myself included, no doubt) |
| 07: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 |
| 07: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 |
| 07:45 | rksm | (http/post (str "http://www.4clojure.com/rest/problem/" 1) |
| 07:45 | rksm | {:form-params {:code "true" :id 1}}) |
| 07:45 | justin_smith | (partial function taking the db bindings at creation time) |
| 07:45 | rksm | is necessary |
| 07:46 | justin_smith | rksm: cool, glad you figured it out |
| 07:47 | michaelr` | yeah well, i was hoping for some way to create the liberator resources as part of the system (component) lifecycle |
| 07: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… |
| 07:47 | michaelr` | instead of passing it at runtime.. |
| 07:48 | justin_smith | michaelr`: yeah, if it isn't going to change at runtime, why not bind it once |
| 07:48 | justin_smith | michaelr`: a similar solution is to use a promise that gets delivered to at init |
| 07:49 | justin_smith | "not going to change at runtime" here means that the component system will be restarted if you rebind the db settings, of course |
| 07: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.. |
| 07:54 | michaelr` | in the sense of a closure.. |
| 07:54 | julianleviston | michaelr`: yeah, but *your* code can do whatever you like, can’t it? |
| 07:55 | michaelr` | sure.. it's all my code :) |
| 07:55 | julianleviston | michaelr`: so… can’t you use a function that returns a function? |
| 07:55 | michaelr` | yes I can |
| 07:55 | julianleviston | michaelr`: I used that a lot in my component code. |
| 07: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 |
| 07:56 | rksm | @alexyakushev cool, thanks! |
| 07: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 |
| 07:59 | michaelr` | hmm |
| 07: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) |
| 07:59 | justin_smith | the vm can't optimize things that are last-minute paramaterized as nicely |
| 08:00 | justin_smith | (or the clj compiler can't compile them to as nice a form, etc.) |
| 08:00 | michaelr` | hmm |
| 08:01 | michaelr` | thinking of it I |
| 08:03 | michaelr` | I'm not sure I understand what you're suggesting me to do :) |
| 08:04 | justin_smith | michaelr`: does liberator have a function version of its route thing? |
| 08:05 | michaelr` | looking.. |
| 08:07 | michaelr` | looks like there is some function which I could use |
| 08:08 | michaelr` | how would that help? |
| 08: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 |
| 08:13 | michaelr` | hmm |
| 08:13 | michaelr` | thanks justin |
| 08:14 | michaelr` | i can see a few ways to do that, i'll play with it a bit more to get a better insight |
| 08:14 | justin_smith | michaelr`: aha - it has the function called resource |
| 08:14 | justin_smith | http://clojure-liberator.github.io/liberator/doc/resource-definition.html |
| 08:14 | justin_smith | shown near the bottom of the page there |
| 08:15 | justin_smith | you should be able to craft a call to resource that captures the db in the definition |
| 08:16 | justin_smith | and (defresource foo ...) is the same as (def foo (resource ...)) |
| 08:17 | michaelr` | how about referencing the system var and taking the db component from there? ; |
| 08:17 | michaelr` | ;) |
| 08:17 | justin_smith | michaelr`: that may be the more straightforward way to do it, actually |
| 08:18 | justin_smith | d'oh |
| 08:18 | michaelr` | on the other hand, but on the other i think it ruins the whole concept of components |
| 08:19 | michaelr` | i mean, the system then becomes a singleton |
| 08:19 | justin_smith | right |
| 08:20 | justin_smith | well, parameterizing the resource on the config data solves the singleton issue, at the cost of a slightly less straightforward impl |
| 08:21 | michaelr` | I thought of maybe defining the resources within the (start) method of a component |
| 08:21 | michaelr` | But then I'd have to create one component for each rest entity or put them all inside one component |
| 08:22 | michaelr` | either way looks bad |
| 08:22 | justin_smith | michaelr`: what about a hash-map to hold the resources, as created by resource |
| 08:22 | justin_smith | michaelr`: then that hash-map can be used by the component that creates the server |
| 08:22 | justin_smith | (and the middleware, presumably) |
| 08:23 | julianleviston | justin_smith: hey do you know… are xhr’s done on the main js thread in the browser? |
| 08:23 | justin_smith | julianleviston: I am actually not sure of that |
| 08:23 | hellofunk | julianleviston: they can be synchronous or asynch. if you use cljs-ajax they are asynx |
| 08: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? |
| 08:24 | julianleviston | hellofunk: I’m using the google closure one, I think. |
| 08:24 | julianleviston | hellofunk: let me check. |
| 08:24 | justin_smith | julianleviston: for cleanliness sake I think putting your logic in a go block rather than a callback tends to work |
| 08: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. |
| 08:24 | michaelr` | julianleviston: either way the callback code would be executed on the main js thread |
| 08:24 | julianleviston | justin_smith: I have the part of my code that writes the data it gets into an atom in there... |
| 08:25 | julianleviston | justin_smith: I just noticed that part of the code seems to take a while... |
| 08:25 | julianleviston | michaelr`: yeah? ok. |
| 08:25 | hellofunk | julianleviston: up to you whether you use a callback directly or use core.async as a handler. |
| 08:25 | julianleviston | hellofunk: I *think* it’s async… just curious. |
| 08:26 | julianleviston | hellofunk: well I’m doing a bit of both… but it seems to be blocking up the UI… |
| 08:26 | julianleviston | hellofunk: I’m probably doing something stupid tho :( |
| 08:26 | hellofunk | julianleviston: i'm a big fan of cljs-ajax and the author is quite opinionated about making sure synchronous activity is avoided |
| 08: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 |
| 08: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"}))) |
| 08:28 | julianleviston | michaelr`: hm… isn’t ajax async by default? |
| 08:28 | julianleviston | michaelr`: how can you have ajax if it’s not async? |
| 08:28 | julianleviston | michaelr`: isn’t that what the A stands for? |
| 08:29 | hellofunk | julianleviston: the question is about xhr and whether that is sync or async |
| 08:29 | julianleviston | hellofunk: it is. |
| 08: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? |
| 08:29 | hellofunk | julianleviston: i mean, xhr can be either. but ajax is typically async xhr |
| 08:29 | Glenjamin | node+cljs is an option |
| 08:29 | justin_smith | hejki_: jvm is not the bottleneck |
| 08:30 | julianleviston | hellofunk: ype |
| 08:30 | julianleviston | hellofunk: yep.* |
| 08:30 | justin_smith | hejki_: but node+cljs / closure advanced compilation mode do lower the startup time |
| 08: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 |
| 08:30 | justin_smith | (we don't have an equivalent optimization in jvm clojure) |
| 08:30 | justin_smith | hejki_: the jvm starts fast |
| 08:30 | justin_smith | hejki_: it is clojure that starts slowly |
| 08:31 | hejki_ | ok |
| 08:31 | hejki_ | and can it be made faster? :P |
| 08:31 | justin_smith | hejki_: you can avoid this by using cljs, which does not bundle the clojure compiler |
| 08:31 | hejki_ | but then I lose some features |
| 08:31 | justin_smith | and which can be optimized with google closure |
| 08:31 | justin_smith | it's true! |
| 08:31 | julianleviston | Well I think (let [xhr (XhrIo.)]) that answers my q… Xhrlo is async…apparently? |
| 08:31 | justin_smith | hejki_: it's a hard tradeoff |
| 08:31 | hejki_ | and actually important ones too :P |
| 08:31 | julianleviston | i’m pretty sure it’s async… anyway. |
| 08:31 | hejki_ | clearly :P |
| 08:32 | justin_smith | hejki_: drip will not help at all though |
| 08:32 | hejki_ | ok |
| 08:32 | julianleviston | it must just by my code doing some blocked up steff... |
| 08:32 | julianleviston | I wonder if I segment it and put it into go blocks if it’s make everything smoother. |
| 08: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 |
| 08: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) |
| 08:33 | justin_smith | hejki_: the limitation there is all usages of grenchman must share the same deps |
| 08:33 | justin_smith | also, there are other lisps that are better for fast startup / short tasks (eg. racket scheme) |
| 08: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. |
| 08:34 | hejki_ | justin_smith: well, grenchman could preload everything my cli tool uses and the tool just connects to that and runs stuff? |
| 08:34 | justin_smith | ocaml is pretty awesome in terms of startup time / low overhead if you might consider an ml, as well |
| 08:34 | justin_smith | hejki_: exactly |
| 08:34 | julianleviston | justin_smith: or maybe even Piumerta’s COLA! |
| 08: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 |
| 08: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 |
| 08:36 | justin_smith | hejki_: yeah, you could probably figure out a managed restart |
| 08:36 | hejki_ | I can do that with the distribution package manager when new version of the cli tool gets installed |
| 08:37 | hejki_ | the nrepl could be ran as a service anyhow |
| 08:37 | hejki_ | justin_smith: thanks for this information. I'll look more deeply into grenchman and perhaps start porting the current tool soonish :) |
| 08:38 | justin_smith | hejki_: the other concern of course is to make sure you aren't relying on globals at all |
| 08:38 | justin_smith | hejki_: but clojure is very good with helping you with that sort of thing |
| 08:38 | hejki_ | i think all global states are in filesystem in my case |
| 08:38 | justin_smith | hejki_: well, for example you would want no defs in namespaces that would be client specific |
| 08: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? |
| 08:39 | justin_smith | but if it's all in files and can be per-execution local, then yeah, great |
| 08:39 | hejki_ | that might require some redesigning |
| 08: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 |
| 08:40 | justin_smith | hejki_: suddenly nothing is global any more! |
| 08: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) |
| 08:41 | justin_smith | what I mean by global is a bit more extensive than what python might mean |
| 08:41 | justin_smith | ie. no singletons are allowed |
| 08:42 | hejki_ | hmm.. I do have user configurations that are 'singletons' (read: python package globals) |
| 08:42 | hejki_ | can't I bind them somehow? |
| 08:42 | justin_smith | pass them in a map to your executing function |
| 08:42 | justin_smith | and it can forward them down the call chain as needed |
| 08:43 | hejki_ | hmm.. maybe I'll just read them whenever I need something from those config files |
| 08:43 | hejki_ | not all operations actually require anything from that global data (those are actually read lazily now in the python tool, too) |
| 08:44 | hejki_ | however the package global state makes the current implementation read that data only once per execution |
| 08:55 | justin_smith | hejki_: you mention user config - be aware that nrepl is not a good idea on true multi-user systems |
| 08:56 | justin_smith | it opens an http port on a local socket that executes arbitrary code (including shelling out) as the user who spawned it |
| 08:56 | justin_smith | with no auth |
| 08:56 | justin_smith | (and grench uses nrepl) |
| 09:05 | gfredericks | ~hi |
| 09:05 | clojurebot | No entiendo |
| 09:06 | justin_smith | nyello |
| 09: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? |
| 09:11 | gfredericks | not much worse than a global atom? |
| 09: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. |
| 09:11 | justin_smith | gfredericks: I replace def inside functions with (def foo (promise)) and then put (deliver foo x) inside a function |
| 09:12 | justin_smith | then of course I need to deref |
| 09:12 | gfredericks | justin_smith: your first question applies to a global atom as well? |
| 09:12 | justin_smith | but it leaves out the open questions that an atom would leave hanging |
| 09:12 | justin_smith | gfredericks: sure, initialization issues |
| 09:12 | justin_smith | but a promise just blocks until delivered |
| 09:12 | justin_smith | which avoids that (as long as someone plans on delivering...) |
| 09:12 | gfredericks | can anybody think of any uses for a validator on a var? |
| 09:13 | gfredericks | a normal var I mean |
| 09:13 | justin_smith | a "normal" var, I only define once |
| 09:13 | gfredericks | exactly |
| 09: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... |
| 09:14 | gfredericks | I feel like the idiomatic use of vars is just don't programmatically redefine them |
| 09:14 | justin_smith | but you should not be letting clients def your vars... |
| 09:14 | justin_smith | gfredericks: perhaps validator on a dynamic var? |
| 09:14 | justin_smith | that kind of makes sense, if you tolerate dynamics |
| 09:15 | gfredericks | yeah that's a good point |
| 09:15 | gfredericks | maybe also for with-local-vars which who even uses that |
| 09:15 | gfredericks | it feels like an almost entirely different kind of thing |
| 09:15 | justin_smith | I mean seriously, yeah |
| 09:15 | justin_smith | would any of us even notice if with-local-vars just disappeared? |
| 09:16 | gfredericks | I once came up with a non-composable tactic for turning a non-dynamic var into a dynamic one |
| 09:16 | gfredericks | I think it might've or could've used with-local-vars in the impl |
| 09:18 | justin_smith | a SO question I provided an inadequate answer to yesterday led to an idea for a useful utility |
| 09:18 | justin_smith | someone wants a command line with a long running lein instance where they can type in lein commands to run them |
| 09:19 | gfredericks | a repl for lein? |
| 09: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 |
| 09:19 | justin_smith | yeah |
| 09:19 | gfredericks | didn't it have that feature at some point? |
| 09:19 | gfredericks | `lein interactive` |
| 09:19 | hyPiRion | yes, we did |
| 09:19 | stuartsierra | I thought it still did. |
| 09:19 | justin_smith | I think there is an issue that lein has some stuff that just breaks in long running processes |
| 09:20 | justin_smith | but what if you (every time? occasionally?) restarted lein after the command to get a fresh start... |
| 09:20 | justin_smith | or, bigger task, fixed the weird stuff that happens when lein stays running |
| 09:20 | justin_smith | said weird stuff I would need to do some more research - I recall technomancy talking about this a while back |
| 09:21 | justin_smith | stuartsierra: I think lein interactive was discontinued with lein 2.x |
| 09:21 | stuartsierra | oh |
| 09:21 | justin_smith | "lein rewrite using component" - awesom gsoc proposal |
| 09:22 | jballanc | justin_smith: according to crossclj, no...nobody would miss with-local-vars: http://crossclj.info/fun/cljs.core/with-local-vars.html |
| 09:22 | justin_smith | (inc jballanc) |
| 09:22 | hyPiRion | lazybot is as dead as every |
| 09:22 | hyPiRion | *ever |
| 09:22 | justin_smith | OK, this is getting way silly |
| 09:23 | justin_smith | yeah, I need to look into implementing "oh, I need to reconnect" logic in lazybot one of these days |
| 09:23 | justin_smith | if I wasn't behind on 3 different contracting jobs... |
| 09:27 | jballanc | ,(rip lazybot) |
| 09:27 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: rip in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 09:33 | Bronsa | jballanc: I would https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader/impl/utils.clj#L74-L77 |
| 09:33 | jballanc | ah, interesting! |
| 09:33 | justin_smith | Bronsa: ahh, I guess crossclj doesn't cross reference tools.reader |
| 09:33 | jballanc | reminds me that I need to spend more time with tools.reader |
| 09: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 |
| 09:35 | jballanc | oh, whoops! |
| 09:35 | jballanc | :-[ |
| 09:35 | justin_smith | ahh, OK |
| 09: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? |
| 09:37 | jballanc | I mean, the whole thread context gets pushed and poped before you return `x`, so that doesn't really do anything for you, right? |
| 09: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? |
| 09:38 | justin_smith | ionthas: use an atom / agent / ref for the counter |
| 09:38 | tbaldridge | ionthas: kindof a odd use-case, but consider using agents |
| 09:38 | tbaldridge | ,(doc agent) |
| 09: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 ... |
| 09:38 | Bronsa | jballanc: yes, except with-local-vars is a public var, Var/create and Var/setDynamic are implementation details |
| 09:39 | jballanc | hmm...true |
| 09:39 | justin_smith | yeah, that is a good use case for agent |
| 09:39 | ionthas | ok, thanks. I will look at them. |
| 09: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 |
| 09:40 | jballanc | yeah, a laudable goal...still makes me think that the ability to create new dynamic vars should be promoted to public API |
| 09:40 | justin_smith | (let [a (agent 0)] (dotimes [i 10000] (send a inc)) @a) |
| 09:41 | justin_smith | ,(let [a (agent 0)] (dotimes [i 10000] (send a inc)) @a) |
| 09:41 | clojurebot | 0 |
| 09:41 | justin_smith | haha |
| 09:41 | Bronsa | jballanc: agreed |
| 09: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 |
| 09:42 | Bronsa | ,(let [a (agent 0)] (dotimes [i 10000] (send a inc)) (await a) @a) |
| 09:42 | justin_smith | aha! |
| 09:42 | clojurebot | eval service is offline |
| 09:42 | Bronsa | well |
| 09:42 | Bronsa | ,(let [a (agent 0)] (dotimes [i 10] (send a inc)) (await a) @a) |
| 09:42 | Bronsa | whatever, that works. |
| 09:42 | clojurebot | eval service is offline |
| 09:42 | Bronsa | ,1 |
| 09:42 | clojurebot | 1 |
| 09:42 | hyPiRion | clojurebot doesn't like threads |
| 09:42 | Bronsa | clojurebot: you're a weirdo |
| 09:42 | clojurebot | Pardon? |
| 09:43 | justin_smith | (inc Bronsa) |
| 09:43 | justin_smith | I had forgotten about await |
| 09:43 | Bronsa | justin_smith: you are now my least favourite person, followed closely by lazybot |
| 09:44 | justin_smith | hehe |
| 09: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 |
| 09:54 | justin_smith | hejki_: OH, OK |
| 09:54 | justin_smith | haha, didn't mean to all caps that. |
| 09:54 | justin_smith | 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) |
| 09:55 | justin_smith | has there been any work done to add local auth to nrepl? |
| 09: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 | hejki_ | 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 | justin_smith | 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 | hejki_ | ? |
| 10:04 | justin_smith | hejki_: not that exact syntax, but yeah |
| 10:05 | hejki_ | well yes |
| 10:05 | hejki_ | :P |
| 10:05 | hejki_ | ' |
| 10:05 | hejki_ | :) |
| 10:05 | hejki_ | 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 | justin_smith | hejki_: I think it could be set up such that you put them in a default ns when they connect |
| 10:06 | justin_smith | 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 | hejki_ | 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 | justin_smith | 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 | jackhill | 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 | justin_smith | jackhill: if your uds replacement for the network socket has the same api as ServerSocket, then it should Just Work™ |
| 10:22 | justin_smith | jackhill: it's a small enough function that you could copy/paste to make a uds using replacement even |
| 10:23 | justin_smith | 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 | martinklepsch | 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 | martinklepsch | 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 | Glenjamin | something like tiny-url? |
| 10:45 | martinklepsch | Glenjamin: yeah I guess that's similar |
| 10:45 | martinklepsch | 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 | llasram | martinklepsch: Can you just e.g. use persistent state to generate integers in standard order? |
| 10:47 | llasram | 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 | martinklepsch | 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 | llasram | martinklepsch: Yes, but they're very different ways of thinking of the problem |
| 10:50 | martinklepsch | llasram: ok, that's right |
| 10:52 | martinklepsch | 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 | martinklepsch | 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 | martinklepsch | $hash = md5(mt_rand(1, 10000).microtime().getmypid().gethostname()); |
| 10:53 | martinklepsch | 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 | martinklepsch | 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 | llasram | 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 | julianleviston | ie… the example on that page has a fn called “unique-randon-numbers” |
| 11:00 | julianleviston | martinklepsch: but that’s talking about uniquneness within itself… you want uniqueness outside of the numbers… sorry. |
| 11:00 | julianleviston | (ie no char repeated versus no repeated set of chars) |
| 11:01 | julianleviston | martinklepsch: can you use gensym? |
| 11:01 | julianleviston | 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 | julianleviston | Decentralized, k-ordered unique ID generator |
| 11:04 | martinklepsch | julianleviston: what does this provide over UUIDs? |
| 11:05 | martinklepsch | https://github.com/boundary/flake#frequently-asked-questions |
| 11:05 | martinklepsch | 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 | julianleviston | 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 | Bronsa | 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 | sardinha_biba | thank you all for the clarifications |
| 11:32 | sardinha_biba | 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 | kodumulo | 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 | tbaldridge | ,(: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 | Bronsa | ,(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 | julianleviston | 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 | ppppaul | which, i'm not (hence web/command line ref) |
| 11:50 | mdrogalis | ppppaul: Cljs doesn't have pprint yet. |
| 11:50 | mdrogalis | 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 | ppppaul | i don't have the option to pprint on the server, as i don't have a server |
| 11:51 | ppppaul | 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 | julianleviston | is it borked? |
| 11:58 | ppppaul | i feel borked |
| 12:00 | julianleviston | ppppaul: same… |
| 12:00 | julianleviston | 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 | {blake} | I'm looking at how to fix. There doesn't seem to be a "Is this connection good?" pingy kind of thing in Monger. |
| 12: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 | {blake} | 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 | {blake} | 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 | {blake} | 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 | julianleviston | tbaldridge: oh too quick! :) |
| 12:20 | julianleviston | (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 | julianleviston | 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 | julianleviston | 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 | julianleviston | 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 | raspasov | 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 | tbaldridge | *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 | julianleviston | whomp: but don’t quote me on that |
| 12:37 | julianleviston | 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 | justin_smith | 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 | justin_smith | whomp: oh, yeah, julianleviston was right https://cursiveclojure.com/userguide/leiningen.html |
| 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 | julianleviston | ugly ugly ugly |
| 12:42 | julianleviston | 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 | julianleviston | {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 | julianleviston | justin_smith: ok I gotta go sleep… :) was lovely talking to all of you today! |
| 12:44 | julianleviston | 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 | justin_smith | ,(#'+ 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 | hyPiRion | if that variable was a function |
| 13:30 | justin_smith | another option would be to always deref |
| 13:31 | justin_smith | the source of the data can deside on what kind of dereffable thing they should provide |
| 13:31 | justin_smith | *decide |
| 13:32 | justin_smith | it could be an atom, a delay, whatever |
| 13:32 | justin_smith | a deftype that calls a function when you deref |
| 13:32 | justin_smith | whatever evil thing you like |
| 13:32 | hyPiRion | call-by-deref |
| 13:32 | justin_smith | right |
| 13:32 | justin_smith | 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 | justin_smith | 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 | justin_smith | 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 | hyPiRion | ,(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 | gfredericks | ,(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 | tomjack | :P |
| 13:43 | gfredericks | downside is it's probably stackful |
| 13:43 | gfredericks | 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 | {blake} | 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 | hyPiRion | Oh right |
| 13:49 | TimMc | There could be bugs anywhere already. |
| 13:49 | hyPiRion | {blake}: #'x is just sugar for (var x) |
| 13:49 | hyPiRion | ,'#'x |
| 13:49 | clojurebot | (var x) |
| 13:49 | TimMc | Maybe we need to add metadata to just the right thing or something. |
| 13:49 | TimMc | or a parser bug somewhere |
| 13:49 | hyPiRion | yeah |
| 13:50 | hyPiRion | How should we go forward though? Make fuzzy tests or something? |
| 13:51 | hyPiRion | maybe we can use this |
| 13:51 | hyPiRion | ,(-> + #'foo) |
| 13:51 | clojurebot | #'clojure.core/+ |
| 13:53 | krat0sprakhar | hi everyone |
| 13:53 | krat0sprakhar | i've been trying to wrack my brains on problem 132 on 4clojure |
| 13:53 | krat0sprakhar | my solution is passing all but the last test case - https://www.refheap.com/96906 |
| 13:53 | krat0sprakhar | any idea whats wrong? |
| 13:56 | krat0sprakhar | my hunch is that my solutions uses reduce with iterate |
| 13:56 | krat0sprakhar | ,(take 10 (->> (iterate inc 10) (reduce +))) |
| 13:56 | krat0sprakhar | will fail |
| 13:56 | clojurebot | Execution Timed Out |
| 13:58 | justin_smith | krat0sprakhar: the last case returns an infinite series |
| 13:58 | justin_smith | krat0sprakhar: so your function needs to be lazy |
| 13:58 | krat0sprakhar | yeah.. |
| 13:59 | krat0sprakhar | 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 | justin_smith | krat0sprakhar: yeah |
| 14:00 | justin_smith | krat0sprakhar: try it with lazy-seq directly - that's the more tedious but more informative way as a beginner I think :) |
| 14:00 | justin_smith | 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 | krat0sprakhar | can i use loop / recur? |
| 14:01 | krat0sprakhar | 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 | justin_smith | 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 | justin_smith | 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 | krat0sprakhar | 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 | justin_smith | (var x) gets the thing def created |
| 14:04 | justin_smith | 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 | justin_smith | it's how laziness is done |
| 14:06 | krat0sprakhar | wow! so *thunk* is really a word :D |
| 14:06 | krat0sprakhar | i had no clue |
| 14:07 | krat0sprakhar | ,(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 | krat0sprakhar | 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 | krat0sprakhar | and boy is clojurebot fast! |
| 14:08 | justin_smith | Raynes has been far from the clojure fold |
| 14:08 | krat0sprakhar | why so |
| 14:08 | krat0sprakhar | ? |
| 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 | krat0sprakhar | anyone with cursive got a clue what does the error msg - "no nREPL ack recieved mean"? |
| 14:10 | krat0sprakhar | 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 | justin_smith | 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 | krat0sprakhar | cant do lein repl from the command line also |
| 14:13 | krat0sprakhar | 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 | hyPiRion | TimMc: If we can find a symbol form for first we can do stuff like |
| 14:16 | hyPiRion | ,(#=(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 | hyPiRion | ,(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 | justin_smith | krat0sprakhar: so did the trampoline repl help? |
| 14:18 | krat0sprakhar | fetching dependancies |
| 14:18 | krat0sprakhar | not on a good connection.. sorry.. taking some time |
| 14:18 | krat0sprakhar | 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 | justin_smith | 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 | krat0sprakhar | i cant do lein repl only inside taht folder |
| 14:22 | krat0sprakhar | 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 | krat0sprakhar | just now |
| 14:23 | justin_smith | krat0sprakhar: recall I said either it did not start, or did not reply in time |
| 14:23 | justin_smith | right |
| 14:23 | krat0sprakhar | the download doesnt happen everytime right? |
| 14:23 | krat0sprakhar | 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 | krat0sprakhar | 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 | krat0sprakhar | 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 | krat0sprakhar | 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 | 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 | 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 | krat0sprakhar | ,(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 | krat0sprakhar | 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 | krat0sprakhar | 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 | justin_smith | so of course it times out, because it wants to evaluate the namespace before giving you your prompt |
| 14:34 | justin_smith | lesson learned, we can hope |
| 14:34 | krat0sprakhar | time to finally give 132 a try :P |
| 14:34 | krat0sprakhar | definitely :D |
| 14:34 | krat0sprakhar | 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 | krat0sprakhar | justin_smith: all lazy-seq examples follow the pattern (cons x (lazy-seq ..)) |
| 14:41 | krat0sprakhar | can I do (conj (lazy-seq ..) a b) |
| 14:41 | krat0sprakhar | instead? |
| 14:41 | justin_smith | krat0sprakhar: sure, but conj ends up doing cons on a lazy seq input |
| 14:41 | justin_smith | err... wait |
| 14:41 | justin_smith | no, use cons |
| 14:41 | justin_smith | because conj messes with the laziness |
| 14:41 | krat0sprakhar | but i want to add more than one elem into teh seq |
| 14:42 | krat0sprakhar | (conj [] a b) |
| 14:42 | justin_smith | amalloy_ is better than me at explaining this stuff |
| 14:42 | justin_smith | krat0sprakhar: check out concat |
| 14:42 | justin_smith | ,(concat [:a :b] (lazy-seq)) |
| 14:42 | clojurebot | (:a :b) |
| 14:43 | justin_smith | concat is alsy lazy |
| 14:43 | justin_smith | ,(type (concat [:a :b] (lazy-seq))) |
| 14:43 | clojurebot | clojure.lang.LazySeq |
| 14:43 | justin_smith | haha, alsy |
| 14:43 | krat0sprakhar | :D |
| 14:44 | krat0sprakhar | ok.. let me give that a shot |
| 14:59 | krat0sprakhar | 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 | auser | 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 | krat0sprakhar | 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 | mmitchell | in clojure/repl that is |
| 15:27 | justin_smith | mmitchell: clj-logging-config and timbre are two options for that |
| 15:28 | justin_smith | 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 | krat0sprakhar | ? |
| 15:41 | amalloy | you can, but don't |
| 15:42 | amalloy | 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 | krat0sprakhar | 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 | justin_smith | which would kind of prevent an ack from coming back in time :) |
| 16:29 | cfleming | justin_smith: That would do it, yes :) |
| 16:30 | cfleming | 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 | llasram | 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 | {blake} | (inc llasram) |
| 16:36 | {blake} | (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 | amalloy | 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. |
| 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 | jballanc | (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 | SagiCZ | 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 | whomp | 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 | SagiCZ | bodie_: yeas |
| 17:20 | SagiCZ | *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 | SagiCZ | 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 | bodie_ | 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 | tehgeekmeister | have two instances of basically this running in parallel: (future (clojure.java.io/copy (:err results) *out* :buffer-size 1)) |
| 17:31 | tehgeekmeister | ending up with output like this on *some* lines eetcchhoe d 'Fetched mmoodduulleess..' |
| 17:31 | tehgeekmeister | but then it goes back to normal |
| 17:31 | tehgeekmeister | also, it truncates the output mid line after a certain point |
| 17:31 | tehgeekmeister | so, seems like race conditions plus timeouts, probably |
| 17:31 | tehgeekmeister | 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 | ibash | 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 | sdegutis | 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 | hiredman_ | ,#(#"/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 | {blake} | Ah, I see my problem. How to construct a string for it. You use # to indicate the pattern, but if you need a concatenation of strings, you can't say #(str...) 'cause...well... |
| 17: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 | {blake} | 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 | {blake} | ##(.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 | {blake} | ##(.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 | amalloy | 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 | {blake} | (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 | amalloy | 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 | {blake} | Reader macros are the theme of the day. |
| 18:00 | ibash | sdegutis: tell me more about using it for large streaming data |
| 18:00 | ibash | we have some streams right now using node.js and highland |
| 18:00 | ibash | they’re okay — but they’re may come a time where we rebuild our data import pipeline |
| 18:01 | sdegutis | ibash: gtg |
| 18:01 | sdegutis | 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 | tehgeekmeister | like, if nothing's happening in the thread, does it just get killed? |
| 18:10 | tehgeekmeister | 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 | tehgeekmeister | say i (future (something)), and then there's nothing else in the program |
| 18:13 | tehgeekmeister | 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 | amalloy | 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 | tehgeekmeister | 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 | tehgeekmeister | 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 | tehgeekmeister | good point! |
| 18:19 | tehgeekmeister | the main one might |
| 18:19 | tehgeekmeister | so i should wait for those threads |
| 18:20 | tehgeekmeister | i'll try |
| 18:20 | hiredman_ | just never close *out* |
| 18:20 | tehgeekmeister | it's not explicitly doing so |
| 18:20 | tehgeekmeister | 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 | tehgeekmeister | and then checking if a a time's been hit |
| 18:39 | tehgeekmeister | lots of lines like this: 67796/0x41532c: psynch_cvwait(0x7F863BF25668, 0x100000100, 0x0) = -1 Err#316 |
| 18:39 | tehgeekmeister | 67796/0x41532c: gettimeofday(0x1279BFC90, 0x0, 0x0) = 1423092974 0 |
| 18:39 | tehgeekmeister | Anyone have some clues based on that? |
| 18:43 | tehgeekmeister | 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 | tehgeekmeister | 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 | pdlug_ | 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 | justin_smith | or are you just looking to remove nils from the map? |
| 18:50 | pdlug_ | More for cleaner output, so, optional assoc |
| 18:50 | pdlug_ | 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 | pdlug_ | 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 | tehgeekmeister | 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 | tehgeekmeister | 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 | 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})) |
| 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 | tehgeekmeister | and then hangs |
| 18:53 | tehgeekmeister | 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 | amalloy | 10 seems ludicrously small |
| 18:54 | tehgeekmeister | 1024 was chunking weirdly |
| 18:54 | tehgeekmeister | i really want line buffering |
| 18:54 | tehgeekmeister | 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 | tehgeekmeister | 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 | tehgeekmeister | 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 | tehgeekmeister | and then a big pause |
| 18:56 | tehgeekmeister | err, bytes, sorry |
| 18:57 | tehgeekmeister | 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 | tehgeekmeister | 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 | tehgeekmeister | core goal is to have a good wrapper for packer based build processes |
| 18:59 | tehgeekmeister | 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 | tehgeekmeister | justin_smith: didn't know line buffering was an os level option. you mean stdlib or syscall? |
| 19:01 | tehgeekmeister | 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 | justin_smith | this looks like a decent intro ^ |
| 19:01 | tehgeekmeister | thanks! |
| 19:02 | tehgeekmeister | so, looks like setting buffer size to 0 doesn't do anything special. |
| 19:02 | tehgeekmeister | 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 | tehgeekmeister | 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 | justin_smith | err, not io.Process |
| 19:05 | justin_smith | 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 | justin_smith | that's trickier |
| 19:06 | tehgeekmeister | but for short term, i can be lenient about that |
| 19:06 | tehgeekmeister | 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 | justin_smith | wei: that's always the reason |
| 19:07 | justin_smith | 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 | tehgeekmeister | crap |
| 19:08 | tehgeekmeister | that's a lot simpler |
| 19:08 | tehgeekmeister | i can just have it forward directly on to the parent streams |
| 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 | wei | 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 | tehgeekmeister | 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 | hiredman_ | 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 | tehgeekmeister | 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 | tehgeekmeister | I don't know leiningen well yet. |
| 19:17 | wei | hiredman_: at xb.helpers$loading__4958__auto__.invoke(helpers.clj:1) |
| 19:17 | wei | 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 | hiredman_ | 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 | amalloy | 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 | justin_smith | 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 | amalloy | and using checkouts simplifies the install-locally process |
| 19:23 | amalloy | justin_smith: shouldn't need to install |
| 19:24 | justin_smith | amalloy: checkouts don't work unless you run lein install first |
| 19:24 | justin_smith | amalloy: or so I heard |
| 19:24 | justin_smith | unless maybe you already have an artifact with that version string maybe |
| 19:24 | amalloy | right |
| 19:24 | amalloy | 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 | justin_smith | so I tend to defensively alter versions right off the bat |
| 19:29 | tehgeekmeister | looks like checkouts work for development |
| 19:29 | tehgeekmeister | not for deploy |
| 19:29 | tehgeekmeister | well, not cleanly for deploy |
| 19:29 | tehgeekmeister | i guess a fork on clojars is the cleanest answer for until a pull is merged |
| 19:29 | tehgeekmeister | aight |
| 19:30 | justin_smith | tehgeekmeister: you can deploy, a checkout is just a symlink to the real project dir |
| 19:30 | justin_smith | tehgeekmeister: on the project dir side, it has no way to know it is even a checkout |
| 19:30 | justin_smith | (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 | tehgeekmeister | in fact, i certainly don't |
| 19:31 | tehgeekmeister | 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 | tehgeekmeister | and use it on a server |
| 19:31 | tehgeekmeister | 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 | tehgeekmeister | cool |
| 19:32 | tehgeekmeister | this is a good enough path |
| 19:32 | justin_smith | tehgeekmeister: unless you need the libs to be published... |
| 19:32 | justin_smith | the uberjar will pull in the stuff from the subdirs |
| 19:32 | tehgeekmeister | it'll be published later |
| 19:32 | tehgeekmeister | 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 | justin_smith | 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 | tehgeekmeister | sometimes by luck |
| 19:58 | tehgeekmeister | 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 | hiredman_ | ,(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 | julianleviston | 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 | amalloy | don't worry about that |
| 20:01 | julianleviston | amalloy: oh ok good :) |
| 20:02 | julianleviston | 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 | julianleviston | and the apply doesn’t feel right to me. |
| 20:04 | amalloy | (apply merge-with m ms) is a pretty common thing |
| 20:04 | amalloy | 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 | julianleviston | amalloy: merge is, yeah. |
| 20:05 | julianleviston | (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 | julianleviston | (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 | julianleviston | oh well |
| 20:39 | julianleviston | 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 | julianleviston | 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 | amalloy | 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 | tehgeekmeister | I only need it in one place |
| 20:57 | amalloy | tehgeekmeister: sure, you can. foo.bar.whatever.ProcessBuilder$Redirect |
| 20:57 | amalloy | 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 | julianleviston | 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 | amalloy | 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 | julianleviston | 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 | julianleviston | 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 | julianleviston | and collects it into a single seq |
| 21:01 | julianleviston | and then goes off and calls an API requesting it |
| 21:02 | julianleviston | {: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 | ticking | because it has duplicate keys |
| 21:04 | ticking | 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 | tehgeekmeister | I need a file subclass |
| 21:04 | tehgeekmeister | 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 | julianleviston | 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 | ticking | 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 | julianleviston | 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 | julianleviston | ticking: but vectors make no sense for some keys. |
| 21:09 | julianleviston | 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 | julianleviston | ticking: “Just change eye colour so it’s a collection” |
| 21:10 | julianleviston | 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 | ticking | 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 | julianleviston | the only thing with this fn is, I can’t work out why it’s taking so long. |
| 21:15 | julianleviston | 430 ms in some invocations in cljs for a few hundred items. |
| 21:17 | julianleviston | ticking: thanks for your attention, tho. |
| 21:18 | ticking | is association-kwd a keyword or a fn? |
| 21:18 | ticking | 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 | ticking | 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 | julianleviston | ticking: the latter is inside the inner reduce |
| 21:22 | ticking | so the entire code is |
| 21:22 | ticking | (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 | ticking | julianleviston: or describe what you're trying to achieve |
| 21:24 | ticking | 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 | julianleviston | 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 | julianleviston | 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 | julianleviston | ticking: and no. |
| 21:30 | julianleviston | 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 | julianleviston | ticking: hm. |
| 21:31 | julianleviston | ,(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 | ticking | ,(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 | julianleviston | 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 | ticking | julianleviston: hrm |
| 21:43 | ticking | julianleviston: It's really hard to visualize what it all does |
| 21:44 | julianleviston | ticking: I know, isn’t it! :) |
| 21:44 | julianleviston | 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 | julianleviston | ticking: I agree |
| 21:45 | ticking | it doesn't have to be that complicated though |
| 21:45 | ticking | 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 | ticking | 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 | julianleviston | 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 | julianleviston | ticking: oh neat. |
| 21:53 | ticking | will behave slightly different though when overriding keys |
| 21:54 | ticking | 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 | julianleviston | d4gg4d: ##”you can do this” |
| 21:57 | julianleviston | 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 | ticking | but merge will override left to right |
| 21:58 | ticking | 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 | julianleviston | ticking: yeah, that didn’t work too well… |
| 22:06 | dweave | how are other commands run against lazybot? |
| 22:06 | dweave | 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 | julianleviston | Lewix: and :reload can be given to require |
| 22:10 | julianleviston | 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 | Lewix | 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 | amalloy | er, (first (vec args)) |
| 22:45 | amalloy | 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 | amalloy | Lewix: vectors are concrete, eager, and finite |
| 22:57 | amalloy | so you can't have an infinite arglist if you use vectors |
| 22:57 | amalloy | 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 | Lewix | amalloy: is an ArraySeq an infinite lazsy seq? |
| 23:01 | amalloy | no, it's a seq wrapper around a java array |
| 23:02 | amalloy | if you call a function "explicitly" like (f x), your args will generally be an ArraySeq |
| 23:02 | amalloy | 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 | amalloy | ,(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 | Lewix | (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 | amalloy | it's fine to use any specific concrete type as the arglist to a function, including vectors |
| 23:06 | amalloy | what's not fine is *requiring* that be the only type, by guaranteeing that function args are always a vector |
| 23:07 | amalloy | 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 |