2013-10-24
| 00:05 | akurilin | Quick question. What's the recommended simple library these days for scheduling recurring tasks in one's Ring app? Looks like at-at has some traction on Github. |
| 00:12 | ToBeReplaced | akurilin: i use ScheduledThreadPoolExecutor directly |
| 00:13 | muhoo | akurilin: there's at-at, and there's a new library raynes did too that's more like a cron |
| 00:14 | akurilin | muhoo, I was looking at chime as well, seems super minimalistic and uses clj-time pretty heavily |
| 00:14 | akurilin | ToBeReplaced, that's fair, looks like a lot of these libs are just wrapping it |
| 00:15 | muhoo | akurilin: https://github.com/Raynes/moments |
| 00:16 | akurilin | muhoo, that's cool! Wasn't there on clojure toolbox |
| 00:20 | akurilin | Hm probably more inclined to go with Raynes' stuff for now, let me try that. |
| 00:25 | arrdem | I feel like one could/should build a crontab like dsl atop that... |
| 00:25 | muhoo | that'd be * * * * * funny |
| 00:38 | marcopolo2 | anyone know is I can do anything asynchronous inside pedestal app transactions? |
| 00:54 | akurilin | Say I'm doing some batch processing on my data set once a day and maybe I want to send out a few thousand analytics events or maybe Mandrill API calls as soon as I'm done fetching and processing this data. |
| 00:55 | akurilin | It's my understanding that just looping through a few thousand entries and sending out HTTP requests for each as fast as you can will very possibly result in many failures on the way |
| 00:55 | akurilin | either because of the network, or maybe the API starts throttling etc. |
| 00:55 | akurilin | I think I read somewhere where for email batch spamming people were using queues and just slowly plowing through them |
| 00:56 | akurilin | making sure the APIs would respond positively |
| 00:56 | bja | aha, my app's configuration is finally sane |
| 00:57 | bja | I now have an app/config.clj where I define all of my config variables including defaults and then it defers to environ to pull out of env variables/properties/etc |
| 00:57 | bja | not littering my app with (get env :random-setting $DEFAULT) is a good feeling |
| 00:58 | bja | just define things like (setting "name" default) |
| 00:58 | bja | and then config/name is a symbol that be referenced throughout |
| 01:14 | bitemyapp | akurilin: clj-http retries failed requests. |
| 01:14 | bitemyapp | akurilin: you can use things like robert.bruce to customize retry logic as well. |
| 01:39 | ToBeReplaced | akurilin: this may sound like flamebait, but i'd avoid moments and chronicle unless your goal is "get done now" |
| 01:39 | ToBeReplaced | akurilin: they use the word "simple" when i think they actually mean "easy"... they are hiding away all of the power of STPE and joda-time in favor of the bare-minimum use case |
| 01:41 | ToBeReplaced | if that's sufficient for you, go ahead, but i had a great time really grokking joda and STPE, and i wouldn't trade the things i've learned in for one of those tools |
| 01:57 | bitemyapp | akurilin: I'd tend to agree with ToBeReplaced. |
| 01:57 | bitemyapp | moments is pretty cool though :) |
| 02:37 | akurilin | ToBeReplaced, bitemyapp , thanks for clarifying, sorry for late response. |
| 02:38 | akurilin | bitemyapp, I guess my question is about whether there are physical limitations to spamming an online HTTP api that would end up dropping a majority of my calls. |
| 02:38 | akurilin | bitemyapp, so say I were to make a hundred futures to make clj-http calls |
| 02:38 | akurilin | there's probably some sort of physical port limit in place |
| 02:39 | akurilin | or the pipe would get clogged |
| 02:39 | akurilin | or something else |
| 02:39 | akurilin | I'm just not really fully conscious of these limitations right now |
| 02:40 | creese | Are there any good libraries for marshalling API requests and responses? |
| 02:41 | akurilin | bitemyapp, but yeah it's really cool that clj-http takes care of retries. Saves me the time to implement a queue, and I can even add some sort of backoff strategy if I wanted to |
| 02:46 | bitemyapp | akurilin: do not spam futures. |
| 02:46 | bitemyapp | akurilin: do not spam external APIs. |
| 02:46 | tsdh | Hi. When hacking clojure, is there a way to only compile and execute a specific test namespace? Always compiling everything and running all tests with "mvn package" takes ages here. |
| 02:51 | jared314 | tsdh: are you using lein or straight mvn? |
| 02:52 | oneness | tsdh: you should be able to run only one namespace by using the -D option just like in java. But this assumption needs to be verified. |
| 02:52 | ambrosebs | tsdh: hacking clojure.core? |
| 02:52 | tsdh | jared314: It's clojure itself, so maven. |
| 02:52 | tsdh | ambrosebs: yep |
| 02:52 | tsdh | oneness: Ah, mvn -Dtest=testclass google says. I'll try that. |
| 02:53 | ambrosebs | tsdh: I don't know, I've have that problem myself. |
| 02:54 | tsdh | Hm, "mvn test" seems to compile everything, too. |
| 02:57 | andyfingerhut | tsdh: Have you looked under "How To Run All Clojure Tests" on this wiki page? http://dev.clojure.org/display/community/Developing+Patches |
| 02:57 | tsdh | andyfingerhut: Not yet. Thanks. |
| 02:57 | andyfingerhut | tsdh: Or rather, just below that under "Run An Individual Test" |
| 02:58 | tsdh | andyfingerhut: Ah, that's it. Thanks! |
| 02:59 | andyfingerhut | tsdh: No problem. I don't have it memorized how to do it, but I remember where to look it up :-) |
| 03:03 | akurilin | bitemyapp, I understand, still doesn't really help me gauge what is considered "spam" |
| 03:03 | akurilin | obviously each API owner has its own policy |
| 03:04 | akurilin | anyways, I'll see if I can dig up some info on this around |
| 03:05 | tsdh | If I have an interface method with 3 parameters, when extending that in a deftype the impl has 4 params (the first being "this"), right? |
| 03:07 | akurilin | bbl |
| 03:08 | bitemyapp | akurilin: pretty easy to dispatch too many futures and run out of threads if you're not careful. |
| 03:08 | bitemyapp | the agents thread pool is 1:1 OS threads. |
| 03:09 | bitemyapp | you can't fire those off willy-nilly against an arbitrarily large coll. |
| 03:14 | andyfingerhut | /whois GOSUB |
| 03:14 | andyfingerhut | sorry. Must have had whitespace there. |
| 03:23 | tsdh | Hm, I have a testcase that uses (is (thrown? SomeEx (macroexpand '(some-form)))). When I eval the macroexpand in a REPL, I can see the exception printed, but still the macroexpansion returns a form. It seems the exception is somehow printed but caught... |
| 03:24 | tsdh | Concretely, (some-form) is a (deftype ...) form that triggers a CompilerException. |
| 03:25 | tsdh | The same applies with (reify ...). (defrecord ...) on the other hand triggeres the same exception, and there it's passed through and my test succeeds. |
| 03:33 | andyfingerhut | tsdh: Can you share the (deftype ...) form that triggers a CompilerException that you are trying? |
| 03:41 | tsdh | andyfingerhut: Sure, but it doesn't trigger the CE without my other patch. ;-) |
| 03:41 | tsdh | andyfingerhut: Check CLJ-888 and the attached patch. |
| 03:41 | tsdh | andyfingerhut: The tests that fail due to swallowed CE are commented out with a big FIXME. |
| 03:42 | andyfingerhut | tsdh: Got it. I may take a look here, but don't know what is going on with the swallowed exceptions yet. |
| 03:45 | iSocket | &"I worship his Shadow" |
| 03:45 | lazybot | ⇒ "I worship his Shadow" |
| 03:47 | johann | hey guys |
| 03:47 | iSocket | johann, |
| 03:47 | iSocket | I Worship His Shadow |
| 03:48 | johann | has anyone had issue with heroku deployment and procfiles? |
| 03:49 | johann | my app is crashing when i deploy it and heroku hasn't been recognizing my procfile so i am hoping that would fix it |
| 03:50 | johann | iSocket--I Hope He Reciprocates Your Shadow Worship |
| 03:59 | andyfingerhut | tsdh: I don't know what is going wrong with those tests, but i tried 'eval' in place of 'macroexpand' on the first commented out one and it passed. |
| 04:00 | andyfingerhut | tsdh: Any particular reason you are using macroexpand there? |
| 04:00 | tsdh | andyfingerhut: Well, it should suffice to trigger the excetion, I've thought. But eval is as fine. I'll try the others. Thanks! |
| 04:02 | andyfingerhut | tsdh: I'm not sure if defprotocol has side effects you want to avoid eval for, but there is also a test helper function eval-in-ns that might be useful. |
| 04:02 | andyfingerhut | tsdh: Sorry, wrong name. It should be eval-in-temp-ns |
| 04:04 | tsdh | andyfingerhut: The worst side effect would be that some new type was defined in the test namespace, so I guess that's no issue. |
| 04:04 | tsdh | andyfingerhut: Indeed, now all tests pass! |
| 04:06 | tsdh | andyfingerhut: Great, I've updated the patch of CLJ-888. |
| 04:07 | andyfingerhut | tsdh: My guess is that macroexpand1 is doing something strange with the exception, but I don't know what. Like you, I see the exception output in the REPL, and it binds *e to it, but still the (is (thrown? ...)) fails. Weird. |
| 04:15 | andyfingerhut | tsdh: A guess: parse-opts+specs calls your new throw-on-varargs lazily, so it isn't being forced to evaluate until later than you would expect. |
| 04:15 | tsdh | andyfingerhut: Ah, that would make sense. So (doall (macroexpand ...)) should also work. |
| 04:16 | andyfingerhut | tsdh: Makes my head swim to try to imagine what is going on there. |
| 04:17 | tsdh | andyfingerhut: Indeed, (doall (macroexpand ...)) works. So it's really caused by lazyness. |
| 04:18 | andyfingerhut | tsdh: Crazy stuff |
| 04:19 | tsdh | andyfingerhut: Totally. :-) |
| 04:20 | andyfingerhut | tsdh: eval is used all over in the Clojure tests, so that seems preferable to me over macroexpand anyway, for this kind of test. |
| 04:22 | tsdh | andyfingerhut: I have no preference. |
| 04:39 | borkdude | why does this get indented like it is? https://www.refheap.com/20129 |
| 04:39 | borkdude | I mean, why don't the maps have an indenting of 2? |
| 04:39 | borkdude | clojure-mode 2.1.0 |
| 04:39 | ddellacosta | do I need to escape this somehow if I'm comparing (with = )? org.docx4j.wml.R$Tab |
| 04:40 | ddellacosta | borkdude: no idea, but presumably it's because you haven't close the s-expression? |
| 04:40 | ddellacosta | *closed |
| 04:41 | ddellacosta | although, I know different s-expressions tab differently. |
| 04:41 | borkdude | ddellacosta what do you mean, I didn't close it? |
| 04:42 | ddellacosta | borkdude: no, not saying you didn't close it, just that at the point the map is written the s-expression is not closed. But anyways, that's wrong since these things get applied differently for different functions, so never mind...haha. |
| 04:42 | ddellacosta | sorry I'm not helpful on this one. |
| 04:50 | borkdude | this is kind of not so nice, because I don't want to fix indentation by hand |
| 04:53 | llasram | borkdude: I'm pretty sure that's standard indentation |
| 04:57 | borkdude | hmm ok |
| 05:00 | clgv | borkdude: talking about CCW? |
| 05:00 | borkdude | clgv emacs / clojure-mode |
| 05:01 | clgv | ah ok, just guessed because of the recent release ;) |
| 05:02 | borkdude | then at least I'm not crazy. I think this makes sense https://www.refheap.com/20130 |
| 05:05 | clgv | borkdude: afaik the second is standard |
| 05:05 | borkdude | clgv seen from the code is data perspective it wouldn't make sense right, because why would you indent all but the non first elements of a list differently |
| 05:07 | clgv | borkdude: because in a list the first element is special as opposed to a vector where all have equal importance |
| 08:00 | clgv | does type hinting not imply interfaces and superclasses automatically? |
| 08:03 | llasram | clgv: It does |
| 08:03 | llasram | As in, the type implies all those things, and so does the type hint |
| 08:03 | clgv | weird in a separate function it works as expected but not in a deftype... |
| 08:04 | llasram | On deftype field or as part of a method signature? |
| 08:04 | clgv | on a deftype field |
| 08:05 | llasram | Hmm, odd. That should work fine. |
| 08:05 | clgv | it works for methods of the class, but not the ones of the super class |
| 08:05 | clgv | I manually hinted the subclass which did it but that is really strange |
| 08:06 | clgv | oh wait. I think I found the odd piece^^ |
| 08:06 | clgv | you'll always get punished if you write (protocol-method [this] ...) and you really do not need `this` instead I need the field ;) |
| 08:08 | clgv | should have used the checking macro for the type info |
| 09:44 | FragDoctor | Hey |
| 10:36 | ohcibi | hi, i have a task in clojure that wants me to generate all palindrome five-tupels like [0 1 2 1 0] [0 1 3 1 0] and so forth.. I have a solution that involves three nested map&range calls which looks kinda ugly to me.. I'm wondering if there is an easy way to generate all 5-tupels with numbers from 0-9 or a better way in general... any ideas? |
| 10:37 | justin_smith | what about generating all the three digit numbers first, and then converting each one into a five digit palindrome? |
| 10:38 | justin_smith | no need for nested anything |
| 10:39 | sszzqq | use lein test clojure code is slow. If have any more rapid way? |
| 10:40 | tbaldridge | sszzqq: tests are just functions, you can run them from the repl |
| 10:40 | tbaldridge | do (require '[my.namespace :reload true])) to reload namespaces after recompilation |
| 10:40 | justin_smith | you can require the namespace with the tests in it from a repl, then (clojure.test/run-tests) |
| 10:41 | tbaldridge | *reload namespaces after modification |
| 10:41 | sszzqq | I want save the edit the code in editor, repl have not syntax highlight.. |
| 10:41 | justin_smith | sszzqq: you can save in an editor, then (require '[] :reload) |
| 10:42 | justin_smith | no need to do any coding directly in the repl |
| 10:43 | sszzqq | justin_smith: what file-name should be use, then in repl: (require '[] :reload) couold load it and test it? |
| 10:44 | justin_smith | (require '[the.namespace.that.changed] :reload) |
| 10:44 | justin_smith | I don't know the name of the namespace, you need to fill that in |
| 10:44 | justin_smith | after editing, of course |
| 10:45 | sszzqq | justin_smith: thanks, i see it .. |
| 10:46 | justin_smith | ohcibi: |
| 10:47 | justin_smith | ,(take 5 (for [a (range 10) b (range 10) c (range 10)] [a b c b a])) |
| 10:47 | clojurebot | ([0 0 0 0 0] [0 0 1 0 0] [0 0 2 0 0] [0 0 3 0 0] [0 0 4 0 0]) |
| 10:47 | justin_smith | ,(take 5 (drop 400 (for [a (range 10) b (range 10) c (range 10)] [a b c b a]))) |
| 10:47 | clojurebot | ([4 0 0 0 4] [4 0 1 0 4] [4 0 2 0 4] [4 0 3 0 4] [4 0 4 0 4]) |
| 10:47 | logicprog | are there any plans to have cljs target asm.js ? that would be insane |
| 10:48 | justin_smith | logicprog: I don't know asm.js - is it really that likely to outperform the jvm? |
| 10:48 | dnolen | logicprog: no, we'll likely benefit from asm.js anyway |
| 10:49 | dnolen | logicprog: I don't see think any browser except FF will actually support the AOT part of it. |
| 10:49 | logicprog | dnolen how cam we benefit if we domt target it? |
| 10:50 | dnolen | logicprog: because engines are optimizing around asm.js benchmarks now |
| 10:50 | dnolen | logicprog: so if you write asm.js style code it will be fast |
| 10:51 | dnolen | logicprog: but as far as compiling CLJS to asm.js itself, I don't really see the benefit, at least yet. |
| 10:51 | logicprog | how does this help me if cljs does not emit asm.js? |
| 10:52 | ohcibi | justin_smith: thanks... |
| 10:52 | dnolen | logicprog: there's an incredible amount of bit twiddling and integer arithmetic in CLJS data structures, you'll benefit |
| 10:53 | justin_smith | ohcibi: now I notice you were only using 3 nestings, so really all I added was the for semantics to replace the nested maps |
| 10:54 | xsyn | just so I understand. Does clojurescript compile to js to then compile on the v8? |
| 10:54 | jtoy | how can I debug why when I run " lein trampoline run -m pusher.campaigns/run'" my program starts up and then quits immediately, but when I run "lein repl; (use 'pusher.campaingns);(run)" works |
| 10:54 | dnolen | logicprog: the other place that asm.js helps is memory usage, but not really of any use to us - we need GC |
| 10:54 | justin_smith | ohcibi: but yeah, that is what for is good for, replacing nested mappings |
| 10:54 | ohcibi | justin_smith: I assume what I did is just what most functional newbies would do 8-)) |
| 10:55 | ohcibi | justin_smith: this in combination with :when just blew my mind 8-)) (i forgot to add that a b c must (< a b c), but no problem with :when 8-)) thanks again |
| 10:55 | justin_smith | ohcibi: even coming from scheme and ocaml, I used nested map before I realized how much simpler for was |
| 10:55 | jtoy | im sure this is a simple fix, but I cant get it to work |
| 10:55 | justin_smith | ohcibi: no prob, glad I could help |
| 10:56 | justin_smith | jtoy: are you starting some thread or async action that somehow isn't being waited for? I thought the default was to wait for agents before exiting though |
| 10:57 | jtoy | justin_smith: no, I dont think i have any |
| 10:59 | justin_smith | jtoy: you could attach jdb to the dt-socket, if there is a way to pause and wait for the debugger inside your code |
| 11:00 | justin_smith | I have had luck when really weird bugs happen, connecting with jdb and seeing exactly what each thread was doing - I don't know if there is a way to "break" in the jvm and wait for a debugger attach off the top of my head, but it should be worth a google |
| 11:02 | jtoy | justin_smith: is there a clojrue way to do that? I have never programmed any java |
| 11:02 | justin_smith | another option: modify your code so that it first reads a line from stdin, then does the rest. then connect with jdb before providing that line |
| 11:02 | justin_smith | jdb is language agnostic |
| 11:03 | justin_smith | it provides an interface to the jvm, like gdb does to raw bytes |
| 11:03 | justin_smith | so you just need to be able to translate from the jvm names of yoru functions / bindings to their actual names |
| 11:05 | justin_smith | so (fn -main [& args] (read-line) ...) - run it, before entering a line of input, connect to the dt-thread with jdb or jvisualvm |
| 11:06 | jtoy | justin_smith: ok thanks, im goign to test it |
| 11:06 | justin_smith | jvisualvm may not be able to set breakpoints or step through code, but it gives a graphic overview of threads etc. |
| 11:07 | justin_smith | on further thought, it may be easier to turn on all profiling in jvisualvm while the app is waiting for input, then provide the input then analyze the profiling data of what happened |
| 11:07 | justin_smith | jvisualvm comes with java |
| 11:21 | edw | Anyone else get "pp does not exist" exceptions when firing up nREPL in Emacs? <https://gist.github.com/edw/7138535> |
| 11:22 | edw | (Using most recent CIDER, but it's been going on sporadically for the last month or so.) |
| 11:22 | ndp | Yeah, I do occasionally |
| 11:22 | ndp | Never made sense to me, I don't require pp in any Lein profiles |
| 11:23 | edw | ndp: Yeah, it's occasional for me too; I've never been able to figure out under what circumstances it does (or doesn't) happen. |
| 11:24 | mdrogalis | Cider.. Huh, is nrepl not a thing anymore? |
| 11:24 | justin_smith | I think cider extends nrepl, trying to be an all around "emacs ide" thing |
| 11:25 | rkneufeld | nrepl.el has become "cider" |
| 11:25 | justin_smith | oh! |
| 11:25 | mdrogalis | Well, I'm late to the party. |
| 11:25 | llasram | I think the name is mostly that people were confusing nREPL and nrepl.el |
| 11:25 | llasram | so nrepl.el -> cider |
| 11:25 | mdrogalis | llasram: I see, thanks. :) |
| 11:26 | edw | In general, I think it's a good idea to give the thing that talks to nREPL qua protocol a different name from its implementation. And we want something that tastes better than SLIME. |
| 11:26 | llasram | nice |
| 11:26 | mdrogalis | edw: Kind of the same problem with the Java platform and Java language having the same name. |
| 11:26 | justin_smith | slime always made me think of nethack, eating slime molds |
| 11:27 | justin_smith | also, slime is what first brought me to emacs over a decade ago, so it was kind of sad moving away from slime with clojure |
| 11:27 | edw | mdrogalis: This "the thing is broader than its single, definitive implementation" idea is relatively new to many languages. |
| 11:28 | justin_smith | edw: you would think lisps would know better :) |
| 11:28 | edw | justin_smith: Using SLIME to talk to Scheme48 felt like being in an abusive relationship; I'm happy to have moved on. |
| 11:28 | edw | justin_smith: Implementations for everyone! |
| 11:28 | justin_smith | heh, it worked nicely with cmucl / sbcl |
| 11:29 | justin_smith | and it was not even comparable to using vi (at the time vim could not even have a process inside a buffer - I had to switch to nvi for that, but nvi did it so badly I had to swollow the lump and learn emacs) |
| 11:30 | justin_smith | in the future, every language will be like linux, with thousands of cosmetically different "distros" |
| 11:30 | xsyn | gawd |
| 11:30 | xsyn | that sounds horrific |
| 11:31 | justin_smith | try, the new snowjure, just like clojure, but let is renamed to ☃ |
| 11:31 | justin_smith | and defn is renamed to ❄ |
| 11:32 | pjstadig | justin_smith: i'm in! |
| 11:33 | justin_smith | the sweet thing, is you can bootstrap it from an existing clojure in two lines of code :) |
| 11:33 | justin_smith | well maybe more now that I think about it... |
| 11:34 | TimMc | (defmacro ☃ [& stuff] `(let ~@stuff)) |
| 11:35 | justin_smith | heh |
| 11:35 | justin_smith | well, the trick is putting it in clojure.core so it gets pulled in by the default refer-clojure |
| 11:35 | pjstadig | justin_smith: https://github.com/sybilant/sybilant/blob/old-master5/sybilant/test/munging.syb#L4 |
| 11:36 | justin_smith | so I think you need more than two lines |
| 11:36 | justin_smith | pjstadig: nice |
| 11:37 | justin_smith | pjstadig: sybilant looks interesting, how mature is it? |
| 11:37 | pjstadig | justin_smith: not really, still very much a work in progress |
| 11:37 | justin_smith | good enough to be a less painful way to play with x86 assembly? |
| 11:37 | pjstadig | a long term project |
| 11:37 | pjstadig | justin_smith: no such thing |
| 11:38 | justin_smith | heh |
| 11:38 | justin_smith | you mean x86 assembly is the least painful thing of all things? I am dubious |
| 11:39 | pjstadig | i want to create a language that can bootstrap itself without having to use another lower level language, one someone *cough* could write an OS in, one you could drop in assembly blocks for performance or whatever |
| 11:39 | pjstadig | i'm the most unlikely person to create such a language |
| 11:40 | justin_smith | heh |
| 11:40 | pjstadig | but typed assembly is interesting, and sybilant will have it |
| 11:40 | justin_smith | even just a good enough binding of assembler to a lispy syntax is interesting to me |
| 11:40 | pjstadig | something like this https://github.com/sybilant/sybilant/blob/old-master5/sybilant/test/types.syb |
| 11:40 | justin_smith | I remember reading about c-- ages ago, and found that very fascinating |
| 11:40 | justin_smith | c-- grew into msft clr |
| 11:41 | cmajor7 | what would be a better collector for a netty based app that accepts many connection on a multicore server to strive for a consistent response times? -XX:+UseConcMarkSweepGC or ‑XX:+UseParallelOldGC (maybe G1, but it is Java 6 not the latest build…)? |
| 11:45 | sluukkonen | start with paralleloldgc |
| 11:45 | hyPiRion | cmajor7: hard to tell in general. The best is to try them out, really. |
| 11:45 | sluukkonen | explore other options if you experience full GC's with it |
| 11:46 | ystael | I'm having a problem with ztellman/byte-streams where it does not seem to load any of the conversions |
| 11:47 | ystael | After I (require '[byte-streams :as bs]) in a lein repl, (bs/possible-conversions String) evaluates to nil |
| 11:47 | ystael | Anyone know a possible cause for this issue? |
| 11:47 | justin_smith | if ram is not an issue, nginx in front load balancing multiple instances (even on the same host, each using its own port) will help keep response times low |
| 11:47 | cmajor7 | hyPiRion, sluukkonen: leaning towards -XX:+UseParallelOldGC, but contemplating, since -XX:+UseConcMarkSweepGC might provide a better response time, but will eat more CPU/RAM and will have fragmentation… hence might bring the overall throughput down.. |
| 11:47 | justin_smith | unless the app is stateful |
| 11:48 | ngw | how do you manage configuration in a compojure web app? |
| 11:49 | jtoy | justin_smith: I fied it by changing for to doseq, why would that fix it? |
| 11:49 | justin_smith | ngw: at my shop (doing brochureware web sites) we have resources/config/<environment>.clj |
| 11:49 | hyPiRion | cmajor7: What do you value the most? Obviously stop-the-world will make response times more varying, but will give a better average |
| 11:49 | justin_smith | jtoy: for is lazy, nothing was consuming it so it realized nothing |
| 11:49 | justin_smith | on a repl it gets consumed by the print part of the loop |
| 11:50 | ngw | justin_smith: and you use normal clojure data types? |
| 11:50 | justin_smith | ngw: yeah, it is a standard clojure edn file |
| 11:50 | justin_smith | we do a deep merge with a "defaults" provided by one of our libs |
| 11:50 | sluukkonen | cmajor7: cms, g1 et al. have more minor gc overhead than paralleloldgc, so if parallelold can keep up with the load (i.e. you don't experience full gcs with it), it's generally the best choice |
| 11:51 | sluukkonen | you'll likely achieve the best throughput and latency in that case |
| 11:51 | justin_smith | ngw: also, we have been experimenting with also having a secret.clj.aes128 so we don't have the credentials for our config naked in the repo |
| 11:51 | justin_smith | for obvious reasons |
| 11:52 | justin_smith | otherwise github may just be our weakest security link |
| 11:53 | logic_prog | what is a godo resource on "recursion = low level, use higher level abstractions" |
| 11:54 | cmajor7 | sluukkonen: yep, that is my thinking as well. thank you. |
| 11:55 | xuser | is it usual to see the Java collections framework being used in Clojure? |
| 11:58 | justin_smith | xuser: only when you care more about performance than sanity |
| 11:58 | justin_smith | less glibly, sometimes it is nice to have something like a dag lib that is mature and featureful in java |
| 11:59 | justin_smith | https://github.com/aysylu/loom for example, has good reason to use java data types |
| 12:02 | silasdavis | better way to remove first char in string than: (comp (partial apply str) rest) ? |
| 12:02 | hyPiRion | ,(subs "foo" 1) |
| 12:02 | clojurebot | "oo" |
| 12:02 | justin_smith | yeah, that is probably best |
| 12:02 | justin_smith | forcing strings to chars kills performance |
| 12:03 | silasdavis | thanks for that |
| 12:05 | justin_smith | logicprog: http://blog.fogus.me/2011/03/09/recursion-is-a-low-level-operation/ |
| 12:07 | justin_smith | logicprog: hmm - actually that asserts the case, but doesn't really give full exposition :( |
| 12:07 | silasdavis | is there a nicer way to check if a string is a URI other than trying to create one and catching the execption? |
| 12:08 | justin_smith | silasdavis: for URL http://commons.apache.org/proper/commons-validator/apidocs/org/apache/commons/validator/UrlValidator.html |
| 12:09 | justin_smith | I dunno about more general URI |
| 12:14 | justin_smith | silasdavis: |
| 12:14 | justin_smith | ,(do (time (dotimes [i 10000] (try (assert false) (catch AssertionError e nil)))) (time (dotimes [i 10000] (if false true)))) |
| 12:14 | clojurebot | justin_smith: No entiendo |
| 12:14 | justin_smith | err |
| 12:15 | justin_smith | anyway, if you run that code, you will see how much slower catching an exception is than checking a boolean |
| 12:15 | justin_smith | if the performance matters at all |
| 12:15 | xuser | justin_smith: thanks |
| 12:18 | silasdavis | that and that it's ugly |
| 12:19 | justin_smith | yeah, there's that too |
| 12:19 | justin_smith | one of those problems you can fix with a macro, the other not so much :) |
| 12:19 | silasdavis | if I registered a custom URLStreamHandler |
| 12:19 | silasdavis | would clojure's slurp use it to read the URL |
| 12:19 | silasdavis | ? |
| 12:20 | silasdavis | thinking about doing this for s3 |
| 12:20 | silasdavis | not clear to me from the source of slurp whether it would work |
| 12:20 | silasdavis | suspect not |
| 12:20 | llasram | It would |
| 12:20 | llasram | It would work |
| 12:21 | silasdavis | ah cool |
| 12:22 | silasdavis | I'll take that approach then, how does make-reader do that? |
| 12:24 | llasram | It just opens a reader on the result of calling the URL's openStream() method |
| 12:25 | xuser | justin_smith: I'll skip this http://docs.oracle.com/javase/tutorial/collections/index.html for now then to finally start getting into Clojure ;) |
| 12:26 | justin_smith | silasdavis: I have a fork of weavejester's s3 lib, specifically so I could upload streams |
| 12:26 | justin_smith | specifically I want to resize an image that comes from a remote host, and store the resize on s3, and not store it on disk in between - so I don't know the size of the output, and don't have a file to read from |
| 12:27 | justin_smith | if generalized stream upload to s3 helps you I can link the change, it is a small patch |
| 12:27 | silasdavis | justin_smith: did you write your own URLStreamHandler? |
| 12:29 | justin_smith | no, I just grabbed the outputstream from the java.net.URL, then feed that into an image resize (bufferedimage), then turn that buffer into a stream and feed that to the s3 upload |
| 12:30 | justin_smith | but most of that I did in my own resizer lib, the only change that required in the clj-aws-s3 lib was a multi-part upload that does not come from disk (multi part because that is the only kind of upload of indeterminate size s3 is ok with) |
| 12:30 | justin_smith | clj-aws-s3 took for granted that a multi-part upload would come from disk |
| 12:31 | justin_smith | I have no idea if any of this is relevant for what you need from your URLStreamHandler though |
| 12:31 | justin_smith | what are you trying to do? |
| 12:31 | staafl | any way to splat a macro? |
| 12:31 | staafl | (apply and '(true true)) gives me an error |
| 12:31 | llasram | staafl: none that are what you likely actually want |
| 12:32 | staafl | llasram, what's a sane solution? |
| 12:32 | llasram | staafl: What are you trying to do? |
| 12:32 | staafl | llasram, aggregate boolean values |
| 12:32 | llasram | Well, you know, at a higher semantic level :-) |
| 12:32 | llasram | Ok, |
| 12:32 | justin_smith | (defmacro andl [& args] `(and ~@args)) ? |
| 12:32 | justin_smith | err |
| 12:33 | llasram | heh |
| 12:33 | justin_smith | (defmacro andl [lst] `(and ~@lst)) ? |
| 12:33 | justin_smith | that may be what you want, but that is not much different from every? |
| 12:33 | silasdavis | justin_smith: I can't get URL to accept the s3 protocol |
| 12:33 | znDuff | Heh. |
| 12:33 | silasdavis | get MalformedURLException unknown protocol: s3 |
| 12:33 | staafl | CompilerException java.lang.RuntimeException: Unable to resolve symbol: quote in this context, |
| 12:34 | llasram | ,(reduce (fn [_ x] (if x true (reduced false))) true [true true true true true]) |
| 12:34 | clojurebot | true |
| 12:34 | llasram | ,(reduce (fn [_ x] (if x true (reduced false))) true [true false true true true]) |
| 12:34 | clojurebot | false |
| 12:34 | llasram | staafl: ^^ I think that's what you want for `and` |
| 12:34 | justin_smith | silasdavis: ahh, going the other way - we are converting s3 via rgex into protocol-relative links (http or https) |
| 12:34 | justin_smith | *regex |
| 12:34 | llasram | You can turn it into a function, for prettiness |
| 12:35 | staafl | llasram, "reduced" |
| 12:35 | staafl | does that short circuit the reduce? |
| 12:35 | justin_smith | llasram: (partial every? identity) |
| 12:35 | silasdavis | anyone know how to register a custom URLStreamHandler by any chance? |
| 12:35 | llasram | staafl: Yep |
| 12:36 | llasram | justin_smith: Ok yeah, that is shorter :-) |
| 12:36 | staafl | llasram, thanks |
| 12:36 | llasram | I just have reducers on the brain right now |
| 12:36 | staafl | justin_smith, thanks to you too |
| 12:36 | staafl | actually, I think I'll use (every? identity lst) |
| 12:36 | xuser | znDuff: you have a list? |
| 12:36 | llasram | For the best |
| 12:37 | justin_smith | daily mail is a big one, also soundcloud |
| 12:38 | justin_smith | there should be a list, if there isn't |
| 12:38 | justin_smith | (re: bit sites running clojure) |
| 12:39 | mavbozo | hi, is there any way to delete html tag in enlive deftemplate? |
| 12:52 | technomancy | there's one on the dev.clojure.org wiki, but you can't edit it |
| 12:59 | justin_smith | technomancy: http://dev.clojure.org/display/community/Clojure+Success+Stories ? |
| 13:00 | hyPiRion | heh, last edited 10 months ago |
| 13:00 | justin_smith | yeah, and the two biggest examples I know of in terms of degree of usage aren't even on that list |
| 13:01 | technomancy | that's the magic of wikis that you can't edit |
| 13:01 | justin_smith | also, needs a "how and how much" column |
| 13:01 | technomancy | ever wonder what were the biggest clojure companies in 2011? now you can know. |
| 13:03 | hyPiRion | heh |
| 13:04 | gfredericks | I do not understand vars |
| 13:06 | gfredericks | what is going on here? https://www.refheap.com/20137 |
| 13:07 | justin_smith | gfredericks: weird, I got :thread-bound |
| 13:07 | justin_smith | which is what you expected, right? |
| 13:09 | hyPiRion | I got :origin-root but hm |
| 13:11 | hyPiRion | gfredericks: I think you're creating a var containing a var |
| 13:11 | hyPiRion | Works fine with let. |
| 13:13 | justin_smith | yeah, when you def something to be a var, that creates a var var right? |
| 13:13 | justin_smith | which is why the @? |
| 13:14 | justin_smith | so why do you guys get :origin-root and my repl gives me :thread-bound? |
| 13:14 | justin_smith | *clojure-version* => {:major 1, :minor 5, :incremental 1, :qualifier nil} |
| 13:15 | hyPiRion | same here |
| 13:18 | justin_smith | so this needs push-thread-bindings because binding would just grab the symbol, and not the var pointed at by the symbol, right? |
| 13:29 | hyPiRion | yeah, but I would guess the metadata fell off the var for some reason |
| 13:32 | si14 | cemerick: hi. can I ask you a question about Friend? |
| 13:33 | cemerick | si14: shoot |
| 13:36 | si14 | cemerick: how can I perform some actions (logging auth to database, for example) after authorization by friend-oauth2? I need to do this only when user is logging in and not every time user's authorization is checked. Can't fully wrap my head around docs on this, so asking you directly :) |
| 13:37 | broquaint | I've just installed cider from MELPA and when I boot the REPL (with cider-jack-in or an existing lein repl) I get the emacs version and nothing else (e.g no prompt) - https://www.refheap.com/20138 |
| 13:37 | broquaint | Is that situation familiar to anyone? |
| 13:38 | technomancy | broquaint: melpa serves unstable packages by design; I highly recommend sticking with marmalade |
| 13:38 | cemerick | si14: sounds like you actually want to write your own workflow, that does whatever logging you want, and delegates all the actual authentication to friend-oauth2 |
| 13:39 | broquaint | Thanks, technomancy, but AFAICT cider isn't on marmalade ATM, in fact I'm only using MELPA because that's I saw it was available there :) |
| 13:39 | technomancy | broquaint: I recommend using nrepl.el until cider stabilizes |
| 13:39 | coventry | broquaint: Why do you want to use cider? |
| 13:39 | broquaint | i.e http://marmalade-repo.org/packages/cider - Package "cider" doesn't exist |
| 13:40 | broquaint | coventry: Because I liked nrepl and prefer my REPLs in emacs. |
| 13:40 | broquaint | technomancy: Thanks I'll switch back to nrepl in the mean time :) |
| 13:40 | coventry | broquaint: Take technomancy's advice, then. |
| 13:40 | broquaint | Indeed :) |
| 13:40 | znDuff | (ie. "back to nrepl", vs "back to nrepl.el"). |
| 13:40 | technomancy | we get people with broken melpa packages in here practically every other day =\ |
| 13:41 | si14 | cemerick: ok, thank you. What's the best doc on this? Friend's README/source code? :) |
| 13:41 | technomancy | the fact that nrepl.el was deleted from melpa is just; ugh |
| 13:42 | technomancy | I guess melpa users are just accustomed to dealing with random breakage |
| 13:43 | cemerick | si14: friend's readme is pretty comprehensive re: the responsibilities of workflow fns. There's no examples of what I just described that I'm aware of, but it's roughly just function composition. |
| 13:43 | cemerick | There's http://friend-demo.herokuapp.com, but that covers more basic matters than e.g. logging particular workflow requests |
| 13:48 | broquaint | Hrm ... same problem with nrepl 0.2.0. |
| 13:48 | broquaint | nrepl.el |
| 13:51 | si14 | *(without /me) |
| 13:51 | cemerick | si14: np, FWIW :-) |
| 14:07 | tsdh | How can I stop java.lang classes being imported in a namespace so that that namespace may define a var Package for example. |
| 14:09 | tsdh | I.e., something like (:refer-clojure :only []) for classes. |
| 14:09 | mtp | pick better names? :) |
| 14:09 | tsdh | mtp: The namespace is generated from some model. |
| 14:10 | mtp | generate better names? |
| 14:10 | mtp | :p |
| 14:12 | tsdh | If the model defines a Package, then there is no better name than that. Adding articifial prefixes like +$+fuddle+$+ is not what I want. |
| 14:12 | tsdh | Hm, if there was a way to enumerate all java.lang classes, I could `ns-unmap` these symbols... |
| 14:15 | arrdem | oh right. great. there goes the nrepl.el package. again. |
| 14:18 | tsdh | Ah, got it. I can iterate over `ns-imports' and `ns-unmap' the syms. |
| 14:28 | rasmusto | why not "clide" |
| 14:28 | technomancy | why not... nrepl-dot-el.el |
| 14:29 | rasmusto | i pronounce it en-prep-uhl-ehl |
| 14:29 | technomancy | man, the one time I go and pick a boring name for a project and it's not good enough |
| 14:29 | rasmusto | should have gone with nrepel |
| 14:29 | cemerick | technomancy: see, shouldn't slack off so hard :-P |
| 14:29 | technomancy | not bad |
| 14:30 | hiredman | enrepal-dot-ee-el.el |
| 14:30 | technomancy | hiredman: unacceptable; that filename is not representable on DOS filesystems |
| 14:31 | rasmusto | nrelpael |
| 14:31 | technomancy | (this is an actual thing real humans say unironically on emacs-devel) |
| 14:31 | technomancy | well, one specific human |
| 14:32 | johann | hi everyone--im trying to deploy a clojure/clojurescript app to heroku and am running into the error R10 issue. i'm pretty new to clojure so i dont really understand how to manage the error |
| 14:32 | technomancy | you think having to deal with com.defunctstartup package names are bad, try dealing with 8.3 filenames |
| 14:32 | cemerick | that's a good domain name! |
| 14:32 | technomancy | johann: are you doing full AOT during push? |
| 14:34 | johann | technomancy: i do not think so. when i check the heroku logs i see that its still trying to grab jars before it times out and crashes and repeats |
| 14:35 | technomancy | johann: highly recommend generating an uberjar at push time |
| 14:35 | technomancy | https://devcenter.heroku.com/articles/getting-started-with-clojure |
| 14:37 | arrdem | gfredericks: your swearjure presentation was glorious. |
| 14:38 | johann | technomancy: i was having issue using an uberjar earlier. i will read through this carefully and try again! thank you :) |
| 14:39 | technomancy | johann: there's a lot more that can go wrong when using lein at runtime; uberjars are a lot simpler |
| 14:41 | johann | gotcha. let me see what arises |
| 14:41 | seangrove | technomancy: uberjar + AOT? |
| 14:41 | technomancy | seangrove: yup |
| 14:41 | johann | technomancy: does it make a difference that im using httpkit? |
| 14:41 | technomancy | johann: no |
| 14:42 | technomancy | seangrove: your doppleganger is screwing with your tab completion |
| 14:42 | technomancy | or rather, everynoe else's tab completion |
| 14:42 | dnolen | Bronsa: let me know when 0.7.10 goes out |
| 14:45 | hyPiRion | http://www.infoq.com/presentations/swearjure :D |
| 14:46 | johann | technomancy: im getting the following error when i try to push it up to heroku https://gist.github.com/anonymous/0f341d99dd3b9ee18cb0 |
| 14:47 | hyPiRion | (inc gfredericks) |
| 14:47 | lazybot | ⇒ 31 |
| 14:48 | Bronsa | dnolen: I wanted to wait for TLDR-9 to get closed, but since it's unlikely that it will be completed by the end of the week I'm probably going to release 0.7.10 today |
| 14:49 | dnolen | Bronsa: if you want to hold it up for that no big deal |
| 14:49 | technomancy | johann: just `lein uberjar` |
| 14:49 | dnolen | Bronsa: there's a few other things I'd like to get into CLJS before the next release as well |
| 14:50 | arrdem | hyPiRion: I almost lost it at "swearjure in production" |
| 14:50 | johann | technomancy: after that i assumed that i have to set the :uberjar-name property in the project.clj right? |
| 14:50 | technomancy | johann: maybe you should start at the top. =) :uberjar-name in project.clj should be enough on its own. |
| 14:51 | Bronsa | dnolen: I think I'm going to release it anyway -- I have a small breaking change I'm going to make once that ticket gets closed and I want to release a 0.8.0 for that |
| 14:51 | hyPiRion | arrdem: yeah, I love it |
| 14:51 | arrdem | hyPiRion: what part did you play in this madness? |
| 14:52 | hyPiRion | ~quicksort |
| 14:52 | clojurebot | quicksort is https://www.refheap.com/paste/284a0552a6b69c6037faa2db5 |
| 14:52 | hyPiRion | and hello swearjure, of course |
| 14:52 | hyPiRion | $google hello swearjure |
| 14:52 | lazybot | [hyPiRion/hello-swearjure · GitHub] https://github.com/hyPiRion/hello-swearjure |
| 14:53 | technomancy | I wonder if swearjure is limited enough for genetic algorithms to operate on it sensibly |
| 14:54 | dnolen | Bronsa: k |
| 14:54 | arrdem | I would doubt it... limited it may be but the trivial operations are so convoluted that despite having very few primitives I think it would be hard. |
| 14:54 | Bronsa | dnolen: FYI not sure if it's something that cljs error messages could benefit from, but the patch aredington is working on adds the source form as metadata where it can,e.g #() -> ^{:source "#()"} (fn* ([])) |
| 14:55 | technomancy | whoa bronsa is into swearjure too? |
| 14:55 | technomancy | =) |
| 14:55 | hyPiRion | technomancy: yeah, he's secretly making an analyzer for it |
| 14:56 | coventry | What the heck is going on with ##(#('%& '%& '%&)) ? |
| 14:56 | lazybot | ⇒ rest__28561# |
| 14:57 | arrdem | coventry: it's a gensym. somehow. |
| 14:57 | Bronsa | hyPiRion: ssssh don't tell them |
| 14:57 | dnolen | Bronsa: hm, that seems useful - not sure where we'd use that in the compiler, but it does seems neat for user macros? |
| 14:57 | coventry | arrdem: Yeah, I meant how is that producing the gensym? |
| 14:57 | technomancy | hyPiRion: do swearjure programs typically depend on the order of compilation via actual gensym values? |
| 14:57 | dnolen | Bronsa: what was the use case aredington had in mind? |
| 14:58 | bitemyapp | You people will use Swearjure but Haskell is a bridge too far? Weirdos. |
| 14:58 | arrdem | (inc bitemyapp) |
| 14:58 | lazybot | ⇒ 5 |
| 14:58 | gfredericks | what my swearjure presentation is online? |
| 14:58 | mdrogalis | Watching the Swearjure talk. Pretty funny. :) |
| 14:58 | Bronsa | dnolen: he said he's working on a static analyzer, I think he needs to map back to the original clojure source |
| 14:58 | coventry | bitemyapp: I've been reading John Hughes lately. He makes an interesting case for monads. |
| 14:58 | hyPiRion | technomancy: no, not generally. My quicksort used one to check if I was at the end of a list |
| 14:59 | hyPiRion | But I don't think it's common practice. I've used few in production at least. |
| 14:59 | dnolen | Bronsa: interesting, though it seems a bit strange to want to do that at the level of forms? |
| 14:59 | seangrove | (inc gfredericks) ; good fun! |
| 14:59 | lazybot | ⇒ 32 |
| 14:59 | Bronsa | coventry: ##'#(%&) |
| 14:59 | lazybot | ⇒ (fn* [& rest__28573#] (rest__28573#)) |
| 14:59 | bitemyapp | coventry: I don't think the case needs to be made in general, but rather a way to make them more accessible/nicer in a dynamically typed lang. |
| 15:00 | hyPiRion | ,'#('%& '%& '%&) |
| 15:00 | clojurebot | (fn* [& rest__29#] ((quote rest__29#) (quote rest__29#) (quote rest__29#))) |
| 15:00 | bitemyapp | coventry: part of what makes Monads nice in Haskell is they get enforced by the type system, with the compiler smacking you in the nose and calling you a bad kitty when you try to reach into an IO () |
| 15:00 | bitemyapp | coventry: maintaining the useful "boxing" of monadic results in a dyn-lang is a matter of discipline rather than tooling at the moment. |
| 15:00 | hyPiRion | Reads as: Call the symbol on the same symbol, and return the symbol if the symbol doesn't contain the symbol. |
| 15:01 | technomancy | hyPiRion: I'd expect that to need `%& though |
| 15:01 | coventry | hyPiRion, Bronsa: Oh, it was the default argument part I was missing. Thanks. |
| 15:02 | coventry | bitemyapp: Yeah, I can see how that would be a problem. |
| 15:02 | hyPiRion | technomancy: heh, to avoid naming collisions? |
| 15:03 | bitemyapp | coventry: it gets worse when you start getting into things like Monad Transformers. |
| 15:03 | bitemyapp | coventry: keeping the monad stack in your head and figuring when to lift and when to send a functor through would be insane |
| 15:03 | technomancy | hyPiRion: oh, it's expanded by the #() reader macro; I see now |
| 15:03 | bitemyapp | I'm way too fucking lazy for that. I'd rather the compiler tell me I'm stupid. |
| 15:03 | technomancy | I was confused because plain '%& doesn't expand |
| 15:03 | Bronsa | dnolen: not sure I get what you mean, his approach looks like the only sane way to go source -> read form -> source without using a parser instead of the reader |
| 15:04 | hyPiRion | technomancy: ah, yeah. It has to be done inside a function literal |
| 15:05 | dnolen | Bronsa: sorry was busy w/ something else and didn't read closely, yes that makes sense. |
| 15:05 | coventry | Interesting that the function literal process gets a crack at them before their quoted. |
| 15:06 | TimMc | coventry: It doesn't, though. |
| 15:06 | arrdem | bitemyapp: and does it do so often? |
| 15:06 | Bronsa | coventry: quoting happens after read-time |
| 15:07 | TimMc | What? Quoting is part of reading. |
| 15:07 | bitemyapp | arrdem: of course - I'm stupid and the compiler is never wrong. |
| 15:07 | Bronsa | TimMc: no, 'foo -> (quote foo) is part of reading |
| 15:07 | bitemyapp | arrdem: I find GHC very very helpful when I'm writing Haskell code - especially in unfamiliar territory. |
| 15:08 | TimMc | gfredericks: It's weird to hear someone I've never met in person speak my name in a video. :-D |
| 15:08 | Bronsa | TimMc: what I'm trying to say is that the reader would have no way of knowing that "%&" #('%&) should stay that way instead of being gensym'd -- it is not aware of the quoting |
| 15:09 | technomancy | bitemyapp: offloading some of the cognitive ovehread to your exocortex, as it were |
| 15:09 | bitemyapp | technomancy: that's precisely it. |
| 15:09 | arrdem | clojurebot: GHC is an exocortex |
| 15:09 | clojurebot | Ok. |
| 15:10 | technomancy | "Computer, it's late. Tell me if this makes any sense." |
| 15:10 | bitemyapp | arrdem: good call. |
| 15:10 | gfredericks | TimMc: I just put your face on infoq |
| 15:10 | bitemyapp | technomancy: since I didn't have the experience of writing grench, how good of a job did OCaml do of catching you? |
| 15:11 | technomancy | bitemyapp: it was extremely helpful |
| 15:11 | technomancy | bitemyapp: I thought that OCaml wouldn't be as good at separating side-effects because it doesn't have the IO monad |
| 15:11 | gfredericks | hyPiRion: okay so did anybody figure out this var thing? I don't understandy your var within a var comment. I know I'm _doing_ that, but I can't see how it should affect the outcome |
| 15:11 | technomancy | turns out returning unit gets you 80% of the way there |
| 15:11 | technomancy | or 80% of where I imagine "there" to be, having never been there myself |
| 15:11 | hyPiRion | gfredericks: no. All I know is that it works inside a let. |
| 15:12 | bitemyapp | technomancy: possibly. the IO Monad as a free-standing "feature" doesn't do a lot, just forces bind out of IO like any other monad. |
| 15:12 | gfredericks | hyPiRion: as in (let [x @v] ...)? |
| 15:13 | bitemyapp | technomancy: the more useful bits are that this works well for all monads in all computation and it can enforce arbitrarily deep stacks of monads if you need the type system to enforce some declarative model of computation for you. |
| 15:13 | hyPiRion | gfredericks: as in (let [v (doto (clojure.lang.Var/create ...))] ...) |
| 15:13 | bitemyapp | technomancy: in practice, simple code in Haskell ends up being similar to simple code in OCaml. it's at the hairy edges where they diverge. |
| 15:13 | technomancy | clojurebot: typed clojure is http://p.hagelb.org/typed-clojure.jpg |
| 15:13 | clojurebot | You don't have to tell me twice. |
| 15:14 | bitemyapp | technomancy: I like the Hotel California in the background. That's where they trap the bugs so they can never leave. |
| 15:14 | technomancy | bitemyapp: there was one place where I wanted to use Option monadically and I would have had to pull in a 3rd-party lib |
| 15:15 | technomancy | but the manual equivalent of map in that case wasn't bad at all; it was more of a "oh, I guess that's what map is for" moment |
| 15:15 | marcopolo2 | technomancy: hovercars and punchcards, that an interesting view of the future |
| 15:16 | bitemyapp | technomancy: that and the lack of "real" concurrency are why I use Haskell. I don't know that concurrency in Haskell would be very much fun if the monads weren't there to enforce barriers. |
| 15:16 | bitemyapp | the features play off each other nicely. |
| 15:16 | bitemyapp | the STM containers in Haskell aren't nearly as "clean" or uniform as Clojure though. |
| 15:16 | dnolen | cemerick: (or anyone else) any thoughts about CLJS warnings?, I was considering changing it so that the only options is enable/suppress :all, or enable/suppress :undeclared. |
| 15:16 | seangrove | ~typed clojure |
| 15:16 | clojurebot | typed clojure is http://p.hagelb.org/typed-clojure.jpg |
| 15:16 | technomancy | bitemyapp: yeah, I wouldn't use OCaml for somewhere concurrency mattered |
| 15:17 | marcopolo2 | dnolen: what about wrong arg count? |
| 15:17 | gfredericks | hyPiRion: oh I see; hmm |
| 15:18 | cemerick | dnolen: Seems like differing use cases really do want/need fine-grained control |
| 15:18 | dnolen | marcopolo2: this is just getting rid of useless knobs - there won't be less warnings |
| 15:18 | gfredericks | hyPiRion: that's super bizarre and I can't explain it. but having it as a local is what I need anyways so I guess I'll just go ahead with it |
| 15:18 | TimMc | gfredericks: That was a good talk! :-D |
| 15:18 | marcopolo2 | dnolen: ok |
| 15:18 | dnolen | cemerick: ok sure, I'm also fine to leave it as is. Just wasn't obvious to me that anybody actually used these knobs. |
| 15:19 | hyPiRion | gfredericks: Can't explain it either :x. I'd guess it inlines the var reference inside the let for some reason? |
| 15:19 | bitemyapp | technomancy: also strange is Clojure's lack of retry. |
| 15:19 | bitemyapp | no orElse either. |
| 15:20 | cemerick | dnolen: I don't think anyone does, yet. I definitely want to make it so that you can configure cljsbuild to fail on certain warnings. |
| 15:20 | seangrove | dnolen: What knobs currently exist? |
| 15:20 | gfredericks | TimMc: phew |
| 15:20 | TimMc | I like all the nervous laughter in the audience. |
| 15:21 | TimMc | At least one person is thinking "Should I be taking notes? Oh no, what if my code isn't swearjure-compatible!" |
| 15:21 | technomancy | hahaha |
| 15:21 | arrdem | more than one person is pondering how many pages would need to be allocated to the JVM's stack in order to run the leiningen build of swearjure... |
| 15:21 | gfredericks | technomancy's tweet afterwards was the best comment that has ever been made about anything I've done |
| 15:22 | technomancy | I don't even remember |
| 15:22 | dnolen | seangrove: :undeclared, :redef, :dynamic, :fn-var, :fn-arity, :fn-deprecated, :protocol-deprecated |
| 15:22 | TimMc | 50 years from now, engineers will stand by the water cooler and complain about the swearjure-implemented financial software they have to maintain. |
| 15:23 | gfredericks | technomancy: you said it was "surprisingly G-rated", which is a reaction I've been trying to duplicate ever since |
| 15:23 | TimMc | haha nice |
| 15:23 | technomancy | oh right; hehe |
| 15:23 | seangrove | dnolen: Thanks, would love to have cljsbuild fail on some of these |
| 15:23 | seangrove | cemerick: I haven't worked on cljsbuild at all, would it be a breaking change, or something that could be in a point release? |
| 15:24 | TimMc | gfredericks: Speak to me of this var within a var; it sounds naughty and I am intrigued. |
| 15:24 | dnolen | seangrove: yes this has come up before, a way to pass a handler into the compiler so that build tools can dictate what happens when errors are encountered. |
| 15:25 | gfredericks | TimMc: https://www.refheap.com/20137 |
| 15:25 | gfredericks | I'm just trying to get a thread-localable reference type |
| 15:25 | gfredericks | that works correctly with bound-fn and friends |
| 15:25 | gfredericks | but without being interned in a namespace |
| 15:25 | seangrove | dnolen: I could work on that sometime next week |
| 15:26 | seangrove | Any existing design doc? |
| 15:26 | stuartsierra | gfredericks: Not sure exactly what you're trying to do, but maybe with-local-vars would help. |
| 15:27 | TimMc | gfredericks: Oh huh. |
| 15:28 | gfredericks | stuartsierra: I tried that but the var seems to quit existing at the end of the scope? or something like that |
| 15:28 | TimMc | technomancy: The "bug-free world" thing, when was that produced? |
| 15:28 | dnolen | seangrove: there isn't, but I don't think this really requires one at this point - the simplest hook is all we need, and best if it's only really supported/documented at closure.clj. |
| 15:28 | stuartsierra | gfredericks: yes |
| 15:29 | seangrove | dnolen: Got it, will take a look. |
| 15:29 | TimMc | If it's any time within the last 30 years I need to smack someone. |
| 15:29 | technomancy | TimMc: wish I had a source, sorry |
| 15:29 | gfredericks | stuartsierra: I'm trying to make a variant of with-redefs (that works only on functions) that makes thread-local modifications via a hidden dynamic var |
| 15:29 | gfredericks | (for testing) |
| 15:29 | Bronsa | gfredericks: putting the push-thread-bindings inside the try seems to work |
| 15:29 | gfredericks | waaat |
| 15:29 | gfredericks | everything about this is weird |
| 15:30 | stuartsierra | gfredericks: "hidden dynamic var" - three words that I never wanted to hear together ;) |
| 15:31 | gfredericks | stuartsierra: the use case is being able to safely parallelize tests that stub functions |
| 15:31 | pepijndevos | What is a good introductory piece on datomic? |
| 15:31 | tbaldridge | pepijndevos: theory or practical use? |
| 15:31 | bitemyapp | pepijndevos: well datalog would be learndatalogtoday.com - Datomic? Maybe the Day of Datomic repo. |
| 15:32 | bitemyapp | Craig Andera had a nifty presentation on some aspects of Datomic not long ago. |
| 15:32 | pepijndevos | tbaldridge, something that would exaplin what datalog is well to someone from a more traditional background |
| 15:32 | pepijndevos | bitemyapp, link doesn;t work |
| 15:33 | tbaldridge | Rich's talks are pretty good: http://www.infoq.com/presentations/datomic-functional-database |
| 15:33 | bitemyapp | BAH |
| 15:33 | bitemyapp | pepijndevos: http://www.learndatalogtoday.org |
| 15:33 | Bronsa | dnolen, cemerick: released 0.7.10 |
| 15:33 | tbaldridge | pepijndevos: and in that one Rich actually pulls out Emacs in the middle of a talk...I thought I'd never see the day. |
| 15:33 | cemerick | yeah, it'll be a breaking v2 change |
| 15:33 | gfredericks | rich was using emacs at the first clojure conj |
| 15:33 | dnolen | Bronsa: sweet |
| 15:34 | tbaldridge | pepijndevos: I've also heard good things about http://www.youtube.com/watch?v=ao7xEwCjrWQ but I haven't watched all of it yet. |
| 15:34 | bitemyapp | Oddly, he's using Aquamacs in the presentation. |
| 15:34 | cemerick | Bronsa: thanks much; I'll tweak up the cljs patch once dnolen gives it a look |
| 15:34 | pepijndevos | http://www.learndatalogtoday.org |
| 15:34 | bitemyapp | pepijndevos: yes. |
| 15:35 | pepijndevos | http://webchat.freenode.net |
| 15:35 | technomancy | bitemyapp: I used to think "oh, rich uses aquamacs; I should make sure my elisp libs support it I guess" but then I realized he's probably not going to use anything fancy =) |
| 15:35 | pepijndevos | oops |
| 15:35 | bitemyapp | technomancy: the man probably uses hammocks more than Emacs :) |
| 15:36 | pepijndevos | bitemyapp, tbaldridge , thanks |
| 15:36 | technomancy | bitemyapp: I wish I could find the sjl tweet where he shows a screenshot of the recommended editor for working through SICP and it's a pen and paper |
| 15:37 | mdrogalis | technomancy: Hah |
| 15:37 | sjl | technomancy: https://twitter.com/stevelosh/status/310487495198523393 |
| 15:37 | technomancy | nice; thanks |
| 15:40 | marcopolo2 | (inc sjl) |
| 15:40 | lazybot | ⇒ 1 |
| 15:41 | technomancy | sjl: been a while. still doing much clojure these days? |
| 15:41 | sjl | technomancy: right now mostly scala at work |
| 15:41 | bitemyapp | I'm actually pretty curious how much of Simple's stack is Scala/Clojure/JRuby. |
| 15:41 | dnolen | cemerick: Bronsa: patch looks good, lets go w/ NO_SOURCE_FILE as in Clojure |
| 15:41 | sjl | we do use some clojure though so I'll be getting back into it at some point |
| 15:41 | sjl | gotta do something now though, back in a bit |
| 15:41 | technomancy | sjl: ah, well hope it happens sooner rather than later =) |
| 15:42 | cemerick | dnolen: sounds good, I'll revisit tonight or tomorrow. Do you have any idea re: the orphaned require-macros expression? Just vestigial? |
| 15:42 | dnolen | cemerick: parse 'ns is a monstrosity, I barely understand any of it. |
| 15:43 | cemerick | heh, fair enough |
| 15:43 | dnolen | cemerick: likely vestigial. |
| 15:43 | cemerick | I'll fix up that misspelling as well |
| 15:43 | dnolen | cemerick: sounds good |
| 15:43 | cemerick | Could use some typed-clojure action in there :-P |
| 15:45 | akurilin | Is the convention of using ! at the end of fun names for functions that have a nil return value + side effect or in general for any side effect? As in, would a logging function get a ! in its name? |
| 15:46 | bitemyapp | akurilin: any side effect unless it's super obvious. |
| 15:46 | bitemyapp | a family of logging fns probably don't need it. they're for logging. that's a side effect. |
| 15:46 | akurilin | In my case, I have a fun that returns a future, but the future itself is doing exclusively a side-effect. So you kind of get something back :P |
| 15:46 | bitemyapp | But, "transfer-money" if it's side-effecting should get a ! |
| 15:46 | bitemyapp | doesn't matter |
| 15:46 | bitemyapp | that's not what I said. |
| 15:47 | bitemyapp | the ! is to prevent anybody from being surprised by side effects. |
| 15:47 | akurilin | bitemyapp, I know, I like your approach. |
| 15:47 | bitemyapp | It's not a hungarian notation for return values. |
| 15:47 | bitemyapp | if you want to note return values, annotate the var with core.typed. |
| 15:47 | akurilin | got it. |
| 15:47 | bitemyapp | principle of least surprise and all that. |
| 15:47 | tbaldridge | akurilin: technically the ! means it's not STM safe. Hence why send doesn't have one. It's side effecting, but still transaction safe. |
| 15:47 | akurilin | bitemyapp, yeah I like that. |
| 15:48 | TimMc | gfredericks: The trouble in implementing the SKI combinator calculus in Swearjure is K, right? That would be like implementing clojure.core/constantly |
| 15:48 | bitemyapp | akurilin: tbaldridge's approach is stricter but also valid. |
| 15:48 | bitemyapp | I don't think any expects a logging fn to be STM safe. |
| 15:48 | bitemyapp | anybody* |
| 15:49 | akurilin | speaking of typed, would it be a good a fit for annotating "controller" functions that get called straight from the router? To make sure the input schema is what I expect it to be rather than anything. |
| 15:49 | bitemyapp | it wouldn't really verify much for you. Just that you're getting request, params, etc? |
| 15:49 | bitemyapp | akurilin: it wouldn't really verify much for you. Just that you're getting request, params, etc? |
| 15:50 | akurilin | bitemyapp, I'm more interested in schema / type verification of the param map I'm getting. |
| 15:50 | akurilin | any way I can declaratively constrain that? |
| 15:50 | bitemyapp | akurilin: that's runtime bro. |
| 15:50 | bitemyapp | akurilin: clj-schema |
| 15:50 | technomancy | TimMc: K is constantly, right |
| 15:50 | bitemyapp | or mississippi |
| 15:51 | akurilin | bitemyapp, so clojure.typed is more of a hinting system? |
| 15:51 | bitemyapp | akurilin: I don't think you're understanding the difference between a type system and runtime schema enforcement. |
| 15:51 | bitemyapp | akurilin: a type system cannot enforce/prevent things that happen at runtime from user input. |
| 15:52 | bitemyapp | it can ensure you don't write any code that expects data to be in the schema of a defined HMap that won't be in there |
| 15:52 | bitemyapp | but it can't spew error messages at users at runtime. |
| 15:52 | bitemyapp | type systems can reach into the nature of "values" with dependent and occurrence typing, but that's *still* nothing to do with runtime schema enforcement. |
| 15:54 | akurilin | I'm probably thinking of something like a map being cast into a well-defined struct, and that would blow up if there's no translation between the two. |
| 15:55 | bitemyapp | core.typed doesn't cast anything or change your code, it enforces the correctness of your types. |
| 15:55 | bitemyapp | you can define an HMap that specs out the contents and types of the contents in a map in core.typed to enforce correct usage of that data. |
| 15:55 | gfredericks | TimMc: I haven't looked at SKI in long enough that I have no idea anymore. I remember having the impression it was conceptually straightforward and just needed a bunch of futzing with rest and that sort of thing |
| 15:55 | gfredericks | i.e., lots of non-objectionable details |
| 15:56 | technomancy | at one point I decided I was going to implement SKI in terms of lein tasks |
| 15:56 | technomancy | I never did, and if anyone else wants to beat me to it I'd be tickled |
| 15:56 | akurilin | bitemyapp, I'd have to look more in depth into it when I have time to better relate to what you're saying. |
| 15:57 | bitemyapp | akurilin: do you want to enforce correct access of a Map with specified keys and values at compile time, or do you want to enforce the schematic correctness of inputs at runtime? |
| 15:57 | bitemyapp | former: core.typed latter: clj-schema/mississippi/etc |
| 15:58 | bitemyapp | well, "compile" time. |
| 15:58 | TimMc | Oh well, back to the URL mines. |
| 15:58 | bitemyapp | I wonder who had the job of making an HTML parser that works everywhere at Google? |
| 15:58 | bitemyapp | and are they still alive? |
| 15:59 | akurilin | bitemyapp, ok thanks for clarifying the distinction, again, I'll have to look further into this before I can appreciate it. |
| 15:59 | dmi3y | Hello, can someone advice please how to make ajax call passing basic authentication parameters using ClojureScript ? |
| 16:00 | TimMc | bitemyapp: They probably have a collection of parsers with weights -- completely broken docs get the strip-tags parser and low weight, nice semanatic markup gets higher weight and maybe knows how to down-weight headers and menus. |
| 16:00 | coventry | If the JVM SecurityManager disallows getStackTrace, does that mean all exceptions come without stack traces? |
| 16:01 | akurilin | Is the idea of a data access layer reasonable with Clojure with cjj and korma? I'm ending up with quite a few different functions for each "model" for just getting hold of the data I need for them. |
| 16:01 | akurilin | So that to me is a DAL as far as I can tell. |
| 16:03 | bitemyapp | akurilin: possibly. |
| 16:03 | bitemyapp | One doesn't really want to be spending a lot of time on CRUD, generaly. |
| 16:03 | bitemyapp | generally* |
| 16:03 | akurilin | I would indeed prefer not to. |
| 16:05 | gfredericks | okay I got this var thing going I think |
| 16:07 | gfredericks | https://gist.github.com/fredericksgary/7143494 |
| 16:09 | gfredericks | ^ clojure stubbing for the paranoid |
| 16:09 | gfredericks | oops it has a borg |
| 16:10 | tbaldridge | resistance is futile |
| 16:11 | hiredman | technomancy: remember the job is one third done, because SK give you I |
| 16:11 | gfredericks | borg eliminated |
| 16:11 | bitemyapp | gfredericks: is there a parallel runner for Clojure? |
| 16:11 | gfredericks | bitemyapp: I have no idea :) |
| 16:11 | bitemyapp | well this is relevant to my interests :) |
| 16:11 | gfredericks | PHEW |
| 16:12 | gfredericks | I didn't mean that ironically that's actually how I react to most things |
| 16:15 | scopedTV | I'm looking for a std library function that applies a function to the values of a map. Is there such a function? |
| 16:16 | tsdh | scopedTV: And what should it return? The map with transformed values? |
| 16:16 | seangrove | Any way to get emacs in I-search to show me "match 2 / 50" as I'm banging C-s? |
| 16:16 | scopedTV | tsdh: Yes. |
| 16:16 | manutter | scopedTV: check out https://github.com/weavejester/medley |
| 16:17 | manutter | specifically the map-vals fn |
| 16:17 | tsdh | This should also do: (apply hash-map (mapcat (fn [k v] [k (transform v)]) my-map)) |
| 16:18 | scopedTV | yeah I figured something like that out, but thought there must be a better method. |
| 16:18 | scopedTV | Thanks! |
| 16:18 | hyPiRion | tsdh: only if you want to use hash maps. Sorted maps go boom with that one |
| 16:18 | bitemyapp | seangrove: hook + count-matches + output to sub-bar. |
| 16:19 | bitemyapp | the 2 out of X part would be a little tricker, still doable. |
| 16:19 | tsdh | hyPiRion: Uh, then use (apply sorted-map ...), no? |
| 16:20 | hyPiRion | tsdh: yeah, I'm just nitpicking. It's just good to be aware of the subtle details |
| 16:20 | seangrove | bitemyapp: The obvious worry being that the size of the buffer may be too big an kill the search |
| 16:23 | tsdh | hyPiRion, scopedTV: Then that's probably better, i.e., works with any kind of map: (into (empty my-map) (map (fn [k v] [k (transform v)]) my-map)) |
| 16:23 | hyPiRion | yeah, medley has a good version of it |
| 16:24 | tsdh | hyPiRion: Indeed, nice. |
| 16:28 | arrdem | bitemyapp: so I'm staring at the do monad... isn't this just excessively complicated function composition or do I need to se the other monads to appreciate it? |
| 16:28 | bitemyapp | technomancy: and to balance out the nice things I said earlier: http://www.yesodweb.com/blog/2013/10/pipes-resource-problems |
| 16:28 | bitemyapp | arrdem: the do monad is just sugar for bind |
| 16:28 | bitemyapp | arrdem: if you want to learn why monads are useful, it's best to just write Haskell programs. |
| 16:29 | bitemyapp | arrdem: also: http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/ |
| 16:29 | TimMc | gfredericks: Man what I don't |
| 16:29 | arrdem | bitemyapp: I may wind up doing just that... lets hope I pass GHC's IQ stat check |
| 16:29 | TimMc | I don't have brain for vars today, I guess. |
| 16:31 | bitemyapp | arrdem: I wouldn't sweat it, I'm an idiot. |
| 16:32 | gfredericks | TimMc: yeah it's a littel hairy |
| 16:33 | gfredericks | TimMc: mostly it's just jumping through hoops to make sure there's only one dynamic hidden var created at a time |
| 16:34 | xuser | bitemyapp: you don't like doing CRUD apps in clojure or in general? |
| 16:34 | bitemyapp | Programmers should automate away boring tasks. |
| 16:35 | bitemyapp | That's our purpose for existence. |
| 16:35 | coventry | arrdem: Still not sure I buy it, but section 2.4 "Why Use Monads?" is a good place to start. http://citeseerx.ist.psu.edu/viewdoc/summary;jsessionid=0F0DFB385D76652AEB59F86E31F368DA?doi=10.1.1.29.4575 |
| 16:36 | coventry | Also section 3.1 "On Category Theory." But I totally don't buy that. |
| 16:36 | TimMc | gfredericks: I'll stare at that on the subway sometime. |
| 16:39 | mdrogalis | Hm, where the heck is BigDecimal? |
| 16:39 | mdrogalis | ,clojure.lang.BigInt |
| 16:39 | clojurebot | clojure.lang.BigInt |
| 16:39 | mdrogalis | ,clojure.lang.BigDecimal |
| 16:39 | clojurebot | #<CompilerException java.lang.ClassNotFoundException: clojure.lang.BigDecimal, compiling:(NO_SOURCE_PATH:0:0)> |
| 16:39 | arrdem | coventry: thanks, I'll throw that on the reading list. |
| 16:39 | mdrogalis | Oh, it's Java's BigDecimal. |
| 16:41 | bitemyapp | coventry: the point is reliable abstractions which you can reason about at a high level. |
| 16:41 | bitemyapp | if certain things aren't guaranteed or ensured by the compiler, then you lose the ability to ignore the less important details and thus cannot continue the march up the abstraction ladder |
| 16:41 | noncom | hi, i have a little question about macros: https://www.refheap.com/20142 |
| 16:41 | bitemyapp | coventry: are you familiar with PG's essay that mentions "blub programmers"? |
| 16:42 | coventry | bitemyapp: Yes, but that's the point of any serious program. |
| 16:42 | bitemyapp | what point, what program? |
| 16:42 | arrdem | noncom: ~@ |
| 16:42 | coventry | bitemyapp: "the point is reliable abstractions etc. etc." |
| 16:43 | bitemyapp | coventry: not long ago programmers were complaining about how procedures were too declarative and restrictive compared to their gotos. |
| 16:43 | arrdem | noncom: that's our sequence insert operator. |
| 16:43 | bitemyapp | coventry: I'm talking about something more universal and important than any one program. |
| 16:43 | arrdem | noncom: so (let [foo [1 2 3 4]] `(~@foo)) -> '(1 2 3 4) |
| 16:43 | bitemyapp | coventry: I'm talking about continually advancing the state of the art by enabling ourselves to build up reusable, composable, reliable abstractions. |
| 16:44 | arrdem | coventry: can I get the title of that paper? my browser isn't loving your link. |
| 16:44 | bitemyapp | Category theory happens to provide some nice faculties for discussing computational models at a high level. |
| 16:45 | coventry | arrdem: Sorry must be cookie-linked. "Generalising Monads to Arrows", John Hughes, 1998. |
| 16:45 | arrdem | coventry: no worries, thanks! |
| 16:46 | noncom | arrdem: hmm, i try and get an error, look the update: https://www.refheap.com/20142 |
| 16:46 | coventry | bitemyapp: We've had this discussion. I don't think anything's changed, although my perspective's a little broader. |
| 16:47 | arrdem | noncom: that's because you aren't in a quoted form... |
| 16:47 | coventry | noncom: ,(macroexpand '(defmacro k [& body] ~@body)) |
| 16:47 | coventry | ,(macroexpand '(defmacro k [& body] ~@body)) |
| 16:47 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 16:47 | noncom | but the second try in the refheap uses quote |
| 16:47 | bitemyapp | coventry: the practical output of what I'm saying should be: learn new things, offer alternatives, don't simply reject things because they're unfamiliar. |
| 16:47 | coventry | Bah. Anyway, when something mysterious happens in a macro, macroexpand is the first tool to reach for. |
| 16:48 | bitemyapp | We're not going to keep making houses with mud forever. |
| 16:48 | arrdem | noncom: http://en.wikibooks.org/wiki/Learning_Clojure/Macros |
| 16:49 | arrdem | noncom: as with normal clojure code a macro "returns" the tail form. In order to generate or return code, the notation used is a backquoted list `(foo bar) |
| 16:49 | arrdem | noncom: you can insert values into a backquoted form via ~<expr> |
| 16:49 | noncom | arrdem: but the second try in the refheap is (defmacro k [& body] `(~@body)) and still gives an error.. |
| 16:50 | arrdem | noncom: probably... because you need do as the first element of that spliced list |
| 16:50 | noncom | i can't find a difference from the example from the wikibook that you referenced |
| 16:50 | noncom | oh that, wait i try |
| 16:51 | noncom | true that was about the (do) thing! |
| 16:51 | noncom | thanks! |
| 16:51 | arrdem | noncom: np |
| 16:55 | coventry | noncom: Sorry, that was a bad example. (macroexpand '(k (+ 1 2) (- 2 1))) would have been informative. |
| 16:56 | noncom | coventry: cool! i have tried like (macroexpand k) before and it failed, but now i'm starting to see things.. |
| 16:58 | coventry | bitemyapp: Obviously, that's preaching to the choir. :-) |
| 16:59 | arrdem | bitemyapp: but I like playing with mud... |
| 16:59 | bitemyapp | arrdem: off to the Fortran mines with you then! |
| 16:59 | arrdem | I suppose clouds would be more fun... |
| 16:59 | coventry | One day, we will build a ball of mud which will build balls of mud for us. |
| 16:59 | arrdem | coventry: the power <strike>set</strike> ball of mud? |
| 17:00 | noncom | might turn out to be something like that: http://filer.case.edu/dts8/thelastq.htm |
| 17:01 | arrdem | bitemyapp: no thanks, that's where they send the grad students |
| 17:10 | avishai | question |
| 17:10 | arrdem | ~answer |
| 17:10 | clojurebot | Excuse me? |
| 17:10 | arrdem | dang. |
| 17:10 | avishai | i want to issue a few parallel actions and have a timeout for the entire operation |
| 17:11 | avishai | i can do this with futures |
| 17:11 | avishai | but |
| 17:11 | avishai | it's damn ugly |
| 17:11 | bitemyapp | avishai: core.async, alts, timeout. |
| 17:11 | bitemyapp | avishai: you're welcome. |
| 17:11 | avishai | core.async ain't good since it's blocking |
| 17:12 | bitemyapp | avishai: could've fooled me, I think it has async in the name bro. |
| 17:12 | avishai | no, |
| 17:12 | avishai | the operations i'm using are |
| 17:12 | bitemyapp | so...change...them? |
| 17:12 | avishai | can't |
| 17:12 | avishai | they're plugins |
| 17:12 | avishai | external |
| 17:13 | bitemyapp | and it's impossible to wrap these operations? |
| 17:13 | avishai | with future or threads |
| 17:13 | avishai | it's possible |
| 17:13 | znDuff | well, there you are. |
| 17:13 | brehaut | avishai: jsut make an alternative to future that wraps up a future and a chan |
| 17:14 | avishai | then use select |
| 17:14 | avishai | good idea |
| 17:14 | avishai | any alternative without core.async? |
| 17:14 | brehaut | avishai: making new bits out of existing bits is what this FP is about |
| 17:15 | avishai | ok |
| 17:15 | avishai | brehaut, thank you very much |
| 17:16 | brehaut | avishai: its worth keeping in mind that in clojure all the different primatives for this stuff are largely intended to be used together |
| 17:16 | brehaut | theres no 'one true model' |
| 17:17 | avishai | yes |
| 17:17 | tbaldridge | avishai: you can do blocking operations with core.async. Just do them inside a (thread...) block. It returns a channel, and then the rest of your code can be async |
| 17:17 | avishai | the problem is i'm still very young clojurer |
| 17:18 | avishai | i find it a bit confusing at this point to jump from blocking to non-blocking code in the same project |
| 17:18 | brehaut | avishai: its only a problem if you arent willing to learn. so looks like not a problem |
| 17:19 | avishai | no, it's not a problem; if anything it's a challenge! |
| 17:19 | avishai | thanks a lot. you people are awesome! |
| 17:24 | brehaut | avishai: i find that the sync / async thing sort of follows the general difficult challenge of partitioning a program into independant components. it mostly takes some experience mucking about learning the capabilities and trade offs of each bit and how they fit together |
| 17:24 | rasmusto | i ran into something last night. I have a bunch stuff that runs in a pmap, and I want to use a memoized function in there, but stuff doesn't get cached until everything has already kicked off... is there something like a "blocking memoize"? |
| 17:26 | brehaut | rasmusto: its possible that core.cache has something for that? |
| 17:27 | arrdem | rasmusto: what clojure version are you using? |
| 17:27 | rasmusto | arrdem: 1.5.1 |
| 17:27 | brehaut | rasmusto: although thats surprising as memoize is jsut using an atom and swap! |
| 17:27 | arrdem | rasmusto: yeah... that should work just fine... |
| 17:27 | coventry | rasmusto: Do you mean that if someone is already computing (f x), all other calls to (f x) should block until the result is cached? |
| 17:28 | rasmusto | coventry: that's what I was thinking, yeah |
| 17:29 | rasmusto | my understanding from reading the source is that it does (apply f args) if it can't find a cached version, and only after doing so will it update the cache |
| 17:30 | rasmusto | so if I have a long-running function that I call a dozen times in parallel, they will all run to completion and each swap in their (identical) results |
| 17:30 | arrdem | rasmusto: yeah. this won't do any blocking on a parallel computation. |
| 17:31 | coventry | rasmusto: Is pmap smart enough to fire up more computations if a current thread is blocking? |
| 17:31 | rasmusto | coventry: I'm not sure |
| 17:31 | arrdem | coventry: if the current thread is blocking then it should yield to other green/real threads and life will be good. |
| 17:31 | rasmusto | arrdem: could I write a similar function to memoize that updates an argument map with values in a future? |
| 17:32 | coventry | rasmusto: pmap only runs (+ 2 (.. Runtime getRuntime availableProcessors)) processors. |
| 17:32 | arrdem | rasmusto: totally. I was just about to. |
| 17:32 | rasmusto | coventry: hmm, ok. What impact does that have in this case? |
| 17:33 | coventry | rasmusto: If more than two threads block, there will be fallow resources. |
| 17:33 | rasmusto | coventry: ah, gotcha |
| 17:34 | coventry | rasmusto: My impression is that reducers are supposed to be smarter about this kind of thing. |
| 17:34 | coventry | rasmusto: But I could be wrong. I have only read / heard about them, not played with them. |
| 17:35 | rasmusto | coventry: same here, I might have to explore them more now that I have a potential application |
| 17:38 | arrdem | rasmusto: https://www.refheap.com/20143 is what I'd do. |
| 17:38 | arrdem | oops. |
| 17:38 | arrdem | bug: the trailing ret needs an @ |
| 17:39 | arrdem | (doall)ing that sequence could be worthwhile depending on your application. |
| 17:39 | coventry | arrdem: That's still going to lead to duplicated work, isn't it? Don't you need some kind of locking based on the arguments? |
| 17:40 | rasmusto | was going to say something ;p |
| 17:40 | arrdem | coventry: no so this does do locking |
| 17:40 | arrdem | unless I'm totally crazy. |
| 17:40 | rasmusto | this will spin up futures for each call, then swap them out when each call completes, yea? |
| 17:40 | arrdem | coventry: because I swap! in the ref returned by the future. |
| 17:41 | arrdem | rasmusto: no. |
| 17:41 | arrdem | so here's my understanding of what this will do. |
| 17:41 | arrdem | for every element of the args, check to see if it's in mem |
| 17:41 | arrdem | mem is _only_ refs, or nil. if the ref exists, deref it (this is blocking) |
| 17:42 | arrdem | if the value is nil, swap! in a new future and yield the deref of the future. |
| 17:42 | rasmusto | ohh, wow. My eyes totally missed the map part |
| 17:42 | arrdem | yeah. so this is sequential on the args, which is why it'll work. |
| 17:42 | arrdem | but it's parallel on the computation. |
| 17:42 | arrdem | potentially. |
| 17:42 | rasmusto | hrm, okay. |
| 17:43 | rasmusto | I'm not sure if I want something that requires a map in its implementation |
| 17:43 | rasmusto | I think I just want a drop-in replacement for memoize |
| 17:44 | rasmusto | arrdem: I will have to think about how yours works a bit |
| 17:44 | arrdem | You could refactor the fn out and use it instead of memoize. Thanks to the atomicity gurantee of swap! it should Just Work (TM) |
| 17:44 | rasmusto | ah okay, so this is something that I'd call at a higher level. |
| 17:45 | rasmusto | my code is a bit nested though, and I'm concerned with a function call that's a few layers deep |
| 17:45 | rasmusto | not something that I can easily pull out and map across |
| 17:45 | rasmusto | (this is an issue on my end) |
| 17:47 | arrdem | I mean... the straight memoize is also trivial... https://www.refheap.com/20146 |
| 17:51 | arrdem | herm... so how does swap! effect the order semantics of an atom... isn't it essentially a (with-lock <atom> (set! <atom> (apply ... )))? |
| 17:53 | arrdem | because if that's the case then you can escape any synchronization issues by getting rid of that (let) form and just swap! associng (future (apply f args)) directly. |
| 17:54 | rasmusto | hmm |
| 17:54 | arrdem | then the return value is just (deref (get .. args)), which expression is guranteed to be blocking :D |
| 17:56 | arrdem | the problem with this is that (future) isn't pure... and (swap!) warns that the update fn may be applied multiple times due to retrying so it's _possible_ that you will be duplicating work depending on weird system synchronization cases. |
| 17:56 | arrdem | s/case/behavior/ |
| 17:56 | coventry | arrdem: I must still be misunderstanding. The following code prints out "1" four times, but if the memoization was working the way I expected, that would only happen once. What am I missing? https://www.refheap.com/20148 |
| 17:57 | turbofail | arrdem: not necessarily even that weird. it should happen fairly often |
| 17:57 | coventry | (Just take out the (user/starbreak) line. It's a convenience function of mine. |
| 17:58 | arrdem | coventry: hum... weird! time to start testing my own snippets before pasting :D |
| 17:59 | coventry | Well, it's what I would expect from reading the code, as I described in my earlier question with the map question. |
| 17:59 | coventry | s/map question/map version/ :-) |
| 18:00 | turbofail | yeah, the future doesn't really help here, the problem is still that the value in the atom won't necessarily get updated with the key in time |
| 18:01 | arrdem | ok ok trying my (swap!) is atomic version.. lets see what happens.. |
| 18:01 | arrdem | L31K A BAu5 |
| 18:01 | arrdem | coventry: this version totally works. |
| 18:01 | arrdem | https://www.refheap.com/20149 |
| 18:02 | arrdem | assuming that swap! never has to retry at any rate. |
| 18:02 | hyPiRion | You could've made it a promise too |
| 18:03 | hyPiRion | doesn't use a new thread for the computation that way |
| 18:04 | rasmusto | why is fact always 1 |
| 18:05 | arrdem | rasmusto: because I suck? :P |
| 18:05 | rasmusto | it looks right to me... |
| 18:05 | rasmusto | I guess I suck too? |
| 18:05 | turbofail | if it checked for the existence of the arguments in the memo table inside the swap! function then it wouldn't matter if swap! retried |
| 18:06 | arrdem | turbofail: oooh cute... |
| 18:06 | turbofail | and rest assured, swap probably will retry if you call the memoized function from multiple threads |
| 18:07 | rasmusto | fact needs to multiply x and (fact (dec x)) |
| 18:07 | rasmusto | otherwise it keeps recursing and then hits 1 * 1 |
| 18:08 | arrdem | rasmusto: lol looks like I mixed fib and factorial to no effect :P |
| 18:09 | rasmusto | factonachi sequence |
| 18:09 | rasmusto | fibotorial |
| 18:09 | rasmusto | arrdem: haha, that's cracking me up. You're 100% right |
| 18:10 | arrdem | Mckenzie Labs: wasting stack frames for multiplying 1 since 1992 :D |
| 18:11 | turbofail | well actually it can still duplicate work because two threads updating the atom for the same arg-value will both create futures that will run in the background, even though only one of those futures will ever end up inside the memo table |
| 18:12 | arrdem | so actually... with that swap-safe-assoc... the v will be (eval)'d first, so you will generate a bogus future which gets thrown away... |
| 18:12 | turbofail | right, that |
| 18:12 | arrdem | o/ |
| 18:13 | turbofail | so a promise is probably what you actually want |
| 18:13 | arrdem | or you could throw the (future) in a (partial) so that it won't be evaluated, then only call the partial if the key isn't in the map... |
| 18:14 | turbofail | well you want to only call the partial if the swap! succeeds |
| 18:14 | turbofail | which is not something you can really do |
| 18:15 | arrdem | oh yeah I see what you're saying. |
| 18:15 | turbofail | i think what you actually want is (delay (apply f args)) |
| 18:16 | turbofail | or something to that effect |
| 18:16 | arrdem | yeah delay is perfect. |
| 18:16 | marcopolo2 | What's that lein config called that lets you reference a dependency you are working on, instead of having it in the dependencies vector |
| 18:17 | technomancy | marcopolo2: checkouts? |
| 18:17 | arrdem | except that it kills all possibility for parallelism in the evaluation.. |
| 18:18 | mtp | yogthos‘ away-nicks are unnecessary. thanks for your understanding. |
| 18:18 | marcopolo2 | technomancy: that's it, thanks! |
| 18:19 | technomancy | np |
| 18:19 | turbofail | arrdem: well it'll still allow parallelism for different arguments. it'll only kill parallelism for calls with the same arguments, which is exactly what we wanted |
| 18:19 | rasmusto | turbofail: that's correct. In my case I want it to block same-argument stuff |
| 18:20 | rasmusto | if the function itself is parallel itself that's still fine, and all of the other callers upstream can just hang out while it finishes |
| 18:22 | arrdem | ok cool! turbofail: good catches :D |
| 18:23 | rasmusto | arrdem: turbofail: is this kind of function something that could be widely used? I know I have an application for it, but I don't know if it could fit elsewhere |
| 18:24 | turbofail | rasmusto: dunno. for all i know core.cache might already have this |
| 18:24 | turbofail | i haven't looked |
| 18:26 | arrdem | I doubt this fits in core.cache, just because that's several cache implementations with no use cases. |
| 18:27 | arrdem | would probably fit in the flatland toolkit or some other snippets lib. |
| 18:27 | arrdem | https://github.com/flatland/useful perfect fit. |
| 18:30 | rasmusto | arrdem: I'll drop it into my code for now and see how it behaves. https://www.refheap.com/20149 is the final one you wrote, yes? |
| 18:30 | arrdem | rasmusto: nope. |
| 18:31 | arrdem | that (future) needs to be a (delay) |
| 18:31 | arrdem | otherwise ok. |
| 18:31 | rasmusto | arrdem: ah, alright. you're awesome :) |
| 18:31 | turbofail | er. also needs to use the non-overwriting swap function |
| 18:32 | arrdem | https://www.refheap.com/20152 |
| 18:42 | kovas | dnolen: u alive? |
| 18:43 | dnolen | kovas: yep |
| 18:43 | rasmusto | arrdem: performance numbers (idk how applicable the test case is) https://www.refheap.com/20153 |
| 18:43 | kovas | dnolen: having trouble loading core.match |
| 18:43 | kovas | getting FileNotFoundException Could not locate clojure/core/match__init.class or clojure/core/match.clj on classpath: clojure.lang.RT.load (RT.java:443) |
| 18:43 | arrdem | turbofail, rasmusto: PR'd to flatland/useful |
| 18:43 | kovas | with [org.clojure/core.match "0.2.0"] |
| 18:43 | rasmusto | arrdem: awesome :) |
| 18:44 | kovas | also tried [match "0.2.0-SNAPSHOT"] |
| 18:44 | kovas | ha |
| 18:44 | kovas | well, just tried again and it works |
| 18:45 | kovas | heisenbug |
| 18:45 | arrdem | rasmusto: yeah that really isn't to surprising. for lightweight fns the coordination overhead of the atom is gonna really kill performance |
| 18:45 | dnolen | kovas: heh |
| 18:45 | seangrove | technomancy: No idea how you manage to even idle in emacs. I can barely glance without eyes glazing over. |
| 18:45 | kovas | damn state |
| 18:45 | dnolen | kovas: I've seen a few projects using it and I haven't heard complaints |
| 18:45 | muhoo | what's the difference between find and get? why would you use find instead of get or vice versa? |
| 18:46 | akurilin | Man, nrepl is the coolest thing ever. Running tasks from production straight from the app, reusing all of the existing code. |
| 18:46 | dnolen | muhoo: find returns the map entry, sometimes useful because it combines the beneft of contains? and get w/o needing to provide a not found value |
| 18:46 | akurilin | On that note, how does nrepl execute code on the target appliction? Does it spin up a new thread for each connection, and run everything on that? |
| 18:47 | muhoo | dnolen: thanks |
| 18:50 | rasmusto | arrdem: I hope to get some real numbers from my horribly inefficient code sometime this week, I'll let you know what happens |
| 18:51 | brehaut | Lexicon PSA: From now on, any bug caused by using when in place of if is now known as a Hagelbug |
| 18:52 | arrdem | ~lexicon |
| 18:52 | clojurebot | I don't understand. |
| 18:52 | arrdem | that should be a wiki page somewhere... |
| 18:52 | brehaut | you'll have to use your on-board memory |
| 18:55 | arrdem | eh I'll just mmap in a markdown file... |
| 19:04 | akurilin | bbl |
| 19:07 | johann | technomancy: got it to work! thanks for your responsiveness earlier :) |
| 19:07 | technomancy | johann: cool. anything confusing or unclear about the docs? |
| 19:09 | johann | techomancy: i probably was such in an ansy that i didn't slow down and understand the whole $PORT variable thing |
| 19:09 | johann | techomancy: but that probably lends to my ability to focus than the docs themselves :P |
| 19:20 | Creap | I just found out about with-test, haven't seen much about it earlier. Is in uncommon for people to use it in their code? I think it looks interesting as an immediate and always up to date example of a function.. |
| 19:21 | arohner_ | Creap: I dont use with-test because I don't like the indention, and I like my src and tests separate |
| 19:21 | coventry | Creap: It hasnt't seen much use because people find it breaks up the flow of reading the code. |
| 19:22 | arrdem | Creap: I'd rather see docstrings or margalina docs than tests inline... tests would be kinda weird. maybe one in the docstring. maybe. |
| 19:23 | dnolen | cemerick: Bronsa: patch landed! a very nice one thanks. |
| 19:24 | Creap | ok, makes sense.. but wouldn't another benefit be to be able to test private functions? |
| 19:26 | coventry | Creap: Personally, I would find using (#'fully.qualified/name args) in the test file less disruptive. |
| 19:26 | arrdem | coventry: wouldn't that be a access error for a private fn? |
| 19:27 | arrdem | wow it isn't... |
| 19:29 | coventry | Be sure to use this power only for good. :-) |
| 19:29 | Creap | :) |
| 19:30 | brehaut | arrdem: theres not really any such thing as a private function. |
| 19:31 | technomancy | brehaut: well, closures =) |
| 19:31 | brehaut | technomancy: not so much private as just local right? |
| 19:31 | arrdem | brehaut: I knew that private was really metadata, but I thought that it did do something in aot. |
| 19:31 | arrdem | s/ato/gen-class/ |
| 19:31 | technomancy | brehaut: not sure the difference is meaningful |
| 19:32 | brehaut | technomancy: probably true |
| 19:32 | technomancy | well, it's different from ^:private, just not "what you think of as the english definition of private" |
| 19:35 | brehaut | technomancy: if it were stateful things it might matter more |
| 19:37 | bitemyapp | arrdem: nope. |
| 19:37 | bitemyapp | arrdem: vars are vars, regardless of when compilation happens. |
| 19:39 | bitemyapp | arrdem: how many communication media can we spread our converations across? Time to fire up SC2 and talk on B.Net too? |
| 19:40 | MrJones98 | i'm pretty new to clojure and experimenting with a library… they use alter-var-root but during testing (via lein test), it seems that the var is not being bound to the expected value |
| 19:40 | MrJones98 | does anyone have helpful links for me to learn more about any nuances that are related? |
| 19:42 | bitemyapp | MrJones98: that's curious. alter-var-root should uh...just work. But lets drop the hypotheticals and just show us the code you're talking about. Use refheap if you need a pastebin. |
| 19:43 | hiredman | the nuances are "libraries that use alter-var-root should be avoided" |
| 19:43 | bitemyapp | that's like half of my libraries. I'm going to choose to take pride in this. |
| 19:43 | MrJones98 | here's a link to the library that i'm trying to use |
| 19:43 | MrJones98 | https://github.com/clojurewerkz/archimedes/blob/master/src/archimedes/core.clj |
| 19:44 | bitemyapp | hahahaha, I fucking knew this was going to be a clojurewerkz library. |
| 19:45 | MrJones98 | i'm still too new to this community to have any idea if i should be laughing or crying |
| 19:45 | coventry | MrJones98: What test is failing? |
| 19:45 | MrJones98 | but… transact!* on line 13 is what's causing me problems |
| 19:45 | coventry | In what context? |
| 19:46 | MrJones98 | so archimedes isn't the test that's failing but one within titanium… i'm trying to modify titanium to work with titan 0.4.0 |
| 19:46 | MrJones98 | and in the process, pointing titanium to the latest version of archimedes |
| 19:47 | bitemyapp | Jenga Tower library usage. |
| 19:47 | MrJones98 | and every test within titanium is failing, appearing as if transact!* is not being bound to something else |
| 19:47 | bitemyapp | "it appears I have too many wobbly wooden blocks stacked on top of each other. Clearly I can only solve this by stacking more wobbly wooden blocks" |
| 19:47 | MrJones98 | bitemyapp: it sort of feels that way |
| 19:47 | bitemyapp | MrJones98: so...stop that. |
| 19:48 | MrJones98 | i've been considering just starting over with just the parts i need to interact with ttian |
| 19:48 | coventry | Wow the titanium dependencies are pretty stupendous. |
| 19:48 | bitemyapp | MrJones98: throwing stuff away is almost always a good idea. |
| 19:49 | MrJones98 | i'm still very new to clojure… so slowly learning which libraries are a good idea or not |
| 19:49 | MrJones98 | i started with titanium… then saw that it built on top of archimedes and ogre |
| 19:50 | bitemyapp | I use some ClojureWerkz libraries but I try to hold them at a distance and not stack up the tower of things I don't understand pretty well very high. |
| 19:51 | MrJones98 | any recommendations of "good" libraries i can take a look at to compare with? |
| 19:51 | coventry | MrJones98: Why do you want bleeding-edge archimedes? |
| 19:52 | MrJones98 | i don't want bleeding edge archimedes necessarily… i'm looking for bleeding edge titan |
| 19:52 | coventry | bleeding-edge titanium works with the specified archimedes dependency. |
| 19:53 | coventry | (In my hands.) |
| 19:53 | coventry | Fails with bleeding-edge archimedes as you describe, though. |
| 19:53 | MrJones98 | bleeding edge titanium doesn't work with bleeding edge titan though… so i started down this path trying to modify titanium to work with the latest titan |
| 19:54 | MrJones98 | and titan 0.4.0 runs with blueprints 2.4.0… so then i decided to look at the latest archimedes |
| 19:54 | MrJones98 | and then started building my jenga tower |
| 19:55 | bitemyapp | MrJones98: do you need to be using Titan specifically? |
| 19:56 | MrJones98 | bitemyapp: that is a very good question… i was originally using neo4j but the graph mutations i was doing required something like faunus which got me to titan |
| 19:57 | bitemyapp | MrJones98: there's also the option of using Titan directly. |
| 19:57 | bitemyapp | which is just Java |
| 19:57 | MrJones98 | bitemyapp: yeah, i started this morning ready to integrate titan directly… then saw titanium so thought i might learn something trying to work with it |
| 19:57 | MrJones98 | figured it might be a good clojure learning experienc3e |
| 19:57 | MrJones98 | i have some decent experience working with titan/faunus directly from groovy |
| 19:58 | bitemyapp | MrJones98: did you try what coventry described? |
| 19:58 | bitemyapp | native Clojure libraries are generally nicer. |
| 19:58 | noprompt | bitemyapp: sketch, refine, repeat. |
| 20:00 | MrJones98 | bitemyapp: i'm thinking it's easiest to just roll my own "library" to interact with titan directly |
| 20:00 | bitemyapp | noprompt: wut |
| 20:00 | noprompt | bitemyapp: about throwing stuff away. |
| 20:01 | bitemyapp | noprompt: ah, yes. |
| 20:01 | bitemyapp | MrJones98: if you make a nice micro-library please put it on github. |
| 20:01 | MrJones98 | bitemyapp: will do |
| 20:01 | MrJones98 | are you working with graph dbs? |
| 20:02 | bja | is tools.logging supposed to clobber pr/prn/print/println? |
| 20:02 | bja | or rather, it clobber print |
| 20:02 | bja | *clobbers print |
| 20:02 | bja | but not pr and prn |
| 20:03 | noprompt | bitemyapp: although i feel programming is more like working with clay. |
| 20:03 | noprompt | or mudd. |
| 20:03 | noprompt | :) |
| 20:03 | technomancy | noprompt: https://mobile.twitter.com/tangentialism/status/379996890366238720?p=v |
| 20:04 | noprompt | technomancy: lol. |
| 20:05 | MrJones98 | general question… if i'm working with something like databases where i need to open a connection, what's the "proper" clojure way to managing that? |
| 20:05 | MrJones98 | i've seen how clojurewerkz does it with monger and titanium... |
| 20:06 | bitemyapp | MrJones98: make the connection a value. bucket of state for talking to the database and retaining results/dispatching queries |
| 20:07 | bitemyapp | MrJones98: then just pass it around. |
| 20:07 | bitemyapp | Be a lazy ass about this at your own peril. |
| 20:07 | noprompt | s/"proper" clojure\(way\)/\1 in which others will not give me "shit" |
| 20:07 | noprompt | damn forgot a space. :/ |
| 20:07 | coventry | MrJones98: Why do you want bleeding-edge titan, out of curiosity? |
| 20:08 | bitemyapp | MrJones98: make the rest of the API as pure as possible. |
| 20:12 | MrJones98 | noprompt: i generally assume that i will always get shit from someone |
| 20:12 | MrJones98 | bitemyapp: i'm not sure i even know what "being lazy" means when it comes to clojure |
| 20:12 | noprompt | MrJones98: you have won at least half the battle. |
| 20:14 | MrJones98 | coventry: regarding titan, i'm looking to experiment with this particular feature of faunus 0.4.0 - Added FaunusRexsterExecutorExtension which allows remote execution of a Faunus script and tracking of its progress |
| 20:15 | noprompt | wow. |
| 20:15 | bitemyapp | MrJones98: proliferating statefulness throughout the API unnecessarily. |
| 20:15 | MrJones98 | otherwise, all of my other development to date has been on titan 0.3.2 |
| 20:16 | MrJones98 | bitemyapp: makes sense… i've become a big believer of not having state if at all possible |
| 20:16 | MrJones98 | frees up my brain to worry about other stuff |
| 20:21 | noprompt | i don't think i actually grok what i'm doing with this lein plugin. |
| 20:25 | noprompt | i just want to watch some files at a path, load a file, grab the value of a var and something with it. |
| 20:26 | arrdem | bitemyapp: -E_BAD_CONTEXT |
| 20:26 | arrdem | oh. right. the ^private thing. |
| 20:33 | noprompt | omfg. clean. i just needed to clean. |
| 20:35 | seangrove | dnolen: What patch was that? |
| 20:50 | Bronsa | seangrove: http://dev.clojure.org/jira/browse/CLJS-632 |
| 20:56 | seangrove | Bronsa: Very nice |
| 21:17 | noprompt | ok. i give up. serious question. if i want to reload source code whenever it changes w/ a leinigen plugin what's a good gameplan? |
| 21:18 | technomancy | noprompt: just use your repl |
| 21:20 | noprompt | technomancy: i'm trying to automate a compilation function. ie. something that writes to a file. |
| 21:21 | noprompt | technomancy: the changes could be in a directory. |
| 21:21 | technomancy | oh gotcha, so not for general dev use |
| 21:21 | technomancy | there's a ring middleware you could try |
| 21:23 | noprompt | technomancy: right. here's the idea: i'd like to specify the name of a var which will contain that data. that data may depend on values in another namespace. whenever i make changes in the "source-paths" whatever they may be i'd like to reload the namespaces and recompile the value of the var. |
| 21:24 | noprompt | do note, i understand my grammar is awful. |
| 21:24 | Raynes | noprompt: I'm gonna need you to head on down to LA now and visit me. |
| 21:25 | noprompt | Raynes: iz that so? |
| 21:25 | Raynes | Iz |
| 21:25 | noprompt | Raynes: :) |
| 21:25 | noprompt | Raynes: what's the score? |
| 21:25 | Raynes | noprompt: wat |
| 21:25 | noprompt | Raynes: as in "what's happening" |
| 21:27 | Raynes | noprompt: Nothing. That's why you should be here. |
| 21:27 | Raynes | We could make things happen. |
| 21:27 | noprompt | ah, indeed. |
| 21:27 | noprompt | well i was supposed to visit bitemyapp/callen next weekend. |
| 21:27 | Raynes | Damn him. |
| 21:27 | Raynes | Why is he special? |
| 21:27 | noprompt | yes. |
| 21:27 | Raynes | Am I not good enough for you? |
| 21:27 | seangrove | dnolen: http://dev.clojure.org/jira/browse/CLJS-636 Didn't touch closure.clj at all, but this seemed like the right place to put the warning hooks to some degree |
| 21:27 | Raynes | Don't answer that. I get it. |
| 21:27 | noprompt | you are worth. |
| 21:27 | noprompt | *worth |
| 21:28 | noprompt | ugggh WORTHY |
| 21:28 | Raynes | That wasn't a word. |
| 21:28 | noprompt | no wait! |
| 21:28 | noprompt | srsly i need lol halp. |
| 21:28 | Raynes | :P |
| 21:28 | fakedrake | hello |
| 21:29 | fakedrake | where does lein download packages it pulls as dependencies? |
| 21:29 | noprompt | i've been at this for like an hour now. |
| 21:29 | noprompt | fakedrake: ~/.m2/repository |
| 21:30 | fakedrake | noprompt: yay! thanx |
| 21:30 | noprompt | Raynes: do you get what i'm trying to do? |
| 21:30 | Raynes | Oh, I didn't actually look. |
| 21:30 | noprompt | Raynes: and perhaps know of how i could do it? |
| 21:31 | Raynes | noprompt: I imagine that lein-prism is probably a good starting point. |
| 21:32 | noprompt | Raynes: well now i have more source to read. |
| 21:32 | Raynes | I'm sorry. |
| 21:33 | noprompt | Raynes: nah it's all good. |
| 21:33 | noprompt | Raynes: good ol watch/load-file do something wasn't working right. |
| 21:36 | noprompt | oh snap it's almost lunchtime :) |
| 21:39 | noprompt | welp better go eat |
| 21:42 | fakedrake | lein repl doesnt seem to find clojure.contrib |
| 21:42 | fakedrake | how do I get that? |
| 21:43 | technomancy | clojurebot: what happened to contrib? |
| 21:43 | clojurebot | Well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 21:45 | fakedrake | so what is the best way to get pwd from the repl? |
| 21:45 | technomancy | should be (System/getProperty "user.dir") |
| 21:47 | fakedrake | aha |
| 21:47 | fakedrake | is that also the best way to do that from an actual app? |
| 21:48 | technomancy | sure |
| 21:48 | technomancy | note that you can't actually change the current directory of the jvm |
| 21:49 | technomancy | so it's really "what directory did I start in" |
| 21:49 | fakedrake | hmm |
| 21:49 | fakedrake | allrighty then |
| 21:50 | fakedrake | so the repl is not like eshell then |
| 21:55 | llasram | In what way is a raven like a writing desk? |
| 21:58 | fakedrake | well eshell is sort of a repl for elisp, and ipython is an interpreter that can be used as a shell to some extent |
| 21:58 | fakedrake | i kind of assumed clojure repl would be something like that |
| 22:00 | llasram | That's fair |
| 22:00 | llasram | But the JVM is a strange beast |
| 22:01 | fakedrake | llasram: indeed it is |
| 22:07 | technomancy | fakedrake: it's more like M-x ielm than M-x eshell |
| 22:08 | technomancy | I don't know anything that's like eshell |
| 22:09 | technomancy | except erlang's interactive prompt has the same name, but that's about as far as the similarities go |
| 22:09 | hyPiRion | no, that's just erl |
| 22:12 | l1x | hey guys |
| 22:13 | l1x | how can i autocompile all the clj files in a src folder? it seems that lein uberjar only compiles the project.core (that is the :main in the project.clj) |
| 22:14 | llasram | l1x: First, why do you want to ahead-of-time compile the files? |
| 22:16 | l1x | llasram: i might be just a noob, so here is what i want to do: i have a project called project, i have project.namesapce1 namespace in src/project/function/namespace1.clj |
| 22:17 | l1x | i would like to have all of the namescpaces available in lein repl |
| 22:17 | l1x | makes sense? |
| 22:17 | llasram | Well, what you want makes sense, but there's some degree of mismatch |
| 22:18 | llasram | Compilation is a deployment optimization, and is only generally necessary if you're using `gen-class` |
| 22:18 | llasram | If you just want stuff in a REPL, you definitely shouldn't need to `compile` |
| 22:18 | llasram | If the paths you mentioned are exactly what you have, there's probably a mismatch between the namespace name and the path to find the associated file |
| 22:19 | llasram | The `project.namespace1` namespaces should be in a `project/namespace1.clj` file under a source path (default just `src`) |
| 22:19 | l1x | i see |
| 22:20 | l1x | so i cant really have a logical source code management when the db layer is in the db directory? |
| 22:21 | llasram | Well, you can have multiple `:source-paths` in your leiningen `project.clj`. But underneath the source path, the directory structure needs to match the namespace |
| 22:21 | l1x | or i can still do project.function.namespace1 and project/function/namespace1.clj? |
| 22:21 | llasram | that's fine |
| 22:21 | l1x | great |
| 22:21 | l1x | this is what i am going to do |
| 22:22 | llasram | Cool beans |
| 22:22 | l1x | thanks a million llasram |
| 22:22 | llasram | np |
| 22:22 | l1x | clj community <3 |
| 22:22 | technomancy | l1x: you can set :init-ns in :repl-options of project.clj, and `lein repl` will start off with that ns loaded |
| 22:22 | technomancy | so if you put a bunch of :requires in that ns it con be convenient |
| 22:23 | coventry | l1x: You can also the necessary (require)s in a file dev/user.clj in your project, and they will be in the repl's "user" namespace. |
| 23:33 | ddellacosta | anything that does filter + remove in the same function? Specifically, give me a list of the values that match and another that doesn't match a specific keyword value in a map? Probably using filter/remove is not the right strategy in this case. |
| 23:33 | seangrove | partition-by? |
| 23:34 | ddellacosta | seangrove: right, that is a good avenue to look down...thanks! |
| 23:34 | seangrove | ,(partition-by even? (range 0 10)) |
| 23:34 | clojurebot | ((0) (1) (2) (3) (4) ...) |
| 23:34 | seangrove | Ah, no, that's wrong... |
| 23:34 | seangrove | group-by? |
| 23:34 | ddellacosta | hmm, that's not was I was hoping for |
| 23:34 | ddellacosta | yeah, I mean, it's definitely something in this family |
| 23:35 | ddellacosta | yep, perfect |
| 23:35 | ddellacosta | ,(group-by #(= (:a %) "foo") [{:a "foo"} {:a "bar"}]) |
| 23:35 | clojurebot | {true [{:a "foo"}], false [{:a "bar"}]} |
| 23:35 | ddellacosta | seangrove: excellent, thanks again |
| 23:36 | seangrove | ddellacosta: No problem, I just looked at the coded where I used partition-by and I sort the collection first |
| 23:36 | ddellacosta | seangrove: ah, I see |
| 23:42 | bitemyapp | ddellacosta: comp? |
| 23:42 | bitemyapp | ddellacosta: you could do it with reduce. |
| 23:42 | ddellacosta | bitemyapp: didn't try comp |
| 23:43 | bitemyapp | ,((comp (partial filter even?) (partial remove string?)) (range 10)) |
| 23:43 | clojurebot | (0 2 4 6 8) |
| 23:43 | ddellacosta | bitemyapp: yeah, reduce would work too I guess. Lots of ways to do it. The thing I like about group-by is it fits what I'm trying to do conceptually perfectly, which is split a group apart based on a predicate though. |
| 23:43 | bitemyapp | ddellacosta: ^^ |
| 23:43 | bitemyapp | oh, okay, well if that works. |
| 23:43 | ddellacosta | bitemyapp: the thing is, comp is just giving me one set of results, isn't it? I need both the matches and non-matches |
| 23:44 | ddellacosta | bitemyapp: which is why I was thinking of something in that family, but didn't quite know until seangrove suggested group-by |
| 23:45 | bitemyapp | ddellacosta: yeah when you said filter and remove I assumed that was literally what you wanted |
| 23:45 | ddellacosta | hmm, bummer that I can't use a boolean like a keyword with a hash though. |
| 23:45 | bitemyapp | it does sound like group-by is what you want |
| 23:45 | ddellacosta | bitemyapp: yeah, it's pretty perfect for this specific scenario. |
| 23:45 | ddellacosta | bitemyapp: in general I think I use filter/remove too much actually |
| 23:46 | `cbp | :-o |
| 23:46 | ddellacosta | should start grabbing comp more off the bat, I'm less comfortable with it |
| 23:46 | seangrove | juxt? |
| 23:46 | clojurebot | juxt is the bestest option though if it doesn't weird you out |
| 23:46 | ddellacosta | haha |
| 23:46 | seangrove | I don't think juxt is appropriate, but it always seems to come up right about now |
| 23:46 | ddellacosta | yeah, I still feel like I don't know what the hell I'm doing when I use juxt |
| 23:46 | ddellacosta | I really need to practice more |
| 23:47 | seangrove | There's always 4clojure |
| 23:47 | seangrove | I'd like to see some of the medley stuff move into core |
| 23:47 | ddellacosta | seangrove: you know, I got through the first 50 or so when I started learning clojure, and haven't gone back |
| 23:47 | seangrove | Especially mapping a function over a map's keys/values and getting a modified map back |
| 23:47 | ddellacosta | seangrove: I really should--I've learned so much since then |
| 23:47 | ddellacosta | seangrove: what's medley? |
| 23:47 | ddellacosta | now my curiosity is piqued |
| 23:48 | ddellacosta | ah, this? https://github.com/weavejester/medley |
| 23:48 | ddellacosta | neat |
| 23:49 | ddellacosta | oh, yeah, some awesome stuff there |
| 23:49 | ddellacosta | dissoc-in seems like a no-brainer, for example |
| 23:49 | ddellacosta | filter-keys/-vals too would be pretty natural to include in core methinks |
| 23:49 | ddellacosta | neat |
| 23:50 | seangrove | Well, prismatic's plumbing has some similar functions |
| 23:51 | seangrove | ddellacosta: If you haven't started using dommy, well, now's a good time to look ;) |
| 23:51 | seangrove | Thoroughly impressed with it |
| 23:51 | ddellacosta | seangrove: ah, man, I just finished porting so much stuff to domina. |
| 23:51 | `cbp | ,(let [m {:a 1 :b 2 :c 3 :d 4}] ((juxt :a (apply juxt (disj (set (keys m)) :a))) m)) |
| 23:51 | clojurebot | [1 [3 2 4]] |
| 23:51 | ddellacosta | seangrove: that said, really not happy with it, I wish dommy had been more mature when I started |
| 23:51 | ddellacosta | or rather, that I'd known about it |
| 23:52 | seangrove | ddellacosta: Probably a mechanical-ish transformation. But if domina works for you (it barely did for us), then there's no worries |
| 23:52 | ddellacosta | for example, hear the crickets chirping: https://github.com/levand/domina/issues/60 |
| 23:53 | ddellacosta | seangrove: it works, mostly...but the problem is, I think, that wrapping Google Closure is fundamentally problematic. It really uses a different paradigm. |
| 23:53 | ddellacosta | seangrove: and domina doesn't make great choices at many points, AND the response from the dev team is painfully slow. |
| 23:54 | seangrove | ddellacosta: Well, dommy's approach seems much smarted to me anyway. Tradeoffs in both directions, but the precompile-everything-possible with a lovely api is great |
| 23:54 | ddellacosta | anyways, enough griping, I'll look into dommy. |
| 23:54 | ddellacosta | seangrove: yeah, that sounds nice, and is the direction we're heading in anyways. Will definitely be investigating it further. |
| 23:55 | seangrove | ddellacosta: What company/product are you working on again? |
| 23:56 | seangrove | bitemyapp: Saw you popup on the nunjuks hn thread, but selmer isn't client-side, right? |