2013-06-22
| 00:00 | hiredman | I played with a lisp that did the source to source thing to go |
| 00:00 | bbloom | hiredman: 1) it's more mature, if that's what you mean and 2) the hotspot JIT really helps dynamic languages, which go's runtime likely won't |
| 00:00 | hiredman | way to static, and not enough of a platform to really leverage |
| 00:00 | hiredman | no dynamic code loading |
| 00:01 | Qortzniv | callen, how did you know it was i? |
| 00:01 | bbloom | hiredman: which is essentially true of cljs when deploying too |
| 00:01 | technomancy | dynamic code loading is a pretty important prerequisite for any platform I'd touch with a ten-foot pole |
| 00:02 | hiredman | the reflection facilities in go are super primitive |
| 00:02 | hiredman | anyway, I did not care for it |
| 00:04 | bbloom | i think you just need to use a slightly different strategy: you can do incremental compilation in memory & then communicate via channels. in production builds, you can statically link, like in cljs |
| 00:05 | bbloom | i really love the incremental work flow in clojure, but i fully appreciate the static-everything approach for deployments |
| 00:05 | bbloom | but still, you're right, it probably wouldn't be great for a dynamic language at all |
| 00:05 | bbloom | not without a lot more work |
| 00:06 | hiredman | bbloom: you would have to write an interpreter, but the interpreter would not be able to call go functions that where not already used in the executable |
| 00:06 | bbloom | hiredman: the interpreter would surely be compiled with a full list of stubs in a dev build, so there would be no dead code to remove |
| 00:07 | hiredman | bbloom: gross |
| 00:07 | bbloom | anyway, let me retract my statement about me wishing golang was the compilation target of choice |
| 00:07 | bbloom | you're right |
| 00:07 | tomjack | is 'dynamic language' about more than the type system? |
| 00:07 | hiredman | bbloom: and what about interoping with go libraries outside of the standard lib? |
| 00:07 | bbloom | where i was really coming from was this: i wish every java (the language) shop magically became a go (the language) shop |
| 00:07 | bbloom | :-P |
| 00:08 | hiredman | I started on this, and it sucked, with exactly that a list of stubs for the interpreter to use, etc |
| 00:08 | cneira | is there any roadmap for clojure the future features in clojure , like continuations ? |
| 00:08 | bbloom | tomjack: if you care about performance, you need a runtime that is defined for dynamic call sites and stuff |
| 00:09 | bbloom | cneira: you can assume that full continuations will never happen & that delimited continuations are mildly unlikely |
| 00:09 | Pupnik_ | clojure on luajit! |
| 00:10 | tomjack | speaking of that, shouldn't it be pretty easy to build delimited continuations using ioc-macros? |
| 00:10 | hiredman | https://github.com/hiredman/qwerty/blob/master/src/qwerty/lisp/golib.q |
| 00:11 | hiredman | it is kind of gross because I was waiting to get the interpreter working to add macros |
| 00:13 | tomjack | bbloom: so could you have a 'dynamic' language with a type system more like what we expect from a 'static' language? |
| 00:14 | tomjack | or are they conflated for a good reason |
| 00:14 | bbloom | tomjack: maybe it's this delicious gin, but i'm going to ignore your question and instead say that it's kinda a false dichotomy to describe dynamic vs static |
| 00:15 | bbloom | everything is always some shade of gray |
| 00:15 | bbloom | there are things you know statically and things you don't know statically |
| 00:16 | bbloom | go has interface{} which is basically the same as "object" in java, which is essentially dynamic typing |
| 00:16 | tomjack | ok, 'false dichotomy' is sort of the answer I was hoping for anyway :) |
| 00:17 | jimrthy | It seems like Qi at least sort-of takes that approach: common lisp with static typing. |
| 00:18 | jimrthy | But I've never gone any further than skimming its web page a few years back. |
| 00:19 | bbloom | tomjack: consider (pop 1 2) for example. |
| 00:19 | bbloom | tomjack: in clj that throws an error at runtime, but there isn't really any strong reason that can't be an error at compile time |
| 00:19 | bbloom | tomjack: module re-defining vars :-/ |
| 00:20 | bbloom | tomjack: but in clojurescript! lol you know what var values are, so if you know you have a var, you can look at it's arities. and in fact, cljs does |
| 00:20 | tomjack | if IPersistentStack were a protocol like it wants to be.. |
| 00:20 | bbloom | tomjack: cljs will emit direct dispatch to a particular arity |
| 00:20 | bbloom | tomjack: ignore protocols, it could be (defn f [x] ...) |
| 00:20 | bbloom | tomjack: in cljs, if you call (f 5) we emit f._some_magic_thing_for_arity_1 |
| 00:20 | tomjack | oh yeah, missed that that was the error |
| 00:21 | bbloom | the point is that we know, statically, some stuff, so we can use that to optimize |
| 00:21 | bbloom | the difference between "static" and "dynamic" languages is one of philosophy |
| 00:21 | bbloom | a static language tries to prevent as many errors as possible at compile time and to perform as many optimizations as possible then too |
| 00:22 | bbloom | a dynamic language tries to stay out of your way at compile time |
| 00:22 | bbloom | and as such, needs to recover error detection and performance at runtime |
| 00:22 | bbloom | this is why i'm a big believer in pluggable type systems |
| 00:22 | bbloom | and extensible compilers |
| 00:23 | bbloom | in theory, if my app is too slow, i want to be able to make it faster by adding static information |
| 00:23 | bbloom | and in fact, clojure does precisely this with type hints |
| 00:23 | bbloom | however, there are non-type related examples of things that you can use as static hints |
| 00:24 | bbloom | like consider the old C macros for LIKELY and UNLIKELY |
| 00:24 | tomjack | I hope someday your dreams about the cljs analyzer/compiler come true |
| 00:24 | callen | clojure -> asm.js? |
| 00:24 | bbloom | callen: you wanna write a garbage collector & compile it to asm.js? :-P |
| 00:24 | callen | clojure -> emscripten JVM implementation? |
| 00:25 | bbloom | callen: honestly, i think it makes much more sense to compile to js directly for a dynamic language. for a static language, sure, compile to asm.js |
| 00:25 | callen | borrow that 30 petaflop chinese supercomputer. should get 30 fps on Minecraft. |
| 00:25 | callen | (30 fps'ish) |
| 00:25 | bbloom | tomjack: check out my little secret project here: https://github.com/brandonbloom/ascribe/blob/cljs/test/ascribe/cljs/attrs/clj.clj |
| 00:26 | bbloom | tomjack: basically finished macro expansion, starting on primitive analysis |
| 00:27 | bbloom | tomjack: my goal is no more than twice as slow as CLJS (without the google closure step) but 100X easier to extend w/ new analysis, better errors, etc |
| 00:28 | bbloom | tomjack: anyway, are you familiar with likely and unlikely? |
| 00:28 | bbloom | http://stackoverflow.com/questions/109710/likely-unlikely-macros-in-the-linux-kernel |
| 00:28 | tomjack | nope |
| 00:28 | bbloom | that's non-type-related static info used for optimization |
| 00:28 | tomjack | makes sense though |
| 00:29 | bbloom | i'm also not a believer that type systems need to be complete/sound/whatever |
| 00:29 | bbloom | i think it's totally fine if a type system runs a core.logic style search & just gives up after some amount of time & compiles the best code it can with the info it gathered in the time it had |
| 00:30 | tomjack | in that case, nothing is non-type-related :) |
| 00:31 | bbloom | sure |
| 00:32 | tomjack | reading ekman now, ascribe looks very interesting |
| 00:32 | tomjack | don't understand it at all but the code you linked looks very clean, especially compared to the macroexpansion code I'm writing |
| 00:33 | bbloom | tomjack: clean is the goal :-) |
| 00:35 | tomjack | holy shit 151 pages |
| 00:36 | bbloom | haha |
| 00:36 | bbloom | yeah, it's a full thesis, lots of individual papers |
| 00:37 | bbloom | tomjack: https://code.google.com/p/racr/ is probably a pretty short intro to the bag of ideas |
| 00:38 | tomjack | I wonder if it's a coincidence that the first paragraph ends with "DADA" |
| 01:35 | tomjack | ouch, nrepl.el doesn't yet support previous-error/next-error? |
| 01:41 | Raynes | tomjack: sofixit |
| 02:15 | spoon16 | anyone know if it's possible with compojure to have a set of middleware applied only to the routes defined within a given (context) expression? |
| 02:19 | SegFaultAX | spoon16: Routes and middleware are just functions. |
| 02:20 | SegFaultAX | You can wrap the middleware around the route directly (my-middleware (GET ...)) |
| 02:39 | spoon16 | thanks SegFault |
| 02:46 | snake-john | how do I do in emacs "select whole s-expr under cursor" … I've got clojure mode and paredit on… |
| 02:48 | tomjack | I think you probably want expand-region |
| 02:49 | tomjack | "whole s-expr under cursor" is ambiguous, right? |
| 02:49 | tomjack | if you mean point is on/before the opening paren, C-M-SPC |
| 02:51 | snake-john | yes that is what I meant! But when I hit continuously C-M-SPC I would like the selection to expand to the parent s-exp. |
| 02:52 | tomjack | yeah that's expand-region I believe |
| 02:52 | tomjack | it's not bundled with emacs |
| 02:52 | tomjack | https://github.com/magnars/expand-region.el |
| 02:53 | snake-john | thanks a lot just give me 5 minutes I will try it out |
| 02:53 | tomjack | I've never used it, just heard about it |
| 02:53 | tomjack | hopefully it actually does what you want.. |
| 03:13 | callen | https://github.com/bgschiller/latex-therefore |
| 03:13 | callen | dnolen_: technomancy ^^ |
| 03:13 | snake-john | @tomjack ha great it works thanks a lot again. One minor thing : I tried to bind it with (global-set-key "\M-C-SPC" 'er/expand-region) in my init.el. but unfortunately when I restart and do a c-h k M-C-SPC I see "C-M-SPC runs the command mark-sexp" |
| 03:16 | tomjack | I'd try (global-set-key (kbd "C-M-SPC") ...) |
| 03:17 | tomjack | no need to restart, just put point on that and do C-M-x |
| 03:18 | snake-john | thank you so much it works now! |
| 03:21 | francis_wolke | has anyone worked with three.js and clojurescript |
| 03:21 | francis_wolke | ? I'm having some issues, but no errors or anything to work from to tell me what I'm doing wrong |
| 03:22 | francis_wolke | the #clojurescript channel is dead - else I'd ask there. |
| 03:24 | murtaza52 | hi I need help with creating a leiningen plugin |
| 03:25 | murtaza52 | I have created a plugin which watches for any changes in a dir, thus the thread needs to keep on running, and not exit. |
| 03:26 | murtaza52 | The main thread actually creates futures which watch for changes. |
| 03:26 | murtaza52 | When i execute the code from repl ( not lein $task), it works well. |
| 03:26 | murtaza52 | However when I run it from another project as lein $task, it doesnt work. |
| 03:27 | murtaza52 | First question how do I get a long running blocking process, like lein cljsbuild :auto ? |
| 03:43 | murtaza52 | got it to work (when true) did the trick ! |
| 03:43 | callen | http://prog21.dadgum.com/3.html |
| 03:46 | tomjack | (when true) ? |
| 03:49 | tomjack | "And what is this really gaining you over C?" -- missing the point |
| 03:49 | tomjack | well.. part of the point |
| 03:51 | tomjack | to be fair I missed that point to when I looked at ztellman's asteroids |
| 03:52 | murtaza52 | I wanted an infinite loop, when the plugin task was run. So (when true) does it. |
| 03:53 | tomjack | if we look at something like ants.clj I think that's a very good point |
| 03:54 | tomjack | refs pointing to persistent data is obviously a lot we gain over C, but ignoring that, what we gain seems to be sanity in the face of parallelism |
| 03:54 | tomjack | which is not enough! |
| 03:55 | tomjack | well maybe it's enough for ants.clj |
| 03:55 | francis_wolke | RE: what I said earlier, figured it out |
| 04:01 | rurumate | I want to add clojure to an existing JAX/RS project. It needs to be a servlet so I can integrate it via web.xml. Is there a elegant / fun way, other than (gen-class :extends HttpServlet)? |
| 04:04 | ddellacosta | aws s3 permissions #*$@%! |
| 04:04 | ddellacosta | that's all I got |
| 04:08 | tomjack | rurumate: you might have a look at https://github.com/ring-clojure/ring/blob/master/ring-servlet/src/ring/util/servlet.clj |
| 04:08 | tomjack | either for inspiration, or just use it |
| 04:09 | callen | ddellacosta: your first mistake was using S3. Your second mistake, and this is the really critical one, was to not anticipate its failure. This damaged your karma. |
| 04:09 | ddellacosta | callen: *sob* |
| 04:09 | tomjack | what's wrong with S3? |
| 04:09 | ddellacosta | ddellacosta: I don't know how to use it for one |
| 04:10 | callen | tomjack: not enough monads. |
| 04:10 | SegFaultAX | ddellacosta: What are you trying to do? |
| 04:10 | ddellacosta | whoops, just addressed myself |
| 04:10 | ddellacosta | brilliant |
| 04:10 | tomjack | ah, true.. |
| 04:10 | callen | ddellacosta: sign of a magnificent conversationalist when they can efficiently pare down the minimum by (dec 2) |
| 04:10 | ucb | monads and S3. Yes. |
| 04:11 | tomjack | hmm, core.logic bug? https://www.refheap.com/84fdcc8257787e30e53187611 |
| 04:11 | callen | ucb: you're in for it now. |
| 04:11 | ddellacosta | I am trying to set ACL for public read on putting an object to S3 using clj-aws-s3. And I just get permission denied, no matter how I try to massage the permissions. |
| 04:11 | rurumate | tomjack: neat, thanks |
| 04:11 | ucb | callen: ruh-roh |
| 04:11 | ddellacosta | sorry, that was to SegFaultAX |
| 04:11 | ddellacosta | callen: I try to be efficient |
| 04:12 | ddellacosta | nothing to do with Clojure really, just felt like venting to someone, anyone (apologies) |
| 04:12 | SegFaultAX | ddellacosta: Is it possible that the access key and secret you're using don't have sufficient permissions on the bucket? |
| 04:12 | callen | ddellacosta: default bucket policy has read access for everybody |
| 04:13 | callen | ddellacosta: so unless your policy is set to something other than the default or the ACL was previously modified, you're failing to modify the ACL of something you shouldn't modify. |
| 04:13 | ddellacosta | SegFaultAX: one can imagine this as a possibility, which is why I explicitly enabled the user whose credentials I'm using to read the bucket list, upload and set permissions |
| 04:13 | tomjack | ddellacosta: dunno if you already know, 404's will look like permission denied too |
| 04:13 | ddellacosta | callen: as far as I can tell, the images are definitely not read-all--tried looking at them without setting permissions |
| 04:13 | callen | ddellacosta: please check the bucket policy. |
| 04:14 | ddellacosta | tomjack: definitely getting a 403 here. |
| 04:14 | SegFaultAX | ddellacosta: ddellacosta Does that mean s3*? |
| 04:14 | SegFaultAX | s3:* rather |
| 04:14 | tomjack | that's what I mean |
| 04:14 | callen | 403s are now 404s? Sweet. |
| 04:14 | SegFaultAX | No, they aren't. |
| 04:14 | SegFaultAX | You'll get a perm denied if that's the case. |
| 04:14 | tomjack | you won't get a 404, you get a 403 |
| 04:15 | callen | ddellacosta: and the bucket policy iiiiiiissssss? |
| 04:15 | ddellacosta | callen: https://www.refheap.com/16010 |
| 04:15 | ddellacosta | yeah, sorry I'm using s3 |
| 04:15 | ddellacosta | but I'm a total beginner, so it's not surprising I'm doing something stupid… |
| 04:15 | callen | ddellacosta: broskie, that's read access to everyone. |
| 04:15 | ddellacosta | callen: *sob* |
| 04:16 | callen | ddellacosta: that's the default policy. uhm. mostly. the Sid is unfamiliar to me. |
| 04:16 | callen | action, effect, principal all mean what I think they mean though. |
| 04:16 | ddellacosta | callen: yeah, the principal thing seems to be the user/role this is being applied to |
| 04:16 | ddellacosta | if I understand it properly |
| 04:17 | ddellacosta | meh, gonna take a break. Maybe I'll have an epiphany and figure it out later. |
| 04:17 | callen | not to be a bore, but you're sure you 1. Need to set the ACL (this isn't publicly accessible?) and 2. You're using the right keys to set the ACL if #1 is true? |
| 04:17 | ddellacosta | thanks for your help, callen, SegFaultAX, tomjack |
| 04:17 | callen | ddellacosta: but now I'm interested. |
| 04:17 | callen | gerd dermert. |
| 04:17 | ddellacosta | callen: heh |
| 04:17 | SegFaultAX | ddellacosta: You didn't say that accessing a blob from the bucket was an error. You said setting the perm was an error. Which is it? |
| 04:17 | callen | ddellacosta: while you're going, I'm going to own your box, steal your keys, and figure it out for myself. |
| 04:18 | ddellacosta | callen: WELL then, the thing I'm getting stymied on is exactly setting the ACL--that's where I get the 403 actually |
| 04:18 | callen | ddellacosta: okay fuck the ACL. Can you load the file as a public reader? |
| 04:18 | callen | ddellacosta: verify that the ACL is a problem to begin with. |
| 04:19 | ddellacosta | SegFaultAX: that's it exactly. I think we got derailed a little when I posted the bucket policy, but that is and was my main problem. |
| 04:19 | SegFaultAX | ddellacosta: Can you change it from the console? |
| 04:19 | SegFaultAX | ddellacosta: Or the API? |
| 04:19 | callen | I asked for the bucket policy to verify the necessity of even touching the ACL. |
| 04:19 | ddellacosta | callen: yeah, I definitely can't get to files by default, and I'd rather be explicitly setting the policy on files in any case. Ah, gotcha. |
| 04:19 | callen | I still want to resolve the ACL permissions issue, mind, I just want to gather more data. |
| 04:19 | SegFaultAX | callen: Entirely irrelevant to the problem. |
| 04:19 | ddellacosta | SegFaultAX: I can change it from the console. Not from the API--that's where I get the 403. |
| 04:20 | SegFaultAX | ddellacosta: Sounds like your access key and secret aren't properly configured. |
| 04:20 | callen | ddellacosta: and you're sure the keys are proper? do the keys work for any other part of the AWS API? |
| 04:21 | SegFaultAX | ddellacosta: Check for stupid stuff, like missing the first/last letter of either the key or the secret during copy/paste. |
| 04:21 | ddellacosta | SegFaultAX, callen: the creds I'm currently using are a separate user I set up just for this bucket. They have allowed me to do stuff like access the list, upload objects, up until now, but now setting this permission seems verboten. |
| 04:21 | callen | ddellacosta: re-verify that other things work (just like one or two) please. |
| 04:21 | SegFaultAX | ddellacosta: Did you add change permissions for this IAM account for this bucket? |
| 04:21 | ddellacosta | sure |
| 04:22 | ddellacosta | SegFaultAX: I explicitly added a permission so that this user can list, upload/delete, view permissions, and edit permissions. |
| 04:23 | ddellacosta | callen: just tried uploading a file via my app again, works fine, as long as I don't attempt to set the permissions. Listing all the current objects works fine too (that's my default view). |
| 04:23 | callen | ddellacosta: dump the user policy please. |
| 04:23 | SegFaultAX | ddellacosta: And you can, from the console, change the perms /as this users/? |
| 04:23 | SegFaultAX | User* |
| 04:23 | callen | SegFaultAX: I think it's a one-off IAM thing he made |
| 04:23 | callen | I don't think he's logged in as this credential in the user in question |
| 04:23 | ddellacosta | callen: that's exactly right |
| 04:24 | callen | ddellacosta: user policy prz. |
| 04:24 | ddellacosta | callen: one sec, getting' it |
| 04:24 | callen | cool. |
| 04:27 | ddellacosta | callen: sorry, not sure exactly how to dump these |
| 04:27 | SegFaultAX | ddellacosta: Easiest from the console. |
| 04:28 | ddellacosta | callen: basically, there's me ddellacosta, and "Authenticated Users", which have all List, Upload/Delete, View Permissions, and Edit Permissions set. That's it on this bucket. |
| 04:28 | callen | ddellacosta: https://aws.amazon.com/iam/ ? |
| 04:28 | ddellacosta | I am using an IAM user to access this, which I *assumed* qualified as an "Authenticated User" |
| 04:28 | SegFaultAX | ddellacosta: What arns? |
| 04:29 | ddellacosta | callen: yeah, just one user there, nothing in particular set--so I have to explicitly enable that user to access the bucket? |
| 04:29 | ddellacosta | SegFaultAX: what's arns, sorry? |
| 04:30 | SegFaultAX | ddellacosta: The thingies in the "Resource" part of the policy. |
| 04:30 | callen | ddellacosta: you need to add the bucket to resource |
| 04:30 | callen | ddellacosta: http://mikeferrier.com/2011/10/27/granting-access-to-a-single-s3-bucket-using-amazon-iam/ |
| 04:30 | callen | SegFaultAX: I'm not paid enough. |
| 04:31 | SegFaultAX | ? |
| 04:31 | ddellacosta | callen: I owe you a beer(s) or, maybe knowing you, tea(s)… |
| 04:32 | ddellacosta | SegFaultAX: https://www.refheap.com/16010, but I'm going to try and update this now after reading the thing callen linked me to |
| 04:33 | SegFaultAX | ddellacosta: Your resource is wrong. |
| 04:33 | SegFaultAX | But try the link first. |
| 04:33 | SegFaultAX | (Your bucket is its own resource separate from its contents) |
| 04:34 | ddellacosta | SegFaultAX: yah, clearly I have more reading to do on AWS. In any case, I think between your pointers and callen's doc I'll be able to get this going…thank you both! |
| 04:34 | SegFaultAX | You mean Mike Ferrier's doc. |
| 04:34 | callen | SegFaultAX: I'm enjoying the attribution/credit - sshhhh |
| 04:35 | callen | SegFaultAX: if Stack Overflow is be taken as an example, discovery and aggregation is as valuable as creation. |
| 04:35 | SegFaultAX | Ok. |
| 04:35 | callen | ddellacosta: so while trying to learn the underpinnings of AWS APIs, it's worthwhile to remember that a lot of this stuff fell out of internal SOA stuff. |
| 04:36 | ddellacosta | callen: interesting…I have to be honest, I've kind of put off learning the AWS security stuff, which is bad form, I know... |
| 04:36 | ddellacosta | my excuse is that I haven't used it to any great extent until now. |
| 04:37 | callen | ddellacosta: I had the same attitude, we're all sinners and all that. |
| 04:37 | ddellacosta | yah, exactly. |
| 04:37 | callen | ddellacosta: I got tired of letting AWS APIs make me play the fool so I paused for a breather and just read for awhile. |
| 04:37 | ddellacosta | callen: yeah, I think I'm at that point too. *sigh* Here we go... |
| 04:38 | callen | ddellacosta: ever work with SOA before? |
| 04:38 | callen | ddellacosta: service composition, policies, etc? |
| 04:38 | ddellacosta | not in any deep way |
| 04:38 | ddellacosta | callen: I've dabbled with the architecture in a few projects here and there, but nothing that really implemented it seriously. More like, "SOA-lite" |
| 04:39 | callen | ddellacosta: I've been meaning to do a tutorial on writing your own micro-SOA but I feel like nobody would read it because nobody really cares until they're forced to about that sort of thing. |
| 04:39 | callen | ddellacosta: yeah I'm usually "SOA-lite" as well. |
| 04:39 | ddellacosta | callen: I think that is sad but true. |
| 04:39 | callen | ddellacosta: well it's not like most projects need it or anything. |
| 04:39 | callen | we're engineers, not cathedral designers. |
| 04:39 | callen | or architects, rather. |
| 04:40 | callen | although if you ask a country with professional engineers, we're not engineers either. |
| 04:40 | callen | so we're just here, futzing around with our code. :) |
| 04:40 | callen | ddellacosta: hear about the smog in Singapore? |
| 04:40 | ddellacosta | callen: yeah, exactly, and after my early career I've actually grown more wary of architecture… |
| 04:40 | ddellacosta | callen: no, although I've been to Singapore a good number of times in the past few years, didn't notice a *ton* of smog |
| 04:41 | callen | ddellacosta: it's a recent phenomenon, AQI of like 200+, hit a peak of 415 the other day. |
| 04:41 | ddellacosta | callen: on the other hand, I spent most the time indoors, as people in Singapore are wont to do |
| 04:41 | callen | ddellacosta: the agricultural field burning in Indonesia is practically killing Singapore. |
| 04:41 | ddellacosta | wooah, no *shit* |
| 04:41 | callen | yeah I think some records for worst AQI were set for SG in the last two weeks |
| 04:41 | callen | terrifying stuff. |
| 04:41 | ddellacosta | ugh |
| 04:42 | ddellacosta | callen: you know, now that you mention it, I recall seeing someone tweet about the smoke |
| 04:42 | callen | I had the same experience where exposure to architecture astronomy scared me off. I re-acclimated to an appreciation of the nicer parts after having to build a larger-than-I-was-used-to service backend |
| 04:42 | ddellacosta | made a scotch joke |
| 04:42 | callen | early exposure, specifically. |
| 04:43 | ddellacosta | callen: yeah, I think that it's about calibration…lots of developers (myself included) start off thinking they can build these big cathedrals, or even that that is worthwhile |
| 04:43 | ddellacosta | then you realize you don't need it for most stuff, and actually it causes huge problems, and you scale back |
| 04:43 | ddellacosta | then you start to realize when you can and can't use it. I'm between that 2nd and 3rd phase I think, still have lots to learn |
| 04:44 | ddellacosta | alright, it's sunny, I'm going out for a change. |
| 04:44 | callen | ddellacosta: cheers. |
| 04:44 | ddellacosta | thanks again for the help. :-) |
| 04:44 | callen | ddellacosta: glad I could be useful. Enjoy your sunny weather. Ours has been great too. |
| 04:44 | ddellacosta | callen: thanks. :-) |
| 04:45 | callen | SegFaultAX: SF was beautiful yesterday. 80% of passersby were remarking upon it. |
| 04:45 | SegFaultAX | callen: Yes. |
| 04:48 | callen | SegFaultAX: how is pair-programming treating you? |
| 04:49 | SegFaultAX | callen: Good. |
| 04:49 | callen | SegFaultAX: well? |
| 04:50 | callen | SegFaultAX: how are you handling the constant stimulus and lack of music? |
| 04:51 | SegFaultAX | Communication, mostly. |
| 05:46 | tomjack | http://www.insteadofawesome.com/ |
| 05:51 | noonian | wizard! |
| 09:20 | jouiswalker | do monads solve any problems in clojure? |
| 09:25 | Bodil | jouiswalker: Yes, but considerably fewer than in Haskell. |
| 09:27 | jouiswalker | Bodil: thanks |
| 09:38 | Rogach | Q: I tried to use import-static like this: (require 'clojure.contrib.import-static) (import-static ...), but it gives me "Unable to resolve symbol: import-static in this context". Why is this happening? |
| 09:38 | hyPiRion | Rogach: do (require '[clojure.contrib.import-static :refer [import-static]]) instead |
| 09:39 | hyPiRion | Otherwise you'd have to fully qualify the namespace each time you invoke a function from it (e.g. you'd have to do (clojure.contrib.import-static/import-static ...)) |
| 09:39 | Rogach | hyPiRion: I tried (use ...), to the same effect. |
| 09:40 | hyPiRion | Rogach: okay, then the function name is possibly different |
| 09:40 | Rogach | Now I have another funny problem - one of the imported symbols collides with clojure.core/once :) |
| 09:42 | Rogach | Ah, it doesn't collide, it is not surrounded with parentheses. |
| 09:42 | hyPiRion | Rogach: a word of advice though, clojure.contrib.* is not maintained anymore. As for import-static, it hasn't been moved over, but most other contrib libraries have |
| 09:43 | Rogach | hyPiRion: Hm. And why import-static hasn't moved? |
| 09:43 | hyPiRion | https://github.com/richhickey/clojure-contrib/blob/master/src/main/clojure/clojure/contrib/import_static.clj |
| 09:43 | Rogach | hyPiRion: It's too small to bother moving? ;) |
| 09:43 | hyPiRion | Because that's it: It's not really much to fix in that library :p |
| 09:43 | hyPiRion | yeah |
| 10:46 | gfredericks | what is the expected behavior when a memoized function throws an exception? |
| 10:49 | gfredericks | in particular if I have (def g (memoize f)) where f throws an exception only on the first invocation, what should I expect g to do on the second invocation? |
| 10:57 | TimMc | Rogach: https://github.com/baznex/imports might be what you want. |
| 10:59 | hyPiRion | gfredericks: oh, hahah |
| 10:59 | hyPiRion | gfredericks: http://dev.clojure.org/jira/browse/CLJ-1053 |
| 11:01 | hyPiRion | gfredericks: Well, it's not referentially transparent then, is it? |
| 11:05 | gfredericks | hyPiRion: what isn't? |
| 11:06 | gfredericks | hyPiRion: with clojure.core/memoize the second invocation of g calls f directly and returns the result |
| 11:07 | gfredericks | but I don't think this is the case with clojure.core.memoize/memo-ttl |
| 11:07 | gfredericks | the latter fact woke me up at 1am a couple nights ago |
| 11:12 | hyPiRion | gfredericks: f is not referentially transparent |
| 11:15 | gfredericks | hyPiRion: that's fine |
| 11:15 | hyPiRion | that's not fine for memoize |
| 11:15 | gfredericks | okay so you're saying the behavior is undefined for good reason? |
| 11:16 | clojurebot | same reason we don't wear animal skins or hunt the wooly mammoth. because we're not savages. |
| 11:16 | gfredericks | and I should use some other abstraction for what I'm doing? |
| 11:22 | hyPiRion | gfredericks: I'm not sure what you mean. Memoize should generally keep the exception and throw it every time you attempt call with the same parameters again |
| 11:22 | gfredericks | oh okay |
| 11:22 | gfredericks | so clojure.core/memoize is the bad one then |
| 11:22 | gfredericks | is core.cache a decent thing to use directly? |
| 11:23 | gfredericks | I want to cache the result of a failable thing such that failure causes it to retry the next time |
| 11:24 | pellis | hello |
| 11:25 | pellis | so i know there are a couple book authors here :), i'm wondering what kind of toolkit to use for self-publishing a clojure mini book (would be my first book) |
| 11:32 | Okasu | pellis: Latex and editor of choice. |
| 11:33 | pellis | was thinking more in the direction of asciidoc |
| 11:40 | Morgawr | can somebody provide me an example of cond-> and cond->>? I don't quite understand how they work |
| 11:42 | gfredericks | Morgawr: they're like -> and ->> but you add a boolean expression before each threading form, which can "turn it off" if it's false |
| 11:42 | gfredericks | ,(-> 3 (* 2) (inc)) |
| 11:42 | clojurebot | 7 |
| 11:42 | gfredericks | ,(cond-> 3 true (* 2) true (inc)) |
| 11:42 | clojurebot | 7 |
| 11:42 | gfredericks | ,(cond-> 3 true (* 2) false (inc)) |
| 11:42 | clojurebot | 6 |
| 11:42 | gfredericks | ,(cond-> 3 false (* 2) true (inc)) |
| 11:42 | clojurebot | 4 |
| 11:42 | Morgawr | okay so, as soon as it hits a "false" expression it returns? |
| 11:42 | pdk | so it lets you switch them off individually to control threading at runtime |
| 11:42 | gfredericks | Morgawr: |
| 11:42 | gfredericks | no |
| 11:42 | Morgawr | oh |
| 11:42 | gfredericks | it skips that one |
| 11:42 | pdk | it sounds like it simply skips all falses |
| 11:42 | Morgawr | oh okay, so it just skips |
| 11:42 | pdk | and continues on with the trues until the end |
| 11:42 | pdk | same for cond->> i imagine |
| 11:43 | gfredericks | yep |
| 11:43 | Morgawr | thanks, that's what I really wanted to know |
| 11:43 | Morgawr | :) |
| 11:43 | Morgawr | (inc gfredericks) |
| 11:43 | lazybot | ⇒ 25 |
| 11:43 | pdk | that's a clever mecro |
| 11:43 | Morgawr | (inc pdk) |
| 11:43 | lazybot | ⇒ 1 |
| 11:43 | pdk | macro |
| 11:43 | pdk | is it able to use a list or something to give it a series of boolean values |
| 11:43 | pdk | as opposed to threading them in piecemeal |
| 11:44 | pdk | or a generated seq for that matter |
| 11:45 | gfredericks | nope |
| 11:45 | gfredericks | I think the idea is instead of simple booleans you'll have more complex expressions |
| 11:48 | gfredericks | the macros aren't really meant for data-oriented algorithms |
| 11:48 | gfredericks | you could easily use reduce for that |
| 11:51 | Morgawr | gfredericks: do I need an :else in cond->/cond->>? |
| 11:51 | gfredericks | nope |
| 11:51 | gfredericks | you don't need an :else in cond either |
| 11:52 | Morgawr | well, as far as I know without a :else (or anything that self-evaluates as true, like any keyword) it will throw an uncaught type exception (or something like that) if no condition matches |
| 11:52 | gfredericks | ,(cond false :not-this) |
| 11:52 | clojurebot | nil |
| 11:52 | gfredericks | ,(cond) |
| 11:52 | clojurebot | nil |
| 11:53 | gfredericks | ,(case :foo :bar :not-this) |
| 11:53 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: :foo> |
| 11:53 | Morgawr | oh |
| 11:53 | Morgawr | ohhhh |
| 11:53 | Morgawr | I was confusing it with condp |
| 11:53 | Morgawr | condp will throw an exception |
| 11:53 | Morgawr | sorry |
| 11:54 | gfredericks | ,(condp = :foo :bar :baz) |
| 11:54 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching clause: :foo> |
| 11:54 | gfredericks | ,(condp = :foo :foo :baz) |
| 11:54 | clojurebot | :baz |
| 11:55 | gfredericks | anyhow no you definitely don't need an else. Even if all your exprs are falsy you'll just get the threaded value back |
| 11:55 | gfredericks | I'll sometimes use cond-> with just one pair because it's a bit less repetetive than the if version |
| 11:55 | gfredericks | ,(cond-> 12 (pos? -4) inc) |
| 11:55 | clojurebot | 12 |
| 11:55 | gfredericks | compared to ##(if (pos? -4) (inc 12) 12) |
| 11:55 | lazybot | ⇒ 12 |
| 11:56 | pdk | it sounds like it only threads through trues |
| 11:56 | pdk | so if everything's false you just get out what you put in |
| 11:56 | gfredericks | yes that's the idea |
| 11:56 | Morgawr | cool |
| 11:56 | gfredericks | it also works nicely with -> |
| 11:56 | gfredericks | ,(-> 12 inc inc dec (cond-> false (* 23)) inc) |
| 11:56 | clojurebot | 14 |
| 11:57 | gfredericks | I'll do that to add a condition to just one or two clauses |
| 11:57 | Morgawr | mmm.. weird, I'm using ClojureScript and it doesn't seem to be working with cond-> |
| 11:58 | gfredericks | do you know for sure it's defined? |
| 11:58 | gfredericks | it's new in 1.5 |
| 11:58 | Morgawr | in the clojurescript source I've seen it referenced with import-macros |
| 11:58 | Morgawr | and I'm using Clojure 1.5.1 |
| 11:59 | gfredericks | I haven't used CLJS lately |
| 11:59 | gfredericks | don't have an easy way to try it out |
| 11:59 | gfredericks | himera doesn't have it |
| 12:02 | Morgawr | it's weird, it just says "cannot call undefined" |
| 12:02 | gfredericks | probably gets compiled to a runtime call to cond-> |
| 12:02 | Morgawr | even in the repl when I do a simple (cond-> true true true) or whatever |
| 12:03 | gfredericks | cljs does not check that things exist I don't think |
| 12:03 | gfredericks | so if you call a nonexisting macro it just compiles it to a function call on an undefined thing |
| 12:03 | Morgawr | yes, probably |
| 12:03 | Morgawr | but the question is... why it's not there? |
| 12:03 | gfredericks | correct. |
| 12:04 | Morgawr | https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L56 it's clearly referenced here |
| 12:10 | Morgawr | maybe dnolen_ knows? :( |
| 12:18 | Morgawr | gfredericks: mm.. I just copy-pasted the cond-> definition from clojure into my own macros file and it seems to be working |
| 12:26 | tmciver | What's the preferred way of working with json in clojure these days? |
| 12:27 | tmciver | Is it clojure.data.json? |
| 12:35 | Okasu | tmciver: Cheshire. |
| 13:06 | tmciver | Okasu: thanks. |
| 13:09 | luxbock | I installed Cygwin and I'm now using Emacs through it (emacs-w32) |
| 13:10 | luxbock | I installed leiningen using the shell script, but now nrepl-jack-in doesn't work anymore |
| 13:10 | luxbock | I get: /usr/bin/env: bash: No such file or directory |
| 13:10 | luxbock | in my *nrepl-server* buffer |
| 13:10 | luxbock | any ideas why this might be? |
| 13:17 | luxbock | 'lein repl' in the cygwin terminal works fine, but not when I call it from Emacs via M-x shell (which is set to use bash as well) |
| 13:48 | luxbock | got it working, had to remove the #!/usr/bin/env bash part from the lein file |
| 15:18 | bbloom | dnolen_: it's really such a bummer that core.async has to copy paste so much code to support cljs :-/ |
| 15:18 | bbloom | i know that 100% cross plat is a NON-goal, but avoiding copy paste seems like it should at least be a goal |
| 15:19 | bbloom | i hope this core.async effort spurs some progress there |
| 15:26 | tomjack | I think it is |
| 15:27 | tomjack | spurring I mean |
| 15:28 | tomjack | or maybe it's just a coincidence, but shared code is a priority for 1.6 |
| 15:35 | bbloom | tomjack: i've heard ppl say that, but i dunno where the evidence or progress is :-) |
| 15:36 | bbloom | besides some notes from stuart halloway on the design wiki, i guess that's the best there is |
| 15:36 | bbloom | granted, async is on that list, so maybe it's partially accurate :-) |
| 15:39 | tomjack | oh nice, new asm as well |
| 15:40 | tomjack | cinc coming soon? :) |
| 15:52 | OneFourSeven | Hey guys. I'm running lein uberjar to package my web application. But the problem is that I'm using a local jar that I've included by adding the :source-paths line to project.clj. This jar isn't included in the uberjar. Is there a way to package the jar with it? |
| 16:07 | Bronsa | tomjack: I'm working on CinC as my GSoC project |
| 16:07 | tomjack | sweet, didn't notice that one |
| 16:08 | tomjack | are you moving to the new asm? |
| 16:09 | Bronsa | I don't see what would prevent me from using the lastest version |
| 16:09 | Bronsa | so, yes. |
| 16:10 | tomjack | exciting :) best of luck |
| 16:10 | Bronsa | thanks :) |
| 16:11 | bbloom | Bronsa: how's it going so far? |
| 16:12 | Bronsa | bbloom: I'm backporting the Compiler.java analysys phase in a clojurescript-ish style right now |
| 16:13 | Bronsa | by next week hopefully the basic analyzer should be done |
| 16:14 | Bronsa | next I'm going to write locals-clearings, constant inlining etc as optional additional passes over that clojurescript-ish AST |
| 16:14 | bbloom | Bronsa: cool! |
| 16:15 | Bronsa | right now I'm trying to come up with a sane way to analyze '. |
| 16:15 | Bronsa | the clojure Compiler is kinda derp about that :/ |
| 16:15 | bbloom | Bronsa: the clojure (and clojurescript) compilers are derpy about a bunch of things :-P |
| 16:16 | bbloom | Bronsa: i'd probably try a direct 1-to-1 syntax port at first & then refactor from there |
| 16:16 | bbloom | trying to keep it working as i go |
| 16:16 | Bronsa | bbloom: right, that's somewhat what i did for tools.reader |
| 16:17 | Bronsa | I planned on taking the same approach with CinC but.. I decided I wanted to get rid of C.EVAL since the beginning |
| 16:18 | bbloom | i'm not super familiar w/ compiler.java, would have to study it |
| 16:20 | Bronsa | well, clojure right now has an interpreted eval for some ops |
| 16:20 | hiredman | Bronsa: how are you getting rid of C.EVAL? explicit statement/return things? |
| 16:20 | Bronsa | e.g. def |
| 16:21 | hiredman | oh, you mean the eval method on Exprs? |
| 16:21 | Bronsa | hiredman: I'm wrapping every top-level in a ((^:once fn* [] ..)) |
| 16:21 | Bronsa | yeah. |
| 16:21 | hiredman | sure |
| 16:21 | bbloom | yea, i saw that at somepoint, but wasn't sure how much of it was still being used. seemed like it was largely vestigial |
| 16:21 | Bronsa | bbloom: when you eval (def foo 1) it's actually interpreted |
| 16:22 | hiredman | it is only used in the repl for some simple toplevel forms |
| 16:22 | bbloom | Bronsa: heh. what's that quote? "The top-level is hopeless" |
| 16:24 | tomjack | so will analysis be side-effect free? |
| 16:25 | bbloom | tomjack: i don't think it can be in the face of def |
| 16:25 | Bronsa | no, there's no way that can be done |
| 16:25 | hiredman | well |
| 16:27 | hiredman | you can have a var environment that is ultimately backed by the real enviroment, but when you add vars they co in some kind of map, and analysis would come with a :vars {} map |
| 16:28 | Bronsa | sure |
| 16:28 | hiredman | which, uh, maybe clojurescript already does? |
| 16:28 | Bronsa | but then you have to put that map in an atom |
| 16:28 | bbloom | hiredman: no, clojurescript uses a global namespaces atom w/ swap! |
| 16:28 | Bronsa | and that's still.. side-effects |
| 16:29 | hiredman | Bronsa: no, you can push it down through the tree, I believe |
| 16:29 | bbloom | (when false (def x 1)) still defines x in clourescript.... |
| 16:29 | hiredman | bbloom: well, but that doesn't have to happen as part of analysis |
| 16:29 | tomjack | I don't care if there are side-effects when my actual top-level clojure code is analyzed, I'd just like to be able to use the analyzer in macros |
| 16:29 | bbloom | yes: you can have env-in and env-out for every ast node |
| 16:29 | hiredman | right |
| 16:30 | Bronsa | hiredman: you'd have to pass to the next call to analyze the previously returned map? |
| 16:30 | hiredman | Bronsa: depends on what you are doing with the analysis results |
| 16:31 | bbloom | you can definitely make analysis pure, but there are other weird things that can happen in that case too |
| 16:31 | hiredman | for the compiler, you are compiling a toplevel form at a time, so analysis->compile->run for every top level form, so you will get the side effects |
| 16:31 | Bronsa | right |
| 16:31 | Bronsa | yeah, I suppose it would be trivial to make a side-effect free version to be used for static analysis of single forms |
| 16:32 | tomjack | cool. not that that's really important compared to the larger goal of CinC :) |
| 16:32 | bbloom | more important than side effect free is idempotent and deterministic :-) |
| 16:33 | bbloom | like in cljs, the analyzer used to do gensym, so multiple calls w/ the same input produced differing results |
| 16:33 | bbloom | i fixed that & was considering fixing the side effects for def, but decided it would only matter if you were doing speculative analysis and then not going to commit creation of those vars via compilation |
| 16:36 | jtoy | what is the best interface for clojure to store data, like a database |
| 16:36 | wei_ | jtoy: edn? |
| 16:36 | wei_ | does anyone have an example of using the :if :then :else construct in clojure.algo.monads? trying to figure out the syntax |
| 16:36 | bbloom | jtoy: need lots more info from you |
| 16:37 | jtoy | i want to program in pure clojure and not have to deal with creating tables, running sql to update the database,etc |
| 16:37 | finishingmove | what's this error? |
| 16:37 | finishingmove | Unable to resolve symbol: union in this context, compiling:(NO_SOURCE_PATH:11:1) |
| 16:37 | finishingmove | i just try to use the union function |
| 16:37 | finishingmove | first i thought something was wrong with my project setup, so i made a new one with lein new |
| 16:38 | arrdem | finishingmove: clojure.set/union? |
| 16:38 | finishingmove | but the error remains |
| 16:38 | bbloom | jtoy: do you need durability? do you need queries? how much data? what are your access patterns? |
| 16:38 | finishingmove | arrdem yes, thanks... i thought it was in core |
| 16:39 | arrdem | finishingmove: np |
| 16:39 | arrdem | finishingmove: that's what IRC is for :P |
| 16:39 | bbloom | jtoy: "what type of vehicle is best?". -- "do you want to go to japan or to the grocery store?" …. "oh, you want to go the bottom of the ocean?" |
| 16:40 | arrdem | bbloom: bottom of the ocean pah. TO THE MOON! |
| 16:40 | jtoy | bbloom: i need durability so i can query later , the queries could be sql or something else, but i want a clojure interface, the db would be small,i like using sqlite but i hate with any sql i need to continuously alter tables as im buidling the code |
| 16:41 | jtoy | bbloom: i am using korma on anohte project, it is nice, but still not easy enough |
| 16:41 | bbloom | jtoy: do you want easy or do you want simple? :-P |
| 16:41 | jtoy | simple |
| 16:41 | arrdem | jtoy: what kind of scale? single local db or do you need a real db? |
| 16:41 | jtoy | single local db |
| 16:41 | jtoy | for now:) |
| 16:41 | SegFaultAX | I feel mongo coming on... |
| 16:42 | arrdem | SegFaultAX: nope |
| 16:42 | bbloom | how much data? a meg? 10? 100? 1,000? |
| 16:42 | SegFaultAX | arrdem: Thank you. :) |
| 16:42 | bbloom | SegFaultAX: mongo should never be coming on |
| 16:42 | arrdem | SegFaultAX: I can play nice :D |
| 16:42 | ohpauleez | haha |
| 16:42 | SegFaultAX | The questions were going all mongoy. I was afraid for a moment. |
| 16:42 | arrdem | SegFaultAX: I'm not blind to Mongo's failings, I just don't care abou tmost of them. |
| 16:43 | arrdem | ibdnox's simpledb? |
| 16:43 | jtoy | to store my browser history, so title,url, and timestamp, it would grow at probably 1 meg a week |
| 16:43 | bbloom | jtoy: why not try a simple atom in memory, plus prn and clojure.edn/read |
| 16:43 | SegFaultAX | jtoy: Sounds like you need something webscale, then. |
| 16:43 | arrdem | jtoy: simpledb is probably right up your alley |
| 16:43 | arrdem | SegFaultAX: gtfo :P |
| 16:43 | arrdem | jtoy: it's an in memory atom that gets dumped to a file by a worker |
| 16:44 | bbloom | jtoy: you can write to /tmp/whatever then atomically file-move over the old version of your file |
| 16:44 | SegFaultAX | jtoy: Have you considered MangoDB? |
| 16:44 | arrdem | SegFaultAX: ....... |
| 16:44 | ohpauleez | HA! |
| 16:44 | SegFaultAX | arrdem: https://github.com/dcramer/mangodb |
| 16:44 | jtoy | SegFaultAX: i tried it a few years ago, data loose |
| 16:44 | SegFaultAX | jtoy: I promise you, Mango is webscale. |
| 16:44 | arrdem | SegFaultAX: raw terminal on an abandoned server atm. will look later. |
| 16:45 | bbloom | you could also try the free/embedded datomic, if you don't mind closed source, but really, flyswatter vs bazooka |
| 16:45 | SegFaultAX | arrdem: You will appreciate it. :D |
| 16:45 | jtoy | I've used riak and postgresql for scaling |
| 16:45 | arrdem | SegFaultAX: I'm sure I will |
| 16:45 | bbloom | since when did people become afraid of file systems? :-P |
| 16:45 | SegFaultAX | arrdem: (Wrapper for /dev/null) |
| 16:45 | bbloom | don't they teach anybody fopen in school anymore!? |
| 16:45 | SegFaultAX | bbloom: Filesystems aren't webscale. |
| 16:45 | arrdem | bbloom: lol wut iz posix? |
| 16:45 | jtoy | bbloom: since coming to clojure i have, it is so much easier to deal with files in ruby/python |
| 16:45 | arrdem | SegFaultAX: ah so it's really nulldb |
| 16:46 | bbloom | jtoy: you need spit and slurp. how much easier does it get? |
| 16:46 | jtoy | bbloom: it is painful for me when i use files in clojure, probably bc im still new |
| 16:46 | bbloom | (doc spit) |
| 16:46 | clojurebot | "([f content & options]); Opposite of slurp. Opens f with writer, writes content, then closes f. Options passed to clojure.java.io/writer." |
| 16:46 | bbloom | (doc slurp) |
| 16:46 | clojurebot | "([f & opts]); Opens a reader on f and reads all its contents, returning a string. See clojure.java.io/reader for a complete list of supported arguments." |
| 16:46 | SegFaultAX | The file interface designed by my x-wife. |
| 16:46 | bbloom | when you outgrow split & slurp, you can A) learn how to use the file APIs better or B) choose a bigger solution |
| 16:46 | jtoy | bbloom: using doseq, doall, do*, and lazy data, resource files vs io ,etc |
| 16:47 | arrdem | (dec SegFaultAX) |
| 16:47 | lazybot | ⇒ 1 |
| 16:47 | bbloom | jtoy: don't bother with lazy io |
| 16:47 | SegFaultAX | arrdem: Learn to laugh, yo. |
| 16:47 | jtoy | bbloom: I have to because I am processing "bigdata" often |
| 16:47 | bbloom | jtoy: with your browser history? |
| 16:47 | arrdem | SegFaultAX: your inuendo is bad and you should feel bad |
| 16:47 | SegFaultAX | arrdem: I let myself out, didn't I? |
| 16:47 | jtoy | bbloom: no with my projects |
| 16:47 | bbloom | jtoy: ok, well for *this* project: forget lazy IO :-P |
| 16:47 | arrdem | wait. shit. copying a running mongo file ain't gonna work. |
| 16:47 | SegFaultAX | arrdem: Unfortunately for you I have IRC on my phone. So there. |
| 16:48 | jtoy | bbloom: haha, I will |
| 16:48 | arrdem | SegFaultAX: Q_Q irssinotify is the bomb |
| 16:48 | bbloom | i know startups who spend 73895783573 hours doing shit that could be solved w/ spit and slurp and would scale better than whatever nonsense they came up with :-P |
| 16:48 | jtoy | arrdem: that db has no examples, hard to tell |
| 16:48 | SegFaultAX | arrdem: I <3 irssi+znc |
| 16:48 | bbloom | hell, hacker news basically runs on the spit/slurp model with binary encoding |
| 16:49 | arrdem | jtoy: chris's noir demo blog uses it |
| 16:49 | arrdem | jtoy: I swear that's how it works 'cause I ported that blog from simpledb to mongo for lulz one time |
| 16:49 | SegFaultAX | bbloom: Yea, but arc. |
| 16:49 | jtoy | ruby has a library called datamapper that will read in an sql definition and auto migrate the tables so you dont have to deal with manually updating the db |
| 16:49 | arrdem | jtoy: it's really just spit and slurp in a library. |
| 16:51 | jtoy | arrdem: where is the blog post about simpledb? |
| 16:52 | SegFaultAX | $google chris granger simpledb |
| 16:52 | lazybot | [Commit History · ibdknox/simpledb · GitHub] https://github.com/ibdknox/simpledb/commits/ |
| 16:52 | arrdem | jtoy: just read the sauce. it's 52 lines and I'm on my phone |
| 16:52 | jtoy | i saw that, didnt explain anything about what it is |
| 16:53 | jtoy | ill just use koram for now then |
| 16:53 | jtoy | korma |
| 16:53 | SegFaultAX | jtoy: It's brief, read harder. |
| 16:53 | arrdem | (inc SegFaultAX) |
| 16:53 | lazybot | ⇒ 2 |
| 16:53 | SegFaultAX | (inc arrdem) |
| 16:53 | lazybot | ⇒ 5 |
| 16:53 | arrdem | welcome to clojure, where the source is probably the only docs. |
| 16:53 | arrdem | but that's ok 'cause the source is readable :D |
| 16:54 | SegFaultAX | Didn't Holloway once say that the ratio from psuedocode to production code should be 1:1? |
| 16:54 | SegFaultAX | Clojure is often pretty damn close. |
| 16:54 | jtoy | i dont mind reading source |
| 16:54 | arrdem | SegFaultAX: could be. I'm still trying to pseudocode in python because interviewers look at me weird when I start writing lisp |
| 16:55 | arrdem | jtoy: it's really just all the clojure.core maps functions wrapping a defonce'd atom |
| 16:55 | tomjack | also, it seems hard to write clojure on a whiteboard :( |
| 16:55 | bbloom | arrdem: fuck 'em, i pseudo code in whatever formalism i make up at the moment |
| 16:55 | SegFaultAX | arrdem: Most of the time I'll code in whatever the primary domain language is. When I use lisp, they think I'm a wizard. |
| 16:55 | amalloy | tomjack: no harder than it is to write it in notepad :P |
| 16:55 | arrdem | SegFaultAX: bust out some macros on that bitch and make 'em figure it out :D |
| 16:56 | tomjack | yes, harder, I claim |
| 16:56 | finishingmove | I'm trying to solve the first euler problem, and I get a weird result |
| 16:56 | tomjack | because you can't move text around, you may have to erase large sections and start over |
| 16:56 | finishingmove | ,(reduce (partial +) 0 (clojure.set/union (range 3 1000 3) (range 5 1000 5)))) |
| 16:56 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set> |
| 16:56 | arrdem | jtoy: the init() just kicks off a worker thread that dumps the atom to the db as the clojure prn render |
| 16:56 | arrdem | for "db" being defined as "./sdb.db" |
| 16:56 | SegFaultAX | finishingmove: Whoa, inefficient much? |
| 16:56 | finishingmove | gives me 266333 |
| 16:57 | finishingmove | instead of 233168 |
| 16:57 | arrdem | jtoy: so you just put! and get, for some implicitly defined record structure which you create. |
| 16:58 | finishingmove | SegFaultAX isn't the point of high-level programming to write code that is easier to reason about rather than being more efficient? |
| 16:59 | SegFaultAX | finishingmove: Um, no? |
| 16:59 | Cr8 | no reason you can't have both |
| 16:59 | finishingmove | anyway, what's wrong with my function? why is it not giving the expected result? |
| 16:59 | finishingmove | Cr8, sure, if there's a more efficient solution, I'd like to know about it |
| 16:59 | arrdem | finishingmove: only if you are willing to live with a shitty compiler.... |
| 16:59 | arrdem | ok gents, say goodby to this host. catch yall later. |
| 17:01 | amalloy | finishingmove: well, math. math is the more efficient way. you can easily enough derive a simple formula with just a couple multiplications, divisions, and additions, for the "fizzbuzz sum" up to any N you want |
| 17:01 | finishingmove | SegFaultAX do you have a more efficient solution? |
| 17:01 | finishingmove | what's so bad about my approach? |
| 17:01 | SegFaultAX | finishingmove: Well first of all, you're duplicating a shitload of work. |
| 17:02 | SegFaultAX | finishingmove: Don't worry about the summing part, that's trivial. |
| 17:02 | SegFaultAX | finishingmove: How can we efficiently find all the numbers between 1 and N that are divisible by 2 co-primes A and B? |
| 17:03 | SegFaultAX | finishingmove: Assume this constraint, you can iterate through the numbers 1 to N at most a SINGLE time. |
| 17:03 | finishingmove | i don't want to iterate at all |
| 17:03 | finishingmove | anyway, can u explain what you mean about duplicate work in my function? |
| 17:03 | finishingmove | how does it execute? |
| 17:04 | finishingmove | i see it as a simple 1-2-3-4-5 done |
| 17:04 | SegFaultAX | finishingmove: If you read what I just said, you might gain some insight. |
| 17:04 | finishingmove | i have, and i haven't |
| 17:04 | finishingmove | :s |
| 17:04 | finishingmove | how about being more concrete? |
| 17:05 | finishingmove | i believe you, but i don't see the problem |
| 17:05 | n_b | finishingmove: What's faster, counting out everything from 3,6...999, or finding the total via the formula for an arithmetic progression? |
| 17:05 | tomjack | clearly the former? |
| 17:06 | SegFaultAX | tomjack: Let finishingmove work it out. |
| 17:06 | finishingmove | i wouldn't think it's slower at all |
| 17:06 | finishingmove | maybe less memory efficient |
| 17:06 | tomjack | maybe you're much faster at algebra, but I can do very little algebra in the time it would take to count everything out |
| 17:08 | tomjack | oh, I misread :) |
| 17:08 | SegFaultAX | tomjack: What? |
| 17:08 | n_b | I should've said, counting and summing |
| 17:08 | tomjack | I read "finding the formula.." |
| 17:08 | SegFaultAX | n_b: I think your meaning was clear anyway, given the context. |
| 17:09 | SegFaultAX | finishingmove: So what do we need to see if any number in our range fits the criteria? |
| 17:11 | finishingmove | haven't given it thought yet |
| 17:13 | SegFaultAX | finishingmove: Write a function that given some number n, returns true if and only if it is divisible by 3 or 5 (or both) |
| 17:21 | n_b | Trying to figure out the fast way of doing this in clojure |
| 17:22 | n_b | my solution seems way slower than it should be |
| 17:23 | SegFaultAX | n_b: What's your solution? |
| 17:23 | n_b | (reduce + (for [i (range 0 1000) :when (or (= 0 (mod i 5)))] i)) |
| 17:23 | amalloy | SegFaultAX: introducing division isn't going to speed things up :P |
| 17:24 | SegFaultAX | amalloy: Over the original approach? How do you figure? |
| 17:25 | n_b | The simplest way is just the sum of divisors of 3 and 5 minus divisors of 15 I think? |
| 17:26 | amalloy | maybe a little, i guess? but i'm not sure why you're leading him down this path instead of just adding and subtracting a few arithmetic series |
| 17:26 | SegFaultAX | amalloy: Actually let me take that back, I don't know enough about the performance characteristics of hashsets to tell offhand if it will be slower or faster. |
| 17:27 | amalloy | SegFaultAX: you're probably right: i was thinking more about the allocation costs of the lazy-seqs, which isn't as large as you'd guess; but hashsets will need to do division anyway |
| 17:27 | n_b | The traditional solution is probably ```java int acc=0; for(int i=0; i<1000; i++) { if (i % 3 == 0 or i % 5 ==0) { acc+=i }};``` |
| 17:28 | SegFaultAX | amalloy: Oh hmm, you bring up and excellent point, though. |
| 17:28 | amalloy | n_b: for a laugh re the traditional solution, you might enjoy http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html |
| 17:29 | gozala | can anyone please help me understand why does (let [x :let] (def x :def) x) evaluates to :let |
| 17:29 | gozala | rather than :def ? |
| 17:30 | bbloom | ,`(let [x :let] (def x :def) x) |
| 17:30 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 17:30 | finishingmove | ,(reduce (fn [x y] |
| 17:30 | finishingmove | (if (or (= (mod y 3) 0) (= (mod y 5) 0)) |
| 17:30 | finishingmove | (+ x y) |
| 17:30 | finishingmove | x)) 0 (range 1 1000)) |
| 17:30 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 17:30 | finishingmove | how is that ^ different to |
| 17:30 | finishingmove | (reduce + 0 (clojure.set/union (range 3 1000 3) (range 5 1000 5))) |
| 17:30 | finishingmove | ? |
| 17:31 | finishingmove | it gives different result (former is correct) |
| 17:31 | gozala | it seems to define x in the top scope rather than with in the let context |
| 17:31 | SegFaultAX | ,(time (let [sum (partial reduce +)] (+ (sum (range 3 1000 3)) (sum (range 5 1000 5)) (- (sum (range 15 1000 15)))))) |
| 17:31 | clojurebot | "Elapsed time: 2.922747 msecs"\n233168 |
| 17:32 | schmir | gozala: def creates a global var. read (doc def). |
| 17:32 | SegFaultAX | amalloy: I guess that's pretty low on a warmed jvm. 0.2ms |
| 17:32 | SegFaultAX | amalloy: I haven't compared it to the hashset version yet though. |
| 17:32 | amalloy | SegFaultAX: well, yeah, but why call (range) at all? |
| 17:32 | amalloy | just look up the formula for summing an arithmetic series |
| 17:32 | SegFaultAX | amalloy: Fewer keystrokes. |
| 17:33 | bbloom | gozala: what schmir says is correct, but to answer the question anyway: x is resolved when that expression is compiled. during compilation, def hasn't run yet, so there is no x var to resolve against |
| 17:33 | bbloom | gozala: that is, def has the side effect of creating a global called x. however, that's some.namespace/x instead of the 'x that is in the local context |
| 17:33 | SegFaultAX | amalloy: Oh well that wasn't the original problem we were discussing. |
| 17:34 | llasram | finishingmove: your `union`-based implementation has the effect of replacing `or` with `and` in the other implementation |
| 17:34 | SegFaultAX | amalloy: We were specifically not talking about the closed form solution, if that's what you mean. |
| 17:34 | gozala | bbloom: schmir thanks |
| 17:34 | finishingmove | llasram, shouldn't that be intersection? |
| 17:34 | gozala | trying to make up my mind what js should it compile to |
| 17:34 | amalloy | i didn't notice anyone stating that constraint |
| 17:35 | SegFaultAX | amalloy: Eh, I was addressing the set thing. |
| 17:35 | n_b | amalloy: That article is great; think I'll be stealing it for an Intro to FP presentation I'm doing next week. Cheers! |
| 17:35 | llasram | finishingmove: Oh, you're right. Brain not at full speed, apparently |
| 17:36 | SegFaultAX | Food time, bbl. |
| 17:36 | finishingmove | the union solution gives a higher number actually |
| 17:42 | Cr8 | here's a weird one |
| 17:42 | Cr8 | ,(apply + (distinct (concat (range 3 1000 3) (range 5 1000 5)))) |
| 17:42 | clojurebot | 233168 |
| 17:42 | n_b | ,(clojure.set/union (range 0 20 3) (range 0 20 5)) |
| 17:42 | clojurebot | #<ClassNotFoundException java.lang.ClassNotFoundException: clojure.set> |
| 17:42 | Cr8 | why is (distinct (concat c1 c2)) behaving differently from (union c1 c2) ? |
| 17:43 | finishingmove | I'd like to know too |
| 17:43 | llasram | Even better: &[(count (clojure.set/union (range 3 1000 3) (range 5 1000 5))) (count (clojure.set/union (set (range 3 1000 3)) (set (range 5 1000 5))))] |
| 17:43 | llasram | Er, |
| 17:43 | llasram | &[(count (clojure.set/union (range 3 1000 3) (range 5 1000 5))) (count (clojure.set/union (set (range 3 1000 3)) (set (range 5 1000 5))))] |
| 17:43 | lazybot | ⇒ [532 466] |
| 17:44 | Cr8 | AH |
| 17:44 | Cr8 | Got it! |
| 17:44 | Cr8 | clojure.set/union *expects to be given sets* |
| 17:44 | n_b | yup |
| 17:44 | Cr8 | as it's just (reduce conj <smaller set> <larger set>) when given two sets |
| 17:44 | llasram | And definitely does the wrong thing when given non-sets |
| 17:44 | Cr8 | with two vectors you are just catting the larger one onto the smaller one |
| 17:44 | n_b | This is where core.typed would help :p |
| 17:44 | Cr8 | or lists, catting in reverse |
| 17:45 | finishingmove | this is where haskell would have helped |
| 17:45 | finishingmove | :D |
| 17:47 | Cr8 | except I had larger/smaller backwards for all of that |
| 17:49 | finishingmove | i still don't see how this: |
| 17:49 | finishingmove | (defn problem' |
| 17:49 | finishingmove | [] |
| 17:49 | finishingmove | (reduce (fn [x y] |
| 17:49 | finishingmove | (if (or (= (mod y 3) 0) (= (mod y 5) 0)) |
| 17:49 | finishingmove | (+ x y) |
| 17:49 | finishingmove | x)) 0 (range 1 1000))) |
| 17:49 | finishingmove | could be faster than |
| 17:49 | finishingmove | (defn problem |
| 17:49 | finishingmove | [] |
| 17:49 | finishingmove | (reduce + 0 (distinct (concat (range 3 1000 3) (range 5 1000 5))))) |
| 17:49 | amalloy | finishingmove: please stop pasting large programs here |
| 17:49 | amalloy | ~paste |
| 17:49 | finishingmove | never have, amalloy |
| 17:49 | clojurebot | paste is not gist.github.com |
| 17:49 | amalloy | $google refheap |
| 17:49 | lazybot | [Refheap - The pastebin for your, you know, pastes] https://www.refheap.com/ |
| 17:49 | finishingmove | and these are not large programs, my dear clojurebot |
| 17:49 | s-h | ,(reduce + (filter #(or (= (mod % 3) 0) (= (mod % 5) 0)) (range 1 1000))) |
| 17:49 | clojurebot | 233168 |
| 17:49 | n_b | I don't see how you could see the former *not* be faster than the latter |
| 17:50 | amalloy | s/large/multi-line |
| 17:50 | llasram | finishingmove: in this channel's etiquette, anything larger than one line is "large" |
| 17:50 | n_b | it's doing more work, plain and simple. |
| 17:50 | finishingmove | the first one generates a list of all numbers from 1 to 1000 |
| 17:51 | finishingmove | the other one generates 2 lists with only a portion of numbers |
| 17:51 | finishingmove | and the total of the two is less than 1000 |
| 17:51 | llasram | finishingmove: And IMHO is less about actual size, than just line breaks. Put your admittedly-small programs on one line, and your fine |
| 17:52 | finishingmove | i got the memo |
| 17:52 | amalloy | finishingmove: putting things into sets is not free. they have to build a data structure that supports conj/disj/contains? operations quickly |
| 17:52 | Cr8 | finishingmove: it's easier to see the difference if you go higher than 1000 |
| 17:52 | Cr8 | https://www.refheap.com/16020 |
| 17:54 | fbernier | so... what's the difference between a mutex and a clojure "dosync" ? |
| 17:55 | finishingmove | interesting, Cr8 |
| 17:55 | bbloom | fbernier: a lot. go read about dosync and "software transactional memory" |
| 17:55 | bbloom | fbernier: but if you're new to clojure, you can basically just ignore dosync… it's pretty rare in most clojure code these days |
| 17:56 | devn | ignore that! :) |
| 17:56 | devn | look into refs, build a simple in-memory db with them |
| 17:56 | devn | it's fun |
| 17:56 | fbernier | bbloom: Ok thanks ... I am new to clojure but will be giving a presentation about it soon. |
| 17:56 | fbernier | looking for cool examples to show off |
| 17:57 | devn | fbernier: i have one for you |
| 17:57 | hyPiRion | fbernier: so with mutexes you may deadlock, but that's impossible with STMs (dosync blocks) |
| 17:57 | devn | fbernier: https://github.com/Licenser/stupiddb |
| 17:57 | devn | fbernier: that's an old project, but a fun one |
| 17:57 | bbloom | fbernier: clojure's concurrency primitives are only one of many interesting things in clojure. however, most would agree with me when i say that immutable/persistent data structures are of far deeper importance and are a prerequisite in understanding |
| 17:58 | llasram | +1. I have yet to need dosync or the STM to solve a real problem |
| 17:59 | fbernier | bbloom: Alright, I'll look into that and see how I can explain it easily. |
| 17:59 | llasram | But persistent data structures fundamentally change how you approach problems |
| 17:59 | devn | what about an agent llasram? an atom? |
| 17:59 | bbloom | fbernier: http://www.infoq.com/author/Rich-Hickey is the place to start if you like videos |
| 18:00 | devn | ^-watch Are We There Yet |
| 18:00 | bpr | ^ this |
| 18:00 | bbloom | yup, then "simple made easy" |
| 18:00 | Cr8 | Atoms are quite useful |
| 18:00 | devn | my brain was like this: http://slackwise.net/files/images/Tim%20and%20Eric%20-%20Space%20Explosions.gif |
| 18:00 | llasram | devn: Sure, but those are different. Agents can participate in STM transactions, but STM isn't fundamental to them. Atoms have nothing to do with either the STM or dosync |
| 18:00 | Cr8 | agents I don't think I've really used "correctly" |
| 18:01 | bpr | imo, rich's "simple made easy" has a larger impact if you watch Stu Halloway's talk about that topic first (iirc it was delivered in the first conj) |
| 18:01 | bpr | http://www.youtube.com/watch?v=cidchWg74Y4 |
| 18:01 | devn | llasram: meh, datomic uses refs from what i understand |
| 18:01 | devn | and that is certainly real world |
| 18:01 | llasram | devn: Hmm, I thought I read that the in-memory state is all just in an atom |
| 18:02 | devn | i might have that wrong |
| 18:02 | fbernier | thanks for the infos everyone |
| 18:02 | devn | you're probably right |
| 18:02 | llasram | devn: But I was specifically talking about my own production Clojure code. I wrote Clojure every day, and never used a ref |
| 18:02 | llasram | s,wrote,write, |
| 18:02 | finishingmove | i did "lein repl" in my project folder, but how do i call functions from my namespace? |
| 18:02 | devn | i wrote refs and then was like: oh, i could write this a different way |
| 18:02 | tomjack | I'd be surprised if datomic didn't use refs |
| 18:02 | devn | slowly unlearning my imperative BS |
| 18:03 | tomjack | they say you should have multiple transactions in flight for best performance |
| 18:03 | devn | ^-that |
| 18:03 | tomjack | which suggests refs underneath to me (though I too have never actually used them) |
| 18:03 | llasram | finishingmove: `require`, then probably `in-ns` |
| 18:03 | finishingmove | thanks |
| 18:03 | hyPiRion | finishingmove: (require '[my.namespace :as my]) then (my/function args) |
| 18:03 | finishingmove | ty! |
| 18:04 | devn | anyone here in SF? |
| 18:04 | bbloom | dnolen_: is refer-clojure not supported in cljs? |
| 18:04 | tomjack | I'm in berkeley, looking for a place in SF now |
| 18:04 | bbloom | dnolen_: the assert string says it is, but the code seems to strip it out |
| 18:06 | tomjack | or maybe pods replace refs in datomic's internals? |
| 18:06 | devn | my guess is: unlikely |
| 18:06 | devn | but that'd be fun if it were true |
| 18:06 | tomjack | there are definitely some things called 'pod' in there |
| 18:06 | devn | tomjack: oh yeah? |
| 18:07 | tomjack | (but I don't actually know wtf pods really are, so..) |
| 18:07 | tomjack | e.g. the log tail is a 'tail-pod' |
| 18:07 | devn | heh |
| 18:08 | bbloom | tomjack: http://dev.clojure.org/display/design/Mutex+references+%28pods%2C+nee+cells%29 |
| 18:08 | devn | this is old chat |
| 18:08 | bbloom | tomjack: plus lots of irc discussion that was hard to find |
| 18:09 | devn | yeah we were talking about pods maybe 6months before the first conj |
| 18:09 | tomjack | I saw the talk about them but it seemed like it still was unclear what they should be exactly |
| 18:09 | devn | it's like transients |
| 18:10 | devn | except it ensures the thread who created it is the the thread that changes it |
| 18:10 | devn | the policy of who can change it is the ref type |
| 18:10 | devn | that's my dumb understanding |
| 18:10 | tomjack | &(let [t (transient [])] @(future (conj! t :foo))) |
| 18:10 | lazybot | java.lang.SecurityException: You tripped the alarm! future-call is bad! |
| 18:11 | tomjack | oya |
| 18:11 | bpr | fbernier: this is one of my fav clojure-specific talks of rich's http://www.youtube.com/watch?v=dGVqrGmwOAw |
| 18:11 | bpr | just fyi |
| 18:11 | fbernier | thanks |
| 18:12 | devn | fbernier: seriously though, and yes, im going to be pushy: watch "Are we there yet?" |
| 18:12 | devn | it's the original talk. it's THE talk |
| 18:13 | bpr | yes, that will change how you think about concurrent programming. |
| 18:13 | fbernier | I will surely watch it, but should I absolutely watch it before my talk on tuesday which should be an introduction to clojure? |
| 18:13 | fbernier | I don't have much time to gather the best info I can ... |
| 18:14 | bbloom | fbernier: you're given a talk on a subject you don't know anything about? :-P |
| 18:14 | fbernier | I do know about basics ... |
| 18:14 | mdeboard | Simple Made Easy is another good talk. My fave talk actually |
| 18:14 | mdeboard | fbernier, I gave a talk on Clojure to a local Scala meetup, I'm a super beginner too. Don't sweat it. |
| 18:15 | mdeboard | I based my talk on Simple Made Easy, actually. |
| 18:15 | fbernier | it'll be an informal talk at a local event |
| 18:15 | bpr | fbernier: is your talk intended to be a first introduction to clojure, or is it more about the deeper rationale behind the design choices Rich made when creating the language? |
| 18:15 | devn | tomjack: http://www.infoq.com/interviews/hickey-clojure-reader |
| 18:16 | mdeboard | Yeah, that's how mine was too. bbloom signing up to give a talk on a subject you're not well-versed in is a great way to get well versed :) |
| 18:16 | fbernier | bpr: first introduction for sure |
| 18:16 | fbernier | most will not be familiar with lisp |
| 18:16 | fbernier | it's a web crowd |
| 18:16 | devn | tomjack: his response to the question about pods has this line in it: "Datomic has informed my thinking about pods and probably will enable me to complete them." |
| 18:18 | tomjack | cool, didn't notice that when I watched that interview before |
| 18:18 | bbloom | mdeboard: yeah, but if you only have a few days to prepare, you're unlikely to become well versed enough to speak about it intelligently. the audience has to sit through your ramblings…. they came to see YOU…. |
| 18:18 | jtoy | anyone here use ring? how am i supposed to reload the server after i change it? right now i have to kill the repl for every change |
| 18:18 | mdeboard | bbloom, Oh, didn't know it was short-fuse like that :) |
| 18:19 | llasram | jtoy: Provide the vars holding your handlers as the handler functions to whatever server you're using. Reader macro: #'my-ring-handler |
| 18:19 | bpr | fbernier: http://bit.ly/11FVEN5 |
| 18:20 | llasram | jtoy: When you make a change and reload the namespace, the function referenced by the var changes, and the server calls the new function |
| 18:20 | bpr | fbernier: I haven't watched all the videos on that list, but it seems like a good model for you. It seems like it's aimed at a similar audience and has similar goals |
| 18:21 | fbernier | bpr: cool thanks |
| 18:21 | bpr | np |
| 18:21 | jtoy | llasram: ok, ill try that |
| 18:23 | jtoy | llasram: good example here: https://github.com/mmcgrana/ring/issues/72 |
| 18:26 | arohner | can someone remind me why take-while says the function should be pure? |
| 18:27 | arohner | I have a list containing a bunch of numbers, and I want to take items off the list while the sum of the items is < N |
| 18:27 | jtoy | hmm, i cant get it to work though |
| 18:28 | tomjack | arohner: interesting! |
| 18:28 | llasram | arohner: Because it just makes no guarantees about when your predicate will be called |
| 18:29 | llasram | That particular problem is pretty easy to lazy-seq up directly though |
| 18:29 | arohner | reading the source, it seems like closing over an atom will work |
| 18:30 | fsmunoz | what0s the cleanest way in Clojure to do (setq foo (or some-value some-other-value))? |
| 18:30 | llasram | jtoy: It does in general. Code gist-able? |
| 18:30 | jtoy | llasram: im testing more |
| 18:32 | jtoy | llasram: https://www.refheap.com/16022 |
| 18:34 | llasram | arohner: But would be poor style! Everyone would frown at you, distressed and saddened |
| 18:35 | arohner | llasram: is there a better abstraction? |
| 18:35 | Cr8 | arohner: https://www.refheap.com/16023 |
| 18:35 | arohner | Cr8: oh, very nice |
| 18:35 | tomjack | :/ |
| 18:36 | arohner | ? |
| 18:37 | amalloy | Cr8, arohner: why define take-while-reduce at all? just use reductions+take-while |
| 18:37 | tomjack | https://www.refheap.com/861a6a77c9f571804e7b06f38 |
| 18:37 | tomjack | I do still feel unsatisfied |
| 18:38 | Cr8 | amalloy: well, he wanted the original list's items |
| 18:38 | Cr8 | you could zip the reductions and the original list together I suppose |
| 18:38 | Cr8 | then unzip |
| 18:38 | arohner | yeah, but that's annoying |
| 18:38 | amalloy | (map (fn [a b] a) xs (reductions ... xs)) |
| 18:39 | amalloy | but, sure, it's not a ton of fun at that point |
| 18:39 | Cr8 | then wrap the (reductions) part with the take-while |
| 18:40 | tomjack | oh, good idea https://www.refheap.com/a2e63743cb5dc99ff046ec31c |
| 18:40 | tomjack | my gut says Data.Lens has a much more beautiful solution |
| 18:40 | llasram | jtoy: Oh! You still need some way of reloadig the namespaces. Something standard provides a `wrap-reload` which will reload files which change. I myself just launch the server from an editor-connected REPL and reload namespaces like for any other Clojure work |
| 18:40 | tomjack | and I wish we could do this with reducers |
| 18:41 | devn | anyone here ever use jode? |
| 18:41 | Cr8 | ,(let [xs (range 10)] (map (fn [a b] a) xs (take-while #(< % 10) (reductions + 0 xs)))) |
| 18:41 | clojurebot | (0 1 2 3 4) |
| 18:41 | devn | (and are willing to admit it?) |
| 18:41 | llasram | tomjack: I wrote a `reductions` implementation for reducers, but it languishes in Jira |
| 18:41 | devn | llasram: it took me 1.5 years to get my patch on range in |
| 18:41 | devn | don't fret |
| 18:41 | tomjack | I wrote one too but that is still unsatisfying |
| 18:42 | llasram | What would you wish instead? |
| 18:42 | dobry-den | Why is `doto` used here instead of the `->` macro? (let [mac (doto (Mac/getInstance hmac-sha1) (.init signing-key))] …) |
| 18:42 | dobry-den | seen here: https://github.com/mattrepl/clj-oauth/blob/master/src/oauth/digest.clj#L10 |
| 18:43 | tomjack | I don't want to have to make a reducer of [reduction elem] and then project |
| 18:43 | tomjack | feels like it should be fused away somehow |
| 18:43 | llasram | dobry-den: `doto` returns the result of evaluating it's first form-argument, while `->` returns the last |
| 18:43 | bpr | dobry-den: prob, b/c .init returns nil (or something other than the mac object) |
| 18:44 | tomjack | actually I don't even see how to do it with reductions |
| 18:44 | dobry-den | llasram: ahh, clojure has gotten me to completely forget about mutation. |
| 18:44 | dobry-den | also reminds me of how funny java apis are |
| 18:45 | bpr | dobry-den: lol, yes. I once had to wrangle BouncyCastle... it was painful |
| 18:46 | dobry-den | bpr: oh man, yeah that's actually my first experience using a java api. |
| 18:47 | bpr | wow. that musta been intense |
| 18:48 | arohner | amalloy tomjack: I learned something today, thanks |
| 18:48 | dobry-den | i dont understand how people are productive with it. there's a magical order in which you apply methods like .init() and .doFinal() and .update() yet the docs never answer simple questions like "how do you go from a string to sha512 hex hash? |
| 18:48 | bpr | although, with class names like DefaultSignatureAlgorithmIdentifierFinder and BcRSAContentVerifierProviderBuilder, it wasn't without it's humor |
| 18:49 | dobry-den | haha. i actually gave up trying to figure out how to implement elliptical curve signing |
| 18:49 | bpr | dobry-den: for real |
| 18:49 | bpr | its* |
| 18:50 | tomjack | s/Data.Lens/Control.Lens/ |
| 18:52 | dobry-den | bpr: i did learn about Apache Commons, though. for instance: http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html |
| 18:52 | bpr | dobry-den: yeah, we looked at that. It wasn't sufficient for all our needs... i forget why |
| 18:55 | dobry-den | with simple methods like sha512Hex("secret") => hex hash, i have to wonder how unidiomatic it is in the java ecosystem |
| 18:56 | dobry-den | not enough object collaboration |
| 18:57 | dobry-den | sorry, the topic opened up old wounds. 'doto' is great |
| 18:57 | bpr | let me just say: clojure does java better than java :-p |
| 18:58 | Raynes | dobry-den: It should definitely return a HexHashFactorySingletonHashMaker |
| 18:59 | amalloy | dobry-den: you don't know true Java Zen until you write a single expression with two `doto` and three `->` |
| 19:00 | hyPiRion | Raynes: I thought it would return IPersistentHashMapMessageStrategyDefinitionIterableTest |
| 19:01 | amalloy | huh. apparently i gisted https://gist.github.com/amalloy/fd3fda4c707802740874 |
| 19:01 | amalloy | i wonder why |
| 19:02 | amalloy | i bet Raynes was trying to bully me into using refheap instead of gist |
| 19:02 | dobry-den | every crypto lib starts like this: SomeCryptoClass.getInstance(KeyMaker.getInstance("secret", "Sha512"), SomeCryptoClass.getAlgorithm("SunSha512")) |
| 19:03 | dobry-den | to see the available magic strings you can get algorithms for, you do SomeCryptoClass.getProviders() and they aren't enumerating in the docs. so it leads me to wonder if the available algorithms change over time even if you don't update your crpto lib version. that's the only explanation i can think of |
| 19:04 | dobry-den | enumerated* |
| 19:04 | gfredericks | dobry-den: it sounds like idiomatic java design to me :P |
| 19:04 | gfredericks | they have obviously attained maximum flexibility |
| 19:05 | llasram | I think it's an artifact of the old US crypto export laws |
| 19:05 | dobry-den | it's just a stone's throw from (do-something "(+ 1 2)") |
| 19:05 | llasram | SHA-2 is a munition etc |
| 19:05 | bbloom | is there a way to make cljsbuild completely override the source-paths? I don't want my src/clj directory on the path at all when building src/cljs |
| 19:05 | amalloy | llasram: probably not; i think it's just DI gone mad |
| 19:06 | tomjack | bbloom: and you are going to produce two separate jars somehow? |
| 19:06 | llasram | amalloy: That might be the simpler explanation |
| 19:06 | bbloom | tomjack: *shrug* i dunno. my issue is that i'm not writing a clojure.core.foo or cljs.core.foo namespace. i have myapp.foo in both clj and cljs, so when looking for macros, i'm getting the clj version from cljs |
| 19:06 | tomjack | my conclusion was that you have to either have separate projects or different namespace names (e.g. cljs.core.async), if I understand the situation you're in |
| 19:07 | bbloom | yeah that's precisely the situtation i'm in |
| 19:07 | tomjack | ..until 1.6, I guess :) |
| 19:07 | bbloom | blargh. can't come fast enough :-P |
| 19:07 | bbloom | i have like 375 things i'm putting off until clj/cljs cooperate better |
| 19:08 | bbloom | gfredericks: 370 of them are happy dance moves |
| 19:08 | llasram | I'm going to imagine that he's doing them in a parallel world with 10 extra days per year, and he does one per day |
| 19:09 | gfredericks | let's all say our favorite thing to imagine about bbloom's list |
| 19:09 | tomjack | having separate projects would force separate projects on consumers who want both, it seems |
| 19:09 | tomjack | so I guess an ugly workaround could be myapp.cljs.core for now :( |
| 19:10 | tomjack | or core.async could maybe have gotten away with using the same namespace since it puts macros in a special cljs.core.async.macros ns anyway? |
| 19:10 | bbloom | tomjack: yeah, i guess that's gotta be the case. i don't want to make two separate projects, since i expect a clj server to talk to a cljs client. i guess i can just version them together... |
| 19:12 | tomjack | I asked about the 'take while cumulative sum' in #haskell-lens, turns out it's not lensy and the solution proposed (in non-lens haskell) was exactly the same as the solution we came up with |
| 19:12 | bbloom | maybe i'll just make two different git branches…. :-P |
| 19:12 | tomjack | actually our solution is ostensibly nicer |
| 19:18 | tomjack | bbloom: still going to fuck consumers, eh? |
| 19:18 | tomjack | I guess if you have no consumers it's ok |
| 19:18 | bbloom | lol |
| 19:18 | bbloom | *shrug* you'll just need two deps |
| 19:18 | bbloom | no big deal |
| 19:18 | tomjack | but won't they conflict? |
| 19:19 | bbloom | they will have different names |
| 19:19 | bbloom | foo and foo-cljs |
| 19:19 | tomjack | but the namespaces? |
| 19:19 | bbloom | oh right. *sigh* |
| 19:20 | bbloom | the git branches are nice tho… i can use git's rename detection to ease the porting of changes :-P |
| 19:23 | bbloom | *shrug* consumers will just need to make two projects too lol |
| 19:23 | bbloom | priority 1 is the port, will worry about that stuff later… |
| 19:24 | tomjack | yeah, oh well |
| 19:25 | tomjack | glad to see an Executor protocol drafted in core.async |
| 19:26 | tomjack | bblöom: maybe you'll be able to swap out setTimeout for your queue thingy |
| 19:29 | bbloom | tomjack: where is that protocol drafted? |
| 19:29 | tomjack | in the forkjoin branch |
| 19:30 | tomjack | looks like they make a choice of executor for you though |
| 19:49 | francis_wolke | What are some good resources to learn how to correctly walk trees? |
| 19:52 | francis_wolke | I realize that clojure.walk exists - but I'm not 'getting it' when it comes to dealing with trees - EG: the algorithms arn't jumping to mind and I think I may need to read some research papers/textbooks/articles |
| 19:53 | bbloom | francis_wolke: i've found that clojure.walk isn't super useful beyond trivial use cases |
| 19:54 | bbloom | francis_wolke: start with just a really simple recursive walk |
| 19:56 | francis_wolke | bbloom - That's actually what I'm having the issue with - as the tree branches I'm not 'seeing' how my program can continue to walk down the tree. I realize that this is n00b stuff, but I've never had to do it before. :/ |
| 19:57 | bbloom | francis_wolke: ah ok. well there are two general approaches to two types of traversals |
| 19:58 | bbloom | there is iterative & recursive, then there is breadth vs first depth first |
| 19:58 | bbloom | recursive and depth first is the easiest, so start with that |
| 19:58 | bbloom | here's a good comparison of iterative solutions for depth vs breadth: http://stackoverflow.com/questions/687731/breadth-first-vs-depth-first |
| 19:58 | bbloom | so you understand how they are related fundamentally :-) |
| 19:58 | cbp` | clojure.zip has functions to walk nested structures |
| 19:59 | bbloom | cbp`: let's not bring zip into this. he needs some practice with the fundamentals, he said |
| 19:59 | bbloom | zippers would dramatically complicate things at this stage of his learning |
| 19:59 | francis_wolke | bbloom: k. Thanks. |
| 20:00 | bbloom | francis_wolke: the wikipedia pages have good pseudo code for all 4 possible approaches |
| 20:00 | bbloom | start here: http://en.wikipedia.org/wiki/Depth-first_search |
| 20:00 | bbloom | don't try to be general or anything yet. just manually traverse over whatever particular structure you're trying to work with |
| 20:03 | bbloom | francis_wolke: oh actually, i showed you search. sorry. start here: http://en.wikipedia.org/wiki/Tree_traversal |
| 20:41 | tomjack | what's the point of IEnforceableConstraint? |
| 20:41 | tomjack | I can understand why it's there for domc |
| 20:41 | tomjack | but not the rest |
| 20:50 | tomjack | callen: apparently my battery was just miscalibrated, been running at 0% for like 20min |
| 20:53 | tomjack` | there it goes :( |
| 20:54 | francis_wolke | bbloom: thanks for the pointers, they set me off in the correct direction. |
| 23:25 | clizzin | hey all, i'm looking to set up an api service that will be an oauth2 provider. what's the state of the art out there in terms of clojure libs for oauth2 providers? i found https://github.com/pelle/clauth but it looks quite old. |
| 23:34 | navgeet | https://github.com/cemerick/friend ? |