2014-01-24
| 00:00 | rovar | it's best to not have dysfunctional bros |
| 00:00 | rovar | all drama |
| 00:01 | rovar | however, I'm afraid clojure is my bro, I don't share my bros |
| 00:02 | deadghost | dude man |
| 00:02 | deadghost | if you love your bro |
| 00:02 | deadghost | you gotta set your bro free |
| 00:02 | deadghost | unless you want to marry your bro |
| 00:02 | deadghost | then you need to ask for rich hickey's permission |
| 00:02 | akurilin | So, I love how ring will add both url and post data params into the params map, except you have to remember that you can't tell if something is a number or a string in a GET's URL param :( |
| 00:03 | akurilin | Do people end up using the two separate param maps to know when they need to parse for numbers and when they can assume the JSON got parsed correctly to a number? |
| 00:03 | bbloom | akurilin: form and url encodings are EVIL |
| 00:03 | bbloom | i can not tell you how many damn rails apps i've seen that just have params[...] with url, form, and json data all conflated |
| 00:04 | bbloom | then they scratch their heads for a month when they have a bool a number and a string and can't tell em all apart |
| 00:04 | guest1234 | can't some bright clojurean fix this intractable 'form params' problem, once and for all? |
| 00:04 | bbloom | frankly, it makes a man wish for tcl :_P |
| 00:05 | deadghost | who is our hero |
| 00:05 | akurilin | bbloom: what kind of options do I have if I need to read the :id in the compojure route and query params? Doesn't sound like I have much of a choice, right? |
| 00:05 | guest1234 | Heroes can run. I'm learning to walk. |
| 00:05 | bbloom | akurilin: i dunno, i haven't used compojure |
| 00:05 | akurilin | outside of redesigning the api to use all posts |
| 00:05 | akurilin | but then you're pooping on http methods |
| 00:05 | deadghost | wrong guest1234 |
| 00:05 | deadghost | heroes can FLY |
| 00:06 | bbloom | http deserves pooping on for most things we try to do with http... and it's too damn complicated for the things that SHOULD be done with something like http :-) |
| 00:06 | deadghost | and breathe underwater |
| 00:06 | deadghost | and shoot laser beams |
| 00:06 | deadghost | like superman and rms |
| 00:06 | akurilin | I get that. |
| 00:07 | guest1234 | how much of the damn web is genuinely, just getting damn form data from a to b. that's the entire 'healthcare' problem |
| 00:07 | guest1234 | problem / industry. |
| 00:07 | guest1234 | but that's another talk |
| 00:09 | guest1234 | dead-ghosts can fly. and presumably breathe under water too? |
| 00:09 | deadghost | it's funny how many different frameworks need to be made for CRUD apps |
| 00:09 | guest1234 | maybe they're all trying to resolve it the same <wrong> way. |
| 00:09 | deadghost | will we ever have one unified thing with skinnable syntax |
| 00:10 | guest1234 | like with the magic of btc, just have data 'zap' from point A to B. |
| 00:11 | guest1234 | magically show up where it needs to, without hassle or conflated, ill-formed nonsense |
| 00:11 | deadghost | I want to hug the internet |
| 00:11 | deadghost | wait no scratch that |
| 00:11 | deadghost | that sounds awful |
| 00:11 | guest1234 | nope. it's logged. |
| 00:12 | deadghost | so what are you guys working on |
| 00:13 | deadghost | I'm herpaderpin a website to keep track of my lists |
| 00:13 | deadghost | compojure + enlive |
| 00:14 | guest1234 | does anyone have the source for D. Nolen's Om ToDo. the source link, https://github.com/tastejs/todomvc/tree/gh-pages/labs/architecture-examples/om has some funky lookin' git jedi |
| 00:15 | guest1234 | off this page: http://swannodette.github.io/todomvc/labs/architecture-examples/om/ |
| 00:15 | deadghost | I have a friend that likes forking everything he uses |
| 00:15 | deadghost | in case stuff disappears one day |
| 00:16 | guest1234 | that's a little creepy, and incredibyl helpful. |
| 00:16 | deadghost | I wouldn't say helpful |
| 00:16 | deadghost | because he doesn't have your package |
| 00:17 | guest1234 | did he fork todo? |
| 00:17 | deadghost | read above^ |
| 00:17 | deadghost | meaning no |
| 00:17 | guest1234 | I guess there's plenty else to read through |
| 00:18 | guest1234 | sorry. misread as fork anything that shows up on his page. |
| 00:19 | guest1234 | as if stalking daily for any updates to grab. |
| 00:20 | guest1234 | anyway, back to the hero that's going to fix FORMS and data integrity across the wire. |
| 00:20 | deadghost | godspeed |
| 00:20 | guest1234 | if you could have that by tomorrow, TTThhhat be great. thanks. |
| 00:27 | akurilin | bbloom: actually I just realized why Parse.com uses POST for fetching and SO uses GET. The former has somewhat complex queries you can define, and so it requires nested datastructures, which you can't really do that well in the URI. SO on the other hand doesn't support complex queries, so it can get away with no nesting. |
| 00:27 | akurilin | So if I want nesting, I'm kind of screwed and need to POST it. |
| 00:28 | akurilin | I guess you can serialize a JSON object into the URI, but I don't know if that's just a recipe for sadness. |
| 00:30 | akurilin | Actually it looks like people do this. |
| 00:30 | akurilin | I don't know if it should make me sad or not. |
| 00:32 | dsrx | deadghost: websocket repl transport for clojurescript |
| 00:33 | deadghost | I'm only vaguely aware of websockets |
| 00:33 | deadghost | you lost me at "repl transport" |
| 00:37 | dsrx | deadghost: right now, browser-connected repls for clojurescript work with the usual iframe cross-page communication hackery which works... except you can't do it unless the page you'd like to run the repl on is served over something besides http (like a spotify application or chrome extension) |
| 00:38 | dsrx | er you can't do it *if* the page isn't served over http |
| 00:39 | deadghost | sounds neato |
| 00:39 | deadghost | I haven't had a chance to try clojurescript |
| 00:39 | deadghost | can that voodoo work with normal js |
| 00:40 | deadghost | or is it some clojurescript specific magic |
| 00:40 | egghead | deadghost: cljs is to js what clojure is to java |
| 00:40 | deadghost | that sounds stupidly amazing |
| 00:42 | deadghost | I'm pretty happy with just clojure in my life |
| 00:42 | deadghost | but a clojure for JS rocks my socks |
| 00:42 | deadghost | I'm not a huge fan of js you see |
| 00:42 | akurilin | Nvm, Parse actually does use GET, they URL-encode a json blob. |
| 00:42 | akurilin | Ugh guess I'm doing that |
| 00:43 | dsrx | deadghost: to be honest i'm not totally sure if it will work, i've implemented the CLJS and still have to do the CLJ side that gets piggiebacked to nrepl and be sure it "acts like" the standard repl enough that it will even work |
| 00:45 | dsrx | hrm i guess i should verify that i can actually use websockets in spotify >:D |
| 00:46 | deadghost | it's k, you can be our hero |
| 00:46 | deadghost | do a write up when you're done |
| 01:02 | andyf_ | Wow, someone has been having fun maintaining the channel topic message |
| 01:06 | coventry | Anything obviously funky about this clojurescript code? I'm getting an assertion failure, "alts! used not in (go ...) block". Also, I get "can't recur here", if I use (go-loop) instead of (go (loop)). https://www.refheap.com/26844 |
| 01:10 | dsrx | coventry: are you requiring the core.async macros? |
| 01:10 | dsrx | have to do it separately in cljs |
| 01:11 | coventry | dsrx: That was the problem. Thanks. |
| 01:27 | akurilin | Sanity check: I should be able to specify environ variables in project.clj's :profiles :uberjar :env, right? |
| 01:33 | andyf_ | when one is using Leiningen and has intra-file dependencies using :require and :use, is there ever a valid reason for a file foo/bar.clj to have any namespace in it other than foo.bar? |
| 01:34 | andyf_ | And as an edit to that question, I would guess that Leiningen has nothing to do with the answer to the question. |
| 01:34 | tomjack | no |
| 01:35 | noonian | i don't think you can do that because of how java expects your file paths to correspond to namespace (package) names |
| 01:35 | tomjack | there are examples in clojure of violations that involve using load instead of require |
| 01:35 | tomjack | clojure/core_*.clj |
| 01:36 | tomjack | etc |
| 01:36 | andyf_ | tomjack: Yeah, I know Clojure implementation itself sometimes uses load, but I'd consider that the exception rather than the rule, from what I have seen |
| 01:37 | andyf_ | But I am pretty sure that the implementation of require, use, and ns always look for a namespace foo.bar.blat in foo/bar/blat.clj, in some directory on your classpath. |
| 01:37 | tomjack | right |
| 01:37 | tomjack | so, no |
| 01:38 | tomjack | is there a sane way to add namespaces to edn? |
| 01:38 | andyf_ | I am testing the Eastwood lint tool on some projects, and finding some placeholder files in the test directory with a namespace declared by ns that does not match the file path, and wondering whether I should make simple-to-understand error message for that. |
| 01:40 | egghead | pretty sure Cannot call method 'call' of undefined is the npe of cljs |
| 01:41 | andyf_ | tomjack: You mean, enable edn to read namespace-qualified symbols? |
| 01:42 | andyf_ | tomjack: At least the tools.reader implementation of an edn reader can read namespace-qualified symbols, so not sure if I understand the question. |
| 01:43 | dsrx | egghead: heh |
| 01:44 | tomjack | andyf_: yes. and keywords |
| 01:44 | tomjack | where "namespace" no longer means clojure.lang.Namespace |
| 01:44 | tomjack | ..and data readers? |
| 01:44 | tomjack | nah |
| 01:44 | tomjack | well, yeah. the tag can be data-namespaced, but the var its bound to by *data-readers* will be clj-namespaced |
| 01:44 | dsrx | weird, i considered changing my nick to 'tomjak' on freenode today |
| 01:45 | andyf_ | tomjack: I am not familiar enough with data readers to give any advice there |
| 02:16 | logic_prog | what browser does lighttable use for rendering? |
| 02:17 | logic_prog | I know lighttable users node.js |
| 02:17 | logic_prog | but it needs to use a browser for rendering -- what browser does it use? |
| 02:19 | xuser | logic_prog: chromium |
| 02:20 | logic_prog | https://github.com/rogerwang/node-webkit/wiki/How-node.js-is-integrated-with-chromium ? |
| 02:20 | logic_prog | or should I be reading something else? |
| 02:21 | xuser | yeah, node-webkit uses chromium, node-webkit is wat LT uses |
| 02:22 | xuser | s/wat/what/ |
| 02:30 | fredyr | have you guys seen anybody doing cljs and node on the server side for web stuff? |
| 02:31 | logic_prog | xuser: nice, thanks! |
| 02:31 | logic_prog | fredyr: I have been wanting to, as a poor man's version of erlang |
| 02:32 | fredyr | erlang? in what way |
| 02:41 | jonathanj | are there any good reads about what core.async isn't? |
| 02:42 | jonathanj | coming from mainly a Deferred/Promise-based workflow, it's kind of surprising to me that core.async channels aren't a more common return value from libraries (i was looking at irclj) |
| 02:43 | tomjack` | does irclj use core.async now? |
| 02:43 | tomjack` | ah |
| 02:45 | tomjack` | go blocks seem reminiscent of promises |
| 02:45 | tomjack` | from the outside.. |
| 02:45 | tomjack` | well, no |
| 02:46 | tomjack` | ok, "reminiscent". but promises "complect control flow and communication" |
| 02:46 | tomjack` | this quote is from the blog post about core.async, which I assume you've already read? |
| 02:46 | egghead | hmm, in om why might i get "Uncaught Error: No protocol method ITransact.-transact! defined for type cljs.core/Atom: [object Object]" |
| 02:47 | egghead | I thought atoms were perfectly fine things to be 'application state' and that you could use (transact! ...) outside of the react lifecycle to change it's state |
| 02:47 | tutysara | ddellacosta: I had tried fixing the issues with error response from provider, update the issue with comments, see if it is ok |
| 02:49 | tutysara | ddellacosta: , and for multiple provider thing changed the implementation to use a :provider-uri config instead of redirecting /login to the form to choose provider, updated that issue with comments :) |
| 02:53 | egghead | or... why might I be getting errors saying that part of my app state isn't a cursor? |
| 02:53 | dsrx | egghead: i think transact! accepts a cursor into the state, not the state itself |
| 02:53 | egghead | ya, I realized I could just use 'swap!' isntead of transact! outside of the react lifecycle, but now it's saying that things like (:thing state) isn't a cursor |
| 02:55 | egghead | i'm probably just misunderstanding something |
| 02:56 | egghead | I'm just trying to do (apply dom/ul nil (om/build-all! my-lis (:get-list-from state))) |
| 02:56 | egghead | but it's saying that the value in (:get-list-from state) isn't a valid cursor |
| 02:56 | jonathanj | tomjack`: no, i don't think it does; it talks about callback functions |
| 02:56 | jonathanj | tomjack`: i don't see a lot of libraries that have an async nature with an outward facing core.async interface (some don't even use core.async) and i'm wondering if i've missed what core.async isn't |
| 02:58 | ddellacosta | tutysara: okay, responded--thanks! |
| 02:58 | dwwoelfel | Is it common knowledge that the :or destructuring form is eagerly evaluated? |
| 02:59 | dwwoelfel | user> (let [{:keys [a] :or {a (println "hi")}} {:a 1}] |
| 02:59 | dwwoelfel | a) |
| 02:59 | dwwoelfel | "hi" |
| 02:59 | dwwoelfel | 1 |
| 03:00 | logic_prog | did the word complect exist before rich hickey? |
| 03:00 | logic_prog | did rich hickey just come up with a word complect |
| 03:00 | ddellacosta | logic_prog: yes, he explains that in one of his early talks in fact, if I recall |
| 03:00 | logic_prog | and the rest of the wold go: okay, we accept this world you've defined |
| 03:00 | dwwoelfel | Seems like a bug in core/destructuring, where it uses a get |
| 03:00 | dsrx | com·plect [kuhm-plekt] Show IPA verb (used with object) Obsolete . to interweave; intertwine. Origin: 1515–25; < Latin complectī to embrace, enfold, equivalent to com- com- + plect ( ere ) to plait, braid + -ī passive infinitive ending; cf. complex |
| 03:00 | ddellacosta | logic_prog: http://wordnetweb.princeton.edu/perl/webwn?s=complect |
| 03:01 | ddellacosta | ah, dsrx beat me to it |
| 03:01 | jonathanj | tomjack`: which core.async blog post are you refering to? |
| 03:01 | tomjack` | the one you almost certainly read |
| 03:01 | tomjack` | clojure.org I think |
| 03:01 | tomjack` | I think a Promise interface is pretty similar to event callbacks as far as the comment in the blog goes |
| 03:02 | tomjack` | but I have thought about that comment for some time and still am not sure I understand it :) |
| 03:02 | jonathanj | yes, it is |
| 03:02 | jonathanj | promises are just a callback abstraction |
| 03:02 | jonathanj | in the promise/deferred world though, whenever you do something async you return a deferred/promise |
| 03:02 | jonathanj | and as such, promises/deferreds permeate almost every aspect of your software |
| 03:03 | tomjack` | ..so core.async isn't that, because it doesn't, uh, complect communication and flow of control |
| 03:03 | jonathanj | tomjack`: definitely, and i understand that part |
| 03:03 | tomjack` | I think I understand the question now |
| 03:03 | jonathanj | tomjack`: but why does irclj (to pick an example) not give me channels out? |
| 03:03 | tomjack` | does it even use core.async? |
| 03:04 | jonathanj | why do i have to put callbacks in? |
| 03:04 | jonathanj | tomjack`: not as far as i can tell |
| 03:04 | jonathanj | tomjack`: why would one not want to use core.async? |
| 03:04 | jonathanj | tomjack`: i feel like i've missed some crucial part of what core.async most definitely is not |
| 03:04 | tomjack` | I'd guess the explanation is probably more about the author than core.async |
| 03:05 | ddellacosta | jonathanj: are you wondering why more libraries don't use core.async, is that part of your question? |
| 03:05 | jonathanj | ddellacosta: yes |
| 03:05 | tomjack` | but if we assume that the author was familiar with core.async (and that all the new functions existed when irclj was written ?), it's an interesting question |
| 03:06 | ddellacosta | jonathanj: one simple answer is that it's relatively new, and a lot of libs haven't had time to adapt it to their needs--pedestal, for one, I recall being a perfect use-case--but they only started to integrate it this fall (I believe). |
| 03:06 | tomjack` | oh interesting |
| 03:06 | jonathanj | ddellacosta: hrm, weird |
| 03:06 | tomjack` | I can't wait to see what pedestal + core.async looks like |
| 03:06 | jonathanj | ddellacosta: i've been reading about it for quite a while (before i decided to find out what it was about) |
| 03:06 | ddellacosta | actually, I think that v.2 already integrates it |
| 03:06 | jonathanj | ddellacosta: but maybe my perception of time is a little... off. |
| 03:07 | ddellacosta | jonathanj: well, it's been proposed and in alpha for a while. But it was only in the latter half of last year that it was officially out, I believe. |
| 03:07 | dsrx | egghead: got context for all that? |
| 03:07 | ddellacosta | here's what I was looking for: https://groups.google.com/forum/#!topic/pedestal-dev/e8MzUH4K-T0 |
| 03:07 | jonathanj | so would a library that uses core.async (and exposes a core.async interface for users) return channels from functions that produce results asynchronously? |
| 03:07 | egghead | sure dsrx |
| 03:08 | ddellacosta | jonathanj: ^ you'll note that that post is from July, and it mentions that "Rich Hickey announced core.async a few weeks ago." |
| 03:08 | jonathanj | ddellacosta: okay, that makes sense; thanks |
| 03:08 | dsrx | afaik om/build and build-all will only accept a cursor, which is created by om/root and passed subsequently to your rendering functions |
| 03:08 | ddellacosta | jonathanj: np, hopefully that puts some of it in context. |
| 03:09 | egghead | dsrx: https://www.refheap.com/26863 |
| 03:10 | tomjack` | "Messages which tell other things to change" |
| 03:10 | tomjack` | https://github.com/pedestal/pedestal/blob/9f7879a6a6fdd5805cb22155d5589a36ae775152/app/examples/walkthrough.clj |
| 03:10 | tomjack` | so I can't tell how core.async affects a typical pedestal user's application code |
| 03:11 | tomjack` | didn't find any core.async requires in files that looked like demo code |
| 03:11 | tomjack` | oh, the app-template is where to look I guess |
| 03:11 | ddellacosta | tomjack`: yeah, I'm not knowledgeable about how it works to say, I think that it's pretty heavily integrated into the codebase at this point though (last I looked at it)--so I think it's more that it provides the wiring for the underlying parts. I think that a Pedestal application developer wouldn't necessarily have much need to touch it, as Pedestal provides a pretty thorough FRP pattern itself on top of it. |
| 03:12 | tutysara | ddellacosta: thanks :) will work no the pull requests and for putting the workflow together I have to see how I can do it |
| 03:12 | ddellacosta | tomjack`: I could be wrong about that...that statement is based on the last time I played with Pedestal, a few months back. |
| 03:12 | egghead | dsrx: I don't see how it could *not* be a cursor, since it was passed to the om component |
| 03:12 | ddellacosta | tutysara: great, thanks for all of your contributions! |
| 03:12 | egghead | app is the thing passed to om/root |
| 03:13 | ddellacosta | tutysara: btw, I'm not positive that it makes sense to have one workflow for all providers vs. one per provider...I'll have to think about it. In some ways it makes sense to consider a single provider a single workflow, but I'm just not sure about it yet. So if you think one makes more sense than the other, let me know why--thanks! |
| 03:13 | tomjack` | ddellacosta: sounds reasonable |
| 03:13 | dsrx | egghead: oh hrm |
| 03:13 | tomjack` | I haven't looked at pedestal in a long time either |
| 03:14 | tomjack` | but it seems you're right that core.async is used quite a bit in pedestal itself |
| 03:14 | tomjack` | not sure why it's used in the walkthrough but not user code |
| 03:14 | tomjack` | maybe the walkthrough is for developers? |
| 03:14 | ddellacosta | tomjack`: yeah, I've gotta check it out again myself...along with hoplon and a few other things...always more to check out! |
| 03:15 | ddellacosta | tomjack`: huh, dunno--I wonder if that walkthrough is v.3 vs. v.2? |
| 03:16 | tomjack` | dunno, will wait and see. won't be using cljs for a long time :( |
| 03:18 | ddellacosta | egghead: I'm still figuring out how this all works, but I've had the same problem, and solved it by passing the whole data structure to the component and deconstructing it within the component code (rather than before I pass it in). I believe it has to do with the structures that can be validly used as a cursor (https://github.com/swannodette/om/blob/master/src/om/core.cljs#L243 for example). |
| 03:19 | ddellacosta | er, not sure if that code example is helpful |
| 03:20 | egghead | ddellacosta: what I don't understand is that it looks exactly like what dnolen is doing in his tutorial example |
| 03:20 | ddellacosta | egghead: which one? the to-do thing? |
| 03:20 | dsrx | most of the om examples and such pull out the state to be used with build-all before calling it |
| 03:20 | dsrx | egghead: yeah thats why i'm confused too |
| 03:21 | egghead | maybe because it is a nested structure or something? |
| 03:21 | egghead | I mean it's a map of keys to sometimes strings sometimes lists of other maps etc |
| 03:21 | egghead | ddellacosta: nah https://github.com/swannodette/om/wiki/Tutorial#wiki-your-first-om-component this one |
| 03:22 | ddellacosta | egghead, dsrx: as I said I'm still figuring it out, but I believe it has to do with how to-cursor works, which is what happens when you create a component: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L387 |
| 03:22 | dsrx | right, it doesn't seem like to-cursor is recursive (heh) |
| 03:23 | fredyr | egghead: are you updating your atom outside of the om lifecycles? |
| 03:23 | dsrx | egghead: what version are you on? |
| 03:24 | fredyr | egghead: bc then you replace the cursor with a plain atom |
| 03:24 | egghead | dsrx: latest |
| 03:24 | egghead | and ya fredyr |
| 03:24 | egghead | I think basically I have a larger structure {:foo [:a :b :c]} and that is a cursor but apparently [:a :b :c] is not? |
| 03:24 | egghead | it makes no sense |
| 03:25 | fredyr | a cursor is a cursor |
| 03:25 | fredyr | :) |
| 03:25 | dsrx | i don't think om/root ever actually swaps in a cursor to replace your state atom |
| 03:26 | egghead | fredyr: do you know what is wrong with my code? https://www.refheap.com/26863 |
| 03:26 | egghead | i mean it'll work if everyone has full access to all the state i just want to know why it doesn't work |
| 03:26 | ddellacosta | dsrx: it explicitly does in root: https://github.com/swannodette/om/blob/master/src/om/core.cljs#L442 |
| 03:26 | egghead | like if instead of (:supervisors state) I just say state like ddellacosta suggested |
| 03:26 | egghead | but that feels lame |
| 03:29 | dsrx | ddellacosta: i see it creating a cursor from the dereferenced state of the atom provided to it (which is then passed onto the render fns), but i don't ever see it updating the atom itself unless i'm missing something |
| 03:30 | fredyr | egghead: can you show the om/root code for creation, as well as the atom updates |
| 03:30 | fredyr | egghead: bc i don't think the code you posted contains the problem |
| 03:30 | dsrx | this is the first time i've really dug deep into om so i very well might have no idea what i'm talking about :D |
| 03:30 | dsrx | the first time i read om source code i didn't know what an atom was |
| 03:31 | egghead | sure thing fredyr |
| 03:31 | ddellacosta | dsrx: that's because you would be doing the updating yourself, using transact! or update! |
| 03:32 | egghead | fredyr: om root creation: https://github.com/eggsby/warden/blob/master/src/cljs/warden/core.cljs#L17 |
| 03:32 | fredyr | egghead: also, i don't think you should update the atom outside of om, but use transact! or update! |
| 03:32 | egghead | swap updating https://github.com/eggsby/warden/blob/master/src/cljs/warden/net.cljs#L19 |
| 03:32 | egghead | fredyr: the whole point of my use case is that I want to keep the ui state in sync with an external resource |
| 03:33 | egghead | so I kind of have to do it outside of the react component |
| 03:33 | fredyr | egghead: sure, but if you look at dnolen's examples, that's usuall done by setting up a channel inside of the will-mount of a component |
| 03:33 | fredyr | egghead: where you have access to the cursor |
| 03:34 | egghead | hmm |
| 03:34 | fredyr | egghead: https://github.com/swannodette/om/blob/master/examples/counters/src/core.cljs#L43 |
| 03:34 | fredyr | egghead: something like that |
| 03:36 | egghead | i'll try kicking off the polling stuff inside of the will mount and using set-state! or update! instead of swap! |
| 03:36 | egghead | thanks fredyr |
| 03:36 | fredyr | np, let us know it you get anywhere |
| 03:40 | quizdr | why do I need to writing something like #(vector %2 %) rather than #([%2 %])? I know #() cannot be nested, but this is not a nested #(), or there another reason? |
| 03:40 | dsrx | quizdr: #(vector %2 %) desugars into (fn [x y] (vector y x)) |
| 03:40 | fredyr | quizdr: its bc of how #() gets expanded |
| 03:40 | clgv | quizdr: because of the definition of the reader macro #() |
| 03:41 | dsrx | ,(fn [x y] ([x y])) |
| 03:41 | quizdr | so my erroneous would just get expanded as (fn [x y] [y x]) ? |
| 03:41 | clojurebot | #<sandbox$eval25$fn__26 sandbox$eval25$fn__26@1d290d1> |
| 03:41 | fredyr | #(%) -> (fn [x] (x)), not (fn [x] x) |
| 03:41 | clgv | quizdr: it expands to a function call and ([]) does only make sense with integers as in ##([4 5 6] 1) |
| 03:41 | lazybot | ⇒ 5 |
| 03:41 | clgv | quizdr: no. (fn [x y] ([y x])) |
| 03:42 | fredyr | ,(macroexpand-1 '#([%2 % 1])) |
| 03:42 | clojurebot | (fn* [p1__52# p2__51#] ([p2__51# p1__52# 1])) |
| 03:43 | quizdr | i see |
| 03:43 | fredyr | ,(macroexpand-1 '#([%2 %1])) |
| 03:43 | clojurebot | (fn* [p1__78# p2__77#] ([p2__77# p1__78#])) |
| 03:43 | fredyr | quizdr: there's an extra parenthesis |
| 03:43 | clgv | ,(read-string "#([%2 % 1])") |
| 03:43 | clojurebot | (fn* [p1__106# p2__105#] ([p2__105# p1__106# 1])) |
| 03:44 | clgv | fredyr: it is not an actual macro ;) |
| 03:44 | fredyr | hah |
| 03:44 | quizdr | clgv macroexpand is quite useful for seeing inside syntax in general even for non macros |
| 03:45 | clgv | quizdr: not more useful then read-string, since that is where the non-macro is happening ;) |
| 03:45 | clgv | *non-macro magic |
| 03:46 | quizdr | ,(read-string "(#(%) 5)") |
| 03:46 | clojurebot | ((fn* [p1__131#] (p1__131#)) 5) |
| 03:47 | quizdr | (inc clgv) |
| 03:47 | lazybot | ⇒ 11 |
| 03:47 | quizdr | (+ clgv 10) |
| 03:47 | lvh | Hello! How can I get the number of days in between two local-dates in clj-time? |
| 03:47 | clgv | quizdr: but macroexpand-1 is *the* tool when writing macros |
| 03:48 | quizdr | (* clgv clgv) |
| 03:48 | clgv | :P |
| 03:48 | fredyr | ~clgv |
| 03:48 | clojurebot | Excuse me? |
| 03:49 | clgv | fredyr: what did you expect as return? |
| 03:49 | CookedGryphon | lvh: Something like (in-days (interval date1 date2)) |
| 03:50 | fredyr | clgv: some witty comment? |
| 03:50 | lvh | CookedGryphon: But interval doesn't work on two dates; because it considers them themselves intervals, not times |
| 03:50 | clgv | :P |
| 03:50 | lvh | CookedGryphon: so I also need a way to tack "noon" onto a date |
| 03:50 | CookedGryphon | lvh: how are you making the dates? |
| 03:51 | lvh | CookedGryphon: clj-time appears to do midnight, but even with my limited understanding of calendaring I'm pretty sure that's fragile unless you only use tz-agnostic types everywhere |
| 03:51 | lvh | right now, (local-date); but they will be read from a CSV file after |
| 03:51 | CookedGryphon | and it does, behind the scenes |
| 03:52 | CookedGryphon | if you put the tz data in, it'll use it. If you don't, I'm not sure what you want it to do? |
| 03:54 | lvh | CookedGryphon: When I use date-time, I appear to be getting Intervals in UTC (ISO timestamps ending in Z) |
| 03:55 | lvh | CookedGryphon: How do I tack on "noon" to something? I mean I guess I could do something like (apply local-time ((juxt year month day) my-date)) |
| 03:56 | lvh | ehh except of course with the times added :) |
| 03:56 | CookedGryphon | lvh: I might be wrong, but I don't think it will make any difference |
| 03:57 | CookedGryphon | if both the dates are in the same timezone (utc) it'll surely just do the arithmetic on the date field and all will be well, I don't see the need to shift it to noon |
| 03:57 | CookedGryphon | and if you did, what good it would do |
| 03:58 | TheDude_ | Hi, I'm new to clojure and trying to rename an uploaded file with a long timestamp, but for some reason the code is not working |
| 03:58 | CookedGryphon | the interval noon to noon is the same as the interval midnight to midnight |
| 03:58 | CookedGryphon | unless there's something fundamentally broken |
| 03:59 | CookedGryphon | especially as doing it at 00:00:00 is used all through the examples for jodatime/clj-time |
| 03:59 | lvh | CookedGryphon: It's probably a nitpick. If you have half an hour, I highly recommend http://pyvideo.org/video/1765/blame-it-on-caesar-what-you-need-to-know-about-d |
| 04:00 | TheDude_ | Thanks, am checking it out |
| 04:00 | TheDude_ | What would you recommend as a unique identifier for renaming an uploaded file? |
| 04:00 | CookedGryphon | lvh: yeah, but I trust jodatime/clj-time people have thought about this a lot more than I have, so trying to trick it by moving things to midday sounds like a bad idea... |
| 04:01 | lvh | CookedGryphon: In that talk, the author makes a cogent argument about exactly why it shouldn't ever be midnight. |
| 04:01 | lvh | CookedGryphon: (The answer is that not every midnight time instance exists.) |
| 04:01 | CookedGryphon | lvh: does this come up in your dataset? |
| 04:02 | CookedGryphon | have you tried putting them into jodatime |
| 04:02 | lvh | CookedGryphon: I have no idea, it's still being constructed. It does come up in real datasets, though. |
| 04:02 | CookedGryphon | i would be very surprised if it didn't work it out, or at least make a reasonable compromise |
| 04:02 | TheDude_ | Hi, does anyone know of a lib to handle file uploads and renaming the uploaded file? |
| 04:03 | lvh | CookedGryphon: (There's people that can't check into certain Alitalia flights because they were born on the wrong day; that particular problem is related to Europe/Rome and someone being under the mistaken impression that doing everything in the same timezone would make it sort of work out.) |
| 04:03 | fredyr | clojurebot: clgv |is| (read-string "((.)$(.))") |
| 04:03 | clojurebot | You don't have to tell me twice. |
| 04:04 | fredyr | ~clgv |
| 04:04 | clojurebot | clgv is (read-string "((.)$(.))") |
| 04:04 | CookedGryphon | lvh: lol, yeah, it is a bit of a minefield! |
| 04:04 | clgv | ,(read-string "((.)$(.))") |
| 04:04 | clojurebot | ((.) $ (.)) |
| 04:04 | clgv | :P |
| 04:04 | lvh | CookedGryphon: Anyway, times and calendars are incredibly complicated, and unfortunately not even Zulu time is as easy as we like to think it is (still has leap seconds) |
| 04:05 | clgv | clojurebot: forget clgv |is| (read-string "((.)$(.))") |
| 04:05 | lvh | also leap days |
| 04:05 | clojurebot | I forgot that clgv is (read-string "((.)$(.))") |
| 04:05 | fredyr | point free owl |
| 04:05 | clgv | ~clgv |
| 04:05 | clojurebot | It's greek to me. |
| 04:05 | fredyr | :( |
| 04:05 | lvh | Anyway, what I want is for something to tell me the number of days between 2014 01 01 and 2014 01 15. |
| 04:05 | clgv | clojurebot: clgv |is| usually very busy |
| 04:05 | clojurebot | You don't have to tell me twice. |
| 04:05 | clgv | ;) |
| 04:06 | TheDude_ | Does anyone know of a good tutorial on file uploads? Am new to clojure and this one issue is throwing me sideways. Rest ref routing, crud, sessions easy peasy. |
| 04:08 | srruby | How do I create a global atom? Thanks. |
| 04:10 | noonian | (def my-atom (atom {})) ? |
| 04:10 | srruby | noonian: Thanks! |
| 04:10 | noonian | np |
| 04:11 | TheDude_ | Hi, is anyone here avaliable to answer a question? |
| 04:12 | lvh | TheDude_: Lots of people. Probably not me. |
| 04:13 | noonian | just ask and if anyone knows the answer they will likely answer it |
| 04:14 | TheDude_ | Thanks. Have made good progress with clojure but stuck on 1 issue, uploading a file via ring and renaming it either with a long timestamp or maybe userid + sessionid |
| 04:14 | TheDude_ | Been trying to crack this nut for 2 days :) |
| 04:17 | noonian | where are you having trouble? |
| 04:17 | clgv | TheDude_: isnt a file upload just a HTTP POST request? |
| 04:18 | clgv | TheDude_: I am not sure about the browser side, but if it is just an HTTP POST request on your server you can just access the input stream of the request to get the contents of the file |
| 04:19 | TheDude_ | Yes, I can get a file and save it to a folder, however where I'm having trouble is renaming the file with a unique identifier such as long timestamp or session userid |
| 04:19 | clgv | when you save it to a folder you specify the filename and thus can use an arbitrary one |
| 04:20 | quizdr | ok, i'm looking at a decurrying excercise. i think i must be brain dead. how is it possible to peer inside a curried function to see what arguments it is using internally? |
| 04:21 | TheDude_ | I found some code, am trying it now by generating a random number via java |
| 04:21 | quizdr | or even to query the number of arguments a fn expects |
| 04:21 | TheDude_ | Does anyone have an idea how I would append or prepend that unique random number to the uploaded file name? |
| 04:22 | clgv | TheDude_: can you upload a minimal gist of your file upload code so that we have some context to help you? |
| 04:23 | clgv | appending to strings is easily done via ##(let [existing-string "my-file.txt"] (str "prefix." existing-string ".postfix")) |
| 04:23 | lazybot | ⇒ "prefix.my-file.txt.postfix" |
| 04:24 | clgv | if you want to append before the ending you can just split the string at the dot |
| 04:24 | clgv | the clojure.string namespace is what you want then |
| 04:25 | TheDude_ | Thanks guys, I will try that right now. My first time to IRC, how do I post the gist here? |
| 04:26 | ddellacosta | TheDude_: just paste it into refheap.com or gist.github.com (or whatever), and paste the link to that gist/refheap into the IRC window. |
| 04:27 | quizdr | ah, of course, use the curried function as a recursive function |
| 04:29 | TheDude_ | Thanks, here's the sample code point where I'm at now https://www.refheap.com/26875 |
| 04:29 | d11wtq | Hi guys. Looking for some input on DSL style choices in Clojure. |
| 04:29 | d11wtq | https://gist.github.com/d11wtq/8594436 |
| 04:30 | d11wtq | I'm writing (for learning only) a cron style scheduler, that distributes work across a number of nodes. It has a schedule file that is written in Clojure, as in that Gist. |
| 04:30 | d11wtq | Does that DSL look like you'd expect, or would you abstract further/less with macros? |
| 04:30 | TheDude_ | The first definition is handle-upload, not handle-upload-original |
| 04:31 | d11wtq | And would you put parentheses around each schedule entry, so it's more logically grouped? |
| 04:31 | d11wtq | (Sorry, I don't really know a better place to ask for peer review... stackoverflow not good for that) |
| 04:31 | CookedGryphon | d11wtq: definitely less with macros |
| 04:32 | CookedGryphon | d11wtq: I would make it data |
| 04:32 | quizdr | d11wtq programmers.stackexchange often boasts itself as a peer review site |
| 04:32 | CookedGryphon | d11wtq: for an amusing explanation of why, see this talk by stuart halloway http://vimeo.com/77199361 |
| 04:32 | quizdr | actually there is this new beta site at stackexchange, fyi: http://codereview.stackexchange.com/ |
| 04:33 | d11wtq | CookedGryphon: Yeah, so the angle was I going for there was, for example, avoiding Keywords and doing somethng like (every 5 minutes (println "Boo")) |
| 04:33 | d11wtq | But I don't like that. |
| 04:33 | d11wtq | Thanks for your suggestions on the other stackexchange sites! |
| 04:33 | d11wtq | I always forget about them :) |
| 04:33 | alandipert | d11wtq: looks cool to me, but yeah macros (if they get big) can be hairy. the only part i might change is to feed it functions instead of exprs for :every and :at; these functions could take the schedule as an arg perhaps |
| 04:34 | CookedGryphon | yeah, you should avoid macros if at all possible |
| 04:34 | clgv | ~gist |
| 04:34 | clojurebot | http://gist.github.com/ |
| 04:34 | clgv | the bot knows ^^ |
| 04:34 | clgv | but refheap as good as well |
| 04:36 | alandipert | d11wtq: also if you feed it functions isntead of exprs, defschedule doesn't need to be a macro anymore |
| 04:36 | d11wtq | Yeah, the macro will (obviously) ultimately construct a function that calls other functions. I think some level of macro usage makes writing something like a schedule cleaner though, so you don't need to wrap everything with lambda. |
| 04:36 | alandipert | (not that macros are bad, i personally think they rule and i write them all the time) |
| 04:37 | d11wtq | It's funny hearing people say to avoid macros. It wasn't that long ago (before I started in Clojure) that I read Let Over Lambda. That puts things in perspective. A little defschedule macro is nothing :P |
| 04:37 | CookedGryphon | d11wtq: DSLs are very rarely a good idea. You make it so people can't compose what you're doing easily, and obscure it so that if people want to do anything out of the ordinary, they will probably need to know something about what your macros are generating |
| 04:37 | CookedGryphon | and heaven forbid there's ever a case you didn't think of ahead of time |
| 04:37 | alandipert | d11wtq: imo clojure is a tighter/better designed system than CL, and macros are scarcer because they aren't needed to stitch together the language as much |
| 04:38 | tomjack` | a project for which a CL'er I know thought essential, in clojure, ended up needing virtually no macros |
| 04:39 | tomjack` | er, "for which a CL'er I know thought _macros_ essential" |
| 04:40 | d11wtq | Thanks guys. I'll do this with functions alone and finish off by providing a convenience macro. I think that's the way to go (and the way I'd naturally TDD this). |
| 04:42 | CookedGryphon | d11wtq: I really recommend that talk I linked to, which would suggest storing your schedule as data where possible. That way other tools can read your data, say you wanted to make a separate app to show you upcoming events rather than scheduling them, or allow you to reconfigure them graphically |
| 04:42 | CookedGryphon | that would be easy with data |
| 04:42 | CookedGryphon | hard with functions, and extremely difficult with a dsl |
| 04:42 | CookedGryphon | http://vimeo.com/77199361 |
| 04:42 | CookedGryphon | there you go again |
| 04:42 | TheDude_ | Would it be possible to get some feedback on this code https://www.refheap.com/26879 |
| 04:43 | d11wtq | http://vimeo.com/77199361 thanks |
| 04:43 | TheDude_ | Am trying to rename an uploaded file |
| 04:44 | steckerhalter | how do I convert long to a byte array? I have found this where the question outlines how to do it with Java, but I'm not sure how to translate that in to Clojure: http://stackoverflow.com/questions/19791255/how-to-convert-byte-array-to-long-without-using-java-nio |
| 04:45 | CookedGryphon | steckerhalter: I would recommend a ByteBuffer instead of an outputstream if you know the length of your data vaguely |
| 04:45 | CookedGryphon | and don't need to stream |
| 04:46 | steckerhalter | CookedGryphon: ok, any examples how to use it for this purpose? |
| 04:46 | CookedGryphon | then you just do (doto (java.nio.ByteBuffer/allocate 8) (.putLong 123) (.putLong 321)) etc |
| 04:47 | CookedGryphon | and then .rewind to go back to the start of the bytebuffer if you want to overwrite, or read out one thing at a time |
| 04:48 | CookedGryphon | and look at the docs for how to get a byte array out of that |
| 04:48 | steckerhalter | thanks |
| 04:48 | CookedGryphon | .array i think |
| 04:48 | noncom | anyone using twitter-api, can show an example of a restful statuses-update call? what will be the :params? |
| 04:49 | CookedGryphon | steckerhalter: np, hope that's enough info to get you started |
| 04:50 | ddellacosta | TheDude_: you need to take a look at ring's multipart-params namespace: https://github.com/ring-clojure/ring/wiki/File-Uploads |
| 04:51 | ddellacosta | TheDude_: http://ring-clojure.github.io/ring/ring.middleware.multipart-params.html |
| 04:53 | TheDude_ | Thanks ddellacosta, am checking that right now |
| 04:53 | ddellacosta | TheDude_: try reading through some of the examples that exist first, because your code doesn't really seem to reflect how ring/compojure works. Google "file upload with ring/compojure" and you should find some good examples. |
| 04:56 | ddellacosta | TheDude_: or at least, I'm not sure what's happen with all the functions that you are including from the pgapp.util namespace; could be they are doing the heavy lifting. |
| 04:58 | TheDude_ | I got it working with file name as is and to a dynamically created directory for user |
| 04:58 | TheDude_ | But I prefer to save em all in one folder with a unique identifier in the file name and store that in the db |
| 04:59 | TheDude_ | I'll try a search with ring compojure, since I'm new to clojure not so familiar with all the plumbing in the various libraries |
| 04:59 | TheDude_ | SQL Crud, views, sessions, all easy peasy, file upload and manpilating how file is name, where saved, etc, bit challenging :) |
| 05:00 | ddellacosta | TheDude_: ah, I see. I think the problem with your example is just that it's hard to see what stuff like upload-file and gallery-path are doing. |
| 05:00 | TheDude_ | The functions in the utils namespace just supply the folder name where to save the file |
| 05:00 | TheDude_ | gallery-path is just a reference to the actual folder to store |
| 05:00 | ddellacosta | TheDude_: it would probably be useful to put that in the refheap next time so people can see what they are returning and how they work. |
| 05:01 | TheDude_ | upload file I myself am confused :) I don't see it in my utls file |
| 05:02 | ddellacosta | TheDude_: if you are just getting familiar w/Ring and Compojure definitely scan through the examples of argument de-structuring and read up on how the request map works--and you may get some of a sense of how it is by simply dumping out the request itself in your code, to start. That can be useful if it's not clear what is getting passed where. |
| 05:02 | TheDude_ | Oh I got it, upload-file is a reference in the [noir.io :refer [upload-file resource-path]] |
| 05:03 | ddellacosta | TheDude_: ah, sorry--I see that referenced in the require form now, I missed it. |
| 05:03 | TheDude_ | How long do you think it typically takes a newbie adpoting clojure from standard 00 langs like ruby or coldfusion? |
| 05:03 | TheDude_ | lisp is def a diff paradigm, enjoying the journey so far |
| 05:03 | AeroNotix | so my co-worker is trying to set up cider, when opening a cider-jack-in repl and then loading code into it, it complains it cannot find classes. Printing out the class path suggests that it's not picking up the project at all. |
| 05:04 | ddellacosta | TheDude_: in that case, take a look at the noir docs: http://yogthos.github.io/lib-noir/noir.io.html#var-upload-file. I would suggest maybe leaving noir off at first and doing it via ring...just so you get how ring works at first. |
| 05:05 | TheDude_ | Is lib-noir created by yogothos? |
| 05:05 | ddellacosta | TheDude_: re: how long it takes? If you've done ruby or python and are familiar with wsgi or rack, then you should get a sense of how ring works pretty quickly. |
| 05:06 | TheDude_ | Yes it seems to work same way as middleware |
| 05:06 | ddellacosta | TheDude_: lib-noir is maintained by yogthos, but grew out of code from the-framework-formerly-known-as-noir by Chris Granger |
| 05:06 | ddellacosta | TheDude_: er, not just yogthos I guess |
| 05:06 | TheDude_ | yogothos is the man, he's been v helpful |
| 05:08 | TheDude_ | I think the key here is reading up the docs and getting more familiar with the plumbing |
| 05:08 | TheDude_ | I'm just a week into it so far, looks v promising |
| 05:08 | ddellacosta | TheDude_: yep, definitely agree--I think you'll feel a lot more comfortable with it once you've gotten through Ring/Compojure docs, especially (if you want to do server-side web stuff). |
| 05:09 | TheDude_ | I'm mostly doing server side stuff, about 99% |
| 05:09 | ddellacosta | TheDude_: and I definitely recommend looking at the codebase for those two projects as well, they are clean and well written, and the ring architecture itself is simple and logical. |
| 05:10 | TheDude_ | Are you doing web dev stuff or you have a diff use case? |
| 05:11 | ddellacosta | TheDude_: I do web dev with Clojure, yep. |
| 05:12 | ddellacosta | TheDude_: but there are a lot of folks using Clojure in a lot of different domains. |
| 05:12 | TheDude_ | Using any framework or you write your own |
| 05:13 | ddellacosta | TheDude_: mostly just Compojure, with various libs here and there. I haven't yet found a framework that is as useful as simply composing libraries together. |
| 05:13 | TheDude_ | Yeah, I like the simplicity of just putting together some libraries |
| 05:13 | fredyr | speaking of server side web in clojure, whats the way to setup user account logins and such, with email verification? |
| 05:14 | TheDude_ | Thanks for your help, calling it a night for now. Goodnight and again thanks. |
| 05:15 | ddellacosta | TheDude_: cheers, good luck! :-) |
| 05:15 | ddellacosta | fredyr: I've built two systems which do that, and they both have required a fair bit of code slinging, unfortunately. :-( |
| 05:15 | fredyr | ddellacosta: too bad |
| 05:15 | ddellacosta | fredyr: but, the one I built with Friend was a bit simpler. For that project, I used mailchimp + friend. |
| 05:16 | ddellacosta | fredyr: I mean, it was a lot of code compared to how I used to set up Rails w/Devise back in my RoR days. But, then again, I had to use Rails. ;-) |
| 05:16 | fredyr | haha right |
| 05:16 | fredyr | yeah, i guess i'm comparing to how i would've done it with django |
| 05:17 | ddellacosta | fredyr: the other way I did it was an even more customized version which uses safeguard (my company's lib: https://github.com/diligenceengine/safeguard) |
| 05:17 | AeroNotix | so my co-worker is trying to set up cider, when opening a cider-jack-in repl and then loading code into it, it complains it cannot find classes. Printing out the class path suggests that it's not picking up the project at all. |
| 05:17 | ddellacosta | fredyr: yeah, I think that friend is the closest thing we've got to anything rails or django could give us (not knowing what is possible with django, but I assume it is easier) |
| 05:18 | ddellacosta | AeroNotix: is he starting it up in the project directory? I've only started up cider by starting a repl in a separate project dir, then connecting to that, which always works nicely for me. |
| 05:19 | ddellacosta | god, that safeguard read me is f*cking terrible |
| 05:19 | ddellacosta | forgive me for saying so boss. ;-) |
| 05:21 | ddellacosta | fredyr: I've actually been meaning to write some sort of "get-going-quickly" thing for friend which wraps up some of the functionality that you get with something like devise in Rails. |
| 05:22 | ddellacosta | fredyr: I should add, there is also going the Java route--there are wrappers for stuff like apache shiro I think |
| 05:22 | ddellacosta | fredyr: https://github.com/inventiLT/Pocheshiro |
| 05:22 | ddellacosta | fredyr: it's just...very Java-y |
| 05:46 | muhoo | i love that there's an oath-clj and a clj-oauth library, which are different but seem to do the same thing |
| 05:47 | steerio | at least there's a different word in both (if that's really oath there) |
| 05:47 | steerio | in both = in each |
| 05:47 | steerio | i can't english |
| 05:52 | katox | is there a simple way in sider to run (macroexpand-1 'form) instead of default (macroexpand-1 form)? |
| 05:57 | katox | what do I do now is to expand all macros from the top level form to get to the proper level - or - just copying the stuff into the repl, adding pprint macroexpand-1 and quote, that seems silly |
| 06:05 | tim__ | what is the difference between '(use 'a.b)' and '(:use a.b)'? |
| 06:10 | katox | tim__: the second is the form used in ns macro, the first is the actual call |
| 06:11 | tim__ | Thanks |
| 06:11 | katox | tim__: np, that said, use is somewhat obsolete now that require has :refer option |
| 06:13 | tim__ | thats a lot of help, i'm very new to clojure. |
| 06:18 | Morgawr | ,(int 1.999999999) |
| 06:18 | clojurebot | 1 |
| 06:18 | Morgawr | ,(int 1.999999999999999999999999) |
| 06:18 | clojurebot | 2 |
| 06:18 | Morgawr | welp |
| 06:19 | Morgawr | https://gist.github.com/tshauck/8591809 <- |
| 06:22 | hyPiRion | Morgawr: well |
| 06:22 | hyPiRion | ,1.999999999999999999999999 |
| 06:22 | clojurebot | 2.0 |
| 06:23 | Morgawr | ,1.999999 |
| 06:23 | clojurebot | 1.999999 |
| 06:23 | Morgawr | I see |
| 06:23 | Morgawr | still fun |
| 06:23 | arcatan | even clojure knows that 1.999... = 2 |
| 06:25 | locks | nothing is true, everything is permitted |
| 06:25 | Morgawr | but then how come (apply + (range)) doesn't return -1/12? :D |
| 06:27 | hyPiRion | because range isn't infinite |
| 06:29 | hyPiRion | ,(doall (range (- Long/MAX_VALUE 1000) Double/POSITIVE_INFINITY)) |
| 06:29 | clojurebot | #<ArithmeticException java.lang.ArithmeticException: integer overflow> |
| 06:32 | AeroNotix | org.apache.commons.io.IOUtils where does this package/class live? Do I need to download it? |
| 06:33 | alew | I find it very curious that (take 2.5 x) returns 3 elements instead o f2 |
| 06:34 | alew | ,(take 2.5 (range 5)) |
| 06:34 | clojurebot | (0 1 2) |
| 06:34 | hyPiRion | AeroNotix: add [commons-io/commons-io "2.4"] to your dep vectory |
| 06:35 | AeroNotix | hyPiRion: cheers |
| 06:37 | TEttinger | ),(take 2.4 (range 5)) |
| 06:37 | TEttinger | ,(take 2.4 (range 5)) |
| 06:37 | clojurebot | (0 1 2) |
| 06:37 | TEttinger | seems to round up |
| 06:37 | alew | If you look at the implementation |
| 06:38 | alew | it's actually just dec'ing each iteration |
| 06:38 | alew | and checking if positive |
| 06:38 | alew | so you get down to 0.4 |
| 06:38 | alew | Still seems like odd behaviour |
| 06:39 | TEttinger | rand-int can take a fraction or float param too. it's even weirder |
| 06:40 | TEttinger | ,(frequencies (repeatedly 1000 #(rand-int 2.5))) |
| 06:40 | clojurebot | {2 201, 1 368, 0 431} |
| 06:41 | TEttinger | note how 2 shows up about half as frequently as the others |
| 06:41 | alew | what the fuck.. |
| 06:47 | TEttinger | alew, that probably has to do with just dividing (rand) by the arg to rand-int |
| 06:48 | TEttinger | or multiplying? |
| 06:49 | CookedGryphon | or it could be that int is truncating, doing a floor |
| 06:49 | CookedGryphon | so 0 and 1 buckets are both twice as big as the 2.5 bucket |
| 06:49 | hyPiRion | CookedGryphon: yeah, rand-int is essentially just (int (* n (Math/random))) |
| 07:18 | lvh | Hi |
| 07:19 | lvh | is there a way to tell group-by what to put items into |
| 07:19 | lvh | I want them also *sorted* by (f elem), not just grouped by. |
| 07:22 | CookedGryphon | (into (sorted-map) (group-by f coll))? |
| 07:23 | CookedGryphon | or sorted-map-by |
| 07:23 | CookedGryphon | as your keys are already the values you want to sort by |
| 07:25 | hyPiRion | I think lvh means that the lists inside the maps are sorted |
| 07:25 | lvh | nope, CookedGryphon had it right |
| 07:25 | lvh | the keys of the map have to be sorted |
| 07:26 | lvh | is there some kind of convention for a memoized function and its unmemoized variant? |
| 07:26 | lvh | Sorry, I mean for the *names* of them. |
| 07:26 | CookedGryphon | lvh, i usually call the unmemoized variant blah* |
| 07:26 | lvh | And then (def blah (memoize blah*))? |
| 07:29 | CookedGryphon | lvh: yeah |
| 07:30 | CookedGryphon | I think I've seen it in a few other libraries too |
| 07:30 | CookedGryphon | only issue with that |
| 07:30 | CookedGryphon | is that the def there isn't going to pick up the docstring from blah* |
| 07:30 | CookedGryphon | and the arglist |
| 07:31 | CookedGryphon | not sure what to do about that other than manually attach the metadata |
| 07:35 | hyPiRion | lvh: we do alter-var-root'ing in Leiningen. Consider doing that if you never use the unmemoized version |
| 07:46 | john2x | can I 'unload' a namespace I use/refer/required in the repl? |
| 07:57 | noidi | ,(doc remove-ns) |
| 07:57 | clojurebot | "([sym]); Removes the namespace named by the symbol. Use with caution. Cannot be used to remove the clojure namespace." |
| 08:02 | locks | ,(doc doc) |
| 08:02 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 08:12 | lvh | Hi |
| 08:12 | lvh | is there a more efficient "intersection?"? Maybe just intersection is already doing what I want |
| 08:12 | lvh | Basically I have a 2-set and an N-set; if either element is in the N-set, give up |
| 08:13 | lvh | I think the way to spell that is (if (seq (intersection s1 s2))) |
| 08:13 | llasram | lvh: You can do way better than that |
| 08:13 | llasram | If you know s1 is smaller than s2, |
| 08:13 | llasram | (if (some s2 s1) ...) |
| 08:13 | lvh | llasram: Nope. The N-set starts out empty. |
| 08:14 | lvh | llasram: Maybe I should explain what I'm trying to do |
| 08:14 | lvh | I'm trying to solve a hotel-pairing optimization problem |
| 08:14 | llasram | Maybe :-) |
| 08:14 | lvh | I've figured out how to produce candidate pairs in terms of decreasing preference |
| 08:14 | alandipert | check each element w/ contains? |
| 08:14 | lvh | if either of the people in the candidate pair is aready assigned, obviously I can't assign them again |
| 08:14 | lvh | so, I'm keeping a set of already assigned people. |
| 08:15 | lvh | Does that make sense? |
| 08:15 | lvh | (That's the big N-set. It obviously starts empty.) |
| 08:15 | lvh | maybe that still means some, though. |
| 08:16 | llasram | Totally. And my suggestion still holds -- I just made it overly-strong. And you can always generalize. The important part is that you only care that there is an intersection vs the content of the intersection |
| 08:16 | lvh | because it doesn't actually matter if the set is bigger |
| 08:16 | lvh | right? |
| 08:16 | lvh | right |
| 08:16 | lvh | llasram: Thanks! |
| 08:16 | llasram | np! |
| 08:16 | hyPiRion | lvh: as far as I understand, you can just do (not-any? #(contains? s2 %) s1) |
| 08:17 | hyPiRion | well heck, llasram's solution is way better. I'll go away now. |
| 08:17 | llasram | hah |
| 08:17 | llasram | Actually *I'll* go away now! |
| 08:17 | llasram | That'll show ya |
| 08:17 | lvh | actually, rethinking my algorithm, it may be necessary to actually have the intersection anyway |
| 08:18 | hyPiRion | I guess I am terrified of nil and write code to defend against them at any momemt. |
| 08:18 | lvh | hmmm, maybe not, because I have every combination |
| 08:18 | lvh | I need a whiteboard |
| 08:18 | alandipert | some is o(n) worst case though, vs. just using 2 contains? checks |
| 08:19 | hyPiRion | alandipert: not if you know that s1 contains 2 elements only |
| 08:19 | lvh | yeah, I can guarantee they're only pairs. |
| 08:19 | lvh | because they come from (combinations all-users 2) |
| 08:20 | alandipert | hyPiRion: oh, right! i had my s1 and s2 backwards |
| 08:24 | lvh | are nested loop/recurs okay? |
| 08:25 | hyPiRion | lvh: I would recommend to split the function up into more functions if that happens |
| 08:25 | hyPiRion | But it's doable, sure, just a bit convoluted :) |
| 08:25 | lvh | I'm having a hard time making function names sane |
| 08:25 | lvh | (defn pair-least-unmatched-days-within-subgroup) |
| 08:26 | lvh | is there a refactoring thing for emacs that understands clj projects |
| 08:26 | lvh | that can rename function names? |
| 08:26 | CookedGryphon | lvh clj-refactor |
| 08:26 | CookedGryphon | is probably the closest thing |
| 08:26 | lvh | oooh! |
| 08:26 | CookedGryphon | you can do nice things like rename file which will update all the references to your namespace too |
| 08:27 | CookedGryphon | and unwind/wind threaded expressions |
| 08:27 | lvh | awesome |
| 08:27 | CookedGryphon | but mainly I use it for shifting namespaces around |
| 08:27 | lvh | there's a few things I'm writing that I'm pretty sure can be rewritten with reducers |
| 08:27 | CookedGryphon | if you open a new .clj file, it'll fill out your ns declaration for you too which is nice |
| 08:31 | alew | CookedGryphon: thanks for the tip |
| 08:32 | lvh | yep |
| 08:32 | lvh | mind blown. |
| 08:32 | CookedGryphon | if you think that's good, wait till I get round to updating latest-clojure-libraries |
| 08:33 | CookedGryphon | my first foray into elisp, which unfortunately doesn't work at the moment thanks to the nrepl->cider thing |
| 08:33 | CookedGryphon | for looking up and inserting teh latest version of a thing into your project.clj, then uses pomegranate to load it into your running repl with no restart if you want |
| 08:42 | katox | another dozen or so hours lost on a dynamic binding |
| 08:43 | katox | reminds me dependency injection - it feels good at first ;) |
| 08:55 | lvh | hey |
| 08:56 | lvh | ... wait, I just figured it out. |
| 08:56 | lvh | Sorry :D |
| 09:16 | steckerhalter | it seems that using a ByteBuffer and then doing .putInt in a map does not operate on the original ByteBuffer? the ByteBuffer stays empty at least |
| 09:18 | andyf_ | map is lazy. Try doseq around things that you want for side effects |
| 09:19 | steckerhalter | andyf_: ok, will do |
| 09:20 | andyf_ | katox: binding and dorun/doall - 2 things that often go well together |
| 09:22 | katox | andyf_: true enough, this time nil crept in sometimes though |
| 09:45 | mikerod | empty? is a fn; not-empty? is not a fn; not-empty is a fn ;= fn naming fail |
| 09:45 | afhammad | what am I missing: I am requiring [monger.core :as mg] within a namespace, however get this: java.io.FileNotFoundException: Could not locate monger/core__init.class or monger/core.clj on classpath |
| 09:45 | afhammad | I have this in my project dependencies: [com.novemberain/monger "1.7.0"] |
| 09:46 | AeroNotix | any httpcs to recommend? |
| 09:46 | AeroNotix | http-kit/aleph? |
| 09:47 | mikerod | maybe `not-empty` was named like that, to make people hate it and just use `seq` instead |
| 09:50 | gfredericks | mikerod: not-empty? would suggest it's a predicate which returns a boolean, which would not be true |
| 09:50 | gfredericks | ,(not-empty {:a 2}) |
| 09:50 | clojurebot | {:a 2} |
| 09:51 | gfredericks | similarly we have some instead of any? |
| 09:51 | gfredericks | ,(some #(when (pos? %) (inc %)) [-2 -1 0 1 2]) |
| 09:51 | clojurebot | 2 |
| 09:52 | mikerod | gfredericks: that's fair enough, but it *should* be a predicate that is analogous to `empty?` |
| 09:52 | gfredericks | presumably rhickey disagrees |
| 09:52 | mikerod | some, is useful to not be a predicate; it can serve as a "get first" fn |
| 09:52 | CookedGryphon | ugh, midje |
| 09:52 | CookedGryphon | sorry, that was meant to be qualified with a complaint :P |
| 09:53 | quizdr | some can return more than just true or false, therefore it is not a predicate |
| 09:53 | CookedGryphon | midje isn't reloading when i change my source, just when i change the test file |
| 09:53 | CookedGryphon | any ideas? |
| 09:53 | mikerod | I'm just coming from the standpoint of helping some people write some clj code. They don't quickly accept `seq` as a "not empty" check. They understand "empty?" of course, but then they always get confused when it comes to "not-empty" - no ? mark. |
| 09:53 | mikerod | I meant, new people to clj. |
| 09:53 | mikerod | anyways, just a little nit pick really. |
| 09:54 | gfredericks | clojure is a constant pile of confusion and surprises to new people |
| 09:54 | mikerod | :P |
| 09:54 | mikerod | fair enough |
| 09:54 | afhammad | gfrederick: yes it is |
| 09:55 | gfredericks | docstrings are often helpful |
| 09:55 | gfredericks | it's nice that they're so integrated |
| 09:55 | gfredericks | rather than having to google to find them |
| 09:56 | gfredericks | I think I had the idea of curating a list of clojure gotchas before |
| 09:58 | gfredericks | ,(doc not-empty) |
| 09:58 | clojurebot | "([coll]); If coll is empty, returns nil, else coll" |
| 09:58 | jcromartie | somebody help me decipher net.cgrand.reload |
| 09:58 | gfredericks | does anybody have a solution for cleaning up resources associated with a ring response after the inputstream has closed? |
| 09:58 | jcromartie | where do the ::deps metadata come from? do I have to add that to the ns myself? |
| 09:59 | jcromartie | the documentation in the README here is clearly insufficient https://github.com/cgrand/enlive |
| 09:59 | jcromartie | it just says call (net.cgrand.reload/auto-reload *ns*) |
| 09:59 | llasram | gfredericks: I just got a PR merged into ring which allow using the CollReduce protocol instead of a seq of strings |
| 09:59 | llasram | You can reify that protocol with your own setup/cleanup surrounding the actual reduce behavior |
| 09:59 | gfredericks | llasram: I'm using cheshire; is there a way to combine those? |
| 10:00 | gfredericks | I guess if I serialized the top-level array myself... |
| 10:00 | llasram | gfredericks: I may have misunderstood. Do you have public code, or more details? |
| 10:01 | llasram | Ooops -- gotta scrum. bbiaf |
| 10:01 | gfredericks | k |
| 10:06 | gfredericks | llasram: it's not public; I'm currently using piped-input-stream to start another thread that uses cheshire.core/generate-stream |
| 10:07 | gfredericks | I'm having trouble figuring out how CollReduce is useful at all, much less for my particular use case |
| 10:07 | gfredericks | I must be missing something |
| 10:08 | clgv | where is piped-input-stream from? |
| 10:08 | gfredericks | ring.util.io |
| 10:10 | gfredericks | I had the impression that pjstadig's scoped library could help with this but then I read through it this morning and I don't think that's true |
| 10:11 | mmitchel_ | stuartsierra: I'm looking at using your component lib for a new web app. Would you consider it to be stable enough for a prod app? Also, do you know who might be using it? |
| 10:11 | clgv | anyone used graphstream from clojure, yet? is it easy to use for visualization? |
| 10:11 | mmitchel_ | stuartsierra: oh well, i see the README - alpha, beta etc :) |
| 10:11 | stuartsierra | mmitchel_: It's quite simple, so yes I consider it stable. I am currently using it on a large client project. |
| 10:11 | mmitchel_ | nice |
| 10:12 | stuartsierra | Where "stable" means "doesn't have any obvious bugs." |
| 10:12 | mmitchel_ | It does look quite simple +1 |
| 10:12 | stuartsierra | But I still reserve the ability to change the public API between 0.x versions. |
| 10:17 | shep-home | Is there a way of telling if putting onto a core.async channel will block? |
| 10:17 | tbaldridge | shep-home: no, but you can make sure it never blocks |
| 10:18 | tbaldridge | shep-home: and you can use alt! with :default (or timeout) to do something else if it tries to block |
| 10:18 | shep-home | tbaldridge: thanks. I was thinking of something like a webservice that gets a request and puts it into a channel |
| 10:19 | shep-home | it could be preferable to return an HTTP busy code right away, and not do the work |
| 10:19 | shep-home | I think this is called backpressure, but I'm still learning my way around :-) |
| 10:20 | tbaldridge | shep-home: yeah, use a channel with a larg-ish buffer and then do (alts!! [[c val]] :default :busy) |
| 10:20 | tbaldridge | that'll instantly return :busy if the channel is full |
| 10:20 | shep-home | Yeah, that makes sense. I was looking at put, but couldnt see how that would help |
| 10:20 | shep-home | thanks! |
| 10:20 | AeroNotix | any httpcs to recommend? |
| 10:22 | llasram | gfredericks: Yeah, you'd need to change your code so that it somehow produces a "collection" of strings instead of writing to an input stream |
| 10:30 | andyf_ | stuartsierra: I didn't look thoroughly, but does tools.namespace or any other lib you know implement a check that source file names and namespace symbols in ns forms are consistent with each other? |
| 10:31 | andyf_ | stuartsierra: And if not, would such a thing be a useful addition to tools.namespace? |
| 10:31 | stuartsierra | andyf_: I'm not sure I understand the question. If ns forms don't match their files, Clojure won't even load them. |
| 10:31 | andyf_ | stuartsierra: But someone can create them and get no errors |
| 10:32 | CookedGryphon | andyf_: in emacs clojure mode you can do (clojure-update-ns) which will replace it with the appropriate namespace |
| 10:32 | andyf_ | stuartsierra: I am testing Eastwood on many projects, and sometimes I run across oddball things like this. They can be hard to debug the exceptions that get thrown |
| 10:32 | CookedGryphon | and clj-refactor automatically fills in the right one when you open a file |
| 10:32 | gfredericks | llasram: what's the advantage over a lazy seq? |
| 10:33 | stuartsierra | andyf_: Sounds like something for a linter like Eastwood to check, then. |
| 10:33 | andyf_ | I am planning on adding an easy-to-understand message: Hey, this file contains a namespace foo.bar, but it should be bar.baz based on its name. |
| 10:33 | andyf_ | stuartsierra: Oh, it will. I'm just asking if tools.namespace is a reasonable home for a function that finds such things or not. |
| 10:34 | stuartsierra | andyf_: Not sure. I'll think about it. |
| 10:34 | hipsterslapfight | express : node :: xxx : clojure ... is there an xxx? |
| 10:35 | andyf_ | I have read an article about someone in academia who took a C lint tool commercial, and the crazy things they found out in the wild in real C code. I am starting to get a tiny idea of 1% of the stuff that they must have come across :-) |
| 10:35 | tim__ | are there any tools like checkstyle / findbugs / pmd etc available for clojure? |
| 10:36 | andyf_ | tim__: I do not know exactly what those tools do, but you may want to look at kibit and Eastwood, both on github |
| 10:38 | llasram | gfredericks: You can have set-up / tear-down code :-) |
| 10:46 | tim__ | @andy_f thanks, they are exactly what i'm after. |
| 10:47 | gfredericks | llasram: where does the teardown code go? the edge-case is when the socket is closed so the whole thing doesn't get sent |
| 10:53 | ambrosebs | dnolen: do I have to maintain my own cljs.env atom when analyzing CLJS forms? And should I always initialise it by loading core.cljs with my env as cljs.env/*compiler* ? |
| 10:53 | llasram | gfredericks: The client socket? So like, your service is streaming a chunked response, and the client just closes the socket as some point? |
| 10:53 | jita | Is IntelliJ good IDE for clojure programming ? |
| 10:55 | saolsen | jita: with the cursive plugin it's pretty great |
| 10:55 | saolsen | http://cursiveclojure.com/ |
| 10:55 | jita | saolsen: there is la clojure too how does it compare to that ? |
| 10:55 | saolsen | I use it a lot, especially if I have to do anything with java interop. |
| 10:55 | blrm | saolsen: i haven't seen that, looks nice. i just knew of la clojure |
| 10:56 | saolsen | This one is newer and I think they built it because of some frustrations they had with la clojure |
| 10:56 | saolsen | I haven't used la clojure though. |
| 10:56 | locks | for some reason I was under the impression that cursive and la clojure were by the same people |
| 10:57 | locks | or at least people in common? |
| 10:57 | saolsen | they might be |
| 10:57 | saolsen | I don't really know who's behind it |
| 10:57 | locks | they changed the name to break backwards compat and etc |
| 10:57 | jita | saolsen: cool, and when you are not working for java interop what do you use? emacs ;) |
| 10:57 | locks | this is mostly guessing tho |
| 10:57 | saolsen | but they're really good, super responsive on twitter and github issues and seem to ship a new version every week or so |
| 10:58 | saolsen | I bounce back and forth between emacs and cursive. |
| 11:00 | llasram | saolsen: Have you tried eclim? |
| 11:01 | saolsen | llasram: nope, never heard of it |
| 11:01 | llasram | saolsen: https://github.com/senny/emacs-eclim |
| 11:01 | llasram | Essentially runs Eclipse as a background service, then lets Emacs talk to it |
| 11:04 | saolsen | interesting |
| 11:04 | saolsen | is there clojure integration? |
| 11:04 | jita | saolsen: do you use cursive plugin or IDE? |
| 11:04 | saolsen | the ide isn't out yet |
| 11:04 | saolsen | just the plugin |
| 11:04 | saolsen | and it's still in alpha so you have to add their repository |
| 11:05 | jita | saolsen: does it work with intelliJ 13ce? |
| 11:05 | saolsen | the site covers how to get set up |
| 11:05 | saolsen | jita: yep |
| 11:05 | jita | saolsen: thanks |
| 11:06 | llasram | saolsen: Oh, no. I misunderstood. It's definitely for writing Java from Emacs, which is for some reason is what I'd taken you to be talking about |
| 11:10 | lvh | my tests appear to have hit an infinite loop. |
| 11:10 | lvh | how do I stop them? I'm using run-tests in the repl |
| 11:10 | arrdem | mash C-g? |
| 11:11 | lvh | Doesn't appear to be working. |
| 11:11 | clgv | Ctrl+C in lein repl |
| 11:11 | kzar | C-c? |
| 11:11 | kzar | oo too slow |
| 11:11 | lvh | nREPL connection closed: connection broken by remote peer |
| 11:11 | lvh | I think that means java gave up |
| 11:11 | lvh | maybe? |
| 11:12 | clgv | lvh: killall -9 java ;) |
| 11:13 | cark | or more mashing on the box itself |
| 11:14 | lvh | hehe :) |
| 11:14 | lvh | if anyone has a second to give me some style advice, I think https://github.com/lvh/pairing/blob/master/src/pairing/core.clj#L81 can use plenty |
| 11:14 | lvh | pair-days is what I'm calling and what's doing what appears to be an infinite loop |
| 11:14 | lvh | maybe it's actually just really really slow |
| 11:15 | Anderkent | well, I don't see pair-days ever going out of the loop |
| 11:15 | Anderkent | it always recurs |
| 11:16 | lvh | ah, yes, that would be bad. |
| 11:16 | Anderkent | pair-subgroup-days seems ok, one thing I'd do is put pairs and paired on separate lines in 0 and 1 cases, so that it looks exactly like the 2 case |
| 11:16 | Anderkent | but it's a very minor issue |
| 11:17 | Anderkent | in pair-days you just want to check if you have any subgroups left, I guess? |
| 11:17 | lvh | yeah; I added the (if (seq |
| 11:18 | jstew | If I have a collection [[1 2] [3 4]], what's a nice way to split them by column so that they're [[1 3][2 4]]? My solution is ugly, and I know there's an elegant way. |
| 11:18 | lvh | it appears that I always get [[] []] back from it though |
| 11:19 | Anderkent | this is another super minor thing, but I prefer to have the terminating case first, since it's so short. saves scanning down to see what the other case is |
| 11:19 | Anderkent | compare https://www.refheap.com/26994 |
| 11:19 | AeroNotix | https://gist.github.com/AeroNotix/eecf8d63aa307381bfff anything more idiomatic than this? |
| 11:19 | Anderkent | lvh: do you know if pair-subgroup-days works? :P |
| 11:20 | lvh | Anderkent: Nope, writing tests |
| 11:20 | clgv | AeroNotix: there was a lib for byte array and such mentioned on the ML some time ago |
| 11:20 | AeroNotix | clgv: I was looking for something like this, decided to just start it myself. |
| 11:21 | Anderkent | AeroNotix: what's it trying to do, split a byte array into two around the first occurence of c? |
| 11:22 | AeroNotix | Anderkent: like string/split for byte-arrays |
| 11:22 | Clome | is there a way to work with java primitives? A java fun returns an int, but in clojure I get an Integer object. Is there a way to tell clojure that I want a normal int. |
| 11:23 | Anderkent | why use BAIS instead of areduce? |
| 11:23 | clgv | Anderkent: +1 |
| 11:24 | Anderkent | Clome: you can tag the arg sometimes. But in general I'd accept boxed stuff most of the time |
| 11:24 | Anderkent | if you really need performance, look into https://github.com/ztellman/primitive-math ? |
| 11:26 | Clome | Anderkent: A method in java returns an int, and then I use this int in a (case ) form which returns always the default, since integer is an object and it test the memory reference? |
| 11:27 | Anderkent | Clome: that doesn't sound right, it should automatically unbox it if your case is int-based |
| 11:28 | Anderkent | ,(case (Integer. 0) 0 :yes :no) |
| 11:28 | clojurebot | :yes |
| 11:28 | Anderkent | Clome: ^ |
| 11:29 | Clome | Anderkent: it is not int based, since in the casess I use static java int fileds, but they too get boxed in Integers. Any easy solution? |
| 11:30 | Anderkent | Clome: I don't follow. If your cases are ints (literal numbers) then it should be int based. can you post your code? |
| 11:31 | clgv | Clome: no. the problem is that case needs compile time constants |
| 11:32 | Anderkent | ('case' has three modes of operations - either ints, where it uses numerical dispatch, or keywords (where it's objects identity), or other stuff (object hashes) |
| 11:32 | Clome | Keyboard/KEY_W here is an case example, which is a normal int but in clojure gets boxed in Integer |
| 11:32 | clgv | Clome: the symbol which resolves to the static integer is no compile time integer constant |
| 11:32 | Anderkent | Ah. That won't work, you need constants. Use condp |
| 11:33 | clgv | Clome: there was a question on the ML recently. where someone solved it via writing a macro on top of case such that static constants are resolved |
| 11:34 | Anderkent | clgv: does marking a def as ^:const make it work with case? |
| 11:34 | clgv | Anderkent: never tried |
| 11:34 | Clome | Can`t I for example say something like this (def ^:const ^int key-w Keyboard/KEY_W), so that clojure dos not box this int? |
| 11:34 | lvh | so, there's a thing I don't get |
| 11:34 | lvh | map is lazy right? but when I put it in a repl expr, I see the full result |
| 11:34 | lvh | is it lazy, but being instantiated for the repl? |
| 11:35 | Anderkent | lvh: the map gets realized when the repl prints it |
| 11:35 | Anderkent | if you do (def result (map ...)) it won't be realized |
| 11:35 | Anderkent | Clome: alas, I don't think you can |
| 11:36 | clgv | Clome: well, easy enough to try and see |
| 11:36 | Anderkent | I think case won't even try to resolve symbols |
| 11:36 | Anderkent | i.e. if you say (case x foo :yes) it's checking if x == 'foo |
| 11:36 | clgv | macroexpand-1 on the case-form might be handy |
| 11:36 | Anderkent | ,(cse 'foo foo :yes :def) |
| 11:36 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: cse in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 11:36 | Anderkent | ,(case 'foo foo :yes :def) |
| 11:36 | clojurebot | :yes |
| 11:36 | clgv | ah right^^ |
| 11:37 | Anderkent | so you can't use symbols to refer to their values |
| 11:37 | Clome | ok, thanks |
| 11:37 | clgv | you cant use lists either if I remember correctly. but vectors work since they are in the same equality partition |
| 11:38 | clgv | ,(case '(1 2) (1 2) :yes :no) |
| 11:38 | clojurebot | :no |
| 11:38 | clgv | ,(case 1 (1 2) :yes :no) |
| 11:38 | clojurebot | :yes |
| 11:38 | Anderkent | Clome: in general. Don't use case unless you really need the performance of javas switch |
| 11:38 | clgv | ,(case 2 (1 2) :yes :no) |
| 11:38 | clojurebot | :yes |
| 11:38 | clgv | ^^ |
| 11:39 | Anderkent | I suppose writing a macro that evaluates case args then produces (case) with literals shouldnt be that hard? |
| 11:39 | clgv | Anderkent: humm I think that statement is not true. case is compiled to jvm code using hashing |
| 11:39 | Anderkent | clgv: not for int or identity matching afaik |
| 11:39 | Clome | why did (case 2 (1 2) :yes :no) returned :no? |
| 11:39 | clgv | I'd think switch is a primitive jvm byte code op, is it? |
| 11:39 | borkdude | what is the fastest/easiest (not necessarily best) way of building a crud web app with datomic as storage nowadays? |
| 11:39 | clgv | Clome: it did not ^^ |
| 11:39 | Anderkent | I'm like 80% sure that (case x 1 :yes :no) compiles to switch |
| 11:39 | clgv | ,(case 2 (1 2) :yes :no) |
| 11:40 | clojurebot | :yes |
| 11:40 | Clome | sorry, I meant :yes |
| 11:40 | Clome | why is that |
| 11:40 | clgv | Anderkent: switch with hashing I think |
| 11:41 | Clome | should not (1 2) return an error, since 1 is not a function |
| 11:41 | Clome | what am I missing here |
| 11:42 | Anderkent | Clome: case is a macro, it gives special syntax. In there, a list means 'one of these elements' |
| 11:42 | clgv | Clome: no. in `case` that's a notation fur alternative values that are matched |
| 11:43 | Clome | oh right, sorry |
| 11:44 | borkdude | I have used case exactly once |
| 11:44 | borkdude | until now |
| 11:45 | borkdude | (* amount (case time :month 1 :quarted 3 :year 12)) something like that |
| 11:45 | Anderkent | clgv: so it's either TableSwitch or LookupSwitch depending on whether your keys are sparse or not |
| 11:46 | Anderkent | I can't excactly find where it's emited in the compielr though. .. |
| 11:47 | clgv | Anderkent: just compile a function with `case` and use a decompiler to look it up |
| 11:49 | borkdude | Ah, the amount of users has grown with about 250 since I last paid attention to it |
| 11:49 | borkdude | here |
| 11:51 | Anderkent | clgv: https://www.refheap.com/27009 yep, tableswitch |
| 11:54 | eyepatch | I'm looking at (take-while #(<= % 4000000) (fib))) I understand the whole bit except for # and % I'm not familiar with those characters. Where could I look them up in docs? |
| 11:55 | eyepatch | Obviously you could tell me what they mean in a few seconds. I'm guessing % is a replacement for some unknown value in a predicate that doesn't know what i'll work on and # will return the value of % when the predicate is true. |
| 11:56 | eyepatch | But I'd be surprised if this was the last time that I ran into unfamiliar characters. |
| 11:56 | borkdude | eyepatch it is the notation for anonymous functions |
| 11:56 | borkdude | ,(#(+ % 10) 1) |
| 11:56 | clojurebot | 11 |
| 11:56 | borkdude | eyepatch it's just fancy notation for ((fn [x] (+ x 10)) 1) |
| 11:56 | llasram | ,`#(expando! %) |
| 11:57 | clojurebot | (fn* [p1__52__53__auto__] (sandbox/expando! p1__52__53__auto__)) |
| 11:57 | llasram | A "reader macro", in the parlance |
| 11:57 | Anderkent | eyepatch: but yes, googling for special symbols is really hard |
| 11:58 | Anderkent | eyepatch: I recommend spelling out symbol names, so try for example "clojure hash symbol" or "clojure pound symbol" (depending on wehre you're from :P) |
| 11:58 | gfredericks | llasram: yes the client closes the socket in the middle; also some other server-side error could happen to interrupt |
| 11:59 | eyepatch | Out of curiosity where is do people say pound and where do they say hash? |
| 12:00 | eyepatch | So it it similar to a lambda. |
| 12:00 | llasram | gfredericks: Ok. So with the CollReduce-based version, any error like that will cause an exception to be thrown within the dynamic scope of code you control |
| 12:00 | llasram | So as the stack unwinds, you can perform clean-up |
| 12:00 | eyepatch | oh silly me, it was in the "clojure in 15 minutes" thing. |
| 12:00 | eyepatch | Which is handy as a reference. |
| 12:01 | eyepatch | ok. Everything makes sense now. |
| 12:01 | Anderkent | eyepatch: I think europe says hash, usa says pound? |
| 12:01 | eyepatch | oh, ok. |
| 12:01 | Anderkent | for me pound is £ :P |
| 12:01 | llasram | eyepatch: What about senseless things? Do those now make sense? |
| 12:01 | eyepatch | I have the tendency to say British slang as an American. |
| 12:01 | eyepatch | llasram, senseless? |
| 12:02 | llasram | Anderkent: I say "hash" and am American |
| 12:02 | Anderkent | eyepatch: beause everything |
| 12:02 | eyepatch | Oh. right. I didn't qualify everything. |
| 12:02 | eyepatch | Hah, hah. |
| 12:02 | Anderkent | llasram: that's because you're a decent person! |
| 12:02 | llasram | heh |
| 12:02 | Anderkent | eyepatch: llasram: related: the only reason I use 7zip for everything is that it tells me 'Everything is OK' on each run |
| 12:02 | Anderkent | uplifting! |
| 12:03 | eyepatch | lol |
| 12:04 | Anderkent | AeroNotix: did you figure out how to do your split thing with areduce? |
| 12:06 | AeroNotix | Anderkent: sorry, no. I was updating my gpg key |
| 12:06 | llasram | gfredericks: The existing options for using a piped input stream or a seq are both fubar'd. With the input stream, nothing closes it, so your threat just fills the output stream buffer then blocks forever |
| 12:06 | llasram | gfredericks: With the seq option, you not only don't have any way of doing clean-up code, but |
| 12:07 | llasram | gfredericks: It turns out PrintWriter (which is what the servlet API uses) has this *insane* detail that it promises never to throw an exception after construction |
| 12:07 | llasram | gfredericks: So if the client connection closes, the ring-servlet loop just keeps pumping your seq into the void |
| 12:11 | TimMc | eyepatch: Hash, pound, sharp, number, octothorpe. |
| 12:11 | TimMc | eyepatch: Some of those are actually different characters, but they are all sometimes written as "#". |
| 12:13 | locks | little-jailcell-window-bar-thingie |
| 12:15 | llasram | I just know that it has to be called "hash" so that Common Lisp's "#|" syntax is "hash-pipe" |
| 12:16 | locks | pound pipe is… yeah. |
| 12:18 | tbaldridge | "hash-pipe" wow, I need to find a reason to use that phrase |
| 12:19 | llasram | tbaldridge: Write more Common Lisp? |
| 12:19 | technomancy | that's asking a lot |
| 12:19 | tbaldridge | and seeing how the winds have changed in Colorado lately, I'm now much less likely to be arrested for using the phrase. |
| 12:20 | llasram | Oh, yeah -- I guess smoking more marijuana would also increase your number of opportunities for that phrase |
| 12:20 | locks | "no no, I meant an ASH pipe. they vintage son" |
| 12:21 | tbaldridge | I plan on using the phrase, not using the device the phrase suggests. |
| 12:21 | llasram | Just exploring the linguistic possibilities! |
| 12:24 | lvh | Hi |
| 12:24 | lvh | how can I do destructuring binding in my repl? |
| 12:24 | gfredericks | ,(let [[a b] (range 10)] [b a]) |
| 12:24 | clojurebot | [1 0] |
| 12:24 | lvh | I want (let [[x y] (f)]), except with keeping the names around |
| 12:24 | lvh | like def |
| 12:25 | gfredericks | (defmacro defs [form expr] (let [syms (->> form flatten (filter symbol?))] `(let [~form ~expr] ~@(for [sym syms] `(def ~sym ~sym)))) |
| 12:25 | Anderkent | (let [[a b] (f)] (def x a) (def y b)) :P |
| 12:26 | gfredericks | I think I left out a paren at the end there |
| 12:26 | gfredericks | but that lets you (defs [a b] (range 10)) |
| 12:26 | Anderkent | #clojurelastwords |
| 12:26 | rasmusto | gfredericks: whoa, I've always assumed it wasn't safe to do defs like that, am I wrong? |
| 12:26 | gfredericks | rasmusto: in what respect? |
| 12:26 | rasmusto | not sure, for code reloading or something? |
| 12:27 | gfredericks | it just expands to what Anderkent suggested |
| 12:27 | rasmusto | oh, maybe I was trying to "def" something in a function as a means of having a mutable variable |
| 12:27 | Anderkent | non-top-level defs are discouraged, but as long as you don't do unsane things it's okay |
| 12:27 | gfredericks | oh yeah that's terrible |
| 12:27 | Anderkent | yeah exactly don't put that ina function |
| 12:27 | Anderkent | just top level |
| 12:27 | rasmusto | (I remember asking about it before I knew a damn thing about clojure) |
| 12:27 | rasmusto | s/clojure/fp |
| 12:28 | gfredericks | looks like that defs doesn't cover map destructuring |
| 12:29 | gfredericks | due to ##(flatten {:a [1 2 3]}) |
| 12:29 | lazybot | ⇒ () |
| 12:29 | rasmusto | ,(seq {:a [1 2 3]}) |
| 12:29 | clojurebot | ([:a [1 2 3]]) |
| 12:30 | lvh | hm |
| 12:30 | rasmusto | ,(flatten (seq {:a [1 2 3]})) |
| 12:30 | clojurebot | (:a 1 2 3) |
| 12:30 | lvh | how can do I step by step debugging? there seem to be a bunch of articles on google with few currently usableconclusions |
| 12:32 | rasmusto | ,(let [a [1 2 3], _ (prn a) b (map inc a), _ (prn b)] 'foo) |
| 12:32 | clojurebot | [1 2 3]\n(2 3 4)\nfoo |
| 12:32 | rasmusto | is how I debug step-by-step |
| 12:32 | rasmusto | lvh: probably not the answer you are looking for |
| 12:33 | `cbp | suddenly I go back to python and I'm at a total loss on how to do recursive traversal algorithms without persistent data structures |
| 12:34 | Anderkent | lvh: debugging is pretty flaky still. Eclipse with counterclockwise can somewhat do it |
| 12:34 | clgv | lvh: you can do that in counterclockwise |
| 12:34 | Anderkent | I usually just deftrace |
| 12:34 | rasmusto | `cbp: use += on mutable lists (and then quit in disgust) |
| 12:34 | Anderkent | and write tests :D |
| 12:35 | `cbp | sys.setsetrecursionlimit(10000) # yeahhhhh |
| 12:35 | TimMc | I tried writing a Python program recently. |
| 12:36 | mmitchel_ | what happened? |
| 12:36 | rasmusto | here's how I write python nowadays: ^I^I(range) # syntax error |
| 12:36 | TimMc | It was going well until I had to figure out how to work with "unicode strings", and I was all http://replygif.net/i/310.gif |
| 12:37 | mmitchel_ | lol |
| 12:37 | mmitchel_ | that's the best |
| 12:37 | rasmusto | TimMc: use bytearray |
| 12:37 | rasmusto | er wait, no that's even more confusing |
| 12:37 | Anderkent | .. I've caught myself doing (. delegate callMethodStuff) while writing java .. |
| 12:37 | `cbp | unicode strings, the GIL |
| 12:37 | `cbp | the spanish inquisition was in the habit of burning python books |
| 12:38 | TimMc | All I wanted to do was to convert some strings to NFD, but nooOOOOoo |
| 12:38 | lvh | Cool, I fixed it by using more REPL. |
| 12:39 | rasmusto | lvh: how do you use the REPL, which environment? |
| 12:39 | lvh | rasmusto: cider |
| 12:39 | rasmusto | lvh: cool, I liked what I used of nrepl.el, but I'm a vim guy personally :D |
| 12:40 | lvh | if anyone feels like giving a newbie code review, https://github.com/lvh/pairing/blob/master/src/pairing/core.clj#L81 could use some |
| 12:40 | lvh | particularly the function on that line I think |
| 12:40 | Anderkent | I'm pretty happy with foreplay for vim |
| 12:40 | Anderkent | wait, it's called something else now isnt it |
| 12:40 | Anderkent | fireplace |
| 12:40 | rasmusto | Anderkent: fireplace, the public isn't ready for a plugin named foreplay |
| 12:41 | `cbp | lvh: would you paste an example input/output please? |
| 12:41 | rasmusto | well, not until we've had a good dose of cider |
| 12:41 | wink | is there a better way to get a mimetype of an image than this? (nio.file.Paths/Files) http://www.rgagnon.com/javadetails/java-0487.html |
| 12:45 | rasmusto | oh, I can't do :if-let in a for/doseq, right? should I nest another form? |
| 12:46 | rasmusto | or just a :let [blah (if ...)]] (if blah ...)) |
| 12:46 | `cbp | you can have a :let and you can have a :when that filters |
| 12:48 | rasmusto | `cbp: hmm, I have a var thats bound to either each thing in a seq of things, or just once to nil, I'm not sure if :when helps |
| 12:51 | lvh | `cbp: Did you see the test file? |
| 12:52 | rasmusto | oh, I didn't know you could do ##(let [[a b] nil] [a b]) |
| 12:52 | lazybot | ⇒ [nil nil] |
| 12:52 | `cbp | lvh: no I just saw your fn |
| 12:52 | rasmusto | ##(let [[a b] '()] [a b]) |
| 12:52 | lazybot | ⇒ [nil nil] |
| 12:53 | rasmusto | is this a lisp-1/2 thing about nil being an empty list of sorts? |
| 12:55 | fredyr | ,(int 1.999999999999999) |
| 12:55 | clojurebot | 1 |
| 12:56 | llasram | rasmusto: "nil punning"; orthogonal to lisp-1 vs -2 |
| 12:56 | fredyr | ,(int 1.999999999999999) |
| 12:56 | clojurebot | 1 |
| 12:56 | fredyr | ,(int 1.999999999999999999) |
| 12:56 | clojurebot | 2 |
| 12:56 | noncom | fredyr: magic |
| 12:56 | fredyr | ^^ did you guys see this rounding thing on twitter? |
| 12:56 | fredyr | i guess its a java thing |
| 12:56 | fredyr | but im not really sure why |
| 12:57 | aperiodic | it's not a java thing, it's a fixed-point thing |
| 12:57 | `cbp | ^ |
| 12:57 | Wild_Cat | what rounding thing? |
| 12:57 | `cbp | does the same thing in most languages |
| 12:57 | llasram | rasmusto: In CL, `nil` *is* (`identical?` to) the empty list. In Clojure, the seq API is to *treat* `nil` as an empty sequence |
| 12:57 | Anderkent | ,1.999999999999999999) |
| 12:57 | clojurebot | 2.0 |
| 12:57 | fredyr | oh right |
| 12:58 | Anderkent | it worked with that paren, wat |
| 12:58 | `cbp | ,( |
| 12:58 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 12:58 | fredyr | on twitter it was |
| 12:58 | metellus | ,213354908fdjk |
| 12:58 | clojurebot | #<NumberFormatException java.lang.NumberFormatException: Invalid number: 213354908fdjk> |
| 12:58 | fredyr | ,(nth [1 2 3 4] 1.9999999999999) |
| 12:58 | clojurebot | 2 |
| 12:58 | fredyr | ,(nth [1 2 3 4] 1.999999999999999999) |
| 12:59 | clojurebot | 3 |
| 12:59 | rasmusto | ah yeah, saw that |
| 12:59 | fredyr | which threw me off a bit |
| 12:59 | rasmusto | ,1.999999999999999999 |
| 12:59 | clojurebot | 2.0 |
| 12:59 | rasmusto | ah ok, it's just a cast-to-int thing |
| 12:59 | Wild_Cat | more like IEEE floating point oddity. |
| 12:59 | fredyr | yeah |
| 13:00 | rasmusto | ,(nth [0 1 2 3] 1.999999999999999999) |
| 13:00 | clojurebot | 2 |
| 13:00 | Wild_Cat | and not JVM-specific, for that matter. |
| 13:00 | rasmusto | illustrates it a bit more clearly |
| 13:00 | fredyr | yeah ofc its for any ieee floating points |
| 13:01 | fredyr | (dec fredyr) |
| 13:01 | lazybot | You can't adjust your own karma. |
| 13:01 | fredyr | :s |
| 13:01 | Wild_Cat | funny how even when aware of the IEEE floating point imprecision thing, I always tended to assume that they were always erring downwards |
| 13:02 | Wild_Cat | (that is, that the number you get is always <= to the literal you typed) |
| 13:02 | Wild_Cat | when there's no such guarantee, as we just saw. |
| 13:02 | Wild_Cat | and I should have known better. |
| 13:02 | strijkijzer | So ehh |
| 13:02 | strijkijzer | People here don't hate a lisp-like syntax but like it more I assume? |
| 13:03 | fredyr | lol |
| 13:03 | BullSherd | Wow, Google is making really strange things http://goo.gl/YEkaMA |
| 13:03 | BullSherd | funny haha xD |
| 13:04 | `cbp | ~guards |
| 13:04 | clojurebot | SEIZE HIM! |
| 13:04 | strijkijzer | fredyr, are you laughing at me? |
| 13:04 | Wild_Cat | strijkijzer: kinda hard to like Clojure and hate the Lisp syntax at the same time |
| 13:04 | Wild_Cat | ...although as far as I'm concerned, I like *Clojure*'s syntax -- that is, I find all the additions it made to the Lisp syntax great. |
| 13:05 | `cbp | I like it the most because of stuff like paredit |
| 13:05 | Wild_Cat | simple stuff like vector, map and set literals make it so much more readable. |
| 13:05 | `cbp | and paredit + multiple cursors = yes plz |
| 13:05 | fredyr | strijkijzer: sorry, but yes it is a reasonable thing to assume, that lispers don't hate lisp |
| 13:05 | strijkijzer | fredyr, maybe they see it as a lesser evil. |
| 13:05 | strijkijzer | Syntax is typically the last concern for me to judge if I like a language, I can get around bad syntax if the semantics are sound. |
| 13:05 | strijkijzer | Like, I hate Haskell syntax but apart from that the langauge is fine. |
| 13:06 | Wild_Cat | strijkijzer: bad syntax is hard to get around. |
| 13:06 | strijkijzer | So I was wondering if maybe people see the lisp like syntax as a lesser evil or something? |
| 13:06 | `cbp | bad syntax is I have to google for how to write the stupid thing but oh guess what the whole thing is ungoogleable |
| 13:06 | strijkijzer | Well, it's one of the least important parts of programming language design insofar that most languages just re-use the same syntax that was used before and slightly modifiy. |
| 13:06 | Wild_Cat | I liken it to typing on an uncomfortable keyboard -- sure, you can do it, but it always gets in the way. |
| 13:06 | strijkijzer | THere are basically 3 big syntax families in use. C-style, Lisp-style and ML-style. |
| 13:07 | strijkijzer | But apparently people don't see it as a lesser evil |
| 13:07 | technomancy | you can tell when someone's new to lisp; it's the people who aren't totally keen on homoiconicity |
| 13:07 | strijkijzer | I hear a lot from people that they don't like it though which confuses me. |
| 13:07 | strijkijzer | It's not as much the homo-iconicity that I like as much as the consistency and simplicity and explicitness. |
| 13:08 | Wild_Cat | strijkijzer: I can see how "bare" Lisp syntax can be a pain. I mean, like I just said, I don't like it when a language goes too far in the minimalism direction. |
| 13:08 | strijkijzer | If you see something like x %% y *# z in Haskell you're just going to guess what the praecedence is. |
| 13:08 | strijkijzer | Hmm, I don't like "special rules" too much. |
| 13:08 | Wild_Cat | vector/map/set literals make Clojure far more readable than most Lisps I've been exposed to. |
| 13:09 | strijkijzer | Like ehh, in Haskell, a year back I was trying to define a (..) operator for double function composition (.) is single function composition, turns out I can't do this because it has [n..k] syntax which is basically (range n k) |
| 13:09 | Wild_Cat | ...for that matter they make any language that has them more readable. |
| 13:09 | strijkijzer | I really wonder why on earth [n..k] is necessary, surely range n k suffices? |
| 13:09 | Wild_Cat | (yes Java, I'm glaring at you) |
| 13:10 | Wild_Cat | (and I'm also glaring harder at C++ which doesn't even have *string* literals) |
| 13:12 | strijkijzer | Wild_Cat, well, the point is it is arbitrary in languages which allow you to define arbitrarily complex new algebraic datatypes. |
| 13:12 | `cbp | strijkijzer: for the same reason you need to put a comma between every item in a data structure |
| 13:12 | strijkijzer | You can't define new datatypes in clojure can you? |
| 13:12 | strijkijzer | `cbp, what is that a reply to? |
| 13:12 | Anderkent | strijkijzer: define datatype. defrecord might be what you want? |
| 13:12 | Wild_Cat | strijkijzer: new datatypes as in new literals, or as in new data structures? |
| 13:12 | `cbp | syntax that seems to be designed for people that write with pen and paper |
| 13:13 | Wild_Cat | because if it's the latter, you absolutely can. |
| 13:13 | `cbp | strijkijzer: the [n..k] thing |
| 13:14 | strijkijzer | Wild_Cat, well is it possible in clojure to create a myList whose interface in every way is identical to the current list |
| 13:14 | jita | Which is better ide eclipse or intellij idea ? |
| 13:14 | strijkijzer | or a my-vector. |
| 13:14 | Wild_Cat | strijkijzer: sure. |
| 13:15 | strijkijzer | Wild_Cat, ah I wasn't aware of that. |
| 13:15 | strijkijzer | And this runs with the same performance internally? |
| 13:15 | Wild_Cat | strijkijzer: it's even necessary to be able to do that, due to the fact that Clojure interops with Java |
| 13:15 | `cbp | strijkijzer: it's usually best to write high performance data structures with java |
| 13:15 | `cbp | then write a clojure wrapper |
| 13:16 | strijkijzer | Well, I'm asking about the possibility. |
| 13:16 | Wild_Cat | strijkijzer: I'm guessing the performance will be inferior because Clojure's vector is implemented in Java at a lower-level. |
| 13:16 | strijkijzer | At least, my point with loads and loads of special syntax for data structures is that it's arbitrary. |
| 13:16 | strijkijzer | I think (vector a b c d) suffices for [a b c d] really. |
| 13:16 | Wild_Cat | strijkijzer: of course it is. But that's not a good enough justification to not add in literals for the most commonly-used data structures. |
| 13:17 | tbaldridge | Wild_Cat: the funny thing is, the java version of vectors is almost exactly like what Clojure would spit out if you used deftype, protocols and type hinting. |
| 13:17 | Wild_Cat | the square brackets jump out at me, making it easier to identify the vector. |
| 13:17 | Wild_Cat | (likewise {} for maps) |
| 13:17 | tbaldridge | Wild_Cat: so there may not be a performance difference at all. |
| 13:17 | strijkijzer | Well, at one point this does some pretty convoluted things wityh the language syntax, OCAml definitely has this problem that the language syntax deifnition becomes too overloaded because of all rthis and typos often result in it not becoming bad syntax but something you didn indend. |
| 13:17 | Wild_Cat | especially when you take into account the fact that Clojure uses vectors and maps *a lot*. |
| 13:18 | technomancy | ocaml's precedence rules =( |
| 13:18 | llasram | Raynes: ping |
| 13:18 | Raynes | Hello, this is Raynes. |
| 13:18 | llasram | Raynes: https://github.com/Raynes/bultitude/commit/68491b281a5de760fc44e087fffdca2e03b2ef6b |
| 13:18 | Wild_Cat | strijkijzer: language design, at that point, becomes a matter of taste and restraint: how many special cases do you add? |
| 13:18 | llasram | THe `(second form)` -> `form` commit changes the public interface |
| 13:18 | llasram | Is this known? |
| 13:19 | Wild_Cat | (that's an open question that every language designer will answer differently. I think Clojure hits a sweet spot, or pretty close to one) |
| 13:19 | Wild_Cat | (I also think Python hits another one) |
| 13:19 | Raynes | llasram: The commit specifically states that it shouldn't break existing functionality. If it does, then I will promptly release a new major version and beat Grayson up. |
| 13:20 | Raynes | And by 'promptly' I mean at like 10PM tonight PST. |
| 13:20 | Raynes | :P |
| 13:20 | llasram | I'm confused why no one has noticed until now, because it breaks the Leiningen test, but yeah -- `ns-form-for-file` used to return just the ns symbol, but now returns the full form |
| 13:20 | strijkijzer | Wild_Cat, well yeah, obviously it's super subjective. |
| 13:21 | strijkijzer | If I designed a syntax, I would probably make numbers default to hexdecimal and read from lefty to right. |
| 13:21 | teslanick | Are there any guides for building an om/clojurescript app side-by-side with a clojure app? |
| 13:21 | strijkijzer | Note that we currently read numbers from right to left ina script that coes from left to right |
| 13:22 | llasram | s,the Leiningen test,a Leiningen test, |
| 13:27 | fredyr | teslanick: do you mean with a clojure backend or something? |
| 13:28 | teslanick | fredyr: Yeah. With the possibility of logic-sharing across the two stacks. |
| 13:29 | fredyr | teslanick: ah right, i haven't seen anything with om/cljs to that end |
| 13:30 | fredyr | teslanick: but there has been alot of buzz about cljx for code sharing between cljs and clj lately |
| 13:32 | teslanick | Interesting, thanks! |
| 13:36 | llasram | Raynes: To clarify, you are planning on bumping the version vs restoring the old interface, yes? |
| 13:36 | llasram | Well, I guess bumping w/o restoring vs bumping + restoring |
| 13:40 | Anderkent | FWIW, the change makes sense to me, and something like 'ns-symbol-for-file' could be added for the old functionality |
| 13:41 | llasram | Anderkent: Yeah, I don't honestly care. I just want to fix Leiningen in a way that won't need to be changed again right away :-) |
| 13:41 | Anderkent | :D |
| 13:41 | Anderkent | (let [ns-sym (if (symbol? ns-form) ns-form (second ns-form))]) ex! |
| 13:41 | Anderkent | *ez! |
| 13:41 | Anderkent | :P |
| 13:42 | gfredericks | (cond-> ns-form (symbol? ns-form) (second)) |
| 13:42 | gfredericks | or the other way |
| 13:43 | llasram | Better, but I'm looking for a social solution :-) |
| 13:49 | Raynes | llasram: Bumping the version number. |
| 13:49 | Raynes | The change was necessary for a Leiningen feature |
| 13:49 | llasram | Raynes: Awesome |
| 14:03 | DomKM | If you were going to read SICP, On Lisp, Lisp in Small Pieces, and Let Over Lambda, in what order would you read them? |
| 14:03 | DomKM | That's the order I'm reading them but I'm interested in what someone who has already read them thinks |
| 14:04 | jcromartie | I'd read half of SICP first, then give up, and then do the same with the rest in any order you'd like. |
| 14:04 | jcromartie | :P |
| 14:04 | jcromartie | that's just what I've done |
| 14:04 | DomKM | lol |
| 14:04 | deadghost | I have a terrible tendency |
| 14:04 | deadghost | to stop reading books half way through |
| 14:04 | deadghost | halfway is enough for me to be dangerous |
| 14:04 | deadghost | then I go be dangerous |
| 14:05 | deadghost | and say I'll go back to finish eventually |
| 14:05 | deadghost | (hasn't happened yet) |
| 14:07 | DomKM | yeah that's a distinct possibility |
| 14:09 | jcromartie | you usually get your dopamine hit (for me, when SICP demonstrated how you can build any data structure with closures) about halfway through these books |
| 14:12 | fredyr | i've never found let over lambda particularly engaging, so never gotten far |
| 14:13 | tbaldridge | DomKM: to be honest, in the older lisp books, the lisp being used is so primitive, I wonder if it's worth reading those before the Clojure books. |
| 14:13 | tbaldridge | I went back and read some Scheme code the other day, and my reaction was "why on earth would you code this way...oh yeah, you don't have types, or literal hash maps, or immutable vectors or....." |
| 14:14 | bbloom | tbaldridge: i'm trying to write some C right now... my brain hurts |
| 14:14 | bbloom | tbaldridge: but it's not the memory management or the low level anything...it's just like... wait... why the fuck are structs in different namespaces from other types? |
| 14:14 | DomKM | tbaldridge: I've already read most of the clojure books, I consider these readings to be more foundational than instructional |
| 14:14 | bbloom | and how come i can't add a new namespace without prefixing symbols? |
| 14:15 | tbaldridge | bbloom: what are you writing? |
| 14:16 | bbloom | tbaldridge: all kinds of fun/terrible stuff :-P |
| 14:19 | deadghost | is there a list of cool stuff written in clojure I can peruse? |
| 14:20 | Anderkent | deadghost: https://github.com/trending?l=clojure ? :D |
| 14:21 | deadghost | that works |
| 14:22 | deadghost | though I'm looking more for a whole project than libraries |
| 14:22 | Anderkent | right, don't know about that, projects by nature don't get as much visibility |
| 14:24 | Anderkent | I mean I guess it depends on what you'd call a project. Maybe just read through sources of tools that you can use? lein, lein plugins (cloverage! except code be ugly) etc. |
| 14:24 | Anderkent | but in general reading sources of real projects is not actually that constructive |
| 14:25 | deadghost | Anderkent, I was more looking for the purpose of hyping myself up |
| 14:25 | deadghost | like FUCK YES CLOJURE |
| 14:25 | Anderkent | oh |
| 14:25 | llasram | Code in a non-library project is just code you don't expect to be able to reuse :-) |
| 14:25 | deadghost | CLOJURE!!!1!!11! |
| 14:25 | Anderkent | right, and because you don't expect to reuse it and just want to get shit done it tends to not be as pretty :P |
| 14:25 | Anderkent | deadghost: I dunno, lighttable? |
| 14:25 | Anderkent | is pretty cool |
| 14:26 | algernon | deadghost: core.logic, kibit are two things that are jawdropping (and are reasonably understandable) |
| 14:26 | Anderkent | core.async is pretty cool too |
| 14:26 | algernon | also, overtone. never forget overtone and what Sam Aaron does with it. |
| 14:26 | deadghost | oh right |
| 14:26 | deadghost | I've been meaning to play with overtone |
| 14:37 | lvh | Hi :) if anyone is willing to scan some newbie code and give feedback, I'd be much obliged: https://github.com/lvh/pairing/blob/master/src/pairing/core.clj#L81 |
| 14:44 | cark | lvh: a cursomary glance, and it looks quite neat |
| 14:44 | lvh | cark: Cool! Thanks :) |
| 14:45 | cark | lvh : tho i personally prefer being a bit more explicit about the data |
| 14:45 | stompyj | Just want to canvas the community here, for those running clojure web apps, whats your deployment vehicle? immutant? jetty + apache, jetty + nginx? beanstalk/ |
| 14:45 | lvh | cark: How do I do that? |
| 14:45 | Anderkent | lvh: the one thing I've mentioned before - I'd swap around the order in if statements, so that you don't have to scan through 15 lines to find the else clause |
| 14:45 | cark | lvh : I like having constructor functions for my data |
| 14:45 | llasram | stompyj: jetty in an uberjar fronted by apache right now. Want to move toward immutant though |
| 14:46 | stompyj | llasram: any reason why apache over nginx? I only ask because I haven't used apache in so long, I'm curious if there's something I'm missing there |
| 14:46 | lvh | cark: Ah. I have not done that yet because the data will be coming from gnlary csv data so I will need to write an explicit munging layer :) |
| 14:46 | cark | lvh : and let it be known that i disagree with Anderkent =) |
| 14:46 | llasram | stompyj: And these are all internal Web service -- nothing public facing |
| 14:46 | lvh | Anderkent: Sorry I missed that before |
| 14:46 | llasram | stompyj: Because we have tiny team who all knows how to make Apache dance :-) |
| 14:46 | lvh | Anderkent: So (if (not (seq x ...? |
| 14:46 | stompyj | llasram: haha, fair enough |
| 14:47 | Anderkent | lvh: (if-not |
| 14:47 | lvh | oh, I didn't know about if-not |
| 14:47 | stompyj | llasram: how do you deploy? |
| 14:47 | cark | don't do that >< |
| 14:47 | cark | it's harder to understand |
| 14:47 | Anderkent | stompyj: the one clojure webapp I've used was on aleph, which I believe is powered by netty. Then just pushed as an uberjar to heroku |
| 14:48 | Anderkent | cark: how come it's harder to understand? |
| 14:48 | llasram | stompyj: jenkins builds .deb packages and pushes them to an APT repo, from where puppet then deploys them |
| 14:48 | stompyj | llasram: wow |
| 14:48 | cark | Anderkent: negation is harder on the brain, at least I think it is |
| 14:48 | Anderkent | huuuh |
| 14:49 | Anderkent | I'm so confused right now but I'll accept that you don't like negation |
| 14:49 | llasram | stompyj: What sort of "wow" was that? :-) |
| 14:49 | Anderkent | for me (if-not (seq)) is completely idiomatic and automatically parses as 'empty seq' |
| 14:50 | Anderkent | and having the short branch first makes it much easier to scan the code |
| 14:50 | Anderkent | indentation's not reliable over 20-lines |
| 14:50 | cark | ahwell that's a fine point anyway |
| 14:50 | Anderkent | I suppose the other solution is to just pull out the long body into a helper fn |
| 14:50 | bhauman | confused about how to determine if an instance implements a Protocol in cljs |
| 14:50 | cark | can't do that with the recur |
| 14:50 | stompyj | llasram: it was a "another deployment strategy I've not heard of yet" wow |
| 14:51 | stompyj | llasram: I've been working in ruby since 2004, and .NET/Java before that... so while I 100% love clojure, I'm still trying to find the right level when it comes to deployment |
| 14:51 | llasram | stompyj: It was inspired by this: https://hynek.me/articles/python-app-deployment-with-native-packages/ |
| 14:51 | Anderkent | bhauman: satisfies? protocol object) I think? |
| 14:52 | stompyj | the ruby in me tells me just to deploy via beanstalk / heroku. But the old enterprise programmer in me wants to invest time in immutant or jetty and do a ansible deploy, etc |
| 14:52 | bhauman | Anderkent: thanks will try that :) |
| 14:52 | Anderkent | llasram: I did something similar in python but only because we had a 2gb dependency (xelatex) |
| 14:53 | cark | lvh : The one thing I don't like is that the shape of your data is not directly apparent. But on the other hand the code is neat. So if it works with you it's all good |
| 14:53 | llasram | stompyj: Yeah, it depends on your use-case. If I were starting from scratch for a public service on cloud infrastructure, would probably do it entirely differently |
| 14:54 | llasram | Anderkent: I did it because we have stuff in Python, Ruby, and Clojure, and our previous system was a mess. |
| 14:54 | bhauman | Anderkent: thanks, that bit of basic knowledge goes a long way. And now I see it there on the protocols page. |
| 14:54 | Anderkent | yeah, got it |
| 14:54 | Anderkent | bhauman: no worries, pretty used to googling stuff for people ;> |
| 14:55 | llasram | Anderkent: Following the same model for everything got deployment entirely automated, and with atomic packages using the language-appropriate tools |
| 14:55 | bhauman | Anderkent: I google the crap out of that and it just wasn't surfacing for me |
| 14:55 | Notte | Hi, is it possible to have a function with two vector parameters that destructures the second one into head (which i don't care) and tail? |
| 14:56 | jcrossley3 | llasram: when the time comes, we'd like to help get debian init scripts hardened for immutant, too. |
| 14:56 | cark | (defn vecs [vec1 [h & tail]] ...) |
| 14:56 | bhauman | Notte: ^ |
| 14:56 | rasmusto | ,(let [a [_ & tail] [[1 2 3] ['foo 4 5]] [a tail]) |
| 14:56 | clojurebot | #<RuntimeException java.lang.RuntimeException: Unmatched delimiter: )> |
| 14:57 | Notte | cark: thanks. I was writing it wrong. |
| 14:57 | llasram | jcrossley3: I have to confess that I personally just use runit :-) |
| 14:57 | rasmusto | whoops, missed something |
| 14:57 | rasmusto | ,(let [a [_ & tail] [[1 2 3] ['foo 4 5]]] [a tail]) |
| 14:57 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: let requires an even number of forms in binding vector in sandbox:> |
| 14:57 | jcrossley3 | llasram: cheater ;) |
| 14:58 | lvh | cark: Would a defrecord fix that |
| 14:58 | cark | lvh : don't sweat it. Your code is idiomatic enough. What matters most is to get the product done ! |
| 14:59 | Anderkent | bhauman: my query was 'clojure implements protocol' FTR, which brings up clojure.org/protocols, which mentions extends? and satisfies? |
| 14:59 | bhauman | genius! |
| 15:00 | esancho | llasram: do you use something like Rundeck to orchestrate deployments with puppet? |
| 15:01 | llasram | esancho: Not yet, but we just finally got an ops person who knows this stuff, and he's got plans |
| 15:01 | Anderkent | queue evil sysop laugh |
| 15:01 | llasram | esancho: For now we just have our internal packages set to be 'latest' and do an `apt-get update` (against internal repos only) on each run |
| 15:02 | danneu | What's a good way to create a config.edn file that lets you change things on the fly in production? slurp + a ttl cache? |
| 15:04 | lvh | is there a refactoring lib that can rename a function across a project |
| 15:04 | lvh | clj-refactor.el |
| 15:04 | lvh | I have that; but it only has file renames. |
| 15:06 | esancho | llasram: gotcha, the tricky part is when you need to orchestrate deployments across multiple servers... I'm working on something similar right now and it was funny to read about it in #clojure |
| 15:07 | llasram | esancho: Ah, yeah. That's rare enough for us that it's still manual. Perfect, enemy of the good, etc :-) |
| 15:09 | stompyj | llasram: back, catchingup |
| 15:10 | stompyj | llasram: I might wimp out and go with clojure to start. the thing is that I want to use fluentd or something like that to capture pretty detailed logging events, etc |
| 15:10 | stompyj | llasram: and if I decide to do apache / jetty, then I need to build a chef script that deploys all that stuff (chef is what we currently use), but what I really want to do is use ansible, |
| 15:10 | stompyj | Im being wishy washy atm :) |
| 15:11 | llasram | You can only find better ways by trying new ways, but you can only get stuff done by doing things which work. Always a dilemma! |
| 15:13 | stompyj | yeah, its further complicated by the fact we are 85% done with this project, and we have about 3 months before it has to launch |
| 15:13 | stompyj | so lots of naval gazing time |
| 15:13 | stompyj | if I don't keep myself on track |
| 15:13 | stompyj | heh |
| 15:17 | gfredericks | I'm seeing some spooky dependency resolution involving lein plugins |
| 15:17 | llasram | Spooooooooky |
| 15:20 | stompyj | llasram: another question, do you guys write tests? and if so, which lib are you using |
| 15:21 | llasram | stompyj: For deployment? |
| 15:21 | stompyj | oh no, TDD type testing |
| 15:21 | Anderkent | midje for functional tests, junit for integration |
| 15:21 | stompyj | i'm using midje right now |
| 15:21 | stompyj | as well |
| 15:21 | dima_ | any quick ideas on how to get lein work with some java code using "lombok"? lein pom; mvn compile works, lein compile and lein javac fail with ClassNotFound for "com/sun/tools/javac/processing/JavacProcessingEnvironment" |
| 15:21 | gfredericks | project has dep [A 2] and plugin [C 1] -> [B 1] -> [A 1] |
| 15:22 | stompyj | I'm finding that unit tests aren't as important due to the functional nature of clojure + the repl |
| 15:22 | llasram | stompyj: Oh, we use clojure.test for all our Clojure testing. |
| 15:22 | llasram | We used midje for some Cascalog projects, because of midje-cascalog, but the level of magic got too intense for me |
| 15:22 | llasram | Plus my experience is that the way midje wants to run tests when compiling a namespace cramps the typical Clojure workflow |
| 15:23 | stompyj | llasram: Anderkent: thanks |
| 15:23 | Anderkent | llasram: yeah thats why our facts are deftest wrapped ;p |
| 15:23 | Anderkent | my pain with midje is mostly that factoring stuff out is really hard |
| 15:23 | Anderkent | because fact is a macro, you cant just call a function that makes some assertions |
| 15:23 | llasram | Anderkent: I remember trying that and running into some sort of issue -- don't recall exactly what |
| 15:23 | stompyj | do you guys have any experience with mocking out third party services in midje? This is the one thing I can't wrap my head around re: tests |
| 15:24 | Anderkent | stompyj: if you have a clojure api for them, just (provided (third-party/request :arg1 "foo") => {:response :body}) |
| 15:24 | gfredericks | oh I think this is speclj's fault somehow |
| 15:25 | stompyj | Anderkent: that makes sense. then where do you stick all the gnarly responses? inside the test suite itself? or do you load them from a file? currently I have a bunch of (def something <INSERT GNARLY JSON HERE>) |
| 15:25 | stompyj | I will say, I've only ever done TDD in ruby (and a smidge in C#) so outside of the ruby world, I have a ton of "where does this go" questions |
| 15:26 | egghead | dnolen: am I correct in my observation that om doesn't support lists (only vectors) ? |
| 15:26 | ddima | nobody? :/ |
| 15:27 | Anderkent | stompyj: so you probably want to separate this into two layers. One that transforms the gnarly responses into nice data structures. In there you can just put the model responses in test-resources and load from file |
| 15:27 | Anderkent | then on the business layer you just mock your interaction layer and return maps with whatever you expect |
| 15:27 | stompyj | interesting. makes sense |
| 15:28 | stompyj | test/resources is an idiomatic clojure directory structure for such things? (I've never heard of it) |
| 15:29 | Anderkent | I believe it's test-resources in lein |
| 15:31 | Notte | ,(do (defn t [coll1 [_ & coll2]] (cond (and coll1 coll2) 0 (and coll1 (not coll2)) 1 :else 2)) (t [] [])) |
| 15:31 | clojurebot | 1 |
| 15:32 | Notte | Would anyone explain me why is it happening, please? |
| 15:33 | Notte | ,(true? (and [] (not []))) |
| 15:33 | clojurebot | false |
| 15:33 | edbond | ,(not []) |
| 15:33 | clojurebot | false |
| 15:34 | edbond | ,(and true false) |
| 15:34 | clojurebot | false |
| 15:34 | edbond | ,(true? []) |
| 15:34 | clojurebot | false |
| 15:34 | RickInAtlanta | ,(if [] true false) |
| 15:34 | clojurebot | true |
| 15:34 | edbond | Notte, ^^^ |
| 15:34 | Notte | ow |
| 15:35 | egghead | Notte: because coll2 doesn't exist? |
| 15:35 | logic_prog | is there a way in clojure code to say: "fire off a nrepl at this point" ? |
| 15:35 | logic_prog | i.e. a nrepl which has (1) the local environments, (2) I can evaluate forms, and (3) pick a value to return? |
| 15:35 | egghead | Notte: why do you expect coll2 to exist? |
| 15:36 | egghead | ,(and [] (not nil)) |
| 15:36 | clojurebot | true |
| 15:36 | Notte | egghead: i don't know. Sorry. |
| 15:36 | egghead | Notte: it's the way destructuring works, if it can't find a match it binds 'nil' |
| 15:37 | Notte | ok |
| 15:37 | Notte | thank you, edbond and egghead |
| 15:37 | egghead | if you have [] as your data and [_ & x] as your match, then it will try to break [] into first and rest, binding x to rest |
| 15:37 | egghead | if you try to get (rest []) you get nil |
| 15:38 | egghead | hope this helps Notte |
| 15:39 | Notte | i'll remember it |
| 15:40 | gfredericks | when a lein plugin has :dependencies, those should never get on the app's classpath, correct? |
| 15:41 | egghead | hopefully gfredericks are you seeing otherwise? |
| 15:42 | hiredman | some plugins will inject things in to the projects deps |
| 15:44 | gfredericks | hiredman: this one doesn't obviously |
| 15:44 | gfredericks | https://github.com/slagyr/speclj/blob/2.9.0/src/leiningen/spec.clj#L23 |
| 15:44 | gfredericks | I am seeing otherwise |
| 15:44 | gfredericks | about to post a minimal reproducing project |
| 15:46 | gfredericks | here it is: https://github.com/fredericksgary/bad-deps |
| 15:46 | gfredericks | actually this is quite weird because it's one plugin causing another unrelated plugin's dep to be used |
| 15:47 | gfredericks | `lein deps :tree` does not pick up on this |
| 15:48 | danielglauser | gfredericks: did you try `lein shadowdeps :tree`? |
| 15:48 | danielglauser | :) |
| 15:48 | gfredericks | :P |
| 15:49 | gfredericks | migratus-lein is a plugin that depends on migratus which depends on an old java.jdbc |
| 15:49 | gfredericks | speclj is a plugin that runs tests |
| 15:50 | Anderkent | gfredericks: when I try running that project I can't even `lein with-profile speclj repl` |
| 15:50 | gfredericks | Anderkent: what's it do? |
| 15:50 | Anderkent | crash saying nrepl is not on classpath |
| 15:50 | gfredericks | me too; I wonder why |
| 15:51 | gfredericks | something about how with-profile works maybe |
| 15:51 | gfredericks | all that profile does is change the :test-paths |
| 15:52 | Anderkent | crazy. that's even if I remove the plugins |
| 15:52 | gfredericks | you should be able to avoid with-profile by setting test-paths at the top level and using `lein spec`; but then `lein test` won't work for normal reasons |
| 15:52 | gfredericks | I think you're describing a different [non-]problem |
| 15:52 | sdegutis | Quick design question. I have a macro that basically does (if ~condition (do ~@body) (handle-error)) and I want to replace it with non-macro code. But I'm finding that `body` is often multiple things, so I need to wrap it in (do), which can look a little ugly inside an (if) but can't be replaced with a (when) on account of the else-clause. What would you do in this case? |
| 15:53 | llasram | sdegutis: Just use the macro |
| 15:54 | gfredericks | so where is the classpath actually constructed? |
| 15:57 | gfredericks | leiningen.core.classpath probably |
| 15:58 | Anderkent | gfredericks: yeah, you get both jdbcs on your classpath with that profile |
| 15:59 | gfredericks | Anderkent: how did you figure that out? |
| 15:59 | Anderkent | printed out the classpath from main |
| 15:59 | Anderkent | :D |
| 15:59 | sdegutis | llasram: hmm, that's one idea, but I can't help feeling like it's non-idiomatic to have (with-some-effect some-arg ...) in my code. |
| 15:59 | Anderkent | (println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader)))) |
| 16:00 | gfredericks | good to know |
| 16:01 | sdegutis | This macro mainly exists to hide a (do) and the else-clause, and I'm not sure that's a good enough reason for it to be a macro. |
| 16:01 | gfredericks | Anderkent: wait are you doing that without running the spec task? |
| 16:01 | gfredericks | Anderkent: I get the normal deps using `lein with-profile speclj run` |
| 16:02 | gfredericks | at least it prints the normal version |
| 16:02 | Anderkent | no, I mean with the spec task |
| 16:02 | Anderkent | so I assume it's the speclj plugin messing things up |
| 16:02 | gfredericks | right |
| 16:03 | gfredericks | I can't figure out how though because it seems like the task gets to eval-in-project pretty quick without touching anything weird |
| 16:03 | Glenjamin | the speclj plugin does something really odd |
| 16:03 | Glenjamin | i ran into this the other week, 1 min |
| 16:03 | sdegutis | gfredericks: why did you choose speclj? |
| 16:03 | gfredericks | sdegutis: I didn't |
| 16:03 | gfredericks | am debugging for a coworker |
| 16:04 | Glenjamin | i chose it because i like the RSpec test spec style |
| 16:04 | Anderkent | gfredericks: but the speclj plugin adds spelcj to your classpath somehow right? |
| 16:04 | Anderkent | I don't see where it happens but it must |
| 16:04 | Glenjamin | in a recent version of speclj they stopped using a second jvm process |
| 16:04 | Glenjamin | and ran tests in the lein process itself |
| 16:04 | gfredericks | waat |
| 16:05 | Anderkent | that'd do it |
| 16:05 | Glenjamin | you can fix by adding ":speclj-eval-in :subprocess" to your project.clj |
| 16:05 | Glenjamin | https://github.com/slagyr/speclj/pull/67 |
| 16:05 | hiredman | https://github.com/slagyr/speclj/blob/2.9.0/src/leiningen/spec.clj#L33 |
| 16:05 | Glenjamin | thats the one. |
| 16:05 | Glenjamin | took me a good hour or so to track down |
| 16:06 | sdegutis | Wow. |
| 16:06 | sdegutis | (re: the pull request) |
| 16:06 | gfredericks | huh |
| 16:06 | Anderkent | gfredericks: so you basically want a dependency on speclj instead of :plugins speclj |
| 16:06 | rasmusto | i had nil pudding for lunch |
| 16:06 | Glenjamin | you need both if you want to do "lein spec" |
| 16:07 | sdegutis | (inc rasmusto) |
| 16:07 | lazybot | ⇒ 3 |
| 16:07 | gfredericks | Anderkent: or both? how does `lein spec` work if it's not a plugin? |
| 16:07 | Glenjamin | "just run it in the same JVM to save 3 seconds" seems like a reasonable idea, apart from the part where it isn't |
| 16:08 | Anderkent | you're right it's both |
| 16:08 | Glenjamin | gfredericks: you need both so you can do lein spec, but adding ":speclj-eval-in :subprocess" should fix classpath weirdness |
| 16:08 | Anderkent | Glenjamin: actually it kind of is, but you want to fire off a new classloader |
| 16:08 | hiredman | it is a plugin that runs code in the projects process, so it injects a speclj dep into the project |
| 16:09 | Glenjamin | Anderkent: i don't know enough about java/jvm to deal with classloaders, but i would love to be able to run stuff with siloed dependencies |
| 16:09 | Glenjamin | defeat callback hell and all that |
| 16:09 | Glenjamin | sorry, dependency hell |
| 16:09 | gfredericks | I'm having trouble getting this to work after adding :subprocess |
| 16:09 | Glenjamin | gfredericks: when i ran into the issue, it was because speclj and lein itself clashed on some dependency |
| 16:10 | pcn | Are there libraries that make file handling easier? I'd like something that implicitly manages a file using with-open, and provides an split. And that buffers reads and writes. |
| 16:10 | Anderkent | lein trampoline was a thing wasnt it |
| 16:10 | Glenjamin | lein trampoline is a funky hack |
| 16:10 | Glenjamin | the lein shell wrapper reads a file that the lein jvm left behind and execs it |
| 16:11 | Glenjamin | but shouldn't make a difference vs subprocess |
| 16:11 | gfredericks | Glenjamin: thanks for figuring this out :) |
| 16:11 | Glenjamin | got it working? |
| 16:11 | Anderkent | ah. I thought trampoline was reusing the same process, just doing classpath magic |
| 16:11 | Anderkent | but I guess it's not |
| 16:12 | hlship | Curiousity: when extending a protocol onto Clojure maps, it seems like you could extend APersistentMap, IPersistentMap, or even Associative. What is the best choice, or what do you need to consider to make a choice. |
| 16:14 | gfredericks | Glenjamin: no but I'm not surprised it doesn't work anymore :) |
| 16:14 | Glenjamin | http://www.flyingmachinestudios.com/programming/lein-trampoline/ : "How Clojure Babies are Made: Leiningen's Trampoline" |
| 16:14 | Glenjamin | gfredericks: downgrading to speclj 2.8 is probably not unreasonable |
| 16:14 | Anderkent | Glenjamin: yeah I found it now |
| 16:14 | Anderkent | gfredericks: I got it to run tests, it just crashed on checking the exit code ;p |
| 16:14 | Anderkent | I'd raise a bug with speclj |
| 16:15 | Anderkent | make them worry about it |
| 16:15 | Glenjamin | yeah, i might see if they'll change the default back - it doesn't seem like a good idea |
| 16:15 | gfredericks | yeah I saw the exit code thing too |
| 16:15 | Glenjamin | the solution to slow jvm startup with speclj is to use --auto |
| 16:15 | gfredericks | so leiningen has a feature where if you say :eval-in :leiningen it... how the hell does it get your normal dependencies in that case? |
| 16:15 | Anderkent | as to classpath isolation, yeah, I'd like a nice thing for it too |
| 16:16 | Anderkent | right now I'm also sharing the classpath with environment project in my plugin (cloverage) |
| 16:16 | llasram | gfredericks: That's intended for plugins and the like, for the plugin code itself. The speclj plugin doing this is totes counter-purpose |
| 16:17 | Anderkent | the current idea to fix it is to switch to subprocess evaluation, but that means I have to make intrumentation produce files rather thane val things, and bleh in general |
| 16:17 | technomancy | gfredericks: :eval-in :leiningen turns :dependencies into :plugins |
| 16:17 | Anderkent | *than eval |
| 16:17 | technomancy | effectively |
| 16:17 | gfredericks | technomancy: how does it do that after the process has already started up? |
| 16:17 | Anderkent | technomancy: does it attempt resolution or just takes project classpath and appends it to current one? |
| 16:18 | technomancy | gfredericks: pomegranate classloader tricks |
| 16:18 | technomancy | Anderkent: it does a new resolution |
| 16:18 | Anderkent | then a duplicate classpath entry is probably a bug there |
| 16:19 | Anderkent | oh unless it did a new resolution, got a differnt version... Can you remove things from classpath? |
| 16:19 | OscarZ | i have a vector x of maps and i want to return the same vector but without a specific map that i can find with (apply min-key :value x).. whats the best way to do this? probably something simple that im missing again :) |
| 16:19 | Glenjamin | gimme 2 mins i can tell you what i conflicted on... |
| 16:20 | AimHere | OscarZ, filter sifts a collection by a predicate |
| 16:21 | technomancy | wow wait... speclj runs project code in leiningen by default? |
| 16:21 | OscarZ | oh i thought i tried filter.. so predicate like #(not= y %) should work ? |
| 16:21 | technomancy | ._. |
| 16:21 | Anderkent | technomancy: yep, because it saves 3 seconds! |
| 16:22 | AimHere | OscarZ, well that's one example of a predicate |
| 16:22 | technomancy | http://p.hagelb.org/10no.gif |
| 16:22 | AimHere | You'll have to craft the appropriate one for your problem! |
| 16:22 | Anderkent | technomancy: https://github.com/slagyr/speclj/pull/67 go and post that there : |
| 16:23 | Glenjamin | right, yeah |
| 16:24 | Glenjamin | the problem I had was speclj wanting a newer version of clj-stacktrace than the one that leiningen had already loaded |
| 16:24 | Glenjamin | which was resolved by telling it not to do :eval-in :leiningen |
| 16:25 | Anderkent | I mean okay, what they did before was also insane |
| 16:26 | Anderkent | they spawned off their own jvm |
| 16:26 | Anderkent | rather than using eval-in-project |
| 16:26 | technomancy | pretty weird |
| 16:26 | Anderkent | yeah I don't even |
| 16:26 | technomancy | http://p.hagelb.org/comfort.jpg |
| 16:27 | Anderkent | How many pics do you even have there. Damn you for not having an index |
| 16:27 | sturner | Anyone familiar with http://www.prismtech.com/opensplice and worked with DDS in general from Clojure? |
| 16:27 | technomancy | mwahaha |
| 16:28 | gfredericks | I bet he has an emacs function that searches his images directory to make sure he gets the url right |
| 16:29 | gfredericks | he can send a gif url in an avg of 4 keystrokes |
| 16:29 | technomancy | I've stopped trying to save keystrokes since getting a mechanical keyboard |
| 16:29 | Anderkent | he just has a mapping from emoticones to gifs on outgoing text |
| 16:29 | technomancy | since each keystroke is so crisp and satisfying |
| 16:29 | technomancy | I no longer want to minimize that feeling |
| 16:30 | seangrove | technomancy: Is there a way to specify host on the command line when starting a repl? |
| 16:30 | bbloom | technomancy: aw yeah, mmm mechanical. love it |
| 16:31 | technomancy | seangrove: LEIN_REPL_HOST I think |
| 16:31 | technomancy | bbloom: cherry MX blues; I heart them so much |
| 16:31 | jkj | steampunkical keyboard |
| 16:31 | teslanick | keyboard nerds are the worst. ;) |
| 16:31 | pcn | technomancy: you must have your own office. I had to take away the keyboard from an intern when he got one a couple of years ago. |
| 16:31 | Glenjamin | wow, this speclj task stuff is really weird now |
| 16:31 | Anderkent | pcn: there are silent mechanical switches |
| 16:31 | pcn | Oooooh. |
| 16:31 | seangrove | pcn: My coworker made me give up the kinesis for the same reason |
| 16:31 | bbloom | technomancy: kenesis man myself |
| 16:31 | Glenjamin | i'm gonna have to dig in and see if i can make this sensible again |
| 16:31 | technomancy | pcn: https://secure.flickr.com/photos/technomancy/tags/laboratory yeap |
| 16:31 | Anderkent | oh sorry didnt see cherry mx |
| 16:31 | seangrove | technomancy: That did it, thank you |
| 16:32 | technomancy | it's not an office; it's a laboratory =) |
| 16:32 | Glenjamin | there's one guy in our office with a mechanical |
| 16:32 | pcn | That's nice. |
| 16:32 | Glenjamin | lucky for us he's a manager now, so doesn't type much |
| 16:32 | technomancy | seangrove: psh; the kinesis is silent compared to this |
| 16:33 | pcn | Where'd you get the desk from? |
| 16:33 | also | is it normal for leiningen to give the error "Checksum validation failed, no checksums available from the repository" only the *first time* the dependency is fetched? |
| 16:33 | technomancy | pcn: ikea jerker, I think |
| 16:33 | seangrove | technomancy: You could just wire your keyboard to play machine-gun fire sound effects whenever you're typing if you're going for a visceral, loud effect |
| 16:34 | teslanick | What's the idiomatic way to loop over something with an incrementing index? loop/recur? |
| 16:34 | AimHere | You want to *feel* the machine gun effects too |
| 16:34 | gfredericks | Glenjamin: coworker pointed out that `run -m speclj.main` works |
| 16:34 | Glenjamin | heh |
| 16:34 | Anderkent | teslanic map-indexed ? |
| 16:34 | technomancy | seangrove: supposedly having audio feedback in the switch itself can help train you to reduce force to the exact amount required for activation rather than bottoming out every time |
| 16:34 | Glenjamin | gfredericks: it's possible to use in a repl too, but a bit fiddly |
| 16:34 | pcn | Ah, they don't make taht any more |
| 16:34 | technomancy | not really something you can do in software |
| 16:35 | technomancy | pcn: I think they just renamed it |
| 16:35 | teslanick | Anderkent: thanks. don't know how I didn't see that. |
| 16:35 | Anderkent | that's okay |
| 16:38 | pcn | technomancy: I think it's dead and gone. The replacements aren't reputed to be as good. |
| 16:39 | logic_prog | has ritz been ported to cider, or is it still nrepl only? |
| 16:39 | technomancy | pcn: ah, shame |
| 16:39 | technomancy | big fan of standing desks |
| 16:41 | Raynes | technomancy: Can you tell that Python tooling frustrates me? https://www.refheap.com/27051 |
| 16:41 | technomancy | Raynes: my deepest condolances |
| 16:42 | bbloom | virtualenv is a massive pain |
| 16:43 | technomancy | "at least it's not rvm" |
| 16:43 | seubert | virtualenvwrapper is fine.. |
| 16:43 | bbloom | ugh. |
| 16:43 | Raynes | Well, my problem is that virtualenv.el expects me to just have a single directory for all my envs. |
| 16:43 | Raynes | I'm fine with virtualenv. |
| 16:43 | bbloom | doesn't python have PYTHON_PATH or something? |
| 16:43 | Raynes | It's also not gonna matter because Python has replaced it in core. |
| 16:43 | Raynes | pyvenv yo |
| 16:44 | Anderkent | technomancy: +1 |
| 16:44 | Anderkent | unless you were being sarcastic |
| 16:44 | Raynes | Presumably at some point people will grow nads and switch to Python 3 across the board... |
| 16:44 | bbloom | meanwhile, plan9 got this right however long ago: union directory mounts > various virtualenv nonsense and PATH variables |
| 16:44 | Glenjamin | does it handle multiple pythons, or does it still just do different package loading dirs per app? |
| 16:44 | sdegutis | I think Take Me Out should be the official Clojure song, it epitomizes everything Clojure's about, from FP to abstracting sequences: https://www.youtube.com/watch?v=Ijk4j-r7qPA |
| 16:46 | pcn | Raynes: python 2 won't dissappear until all of numpy and scipy work |
| 16:48 | Anderkent | pcn: it won't dissapear from enterprise even then |
| 16:48 | Anderkent | http://www.robg3d.com/?p=1175 etc. |
| 16:49 | gozala | dnolen: tbaldridge do you have little bit of time I have some questions in regards to core.async |
| 16:50 | pcn | Sure, but by the same token once you only have it in enterprises, it's dead. |
| 16:50 | tbaldridge | gozala: sure |
| 16:50 | rasmusto | :< |
| 16:50 | rasmusto | that's not true of humans, is it? |
| 16:51 | pcn | My recollection of being in big enterprises is that all learning stopped when I walked in the door |
| 16:51 | logic_prog | tbaldridge: if I want uber clojure debugging tools, do I want ritz or cider? |
| 16:52 | logic_prog | http://www.youtube.com/watch?v=sA5zOLCa3Xw <-- anyone know a link for this talk, where, starting at 11:25, the slides aren't suffering from parallax ? |
| 16:53 | tbaldridge | logic_prog: there really isn't a good debugger for clojure. You can use JVM debuggers if you want. Most people just get comfortable with smaller functions and the repl |
| 16:53 | tbaldridge | not to mention that the Clojure compiler does some stuff that makes debugging with a debugger really hard. For example it clears locals after its done (so the data in the locals can be GC'd) |
| 16:54 | gozala | tbaldridge: I’m trying to wrap node IO libs for cljs |
| 16:54 | logic_prog | tbaldridge: so the notion of "when an exception happens, fire me up a repl (1) with access to local vars (2) lets me evaluate forms and (3) pick what value to return" is not part of stadard clojure workflow ? |
| 16:54 | gozala | and expose channel based APIs |
| 16:54 | logic_prog | tbaldridge: the compiler argument makes sense |
| 16:54 | tbaldridge | logic_prog: no, and I'm not even sure such a tool exists for clojure |
| 16:54 | gozala | tbaldridge: one thing that I çant figure out is what’s idiomatic way to report and handle errors |
| 16:55 | technomancy | getting access to locals is not that tricky if you set the point beforehand |
| 16:55 | technomancy | https://github.com/technomancy/limit-break |
| 16:55 | gozala | tbaldridge: two options I considered were |
| 16:55 | tbaldridge | gozala: what I recommend is having a dedicated "error" channel. Report exceptions to that channel and have that channel log them or something. |
| 16:55 | technomancy | logic_prog: the difficult part is a stepping debugger |
| 16:55 | gozala | 1. Make apis that return records with output channel and error channel |
| 16:56 | sdegutis | technomancy: ffvii!! |
| 16:56 | gozala | 2. Make Error protocol an put them on the same result channel |
| 16:56 | sdegutis | <3 |
| 16:56 | logic_prog | tbaldridge , technomancy: this makes sense, I can see how this is easy in "interpreted scheme" but hard in "clj compiled to java" |
| 16:56 | technomancy | sdegutis: necessarily |
| 16:56 | sdegutis | oh? |
| 16:56 | technomancy | logic_prog: the other thing is you have to be in pretty deep in the guts of some nasty stateful code to actually need a stepping debugger in clojure |
| 16:57 | technomancy | due to referential transparency everywhere |
| 16:57 | logic_prog | technomancy: I can't belive limit-break is just 32 lines of code: https://github.com/technomancy/limit-break/blob/master/src/limit/break.clj |
| 16:57 | technomancy | logic_prog: it's pretty, errr... limited |
| 16:57 | Anderkent | badumtsss |
| 16:57 | danneu | I'm just faking it til I make it with my VPS. If I start a datomic-pro SQL transactor on a remote server, then my local peer connects to the jdbc connection with <remote-ip>:4334 (default port), right? |
| 16:57 | gozala | tbaldridge: ok the only inconvenience is that then I end up with ton of APIs that return two channels and on each read one needs to alt! between error and data |
| 16:58 | gozala | tbaldridge: I felt like it would be nice to have something built-in |
| 16:58 | technomancy | logic_prog: however, its simplicity makes it good for understanding what's really at the core of locals-inspection and possibly building something better from that, should anyone be so inclined |
| 16:58 | technomancy | hint hint |
| 16:58 | logic_prog | technomancy: yeah, exactly why I'm reading it beacuse it's more instructional than production quality |
| 16:59 | gozala | tbaldridge: another question was on how would one communicate back |
| 16:59 | logic_prog | technomancy: is there a good nrepl tutorial somewhere where I can play with integrating limit-breka into repl-y, instead of only with stdin repl> |
| 16:59 | technomancy | sdegutis: dang now you got me listening to http://ff7.ocremix.org |
| 16:59 | Anderkent | logic_prog: reply can do standalone, i think? |
| 16:59 | technomancy | logic_prog: unfortunately afaik the details are scattered |
| 17:00 | technomancy | beyond just the nrepl readme I mean |
| 17:00 | gozala | tbaldridge: what I mean is let’s say (fs/read path) returns a {:output (chan) :error (chan)} |
| 17:00 | gozala | tbaldridge: what if consumers want’s sot stop reading from output at some point |
| 17:00 | gozala | tbaldridge: Ideally file descriptor should be closed |
| 17:01 | gozala | tbaldridge: but how should one communicate intent that it’s done consuming channel |
| 17:01 | gozala | tbaldridge: I guess what I’m asking for is something like (take-while p c) |
| 17:01 | tbaldridge | gozala: the problem is that the person reading from the channel is very rarely able to do something about the error. |
| 17:02 | tbaldridge | gozala: have you read Joe Armstrong's papers on this sort of thing |
| 17:02 | logic_prog | tbaldridge , technomancy : I am considering spening today + weekend studying ritz. Is there anything I should know before hand? (Or is this even a good investment of time -- are there known flaws with ritz?) |
| 17:02 | gozala | tbaldridge: I have not (do you have a link by a chance) |
| 17:03 | sdegutis | technomancy: dang now you got me listening to https://www.youtube.com/watch?v=LfB3aEOWAlk |
| 17:03 | gozala | tbaldridge: sure reared will rarely handle errors |
| 17:03 | gozala | tbaldridge: but in my frp lib for example I had an error type |
| 17:03 | technomancy | logic_prog: the main complaint is that it's difficult to set up and get working, and it's incompatible with cider. I haven't tried it myself. |
| 17:04 | tbaldridge | gozala: the first part of this paper is good: http://www.erlang.org/download/armstrong_thesis_2003.pdf |
| 17:04 | gozala | so values put on signal if they of error type would thread through high order functions |
| 17:04 | tbaldridge | it follows the actor model, but many of the ideas work well in core.async |
| 17:04 | gozala | and there were functions like catch that could be used to handle those casess |
| 17:05 | sdegutis | technomancy: True story, this is the playlist that runs 8+ hours a day for me: https://www.dropbox.com/s/zyf3814c2tey0oh/bahamut.png |
| 17:05 | gozala | tbaldridge: I’ll take a look at the paper |
| 17:05 | technomancy | sdegutis: there is no shame |
| 17:06 | sdegutis | Also I designed that app. I think like 3 people know it exists. |
| 17:06 | gozala | tbaldridge: I think it would be good to have some examples with suggestions on how to handle this kind of stuff though |
| 17:07 | Raynes | I swear by pebble for wrist notifications, but I've gotta say, the notification load of this new job and bitemyapp's tweets is going to cause my arm to be perpetually vibrating. |
| 17:09 | gozala | tbaldridge: also how about the other question of letting reader communicate with writer that it’s done |
| 17:10 | tbaldridge | gozala: when its done it normally will just close the channel. |
| 17:10 | gozala | tbaldridge: so you mean reader should (close! input) ? |
| 17:10 | gozala | tbaldridge: is that observable for the writer ? |
| 17:11 | gozala | tbaldridge: so that it could close error channel and free up resources ? |
| 17:11 | teslanick | sdegutis: That's a handsome music player |
| 17:11 | sdegutis | teslanick: thx. src: https://github.com/sdegutis/bahamut |
| 17:12 | tbaldridge | gozala: yeah, if you're looking for resource type stuff, then yes, there probably needs to be a 2nd channel involved that the writer alts over. When the "shutdown" channel is closed it frees the resources and exits. |
| 17:12 | tbaldridge | but it's hard to say without seeing a usecase |
| 17:12 | Notte | Would you help me with this function? http://hastebin.com/minuxibira.lisp It should return a lazy-seq of tuples |
| 17:13 | Notte | I don't get why i can't realize it even with doall or similar |
| 17:13 | gozala | tbaldridge: how would you implement (fs/read path) ? |
| 17:13 | gozala | tbaldridge: assuming that content maybe large and there for you would wanna stream it |
| 17:14 | gozala | tbaldridge: that’s basically what I’m trying |
| 17:14 | jstew | If I have a collection [[1 2] [3 4]], what's a nice way to split them by column so that they're [[1 3][2 4]]? My solution is ugly, and I know there's an elegant way. |
| 17:14 | alandipert | Notte: you can use the fact that map takes n colls and do something similar with (map vector colls...), eg |
| 17:14 | hyPiRion | jstew: (apply map list ...) |
| 17:14 | hyPiRion | ,(apply map list [[1 2] [3 4]]) |
| 17:14 | clojurebot | ((1 3) (2 4)) |
| 17:14 | jstew | wow... very nice! |
| 17:14 | gozala | tbaldridge: I can put my current code somewhere if you want to take a look |
| 17:14 | hyPiRion | eventually (apply mapv vector ...) if you want them on vector form |
| 17:15 | jstew | clojure is so elegant. My solutions thus far haven't been as sexy as they can be. Thanks :) |
| 17:16 | Notte | alandipert: i thought about it, but i don't want pair like (a a), (b b) |
| 17:16 | Notte | also i really want to understand what i'm doing wrong |
| 17:16 | alandipert | Notte: what's an example desired in/out? |
| 17:16 | hyPiRion | jstew: It comes with experience, it's hard at first if you've used imperative languages earlier :) |
| 17:17 | Notte | alandipert: (tuples [1 2 3]) ; -> [[1 2] [1 3] [2 3]] |
| 17:17 | jstew | It's starting to click. I can write clojure, just not "good" clojure yet. |
| 17:17 | Glenjamin | gozala: the node streams api is pretty well formed and offers approaches for most of the problems you just mentioned |
| 17:18 | Notte | jstew: what docs are you using? |
| 17:18 | Glenjamin | i'm not sure channels alone are rich enough to be streams in the node sense |
| 17:19 | jstew | hyPiRion: Could you be so kind as to explain how that works? map list makes a list out of hte vector, but apply will do what in that context? I thought apply just sort of flattens a list so that it can be used as args? |
| 17:19 | Glenjamin | jstew: yup, it's like * in ruby or ptthon |
| 17:20 | jstew | Notte: docs for what? |
| 17:20 | Notte | jstew: to learn clojure |
| 17:20 | Anderkent | jstew: apply turns it into (map list [1 2] [3 4]). Map then takes the first element from each list, applies list to it (giving (1 3)), then does it again |
| 17:20 | Notte | i can't find much online, compared to other languages |
| 17:20 | jstew | Notte, 4clojure.org, clojure for the brave and true, and google code jam |
| 17:20 | hyPiRion | jstew: (apply map list [[1 2] [3 4]]) is just like (map list [1 2] [3 4]). Since map allow a variadic amount of lists, it works |
| 17:21 | jstew | Got it! Thank you both, Anderkent and hyPiRion. you;ve been helpful |
| 17:21 | Glenjamin | Notte / jstew http://aphyr.com/tags/Clojure-from-the-ground-up is good also |
| 17:21 | technomancy | (inc aphyr) |
| 17:21 | lazybot | ⇒ 1 |
| 17:21 | technomancy | ...! |
| 17:22 | technomancy | I guess he's not on IRC much, but styll |
| 17:22 | technomancy | still |
| 17:22 | Glenjamin | i suspect lazybot needs some spit/slurp |
| 17:22 | hyPiRion | (inc aphyr) |
| 17:22 | lazybot | ⇒ 2 |
| 17:22 | hyPiRion | $seen aphyr |
| 17:22 | lazybot | aphyr was last seen talking on #riemann 2 hours and 25 minutes ago. |
| 17:22 | jstew | technomancy: your nick looks familiar for some reason. Were you a rubyist in the past? |
| 17:23 | technomancy | jstew: hush not so loud |
| 17:23 | jstew | hah, knew it. :) |
| 17:23 | insamniac | It looked familiar to me when I got here, but then I realized it was because of github. |
| 17:23 | Notte | Glenjamin: thanks |
| 17:24 | rasmusto | technomancy += 1 |
| 17:24 | Glenjamin | mutable state! |
| 17:24 | technomancy | http://thisotplife.tumblr.com/post/63360807823/mutable-data-structures |
| 17:27 | Anderkent | OTP? |
| 17:27 | Anderkent | Open Telecom Platform? Seems weirdly specific |
| 17:28 | ro_st | dnolen: howdy |
| 17:28 | technomancy | the reference implementation of erlang is often called OTP |
| 17:28 | Anderkent | right. Didn't realize it's all about erlang |
| 17:29 | Anderkent | I guess that'll join security reactions and plt life in my rss reader.. |
| 17:30 | ro_st | what does the t in PLT stand for? |
| 17:31 | Anderkent | you know I thought it was theory, but now I figure itmight be a reference to racket? |
| 17:33 | gozala | Glenjamin: node streams are like set of channels |
| 17:33 | gozala | and they are far from ideal |
| 17:33 | gozala | not to mention there’s no syntax support |
| 17:33 | hyPiRion | ro_st: theory, theorists |
| 17:33 | gozala | that’s why I’m trying to wrap them in core.async flavoured API |
| 17:34 | ro_st | aha |
| 17:34 | Glenjamin | gozala: i think it's worth exploring, but you'll need quite a few channels |
| 17:34 | Glenjamin | streams form a pipeline, to handle backpressure correctly - they're actually more similar to Seqs than core.async i would say |
| 17:35 | gozala | Glenjamin: Not necessarily there are two approaches |
| 17:35 | gozala | one is more haskelly where you deal with different messages types with actual types |
| 17:35 | gozala | or you use multiple channels |
| 17:36 | gozala | I’ve done implementation of both approaches in js in a past |
| 17:36 | gozala | and kind of prefer former |
| 17:36 | ro_st | http://this-plt-life.tumblr.com/post/36425247242/when-i-hear-of-a-lisp-success-in-industry this one |
| 17:36 | Glenjamin | in node nowadays it tends to be more common to define things as streams, and use pipe() |
| 17:36 | gozala | but I’m not sure how well it maps to core.async |
| 17:36 | Glenjamin | i'm unsure which of those categories it fits into |
| 17:37 | gozala | Glenjamin: none, they basically have one channel in form of event emitter |
| 17:37 | gozala | and event types serve as a channel / message type |
| 17:37 | Glenjamin | the client-side examples i've seen from rich have been to attach a single channel to one event listener |
| 17:37 | Glenjamin | but i can see how one channel would be simpler |
| 17:38 | gozala | Glenjamin: I also think core.async has a lot more saner approach to IO coordination than node’s hard coded backpressuer |
| 17:38 | Glenjamin | do channels do backpressure? |
| 17:38 | gozala | channel is sync point |
| 17:39 | gozala | you can’t write until other end reads |
| 17:39 | gozala | and you can make buffered channels |
| 17:39 | Glenjamin | right, yes |
| 17:39 | gozala | that would allow to buffer |
| 17:39 | Glenjamin | so you probably want to work with the .on('readable') api |
| 17:39 | Glenjamin | can a channel be closed? |
| 17:39 | gozala | Glenjamin: yes |
| 17:40 | Glenjamin | then that fits a single channel pretty well, and you just have to deal with errors - i think i've caught up with where you started? |
| 17:40 | Glenjamin | can you make a channel throw? |
| 17:40 | gozala | tbaldridge so here is a code I’ve being working on https://github.com/Gozala/clojurescript.node/blob/master/src/node/fs.cljs#L149 |
| 17:40 | mmitchel_ | technomancy: For :repositories setting in project.clj -- Is there a way to provide a password for each :repository from the environment? |
| 17:41 | gozala | Glenjamin: you don’t throw, but you can make (Errro. message) |
| 17:41 | technomancy | mmitchel_: yeah, check out `lein help deploying` under "credentials in the environment" |
| 17:42 | gozala | and reader can (if (error? message) (handle error) (do-something message)) |
| 17:42 | mmitchel_ | technomancy: excellent thanks! |
| 17:42 | gozala | tbaldridge: in this implementation I box errors in error type |
| 17:43 | gozala | rather than implying second channel for errors |
| 17:43 | gozala | Initially I tried using two channels instead but felt a lot more hassle |
| 17:44 | gozala | tbaldridge: so net module actually uses two channel approach |
| 17:45 | gozala | but as you can see from example on readme https://github.com/Gozala/clojurescript.node#examples |
| 17:45 | gozala | API tends to become a lot more complex that way |
| 17:46 | gozala | that’s why I’m leaning towards elm like approach of using types to distinguish data & errors |
| 17:47 | gozala | but then map, filter and all high orders functions would ideally pass through errors otherwise user will need to do it manually |
| 17:48 | gozala | tbaldridge: another thing is that consumer is forced to handle errors since it’s on the same channel |
| 17:49 | gozala | while with two channel approach it felt like it’s easy to forget you to even handle error channel |
| 17:49 | gozala | tbaldridge: does any of my reasoning makes sense to you ? |
| 17:53 | tbaldridge | gozala: so this is a rare example where I'm going to recommend something I don't normally recommend. |
| 17:54 | tbaldridge | 1) box errors and then write a macro that I prefer to call <?, this will create a take and if the value is a boxed error, then re-throw it. |
| 17:55 | gozala | tbaldridge: but don’t you think there should be something alike in core.async itself ? |
| 17:55 | gozala | I feel like it’s not very exotic use case |
| 17:56 | gozala | most of node APIs will have a same concerns |
| 17:56 | gozala | tbaldridge: what you suggest actually is very similar to what Task.js does |
| 17:56 | gozala | tbaldridge: http://taskjs.org/ |
| 17:57 | tbaldridge | 2) if you use the latest version of core.async >! now returns falsey if the put happens on a closed channel. |
| 17:57 | tbaldridge | So with that you can easily write a with-open macro that calls close! when control escapes the current block. |
| 17:58 | tbaldridge | That will allow the file reader to detect that the channel is closed and free up resources. |
| 17:58 | gozala | tbaldridge: but that means producer will have to waste one read until it knows no writes are possible |
| 17:58 | gozala | ideally it would happen prior to that |
| 17:59 | gozala | tbaldridge: also ideally producer will still confirm close |
| 17:59 | gozala | since there still maybe an error on attempt to free resources |
| 17:59 | tbaldridge | gozala: why do you need to confirm freeing of resources? |
| 18:00 | tbaldridge | what are you going to do if freeing fails? |
| 18:00 | Anderkent | that seems excessive. IF there might be an error, the producer should handle it |
| 18:00 | Anderkent | otherwise it's something you cant handle, so why tell the consumer |
| 18:00 | tbaldridge | (inc Anderkent) |
| 18:00 | lazybot | ⇒ 5 |
| 18:01 | gozala | tbaldridge: Anderkent I see your point, but freeing up resources may take a time |
| 18:01 | gozala | so I feel like it’s awkward to pretend that it’s already closed |
| 18:02 | gozala | that being said I don’t think it’s a big deal in my case so I can ignore it until I have a better use case |
| 18:03 | gozala | tbaldridge: Anderkent don’t you think suggested <? should just be a !< |
| 18:04 | gozala | although to be honest I prefer handling cases via cond rather than catch |
| 18:04 | tbaldridge | gozala: that's an entire other argument, lol |
| 18:05 | tbaldridge | see arguments over Go's error handling (or lack of it) |
| 18:05 | gozala | specially since error propagation is not that useful with async code |
| 18:05 | Anderkent | I do like cond over catch, but also prefer silent error propagation. I.e. monads! |
| 18:05 | tbaldridge | gozala: true, so it's not a bad idea to just box everything into a hashmap and then do cond on it. |
| 18:05 | Glenjamin | the node core has a "if you subscribe to error you can have it, if you don't then i'll throw" - is there a parallel to be drawn here? |
| 18:06 | gozala | Anderkent: tbaldridge that’s what I’m suggesting though |
| 18:06 | tbaldridge | {:op :more-data :value "4444"} |
| 18:06 | gozala | if high order functions would just propagate errors |
| 18:07 | gozala | Glenjamin: node has domains, and please don’t get me started on them |
| 18:07 | tbaldridge | gozala: well there's another argument to be made here. Let's say I have a chain of (-> read-file map filter map output-data) |
| 18:07 | Glenjamin | domains are awful |
| 18:07 | tbaldridge | each of those being a go block doing some processing |
| 18:07 | Glenjamin | even the core devs agree |
| 18:08 | tbaldridge | gozala: some would say that an error in any of those should cause read-file to close it's channel, map filter, etc then all close, propagating the close. Then report the error to a single reporting channel. |
| 18:09 | gozala | tbaldridge: I think it’s more reasonable to have another control structure to handle that |
| 18:09 | tbaldridge | So output-data alts on the error channel and the response. If the response channel closes without sending a response the error channel is read and that generates a 500, or something like that |
| 18:09 | gozala | (-> read catch map filter map …) |
| 18:09 | gozala | or (-> read map filter map catch) |
| 18:10 | gozala | that way user can decided where to handle errors and how |
| 18:10 | tbaldridge | gozala: this follows the erlang pattern of "let it die". When things error out you crash the entire request/response chain and report the error to a central channel. |
| 18:10 | gozala | that how most reactive libs deal with that |
| 18:11 | gozala | tbaldridge: now that I think about it’s fine |
| 18:11 | gozala | it’s actually the same |
| 18:11 | gozala | as long as you have something like catch control structure to deal with recovery |
| 18:12 | gozala | tbaldridge: so only diff is weather channel should be closed on errors or not |
| 18:13 | gozala | I’d be fine with either option |
| 18:14 | Glenjamin | i don't think you should be taking data off a stream that has errored, so i would vote for closed |
| 18:15 | gozala | tbaldridge: Anderkent so are there any chances to incorporate something like this into core.async ? |
| 18:16 | tbaldridge | like what? |
| 18:18 | gozala | tbaldridge: like incorporate some error support |
| 18:18 | gozala | catch style control structure |
| 18:18 | gozala | and special handling of errors |
| 18:18 | gozala | which can abort tasks and report errors as you suggested |
| 18:19 | gozala | ms rx has such catch like control structure |
| 18:20 | tbaldridge | the problem is, this use case doesn't really fit well with how core.async is normally used. The idea behind core.async is to turn deep call stacks into linear data flows. This sort of error propagation doesn't really fit with that model. |
| 18:20 | tbaldridge | the adaption of node.js to core.async is a very interesting use case, but I'm not convinced what we've come up with here is the best solution. |
| 18:21 | tbaldridge | The better route is something were we can add monitoring of go blocks. Erlang does this via supervisor trees, where you can say "if this block dies, kill me" or "if this block dies, let me know". |
| 18:21 | gozala | tbaldridge: to me core.async is lower layer to reactive programming like ms rx |
| 18:22 | tbaldridge | That allows you to turn your entire HTTP request/response chain into a single dataflow that will crash/cleanup if a single error occurs, which is exactly what you want most of the time. |
| 18:23 | gozala | tbaldridge: that’s fine too |
| 18:23 | gozala | but some way to communicate errors is necessary, is kind of my point |
| 18:23 | gozala | tbaldridge: at the moment if producer has an error there’s nothing in core.async to support that |
| 18:24 | tbaldridge | gozala: sure there is, the producer sends an error to a channel. build whatever you want on top of that. |
| 18:25 | tbaldridge | It's a design decision for the library to not go any further than that. We don't want to dictate how errors should be handled. |
| 18:25 | gozala | tbaldridge: ok |
| 18:26 | gozala | tbaldridge: only issue with that is built in control structures won’t do anything on errors |
| 18:27 | gozala | so libraries will have to build their own control structures to support errors |
| 18:27 | gozala | which may be ok too |
| 18:28 | gozala | tbaldridge: for example generators in JS sort of solve the same problems as core.async |
| 18:28 | gozala | buth they allow user to throw in exceptions |
| 18:29 | gozala | I kind feel this is what missing |
| 18:29 | tbaldridge | If I were building a node.js interface, I would probably sit and think for about a month on how I might want to handle exceptions. Should they be handled, by whom? Why do we need to handle exceptions, etc. When code starts to get ugly, I like to go back and re-think my assumptions. If the code doesn't "feel right" perhaps I'm wrapping the API in the wrong way. |
| 18:30 | Glenjamin | i always thought that core.async was to solve the problem of decoupling bits of your application, and the callback soup was a handy side benefit |
| 18:30 | Glenjamin | the problem with reading from a stream is that you are actually somewhat coupled to the stream's state |
| 18:30 | gozala | tbaldridge: I have being thinking about it for 2 years now :P |
| 18:31 | tbaldridge | Glenjamin: agreed |
| 18:31 | gozala | started with https://github.com/Gozala/streamer |
| 18:31 | gozala | then moved to https://github.com/Gozala/streduce |
| 18:31 | Glenjamin | this is why Node.js has "evolved" a whole new set of libraries and abstractions around streams, separate from callbacks - it's still young and experimental |
| 18:31 | gozala | and then to https://github.com/Gozala/elmjs |
| 18:31 | Glenjamin | but there's people playing with lots of approaches |
| 18:32 | gozala | plus explored all the other reactive things that came up like ms rx, elm |
| 18:32 | dnolen | gozala: generators are even more low level than core.async, and you can throw exceptions in core.async too. |
| 18:32 | gozala | dnolen: how can producer of channel communicate error with a consumer ? |
| 18:33 | dnolen | gozala: many ways exactly the same as generators |
| 18:33 | gozala | dnolen: I agree generators are more low level |
| 18:33 | dnolen | gozala: generators don't dictate anything |
| 18:33 | gozala | dnolen: generators have g.next and g.throw |
| 18:33 | gozala | later throws in exception into routine |
| 18:34 | gozala | how one can throw in exception into go routine ? |
| 18:34 | dnolen | gozala: yes really low level, you gotta do something different if you want to use promises + generators, or channels + generators |
| 18:34 | Glenjamin | gozala: are you familar with caolan as in caolan/async? |
| 18:35 | gozala | dnolen: I really just want a channels, but with some error reporting support from the data producer side |
| 18:35 | dnolen | gozala: as people have already said, dictating something is pretty unwise given differing needs for different applications |
| 18:35 | gozala | there are some adhok ways |
| 18:36 | dnolen | gozala: I've done error channels stuff and supervisor stuff, both are appropriate sometimes |
| 18:36 | gozala | dnolen: maybe seeing those examples would help |
| 18:36 | dnolen | gozala: or try it yourself :) |
| 18:37 | gozala | dnolen: also adding some error reporting support does not prevents supervisor stuff I think |
| 18:37 | gozala | dnolen: I did that, that’s why I’m trying to get more input from people like you :P |
| 18:39 | gozala | ok I guess I’ll try to finish version with boxed errors on a channel & we’ll see from there |
| 18:39 | gozala | Glenjamin: yeas I’m aware of async not a fan |
| 18:39 | tbaldrid_ | gozala: also remember that core.async channels are multi writer, unlike rx which is (for the most part) single writer |
| 18:40 | gozala | tbaldridge: although you can mix multiple channels in rx so it’s really just defaults |
| 18:40 | tbaldridge | Imagine your surprise if you have two producers writing to a single map channel. One producer errors, and sends an error to map. Map then passes the error on and exits. |
| 18:41 | tbaldridge | Now the 2nd producer tries to write but the other end is dead. |
| 18:41 | Glenjamin | gozala: well caolan has been working on trying to implement decent map/filter/reduce type functions for node streams lately, and strugging with these same issues |
| 18:41 | bbloom | tbaldridge: the Rx source is available & i looked at it closely. i was like "holy crap. so much error propagation logic!" |
| 18:41 | Glenjamin | i wasn't suggesting async.js was helpful for this problem :) |
| 18:41 | gozala | tbaldridge: tbaldridge other end maybe dead either way though no ? |
| 18:42 | gozala | if consumer closed it’s end it’s kind of dead |
| 18:42 | bbloom | tbaldridge: Rx existed prior to async was in C# too, so there's tons of manual state machines. it's pretty horrific in hindsight |
| 18:42 | egghead | dnolen: ping |
| 18:42 | dnolen | egghead: saw your question earlier, only associative data structures in the app state for Om |
| 18:42 | gozala | Glenjamin: https://github.com/Gozala/reducers are monadic |
| 18:42 | gozala | and they do work with node streams |
| 18:43 | gozala | if you import https://github.com/Gozala/streduce |
| 18:43 | egghead | dnolen: ya I didn't know that '() wasn't associative but [] was, I figured because you could *nth* on both of them |
| 18:43 | tbaldridge | gozala: actually, the core.async code in master is written to shutdown when the channel the writer is producing to is closed. So closing channels the the "idiomatic" way to terminate processes in core.async. |
| 18:43 | gozala | Glenjamin: all of the back pressure etc is preserved |
| 18:43 | egghead | om is awesome but I was so frustrated last night trying to figure out why om was saying my data wasn't a valid cursor :p |
| 18:44 | dnolen | egghead: i've documented this restriction in several places |
| 18:44 | egghead | my fault then |
| 18:44 | gozala | tbaldridge: sorry I did not quite got the last comment |
| 18:44 | gozala | you mean idiomatic way to close channel is from producer side you mean ? |
| 18:46 | egghead | dnolen: I see it now here: https://github.com/swannodette/om/wiki/Documentation#wiki-root -- I was just unaware that for example the result of 'map' isnt something that is associative |
| 18:46 | egghead | or the result of a for comprehension or something similar |
| 18:46 | dnolen | egghead: Clojure documentation says they return lazy seqs |
| 18:47 | tbaldridge | gozala: in the code in master, it's idiomatic to do it from either side. Both sides should be watching for the channel to close, and shutdown when it happens. |
| 18:47 | dnolen | egghead: other people have encountered this before, but there's not much I can do about it. I wan't to enforce associative data structures for future perf reasons. |
| 18:49 | dsrx | ,(doc bean) |
| 18:49 | clojurebot | "([x]); Takes a Java object and returns a read-only implementation of the map abstraction based upon its JavaBean properties." |
| 18:49 | egghead | dnolen: I'm not against the restriction, maybe the docs could be more explicit and say 'For practical purposes this means you can only use vectors and maps, but not lists or lazy seqs' |
| 18:49 | dnolen | egghead: sure can do that. |
| 18:49 | gozala | tbaldridge: is core.reactive is a thing ? maybe core.async is too low level for what I’m trying to do |
| 18:50 | gozala | tbaldridge: Asking because I noticed your repo |
| 18:51 | tbaldridge | gozala: oh, that repo is super old. |
| 18:51 | tbaldridge | it predates core.async by a few years. |
| 18:52 | tbaldridge | gozala: as to my point, onto-chan is a producer that shuts down when the channel closes: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L615 |
| 18:52 | dsrx | ,(instance? clojure.lang.Associative (map identity [1])) |
| 18:52 | clojurebot | false |
| 18:53 | egghead | dsrx: obvious when you know it :p |
| 18:54 | rasmusto | dsrx: ##(associative? (map identity [1])) |
| 18:54 | lazybot | ⇒ false |
| 18:57 | Glenjamin | is there a better way to get it back into a vector than just calling (vec) on the Seq? |
| 18:57 | rasmusto | ##(associative? (mapv identity [1])) |
| 18:57 | lazybot | ⇒ true |
| 18:58 | Glenjamin | aha |
| 18:59 | rasmusto | Glenjamin: assuming you're doing a map |
| 18:59 | Glenjamin | mm |
| 18:59 | Glenjamin | found the related variants |
| 19:00 | rasmusto | is there one for hash-maps? |
| 19:00 | Glenjamin | (mapv identity {:a :b}) |
| 19:00 | Glenjamin | ,(mapv identity {:a :b}) |
| 19:00 | clojurebot | [[:a :b]] |
| 19:02 | rasmusto | ,(let [a {:a :b}] (into (empty a) (map identity a))) |
| 19:02 | clojurebot | {:a :b} |
| 19:02 | Glenjamin | (into {} (map identity {:a :b :c :d})) |
| 19:02 | Glenjamin | ,(into {} (map identity {:a :b :c :d})) |
| 19:02 | clojurebot | {:a :b, :c :d} |
| 19:02 | rasmusto | Glenjamin: hi5 |
| 19:02 | Glenjamin | o/ |
| 19:04 | Glenjamin | which is basically what mapv does \o/ https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/clj/clojure/core.clj#L6232 |
| 19:05 | rasmusto | mine gives you back the same coll type that you started with, which might be useful? Maybe mapv is moreso because you know what you're getting out |
| 19:05 | Glenjamin | mapmap would be a rubbish name, i guess |
| 19:05 | rasmusto | mashmap |
| 19:06 | technomancy | mapmap would be a great name |
| 19:06 | rasmusto | yeah, map vs hash-map is a hard thing to explain |
| 19:06 | Glenjamin | add it to core! that's easy to do, right? |
| 19:06 | rasmusto | mapmap is a good name, assuming you're OK with map as a coll name |
| 19:06 | technomancy | in mapmap it's at least clear you mean both meanings =) |
| 19:06 | rasmusto | true |
| 19:06 | rasmusto | but in which order? |
| 19:07 | dsrx | oh i know, call it collectmap[ |
| 19:07 | dsrx | :p |
| 19:07 | rasmusto | mapm, alternatively maph |
| 19:08 | rasmusto | maph.numeric-tower |
| 19:08 | Glenjamin | i guess it's too late to rename Map to Dict :p |
| 19:09 | bbloom | Glenjamin: heh, i've had that thought too, but for some reason "dict" implies to me that the keys are strings |
| 19:09 | bbloom | *shrug* dunno why |
| 19:09 | Glenjamin | ah, i can see that |
| 19:09 | technomancy | "Dictionary" is too many syllables |
| 19:10 | bbloom | technomancy: that's why python people just call them "dicts" |
| 19:10 | technomancy | "Dict" invites too many jr. high jokes |
| 19:10 | Glenjamin | Mapping perhaps? |
| 19:10 | bbloom | factor calls a map an "assoc" |
| 19:11 | bbloom | but i've found that awkward to say, since my brain reads "assoc" as a verb |
| 19:11 | rasmusto | (assoc (dict :a 1)) |
| 19:11 | bbloom | association vs associate |
| 19:11 | btcNeverSleeps | Hey all... I've got a question regarding the kinda "long" stacktrace, and this question and its answer: http://stackoverflow.com/questions/14297079/ ("Why are Clojure stacktraces so long?") |
| 19:12 | Glenjamin | i blame the map function |
| 19:12 | Glenjamin | i suppose they both do the same thing, so that's the main issue |
| 19:12 | btcNeverSleeps | Isn't the way the Clojure code (and Clojure Java code) decided not to use many checked exception a major reason for the long stacktraces? |
| 19:13 | btcNeverSleeps | (btw this isn't a criticism of runtime exceptions: I'm just asking if "doing without checked exception" is, or not, a big reason for long stacktraces) |
| 19:13 | bbloom | btcNeverSleeps: whether or not exceptions are checked has nothing (theoretically) to do with the length of a stack trace |
| 19:13 | Anderkent | btcNeverSleeps: not really. it's just that because of its dynamicity (ww?) the stacks are necessarily deep |
| 19:14 | bbloom | however, in practice, checked exceptions tend to cause a lot of re-throwing and exception swallowing, both of which will shorten visible stack traces, but are generally a bad idea |
| 19:14 | Anderkent | and recursion doesnt help either |
| 19:14 | Anderkent | bbloom: eh, they just separate the stack trace into X (20 lines) caused by Y (40 lines) cause dby ... |
| 19:14 | Anderkent | unless you eat the cause in which case you're evil |
| 19:14 | bbloom | Anderkent: indeed |
| 19:15 | btcNeverSleeps | (semi-related): when you code in Clojure (on the JVM), are there any checked exceptions that can happen and that you'd then be forced to catch? |
| 19:16 | bbloom | btcNeverSleeps: no. checked exceptions are an illusion of the java compiler. they are not a JVM byte code feature |
| 19:16 | btcNeverSleeps | and what happens in Clojure if I do Java interop and use a Java method that, in a .java, would refuse to compile if I didn't catch the exception? |
| 19:17 | bbloom | btcNeverSleeps: only the java compiler checks exceptions. neither the JVM nor the clojure compiler checks exceptions. |
| 19:18 | btcNeverSleeps | so if the checked exception is thrown, I end up with a checked exception manifesting itself as a runtime exception? |
| 19:19 | bbloom | btcNeverSleeps: if by "manifest" you mean "be raised at runtime" then yes. if you mean "magically becoming a subclass of the RuntimeException class" then no |
| 19:21 | socksy | not exactly a clojure question, but does anyone know how to speed up infoq videos? Rich Hickey can talk quite slowly |
| 19:21 | bbloom | socksy: use the extra time between words to reflect on what he's saying :-) |
| 19:22 | bbloom | rich isn't some awful professor whose class you skip and watch later at 2X speed just to make sure you know what's going to be on the test |
| 19:23 | bbloom | every one of his talks are worth the time to watch and then some |
| 19:23 | socksy | I have the attention span of a gnat, and inevitably my mind starts to wonder and I end up having to rewind and watch the same sentence again and again. I don't get that when the video is sped up :) |
| 19:24 | socksy | *wander |
| 19:24 | bbloom | heh.... ok |
| 19:24 | technomancy | socksy: you can download infoq videos if you change your browser user-agent |
| 19:24 | bbloom | does it wonder to things related to what he's talking about? |
| 19:25 | bbloom | if your wandering mind is at least somewhat on topic, that's probably fine to rewind a bunch :-) |
| 19:25 | socksy | I'm not sure... |
| 19:25 | socksy | technomancy: useful info, thanks |
| 19:26 | btcNeverSleeps | ,(.getBytes "a" "non-existing-encoding") |
| 19:26 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 19:29 | ivan | socksy: there are three infoq downloaders, but none can put the slides next to the video |
| 19:29 | ivan | one can replace the video with the slides |
| 19:29 | ivan | https://github.com/cykl/infoqscraper https://github.com/mtayseer/infoq-downloader https://github.com/rg3/youtube-dl |
| 19:37 | steckerhalter | any idea why reading a file with (slurp "file.txt" :encoding "UTF-8") that contains one 4-byte utf-8 character prints a string with 4 characters? |
| 19:40 | alxlit | ivan: infoqscraper can, get it from master |
| 19:41 | ivan | steckerhalter: maybe you've got a double-encoded UTF-8 file? |
| 19:42 | alxlit | ivan: infoqscraper presentation download --type h246_overlay or something like that |
| 19:43 | steckerhalter | ivan: not sure what double encoded means, but I created the file myself containg just that utf-8 character in 4 bytes |
| 19:44 | ivan | steckerhalter: does ls -l confirm that it's 4 (or 5) bytes? |
| 19:44 | steckerhalter | ivan: yes, 4 |
| 19:44 | ivan | alxlit: thanks. will try after I figure out the python 2/3 mess within |
| 19:45 | steckerhalter | xxd -b file >>> 0000000: 11110101 10100111 10111101 10110101 .... |
| 19:46 | steckerhalter | maybe it just can't deal with 4 bytes or something? |
| 19:49 | steckerhalter | ok, hmm... emacs displays one character, gedit says it's invald |
| 19:49 | steckerhalter | õ§½µ |
| 19:50 | ivan | Python says |
| 19:50 | ivan | UnicodeDecodeError: 'utf8' codec can't decode byte 0xf5 in position 0: invalid start byte |
| 19:54 | steckerhalter | well, that is 0xf5 should be valid looking at https://en.wikipedia.org/wiki/UTF-8 |
| 19:55 | steckerhalter | s/that is// |
| 19:58 | ivan | steckerhalter: that table refers to some obsolete original design |
| 19:58 | steckerhalter | ivan: yeah, it could be the restriction kicking in |
| 19:59 | AeroNotix | what can I do if I want to run a test suite with profiling enable? |
| 19:59 | AeroNotix | enabled* |
| 19:59 | AeroNotix | is there a plugin with lein test? |
| 19:59 | Anderkent | AeroNotix: what kind of profiling? |
| 19:59 | Anderkent | timbre? |
| 20:00 | AeroNotix | Anderkent: memory, cpu, call tracing |
| 20:00 | AeroNotix | Anderkent: never used timbre |
| 20:00 | Anderkent | oh, some jvm agent? |
| 20:00 | AeroNotix | jvm agent? |
| 20:01 | Anderkent | well, what are you going to use to profile it |
| 20:01 | Anderkent | there's jvm profilers like yourkit etc |
| 20:01 | AeroNotix | ok |
| 20:01 | Anderkent | these work by attaching an agent ot the jvm, they will tell you what options to add to a process |
| 20:01 | Anderkent | then you just pass these to :jvm-opts in lein |
| 20:01 | AeroNotix | gotcha, ok |
| 20:01 | Anderkent | or alternatively oyu can use a native clojure profiling lib like timbre |
| 20:02 | AeroNotix | Thanks for the info |
| 20:02 | Anderkent | that works by wrapping your code |
| 20:02 | Anderkent | no worries :) |
| 20:02 | AeroNotix | timbre looks like it can do individual form profiling, which is cool |
| 20:02 | steckerhalter | ivan: ok, got it, it's out of bounds after RFC 3629. thanks |
| 20:04 | Anderkent | steckerhalter: yeah it says 'octet values c0 c1 f5 to ff never appear'. I wonder what purpose that has |
| 20:06 | steckerhalter | Anderkent: the limitation? |
| 20:33 | akurilin | Is it generally a poor idea to cache data on (def) calls because of the potentially varying order in which this can happen? |
| 20:34 | akurilin | e.g. I have a very static table in the db which I want to cache into a var on my app's boot. Doing it in a def seems potentially risky. |
| 20:35 | akurilin | Or I guess not necessarily. Should I consider exporting this to some kind of "init function"? |
| 20:44 | Morgawr | how would I test if a vector contains an element? |
| 20:45 | Morgawr | I could write my own function with empty? and filter but there probably is a function that does that...? |
| 20:46 | arrdem | what SQL layer(s) are people using? |
| 20:46 | arrdem | all I'm really finding is korman and java.jdbc.. |
| 20:48 | akurilin | I'm using both. Korma for the boring crud or any time I need to translate something procedurally to a query, and cjj for complex queries. |
| 20:55 | dee5 | What's the normal way of running a leiningen task in the background? |
| 20:58 | hiredman | don't? |
| 20:58 | dee5 | :( |
| 20:59 | hiredman | if you want to run some lein uberjar up an uberjar and run that |
| 20:59 | hiredman | something |
| 20:59 | dee5 | Alright thanks |
| 21:16 | x^2 | im reading through the O'Reilly clojure book |
| 21:16 | x^2 | and i understand a lot of the syntax of this now |
| 21:16 | x^2 | but im just tryingg to better understand |
| 21:16 | x^2 | does Clojure completely abandon the idea of anything object/struct like, and instead carry on through functions passing data to other functions? |
| 21:16 | x^2 | or can anyone give me some insight on this |
| 21:16 | x^2 | i am kind of reading through, and i understand how to do basic things |
| 21:17 | x^2 | but i dont feel like i "get" the big picture on this yet |
| 21:17 | x^2 | maybe someone here can shed some light on that |
| 21:19 | dnolen | x^2: there are object/struct like things in the language - but it's common to encourage people to not reach for them unless they really need it. |
| 21:20 | hiredman | dnolen: maps are used all the time |
| 21:20 | hiredman | x^2: it depends what you mean by object/struct |
| 21:21 | x^2 | i mean like |
| 21:21 | hiredman | generally clojure code tends to pass around values (immutable data) and call functions on them |
| 21:21 | hiredman | er |
| 21:21 | x^2 | enclosure of data basically |
| 21:21 | hiredman | call functions with them as the arguments |
| 21:21 | x^2 | i know about vectors and stuff |
| 21:21 | x^2 | like |
| 21:22 | x^2 | i feel i can write some very basic things right now |
| 21:22 | x^2 | but i want to make them in the clojure way |
| 21:22 | hiredman | yeah, so vectors and maps and seqs and functions |
| 21:22 | hiredman | that is how you do it |
| 21:22 | x^2 | i dont want to be writing java or C++ using clojure if you know what i mean. |
| 21:22 | x^2 | okay |
| 21:22 | x^2 | this seems like a really wonderful language |
| 21:22 | x^2 | i get bored reading about ones that are so similar |
| 21:22 | x^2 | but all of these new ideas have me really excited |
| 21:23 | x^2 | i am just trying to think of something now i could write to put the ideas of clojure to good use |
| 21:23 | Morgawr | try writing a LightTable plugin :P |
| 21:23 | Morgawr | it's fun |
| 21:23 | Morgawr | and not that hard |
| 21:23 | x^2 | im not sure what that is, and ive only written a couple very basic programs before. so i might want to start at something above a 'hello world' |
| 21:23 | x^2 | but not much above |
| 21:23 | x^2 | lol |
| 21:23 | Morgawr | https://github.com/mdhaney/lt-plugin-template <-- a template for LT plugins |
| 21:24 | Morgawr | LightTable is an editor written in Clojure (for clojure and other languages) |
| 21:24 | Morgawr | but yeah, just get familiarized with the language, I guess a plugin might be too complex |
| 21:24 | x^2 | ooo |
| 21:24 | x^2 | yeah for now i think |
| 21:24 | dnolen | Morgawr: well ClojureScript :) |
| 21:24 | Morgawr | it's a pretty neat editor, really extensible, I'm loving it |
| 21:24 | x^2 | i am developing using lein- do you think this is a good idea? |
| 21:24 | teslanick | I spent a few weeks banging around in LightTable just to get acquainted with the language. |
| 21:24 | Morgawr | dnolen: well, still Clojure :P |
| 21:24 | teslanick | Lein is definitely the thing for development in clojure. |
| 21:25 | x^2 | alright well im off to a start then lol |
| 21:26 | x^2 | also - i have one question of logistics, i guess |
| 21:26 | x^2 | in my lein project directory |
| 21:26 | x^2 | or rather |
| 21:27 | x^2 | let me start over: i have a directory called "hello" for a basic hello world project |
| 21:27 | x^2 | and in the /src folder, i have: |
| 21:27 | x^2 | i have a "hello" folder, with core.clj |
| 21:27 | x^2 | that reads: |
| 21:28 | x^2 | (ns hello.core (:gen-class)) |
| 21:28 | x^2 | (defn greet[who] (println (str "Hello " who "!"))) |
| 21:28 | x^2 | (defn -main[who] (greet who)) |
| 21:28 | x^2 | so obviously in this core.clj, i have one regular function and my main functio |
| 21:28 | x^2 | n |
| 21:28 | x^2 | how do people usually lay these things out in lein? |
| 21:28 | x^2 | like would someone put a bunch of other functions and main in the core.clj? |
| 21:28 | x^2 | or would they usually split it up into different files |
| 21:29 | teslanick | A file contains one (or sometimes more) namespaces. But a file contains the same namespace as the file name. |
| 21:29 | s4muel | Like that. Look at project.clj you'll see a :main entry. Usually you split up files by namespace, like example if you have a client server app you'd have (ns foo.client) and (ns foo.server) in src/client.clj and src/server.clj |
| 21:29 | teslanick | So really you'd be dividing functions up across namespaces related to what they do. |
| 21:30 | teslanick | By way of example, Clojure has clojure.core, clojure.string, clojure.zip, clojure.pprint, etc. |
| 21:31 | teslanick | Where core has most of the common functionality, and each of the others have functions specialized to a particular task (strings, tree structures, and pretty-printing respectively) |
| 21:32 | s4muel | Indeedy. There's nothing preventing you from throwing it all in one giant file, either, per se. It is just a matter of style and organization. Take a look at some of the more popular libs to see how they are organized (or as teslanick points out, clojure itself) |
| 21:32 | x^2 | YEhmmm, okay |
| 21:32 | x^2 | i was going to do that, look at some of what is out there |
| 21:33 | teslanick | A lot of the popular libs are relatively easy to read; as you may have noticed, Clojure is very terse. |
| 21:33 | s4muel | Of course, file paths do come into play when you start adding test frameworks and working more with leiningen in terms of advanced build/compilation stuff. Depends, again, on what you're using. |
| 21:34 | x^2 | yeah, that is all very confusing to me right now |
| 21:34 | x^2 | now i would like to ask |
| 21:34 | x^2 | for a beginning 'first' project, would it be okay to put everything (inluding main) in that core.clj and just work off of that? |
| 21:35 | x^2 | for a relatively small project, of course |
| 21:35 | x^2 | with just a few functions most likely |
| 21:35 | teslanick | Yeah. You can break it up into namespaces later if it grows. |
| 21:35 | x^2 | okay, cool |
| 21:35 | teslanick | I've been writing stuff in little clj files scattered across my desktop and copy them into my project when I think they're done. |
| 21:36 | x^2 | so you just write them in separate clj files, put them in the same directory, and build? |
| 21:36 | x^2 | (simplifying, of course) |
| 21:39 | teslanick | Well, I write a bunch of related functions and test them together, then copy the file into the project and give it a namespace. |
| 21:39 | teslanick | Because LightTable doesn't care about projects, you can just live-eval stuff as you're working to build things incrementally. The amount of boilerplate necessary is basically nil |
| 21:40 | x^2 | hmm, okay. |
| 21:40 | x^2 | i do really like the REPL environment, too |
| 21:40 | x^2 | it seems very cool. |
| 21:45 | teslanick | I should say that I'm very much a Clojure neophyte myself |
| 21:46 | teslanick | The REPL is pretty neat, though the thing that gets me is connecting to a running application and manipulating its state as its operating. |
| 21:48 | x^2 | i've heard you can do that |
| 21:48 | x^2 | i have no idea how yet |
| 21:48 | x^2 | but i have seen that as a feature of clojure |
| 21:48 | x^2 | which amazes me |
| 21:48 | x^2 | it must tie back to the 'code as data' idea, right? |
| 21:49 | x^2 | in that you can just feed some 'data' (being code) into an application, and it is evaluated like anything else. |
| 21:49 | teslanick | Also that mutable state is called out very explicitly. |
| 21:49 | x^2 | oo |
| 21:50 | teslanick | And altering stateless components is relatively safe. |
| 21:50 | arrdem | if I wanted a doseq with a carry-forwards state that's for, right? |
| 21:50 | arrdem | sorry. loop/recur |
| 22:02 | gfredericks | arrdem: I have no idea what that means |
| 22:03 | arrdem | gfredericks: I was refactoring a doseq and realized that I really wanted an eager reduce, which is just for with some destructuring. |
| 22:03 | arrdem | gfredericks: that was as much me muttering to myself as anything :/ |
| 22:03 | mklappstuhl | curious how the parsing of namespaced function calls like (string/split ...) works in clojure |
| 22:04 | hiredman | parsing? |
| 22:04 | mklappstuhl | is the parse looking for a slash and than splitting the string? |
| 22:04 | arrdem | mklappstuhl: fully qualified symbols are written ns.sub-ns.sub-sub-ns/symbol |
| 22:04 | hiredman | oh, how symbols are read? |
| 22:04 | mklappstuhl | hiredman: sorry — reading is probably more appropriate |
| 22:05 | mklappstuhl | ah |
| 22:05 | quizdr | this just blew my mind: #(reduce deliver f %&) |
| 22:06 | mklappstuhl | so basically if you use :require [clojure.string :as str] it basically maps str to clojure.str |
| 22:06 | hiredman | that has nothing to do with reading though |
| 22:07 | hiredman | at read time foo/bar is just a symbol with namespace slot foo and a name slot bar |
| 22:07 | gfredericks | quizdr: what on earth is that useful for |
| 22:07 | hiredman | same with str/foo |
| 22:07 | hiredman | ,(read-string "str/foo") |
| 22:07 | clojurebot | str/foo |
| 22:07 | gfredericks | ,(read-string "doesn't/exist") |
| 22:07 | clojurebot | doesn't/exist |
| 22:07 | quizdr | gfredericks it was amalloy's answer to a problem on 4clojure; I think pretty crafty. more elegant. |
| 22:08 | x^2 | ,(read-string "testfunc") |
| 22:08 | clojurebot | testfunc |
| 22:08 | teslanick | quizdr: What was the problem? |
| 22:08 | gfredericks | quizdr: ooh he must be taking advantage of the impl |
| 22:08 | mklappstuhl | hiredman: I guess my terminology was wrong |
| 22:08 | quizdr | impl? what do you mean? |
| 22:08 | gfredericks | deliver is supposed to be for promises but functions as a generic call function |
| 22:08 | gfredericks | ,(deliver inc 42) |
| 22:08 | clojurebot | 43 |
| 22:09 | gfredericks | ^ not what deliver is for |
| 22:09 | quizdr | oh i see. |
| 22:09 | gfredericks | there'd be no reason to even suspect it would do that without reading the source |
| 22:09 | gfredericks | which is what I meant by "impl" |
| 22:09 | quizdr | the doc mentions it as "alpha" anyway and "subject to change" so probably not a good idea to depend on it as habit |
| 22:09 | quizdr | "impl" = "implementation" ? |
| 22:09 | gfredericks | no not for use in production 4clojure |
| 22:09 | gfredericks | yes |
| 22:10 | quizdr | it's amazing to see the paradigm shift among programmers on that site when reviewing others' answers. so many still use loop/recur with a single line alternative does the trick with 25% as much code. fascinating. |
| 22:10 | quizdr | *when a single line alternative... |
| 22:11 | quizdr | my main take away from those execersizes is that the vast majority of the time, when I approach a problem with a loop in mind, strong liklihood there is a more elegant way instead. |
| 22:11 | gfredericks | yep |
| 22:14 | bbloom | quizdr: i frequently write loops then look at them and say "now what does that actually do?" before refactoring it |
| 22:14 | bbloom | sometimes, i know the algorithm & don't need laziness, but don't know what it is called until i *see* it |
| 22:15 | mklappstuhl | I'd love to see a blog that features small overly complex code snippets and then simplifies them reading that, quizdr |
| 22:15 | teslanick | Speaking of which, is there any clojure-oriented code review groups out there? The clojure tag on codereview.stackexchange is pretty dead. |
| 22:16 | teslanick | I see the clojure a coworker can write, and I feel like Phillip Fry with a Holophonor |
| 22:17 | insamniac | lol |
| 22:17 | insamniac | you're not alone |
| 22:19 | ivan | I can confirm that infoqscraper finally does the right thing, if you download a recent ffmpeg build and run PYTHONPATH=. python bin/infoqscraper presentation download --ffmpeg ./ffmpeg --type h264_overlay core-async-clojure |
| 22:20 | ivan | the aspect ratio on the video recording is slightly off but that is ignorable or fixable |
| 22:25 | quizdr | mklappstuhl just perusing the solutions at 4clojure will give you all you need to know and more, it's a fantastic learning resource |
| 22:25 | quizdr | of course, you can't see the solutions until you've come up with one of your own! |
| 22:27 | mklappstuhl | quizdr: yeah probably thats better for learning, coming up w/ sth on your own first |
| 22:28 | quizdr | being able to mix map, apply, reduce all in a single line of code is really extraordinary, all these tools available for genuine creativity. if you ask a c++ person to write a particular function, most of them will do it more or less the same way, because there aren't as many options. but these lisps bring ideas to the surface and really open up the process in ways i've never seen before. i really had no idea what computer programming |
| 22:28 | quizdr | could be until i discovered this stuff |
| 22:30 | quizdr | i know i'm preaching to the choir, but not having to think about low-level details and also getting to increase the thinking/typing ratio when coding has really spoiled me quickly. |
| 22:31 | insamniac | Yeah I follow a bunch of people on 4clojure, and it's crazy to see the variety of ways one can approach a problem. |
| 22:32 | insamniac | To be honest, I'm still uncomfortable with the freedom. |
| 22:33 | quizdr | insamniac i think that will change as you master the various functions. for me i simply don't know what a lot of those functions are, so I resort to basically implementing them on my own to solve a problem, hence why loop/recur ends up getting more air time than it deserves. then I see code on there that uses cool little built-in tools and i realize I should be memorizing the clojure.core API! |
| 22:33 | gfredericks | random function you don't know about yet: fnil |
| 22:34 | quizdr | ,(doc fnil) |
| 22:34 | insamniac | true story |
| 22:34 | clojurebot | "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched." |
| 22:34 | quizdr | wow |
| 22:34 | insamniac | i remember when i first saw juxt and got all giggly. |
| 22:34 | gfredericks | ,(update-in {:foo 12} [:bar :baz] (fnil conj #{}) 42) |
| 22:34 | clojurebot | {:bar {:baz #{42}}, :foo 12} |
| 22:37 | quizdr | that's an eye-full |
| 22:38 | gfredericks | I've mostly only used it to add things to collections that might be nil |
| 22:39 | dsrx | ,(doc fnil) |
| 22:39 | clojurebot | "([f x] [f x y] [f x y z]); Takes a function f, and returns a function that calls f, replacing a nil first argument to f with the supplied value x. Higher arity versions can replace arguments in the second and third positions (y, z). Note that the function f can take any number of arguments, not just the one(s) being nil-patched." |
| 22:42 | teslanick | One thing I've noticed -- and maybe this is because I write clojure after work but before bed -- is that I have really weird dreams about homoiconicity |
| 22:44 | quizdr | telansick actually i kid you not so have i. when i first discovered common lisp, i was dreaming about it at night for several days. |
| 22:44 | quizdr | almost like discovering a drug, to be honest. |
| 22:44 | technomancy | quizdr: I had a fever like that once |
| 22:45 | quizdr | technomancy ha i got the clojure fever every day, son! |
| 22:45 | technomancy | I dreamed I was implementing https://en.wikipedia.org/wiki/Puyo_Puyo_(series) in emacs lisp as a derived mode of M-x tetris |
| 22:45 | quizdr | really, you too? that's quite a coincidence |
| 22:45 | technomancy | it was a really high fever |
| 22:46 | quizdr | ...they always are |
| 22:47 | teslanick | I think my brain made the linguistic connection between homo-iconic and homo-sapiens, so I was dreaming of humans implemented as self-modifying s-expressions. I also haven't been sleeping well, so maybe there's a connection. |
| 22:50 | quizdr | i went to a lecture last night, the guy runs a company where they treat the brain as a computer that runs software programmed by nature over large stretches of natural selection, proposing that modern day problems already have solutions in the software. they use Haskell. |
| 22:51 | quizdr | to uncover what the software actually is, they look at statistical analysis of historical problems and how they resolved, using that as evidence of what the inner implementations might be. almost seems like decurrying to me. |
| 22:51 | teslanick | That's a little arrogant, but then… haskell. ;) |
| 22:51 | technomancy | that sounds like one of the talks I heard at strangeloop |
| 22:53 | quizdr | check it out http://www.appliedcognitivescience.com/ |
| 22:53 | quizdr | well, looks like there isn't much there on the site |
| 22:54 | quizdr | he used topology to showcase the ivention of functors |
| 22:56 | quizdr | in which I discovered that the word "functor" in haskell has a completely different meaning than the same word in c++ :) |
| 23:01 | KeithPM | Good day all. I am trying to figure out why I am not receiving any input from the following function. (compute-winnings-for-a-trial n ) works on its own https://gist.github.com/kpmaynard/8611605 |
| 23:02 | TEttinger | KeithPM, conj doesn't change acc |
| 23:02 | TEttinger | so you return the original acc, [] |
| 23:02 | TEttinger | you need to just take out the acc after that compute-winnings call |
| 23:02 | quizdr | KeithPM yes remember all data is immutable. you should just pass the conj statemet to recur |
| 23:03 | quizdr | or whatever is appropriate |
| 23:03 | KeithPM | TEttinger: Yes, yes… Bad error :) |
| 23:03 | TEttinger | err I think I read it wrong btw |
| 23:05 | KeithPM | TEttinger: I think I should perform the conj within the recur... |
| 23:06 | quizdr | KeithPM yes that would be a good way |
| 23:06 | quizdr | alternately you could use a let form up top if you need the conj result more than once |
| 23:07 | KeithPM | quizdr: OK let within the loop right? |
| 23:08 | quizdr | only if you need the conj result more than once, you could put a let in there yes |
| 23:08 | TEttinger | oh and when I ran it the loop never terminated? |
| 23:08 | TEttinger | not sure what condition it should end on, but I'm guessing m <= 0 |
| 23:08 | akurilin | Does anybody know of a guide for how to set up running unit test from the repl, including reloading the project if it needs to be. |
| 23:09 | KeithPM | TEttinger: Really? But I'm decrementing m each time… Hmmmm |
| 23:09 | KeithPM | TEttinger: Thanks, I will look in to that problem |
| 23:10 | quizdr | you are decrementing m each time, but where is the exit? the recur is outside of your if test |
| 23:10 | quizdr | KeithPM ^ |
| 23:12 | quizdr | KeithPM you don't need a let because looks like you are only conj when you recur, so put your conj in the recur only. |
| 23:12 | quizdr | you could replace your current conj form with the recur form to move recur inside the if test, and put the conj inside the recur. |
| 23:13 | TEttinger | try https://gist.github.com/tommyettinger/8611744 , KeithPM |
| 23:13 | KeithPM | quizdr: I agree, The idea is that I would loop to the loop point, with m decremented. If m becomes 0 the else-part should be executed, I think |
| 23:14 | quizdr | if you are going to recur, you a test inside the loop where the result is not a recur, or else you have an infinite loop. |
| 23:14 | KeithPM | quizdr: Yes, I am trying that, recurring in the then-part and returning acc in the else-part |
| 23:14 | quizdr | currently, recur is always getting called no matter what |
| 23:15 | KeithPM | quizdr: OK, let me take a look at it. Wow, amazing how easily one can blow one's foot off LOL… 5 lines of code!!!! |
| 23:15 | TEttinger | infinite loops are easy, fixing them not so much |
| 23:15 | KeithPM | TEttinger: Thanks, looking at it now |
| 23:15 | quizdr | for example you could have a line like this: (recur (dec m) n (conj acc (compute-winnings-for-a-trial n))) |
| 23:15 | KeithPM | TEttinger: :) |
| 23:15 | TEttinger | don't need the n actually, since it doesn't change |
| 23:16 | quizdr | put that as one of the if branches and you at least have a non-recurring branch to exit the loop |
| 23:16 | KeithPM | TEttinger: Rightm, right… The n is available already… |
| 23:17 | KeithPM | TEttinger: That's exactly what it should look like, thanks |
| 23:18 | joshuafcole | Hey folks, where do leiningen plugins get stored at? |
| 23:18 | joshuafcole | I'm trying to patch cljsbuild but can't seem to find it. |
| 23:18 | quizdr | ha ha i just saw TEttinger gist, don't know why i was repeating it |
| 23:18 | quizdr | could have saved some typing |
| 23:18 | quizdr | :) |
| 23:19 | KeithPM | quizdr: Thanks anyway, I appreciate it |
| 23:19 | TEttinger | KeithPM, there's an easier way too |
| 23:19 | TEttinger | ,(defn multiple-trials [m n] (repeatedly m #(compute-winnings-for-a-trial n))) |
| 23:19 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: compute-winnings-for-a-trial in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 23:19 | TEttinger | oh right |
| 23:19 | TEttinger | well it does almost the same thing, just as a seq not a vector |
| 23:19 | KeithPM | TEttinger: I tried that but repeatedly needs a no-arg function |
| 23:20 | TEttinger | it is, n is outside the closure |
| 23:20 | KeithPM | Oh OK, you used the anonymous function… I did not try THAT… That's neat |
| 23:21 | TEttinger | assuming your compute just returned a random number... ##(let [m 6 n 8] (repeatedly m #(compute-winnings-for-a-trial n))) |
| 23:21 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: compute-winnings-for-a-trial in this context |
| 23:21 | TEttinger | dammit! |
| 23:21 | KeithPM | For any beginners out there, I am actually following an article which tries to introduce developing an entire clojure program which runs a heads and tails (coin flipping) game. http://archive.eddology.com/post/14592579289/busy-persons-clojure?goback=.gde_1058217_member_5831664140367724547#! |
| 23:21 | TEttinger | assuming your compute just returned a random number FOR REAL... ##(let [m 6 n 8] (repeatedly m #(rand-int n))) |
| 23:21 | lazybot | ⇒ (7 2 7 6 1 1) |
| 23:22 | KeithPM | TEttinger: I will try again with the anonymous function |
| 23:23 | TEttinger | repeat and repeatedly have some interesting subtle differences... the anonymous fn syntax creates a no-arg fn if no % args are used in the body |
| 23:24 | KeithPM | TEttinger: Yes, I think you already bound the n so anonymous function is in fact no-arg |
| 23:24 | TEttinger | (that's a fun catch, you would expect it to at least have a % single arg, right? but it is smart about it) |
| 23:30 | KeithPM | TEttinger: repeatedly works wonderfully well :) … Fewer keystrokes extends programmers' lives :) |
| 23:38 | akurilin | Hey folks. Is there a way to (require) all the namespaced under a certain folder? |
| 23:38 | akurilin | I'd love to be able to require all my test nses at once so that I can do (clojure.test/run-all-tests) on them. |
| 23:40 | Anderkent | akurilin: bultitude can tell you what is on the classpath |
| 23:45 | technomancy | akurilin: the fact that `lein test` can't be invoked from within your project itself is a big failing of the design there |
| 23:47 | technomancy | hopefully we can fix it in 3.0 |
| 23:54 | akurilin | technomancy: I was reading your guide for lein test and you say in there that we should use clojure.test/run-all-tests to test from the REPL. What's your recommendation for getting those namespaces loaded int he first place? |
| 23:55 | akurilin | Should I use bultitude and require all of the test ones? |
| 23:55 | technomancy | akurilin: bultitude is about the only way, yeah |
| 23:56 | akurilin | Ok, will give that a try then. |
| 23:56 | akurilin | Any guides for how to UT from one's REPL you might be aware of ? |
| 23:56 | akurilin | I couldn't find anything in the "blogosphere" |
| 23:57 | akurilin | Which is surprising because this is pretty basic. |
| 23:58 | technomancy | akurilin: I don't ever do a full test from the repl |
| 23:58 | technomancy | I just est the specific nses that I'm working on |
| 23:59 | technomancy | and then before merging or pushing or whatever run a fresh `lein test` from the CLI so I know that the JVM state hasn't been corrupted |
| 23:59 | technomancy | personally anyway |