#clojure logs

2013-10-24

00:05akurilinQuick 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:12ToBeReplacedakurilin: i use ScheduledThreadPoolExecutor directly
00:13muhooakurilin: there's at-at, and there's a new library raynes did too that's more like a cron
00:14akurilinmuhoo, I was looking at chime as well, seems super minimalistic and uses clj-time pretty heavily
00:14akurilinToBeReplaced, that's fair, looks like a lot of these libs are just wrapping it
00:15muhooakurilin: https://github.com/Raynes/moments
00:16akurilinmuhoo, that's cool! Wasn't there on clojure toolbox
00:20akurilinHm probably more inclined to go with Raynes' stuff for now, let me try that.
00:25arrdemI feel like one could/should build a crontab like dsl atop that...
00:25muhoothat'd be * * * * * funny
00:38marcopolo2anyone know is I can do anything asynchronous inside pedestal app transactions?
00:54akurilinSay 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:55akurilinIt'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:55akurilineither because of the network, or maybe the API starts throttling etc.
00:55akurilinI think I read somewhere where for email batch spamming people were using queues and just slowly plowing through them
00:56akurilinmaking sure the APIs would respond positively
00:56bjaaha, my app's configuration is finally sane
00:57bjaI 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:57bjanot littering my app with (get env :random-setting $DEFAULT) is a good feeling
00:58bjajust define things like (setting "name" default)
00:58bjaand then config/name is a symbol that be referenced throughout
01:14bitemyappakurilin: clj-http retries failed requests.
01:14bitemyappakurilin: you can use things like robert.bruce to customize retry logic as well.
01:39ToBeReplacedakurilin: this may sound like flamebait, but i'd avoid moments and chronicle unless your goal is "get done now"
01:39ToBeReplacedakurilin: 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:41ToBeReplacedif 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:57bitemyappakurilin: I'd tend to agree with ToBeReplaced.
01:57bitemyappmoments is pretty cool though :)
02:37akurilinToBeReplaced, bitemyapp , thanks for clarifying, sorry for late response.
02:38akurilinbitemyapp, 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:38akurilinbitemyapp, so say I were to make a hundred futures to make clj-http calls
02:38akurilinthere's probably some sort of physical port limit in place
02:39akurilinor the pipe would get clogged
02:39akurilinor something else
02:39akurilinI'm just not really fully conscious of these limitations right now
02:40creeseAre there any good libraries for marshalling API requests and responses?
02:41akurilinbitemyapp, 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:46bitemyappakurilin: do not spam futures.
02:46bitemyappakurilin: do not spam external APIs.
02:46tsdhHi. 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:51jared314tsdh: are you using lein or straight mvn?
02:52onenesstsdh: 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:52ambrosebstsdh: hacking clojure.core?
02:52tsdhjared314: It's clojure itself, so maven.
02:52tsdhambrosebs: yep
02:52tsdhoneness: Ah, mvn -Dtest=testclass google says. I'll try that.
02:53ambrosebstsdh: I don't know, I've have that problem myself.
02:54tsdhHm, "mvn test" seems to compile everything, too.
02:57andyfingerhuttsdh: Have you looked under "How To Run All Clojure Tests" on this wiki page? http://dev.clojure.org/display/community/Developing+Patches
02:57tsdhandyfingerhut: Not yet. Thanks.
02:57andyfingerhuttsdh: Or rather, just below that under "Run An Individual Test"
02:58tsdhandyfingerhut: Ah, that's it. Thanks!
02:59andyfingerhuttsdh: No problem. I don't have it memorized how to do it, but I remember where to look it up :-)
03:03akurilinbitemyapp, I understand, still doesn't really help me gauge what is considered "spam"
03:03akurilinobviously each API owner has its own policy
03:04akurilinanyways, I'll see if I can dig up some info on this around
03:05tsdhIf 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:07akurilinbbl
03:08bitemyappakurilin: pretty easy to dispatch too many futures and run out of threads if you're not careful.
03:08bitemyappthe agents thread pool is 1:1 OS threads.
03:09bitemyappyou can't fire those off willy-nilly against an arbitrarily large coll.
03:14andyfingerhut /whois GOSUB
03:14andyfingerhutsorry. Must have had whitespace there.
03:23tsdhHm, 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:24tsdhConcretely, (some-form) is a (deftype ...) form that triggers a CompilerException.
03:25tsdhThe same applies with (reify ...). (defrecord ...) on the other hand triggeres the same exception, and there it's passed through and my test succeeds.
03:33andyfingerhuttsdh: Can you share the (deftype ...) form that triggers a CompilerException that you are trying?
03:41tsdhandyfingerhut: Sure, but it doesn't trigger the CE without my other patch. ;-)
03:41tsdhandyfingerhut: Check CLJ-888 and the attached patch.
03:41tsdhandyfingerhut: The tests that fail due to swallowed CE are commented out with a big FIXME.
03:42andyfingerhuttsdh: Got it. I may take a look here, but don't know what is going on with the swallowed exceptions yet.
03:45iSocket&"I worship his Shadow"
03:45lazybot⇒ "I worship his Shadow"
03:47johannhey guys
03:47iSocketjohann,
03:47iSocketI Worship His Shadow
03:48johannhas anyone had issue with heroku deployment and procfiles?
03:49johannmy app is crashing when i deploy it and heroku hasn't been recognizing my procfile so i am hoping that would fix it
03:50johanniSocket--I Hope He Reciprocates Your Shadow Worship
03:59andyfingerhuttsdh: 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:00andyfingerhuttsdh: Any particular reason you are using macroexpand there?
04:00tsdhandyfingerhut: Well, it should suffice to trigger the excetion, I've thought. But eval is as fine. I'll try the others. Thanks!
04:02andyfingerhuttsdh: 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:02andyfingerhuttsdh: Sorry, wrong name. It should be eval-in-temp-ns
04:04tsdhandyfingerhut: The worst side effect would be that some new type was defined in the test namespace, so I guess that's no issue.
04:04tsdhandyfingerhut: Indeed, now all tests pass!
04:06tsdhandyfingerhut: Great, I've updated the patch of CLJ-888.
04:07andyfingerhuttsdh: 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:15andyfingerhuttsdh: 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:15tsdhandyfingerhut: Ah, that would make sense. So (doall (macroexpand ...)) should also work.
04:16andyfingerhuttsdh: Makes my head swim to try to imagine what is going on there.
04:17tsdhandyfingerhut: Indeed, (doall (macroexpand ...)) works. So it's really caused by lazyness.
04:18andyfingerhuttsdh: Crazy stuff
04:19tsdhandyfingerhut: Totally. :-)
04:20andyfingerhuttsdh: eval is used all over in the Clojure tests, so that seems preferable to me over macroexpand anyway, for this kind of test.
04:22tsdhandyfingerhut: I have no preference.
04:39borkdudewhy does this get indented like it is? https://www.refheap.com/20129
04:39borkdudeI mean, why don't the maps have an indenting of 2?
04:39borkdudeclojure-mode 2.1.0
04:39ddellacostado I need to escape this somehow if I'm comparing (with = )? org.docx4j.wml.R$Tab
04:40ddellacostaborkdude: no idea, but presumably it's because you haven't close the s-expression?
04:40ddellacosta*closed
04:41ddellacostaalthough, I know different s-expressions tab differently.
04:41borkdudeddellacosta what do you mean, I didn't close it?
04:42ddellacostaborkdude: 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:42ddellacostasorry I'm not helpful on this one.
04:50borkdudethis is kind of not so nice, because I don't want to fix indentation by hand
04:53llasramborkdude: I'm pretty sure that's standard indentation
04:57borkdudehmm ok
05:00clgvborkdude: talking about CCW?
05:00borkdudeclgv emacs / clojure-mode
05:01clgvah ok, just guessed because of the recent release ;)
05:02borkdudethen at least I'm not crazy. I think this makes sense https://www.refheap.com/20130
05:05clgvborkdude: afaik the second is standard
05:05borkdudeclgv 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:07clgvborkdude: because in a list the first element is special as opposed to a vector where all have equal importance
08:00clgvdoes type hinting not imply interfaces and superclasses automatically?
08:03llasramclgv: It does
08:03llasramAs in, the type implies all those things, and so does the type hint
08:03clgvweird in a separate function it works as expected but not in a deftype...
08:04llasramOn deftype field or as part of a method signature?
08:04clgvon a deftype field
08:05llasramHmm, odd. That should work fine.
08:05clgvit works for methods of the class, but not the ones of the super class
08:05clgvI manually hinted the subclass which did it but that is really strange
08:06clgvoh wait. I think I found the odd piece^^
08:06clgvyou'll always get punished if you write (protocol-method [this] ...) and you really do not need `this` instead I need the field ;)
08:08clgvshould have used the checking macro for the type info
09:44FragDoctorHey
10:36ohcibihi, 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:37justin_smithwhat about generating all the three digit numbers first, and then converting each one into a five digit palindrome?
10:38justin_smithno need for nested anything
10:39sszzqquse lein test clojure code is slow. If have any more rapid way?
10:40tbaldridgesszzqq: tests are just functions, you can run them from the repl
10:40tbaldridgedo (require '[my.namespace :reload true])) to reload namespaces after recompilation
10:40justin_smithyou can require the namespace with the tests in it from a repl, then (clojure.test/run-tests)
10:41tbaldridge*reload namespaces after modification
10:41sszzqqI want save the edit the code in editor, repl have not syntax highlight..
10:41justin_smithsszzqq: you can save in an editor, then (require '[] :reload)
10:42justin_smithno need to do any coding directly in the repl
10:43sszzqqjustin_smith: what file-name should be use, then in repl: (require '[] :reload) couold load it and test it?
10:44justin_smith(require '[the.namespace.that.changed] :reload)
10:44justin_smithI don't know the name of the namespace, you need to fill that in
10:44justin_smithafter editing, of course
10:45sszzqqjustin_smith: thanks, i see it ..
10:46justin_smithohcibi:
10:47justin_smith,(take 5 (for [a (range 10) b (range 10) c (range 10)] [a b c b a]))
10:47clojurebot([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:47justin_smith,(take 5 (drop 400 (for [a (range 10) b (range 10) c (range 10)] [a b c b a])))
10:47clojurebot([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:47logicprogare there any plans to have cljs target asm.js ? that would be insane
10:48justin_smithlogicprog: I don't know asm.js - is it really that likely to outperform the jvm?
10:48dnolenlogicprog: no, we'll likely benefit from asm.js anyway
10:49dnolenlogicprog: I don't see think any browser except FF will actually support the AOT part of it.
10:49logicprogdnolen how cam we benefit if we domt target it?
10:50dnolenlogicprog: because engines are optimizing around asm.js benchmarks now
10:50dnolenlogicprog: so if you write asm.js style code it will be fast
10:51dnolenlogicprog: but as far as compiling CLJS to asm.js itself, I don't really see the benefit, at least yet.
10:51logicproghow does this help me if cljs does not emit asm.js?
10:52ohcibijustin_smith: thanks...
10:52dnolenlogicprog: there's an incredible amount of bit twiddling and integer arithmetic in CLJS data structures, you'll benefit
10:53justin_smithohcibi: now I notice you were only using 3 nestings, so really all I added was the for semantics to replace the nested maps
10:54xsynjust so I understand. Does clojurescript compile to js to then compile on the v8?
10:54jtoyhow 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:54dnolenlogicprog: the other place that asm.js helps is memory usage, but not really of any use to us - we need GC
10:54justin_smithohcibi: but yeah, that is what for is good for, replacing nested mappings
10:54ohcibijustin_smith: I assume what I did is just what most functional newbies would do 8-))
10:55ohcibijustin_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:55justin_smithohcibi: even coming from scheme and ocaml, I used nested map before I realized how much simpler for was
10:55jtoyim sure this is a simple fix, but I cant get it to work
10:55justin_smithohcibi: no prob, glad I could help
10:56justin_smithjtoy: 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:57jtoyjustin_smith: no, I dont think i have any
10:59justin_smithjtoy: you could attach jdb to the dt-socket, if there is a way to pause and wait for the debugger inside your code
11:00justin_smithI 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:02jtoyjustin_smith: is there a clojrue way to do that? I have never programmed any java
11:02justin_smithanother 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:02justin_smithjdb is language agnostic
11:03justin_smithit provides an interface to the jvm, like gdb does to raw bytes
11:03justin_smithso you just need to be able to translate from the jvm names of yoru functions / bindings to their actual names
11:05justin_smithso (fn -main [& args] (read-line) ...) - run it, before entering a line of input, connect to the dt-thread with jdb or jvisualvm
11:06jtoyjustin_smith: ok thanks, im goign to test it
11:06justin_smithjvisualvm may not be able to set breakpoints or step through code, but it gives a graphic overview of threads etc.
11:07justin_smithon 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:07justin_smithjvisualvm comes with java
11:21edwAnyone else get "pp does not exist" exceptions when firing up nREPL in Emacs? <https://gist.github.com/edw/7138535&gt;
11:22edw(Using most recent CIDER, but it's been going on sporadically for the last month or so.)
11:22ndpYeah, I do occasionally
11:22ndpNever made sense to me, I don't require pp in any Lein profiles
11:23edwndp: 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:24mdrogalisCider.. Huh, is nrepl not a thing anymore?
11:24justin_smithI think cider extends nrepl, trying to be an all around "emacs ide" thing
11:25rkneufeldnrepl.el has become "cider"
11:25justin_smithoh!
11:25mdrogalisWell, I'm late to the party.
11:25llasramI think the name is mostly that people were confusing nREPL and nrepl.el
11:25llasramso nrepl.el -> cider
11:25mdrogalisllasram: I see, thanks. :)
11:26edwIn 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:26llasramnice
11:26mdrogalisedw: Kind of the same problem with the Java platform and Java language having the same name.
11:26justin_smithslime always made me think of nethack, eating slime molds
11:27justin_smithalso, 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:27edwmdrogalis: This "the thing is broader than its single, definitive implementation" idea is relatively new to many languages.
11:28justin_smithedw: you would think lisps would know better :)
11:28edwjustin_smith: Using SLIME to talk to Scheme48 felt like being in an abusive relationship; I'm happy to have moved on.
11:28edwjustin_smith: Implementations for everyone!
11:28justin_smithheh, it worked nicely with cmucl / sbcl
11:29justin_smithand 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:30justin_smithin the future, every language will be like linux, with thousands of cosmetically different "distros"
11:30xsyngawd
11:30xsynthat sounds horrific
11:31justin_smithtry, the new snowjure, just like clojure, but let is renamed to ☃
11:31justin_smithand defn is renamed to ❄
11:32pjstadigjustin_smith: i'm in!
11:33justin_smiththe sweet thing, is you can bootstrap it from an existing clojure in two lines of code :)
11:33justin_smithwell maybe more now that I think about it...
11:34TimMc(defmacro ☃ [& stuff] `(let ~@stuff))
11:35justin_smithheh
11:35justin_smithwell, the trick is putting it in clojure.core so it gets pulled in by the default refer-clojure
11:35pjstadigjustin_smith: https://github.com/sybilant/sybilant/blob/old-master5/sybilant/test/munging.syb#L4
11:36justin_smithso I think you need more than two lines
11:36justin_smithpjstadig: nice
11:37justin_smithpjstadig: sybilant looks interesting, how mature is it?
11:37pjstadigjustin_smith: not really, still very much a work in progress
11:37justin_smithgood enough to be a less painful way to play with x86 assembly?
11:37pjstadiga long term project
11:37pjstadigjustin_smith: no such thing
11:38justin_smithheh
11:38justin_smithyou mean x86 assembly is the least painful thing of all things? I am dubious
11:39pjstadigi 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:39pjstadigi'm the most unlikely person to create such a language
11:40justin_smithheh
11:40pjstadigbut typed assembly is interesting, and sybilant will have it
11:40justin_smitheven just a good enough binding of assembler to a lispy syntax is interesting to me
11:40pjstadigsomething like this https://github.com/sybilant/sybilant/blob/old-master5/sybilant/test/types.syb
11:40justin_smithI remember reading about c-- ages ago, and found that very fascinating
11:40justin_smithc-- grew into msft clr
11:41cmajor7what 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:45sluukkonenstart with paralleloldgc
11:45hyPiRioncmajor7: hard to tell in general. The best is to try them out, really.
11:45sluukkonenexplore other options if you experience full GC's with it
11:46ystaelI'm having a problem with ztellman/byte-streams where it does not seem to load any of the conversions
11:47ystaelAfter I (require '[byte-streams :as bs]) in a lein repl, (bs/possible-conversions String) evaluates to nil
11:47ystaelAnyone know a possible cause for this issue?
11:47justin_smithif 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:47cmajor7hyPiRion, 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:47justin_smithunless the app is stateful
11:48ngwhow do you manage configuration in a compojure web app?
11:49jtoyjustin_smith: I fied it by changing for to doseq, why would that fix it?
11:49justin_smithngw: at my shop (doing brochureware web sites) we have resources/config/<environment>.clj
11:49hyPiRioncmajor7: What do you value the most? Obviously stop-the-world will make response times more varying, but will give a better average
11:49justin_smithjtoy: for is lazy, nothing was consuming it so it realized nothing
11:49justin_smithon a repl it gets consumed by the print part of the loop
11:50ngwjustin_smith: and you use normal clojure data types?
11:50justin_smithngw: yeah, it is a standard clojure edn file
11:50justin_smithwe do a deep merge with a "defaults" provided by one of our libs
11:50sluukkonencmajor7: 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:51sluukkonenyou'll likely achieve the best throughput and latency in that case
11:51justin_smithngw: 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:51justin_smithfor obvious reasons
11:52justin_smithotherwise github may just be our weakest security link
11:53logic_progwhat is a godo resource on "recursion = low level, use higher level abstractions"
11:54cmajor7sluukkonen: yep, that is my thinking as well. thank you.
11:55xuseris it usual to see the Java collections framework being used in Clojure?
11:58justin_smithxuser: only when you care more about performance than sanity
11:58justin_smithless glibly, sometimes it is nice to have something like a dag lib that is mature and featureful in java
11:59justin_smithhttps://github.com/aysylu/loom for example, has good reason to use java data types
12:02silasdavisbetter way to remove first char in string than: (comp (partial apply str) rest) ?
12:02hyPiRion,(subs "foo" 1)
12:02clojurebot"oo"
12:02justin_smithyeah, that is probably best
12:02justin_smithforcing strings to chars kills performance
12:03silasdavisthanks for that
12:05justin_smithlogicprog: http://blog.fogus.me/2011/03/09/recursion-is-a-low-level-operation/
12:07justin_smithlogicprog: hmm - actually that asserts the case, but doesn't really give full exposition :(
12:07silasdavisis there a nicer way to check if a string is a URI other than trying to create one and catching the execption?
12:08justin_smithsilasdavis: for URL http://commons.apache.org/proper/commons-validator/apidocs/org/apache/commons/validator/UrlValidator.html
12:09justin_smithI dunno about more general URI
12:14justin_smithsilasdavis:
12:14justin_smith,(do (time (dotimes [i 10000] (try (assert false) (catch AssertionError e nil)))) (time (dotimes [i 10000] (if false true))))
12:14clojurebotjustin_smith: No entiendo
12:14justin_smitherr
12:15justin_smithanyway, if you run that code, you will see how much slower catching an exception is than checking a boolean
12:15justin_smithif the performance matters at all
12:15xuserjustin_smith: thanks
12:18silasdavisthat and that it's ugly
12:19justin_smithyeah, there's that too
12:19justin_smithone of those problems you can fix with a macro, the other not so much :)
12:19silasdavisif I registered a custom URLStreamHandler
12:19silasdaviswould clojure's slurp use it to read the URL
12:19silasdavis?
12:20silasdavisthinking about doing this for s3
12:20silasdavisnot clear to me from the source of slurp whether it would work
12:20silasdavissuspect not
12:20llasramIt would
12:20llasramIt would work
12:21silasdavisah cool
12:22silasdavisI'll take that approach then, how does make-reader do that?
12:24llasramIt just opens a reader on the result of calling the URL's openStream() method
12:25xuserjustin_smith: I'll skip this http://docs.oracle.com/javase/tutorial/collections/index.html for now then to finally start getting into Clojure ;)
12:26justin_smithsilasdavis: I have a fork of weavejester's s3 lib, specifically so I could upload streams
12:26justin_smithspecifically 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:27justin_smithif generalized stream upload to s3 helps you I can link the change, it is a small patch
12:27silasdavisjustin_smith: did you write your own URLStreamHandler?
12:29justin_smithno, 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:30justin_smithbut 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:30justin_smithclj-aws-s3 took for granted that a multi-part upload would come from disk
12:31justin_smithI have no idea if any of this is relevant for what you need from your URLStreamHandler though
12:31justin_smithwhat are you trying to do?
12:31staaflany way to splat a macro?
12:31staafl(apply and '(true true)) gives me an error
12:31llasramstaafl: none that are what you likely actually want
12:32staaflllasram, what's a sane solution?
12:32llasramstaafl: What are you trying to do?
12:32staaflllasram, aggregate boolean values
12:32llasramWell, you know, at a higher semantic level :-)
12:32llasramOk,
12:32justin_smith(defmacro andl [& args] `(and ~@args)) ?
12:32justin_smitherr
12:33llasramheh
12:33justin_smith(defmacro andl [lst] `(and ~@lst)) ?
12:33justin_smiththat may be what you want, but that is not much different from every?
12:33silasdavisjustin_smith: I can't get URL to accept the s3 protocol
12:33znDuffHeh.
12:33silasdavisget MalformedURLException unknown protocol: s3
12:33staaflCompilerException java.lang.RuntimeException: Unable to resolve symbol: quote in this context,
12:34llasram,(reduce (fn [_ x] (if x true (reduced false))) true [true true true true true])
12:34clojurebottrue
12:34llasram,(reduce (fn [_ x] (if x true (reduced false))) true [true false true true true])
12:34clojurebotfalse
12:34llasramstaafl: ^^ I think that's what you want for `and`
12:34justin_smithsilasdavis: ahh, going the other way - we are converting s3 via rgex into protocol-relative links (http or https)
12:34justin_smith*regex
12:34llasramYou can turn it into a function, for prettiness
12:35staaflllasram, "reduced"
12:35staafldoes that short circuit the reduce?
12:35justin_smithllasram: (partial every? identity)
12:35silasdavisanyone know how to register a custom URLStreamHandler by any chance?
12:35llasramstaafl: Yep
12:36llasramjustin_smith: Ok yeah, that is shorter :-)
12:36staaflllasram, thanks
12:36llasramI just have reducers on the brain right now
12:36staafljustin_smith, thanks to you too
12:36staaflactually, I think I'll use (every? identity lst)
12:36xuserznDuff: you have a list?
12:36llasramFor the best
12:37justin_smithdaily mail is a big one, also soundcloud
12:38justin_smiththere should be a list, if there isn't
12:38justin_smith(re: bit sites running clojure)
12:39mavbozohi, is there any way to delete html tag in enlive deftemplate?
12:52technomancythere's one on the dev.clojure.org wiki, but you can't edit it
12:59justin_smithtechnomancy: http://dev.clojure.org/display/community/Clojure+Success+Stories ?
13:00hyPiRionheh, last edited 10 months ago
13:00justin_smithyeah, and the two biggest examples I know of in terms of degree of usage aren't even on that list
13:01technomancythat's the magic of wikis that you can't edit
13:01justin_smithalso, needs a "how and how much" column
13:01technomancyever wonder what were the biggest clojure companies in 2011? now you can know.
13:03hyPiRionheh
13:04gfredericksI do not understand vars
13:06gfrederickswhat is going on here? https://www.refheap.com/20137
13:07justin_smithgfredericks: weird, I got :thread-bound
13:07justin_smithwhich is what you expected, right?
13:09hyPiRionI got :origin-root but hm
13:11hyPiRiongfredericks: I think you're creating a var containing a var
13:11hyPiRionWorks fine with let.
13:13justin_smithyeah, when you def something to be a var, that creates a var var right?
13:13justin_smithwhich is why the @?
13:14justin_smithso why do you guys get :origin-root and my repl gives me :thread-bound?
13:14justin_smith*clojure-version* => {:major 1, :minor 5, :incremental 1, :qualifier nil}
13:15hyPiRionsame here
13:18justin_smithso this needs push-thread-bindings because binding would just grab the symbol, and not the var pointed at by the symbol, right?
13:29hyPiRionyeah, but I would guess the metadata fell off the var for some reason
13:32si14cemerick: hi. can I ask you a question about Friend?
13:33cemericksi14: shoot
13:36si14cemerick: 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:37broquaintI'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:37broquaintIs that situation familiar to anyone?
13:38technomancybroquaint: melpa serves unstable packages by design; I highly recommend sticking with marmalade
13:38cemericksi14: 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:39broquaintThanks, 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:39technomancybroquaint: I recommend using nrepl.el until cider stabilizes
13:39coventrybroquaint: Why do you want to use cider?
13:39broquainti.e http://marmalade-repo.org/packages/cider - Package "cider" doesn't exist
13:40broquaintcoventry: Because I liked nrepl and prefer my REPLs in emacs.
13:40broquainttechnomancy: Thanks I'll switch back to nrepl in the mean time :)
13:40coventrybroquaint: Take technomancy's advice, then.
13:40broquaintIndeed :)
13:40znDuff(ie. "back to nrepl", vs "back to nrepl.el").
13:40technomancywe get people with broken melpa packages in here practically every other day =\
13:41si14cemerick: ok, thank you. What's the best doc on this? Friend's README/source code? :)
13:41technomancythe fact that nrepl.el was deleted from melpa is just; ugh
13:42technomancyI guess melpa users are just accustomed to dealing with random breakage
13:43cemericksi14: 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:43cemerickThere's http://friend-demo.herokuapp.com, but that covers more basic matters than e.g. logging particular workflow requests
13:48broquaintHrm ... same problem with nrepl 0.2.0.
13:48broquaintnrepl.el
13:51si14*(without /me)
13:51cemericksi14: np, FWIW :-)
14:07tsdhHow can I stop java.lang classes being imported in a namespace so that that namespace may define a var Package for example.
14:09tsdhI.e., something like (:refer-clojure :only []) for classes.
14:09mtppick better names? :)
14:09tsdhmtp: The namespace is generated from some model.
14:10mtpgenerate better names?
14:10mtp:p
14:12tsdhIf the model defines a Package, then there is no better name than that. Adding articifial prefixes like +$+fuddle+$+ is not what I want.
14:12tsdhHm, if there was a way to enumerate all java.lang classes, I could `ns-unmap` these symbols...
14:15arrdemoh right. great. there goes the nrepl.el package. again.
14:18tsdhAh, got it. I can iterate over `ns-imports' and `ns-unmap' the syms.
14:28rasmustowhy not "clide"
14:28technomancywhy not... nrepl-dot-el.el
14:29rasmustoi pronounce it en-prep-uhl-ehl
14:29technomancyman, the one time I go and pick a boring name for a project and it's not good enough
14:29rasmustoshould have gone with nrepel
14:29cemericktechnomancy: see, shouldn't slack off so hard :-P
14:29technomancynot bad
14:30hiredmanenrepal-dot-ee-el.el
14:30technomancyhiredman: unacceptable; that filename is not representable on DOS filesystems
14:31rasmustonrelpael
14:31technomancy(this is an actual thing real humans say unironically on emacs-devel)
14:31technomancywell, one specific human
14:32johannhi 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:32technomancyyou think having to deal with com.defunctstartup package names are bad, try dealing with 8.3 filenames
14:32cemerickthat's a good domain name!
14:32technomancyjohann: are you doing full AOT during push?
14:34johanntechnomancy: 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:35technomancyjohann: highly recommend generating an uberjar at push time
14:35technomancyhttps://devcenter.heroku.com/articles/getting-started-with-clojure
14:37arrdemgfredericks: your swearjure presentation was glorious.
14:38johanntechnomancy: i was having issue using an uberjar earlier. i will read through this carefully and try again! thank you :)
14:39technomancyjohann: there's a lot more that can go wrong when using lein at runtime; uberjars are a lot simpler
14:41johanngotcha. let me see what arises
14:41seangrovetechnomancy: uberjar + AOT?
14:41technomancyseangrove: yup
14:41johanntechnomancy: does it make a difference that im using httpkit?
14:41technomancyjohann: no
14:42technomancyseangrove: your doppleganger is screwing with your tab completion
14:42technomancyor rather, everynoe else's tab completion
14:42dnolenBronsa: let me know when 0.7.10 goes out
14:45hyPiRionhttp://www.infoq.com/presentations/swearjure :D
14:46johanntechnomancy: im getting the following error when i try to push it up to heroku https://gist.github.com/anonymous/0f341d99dd3b9ee18cb0
14:47hyPiRion(inc gfredericks)
14:47lazybot⇒ 31
14:48Bronsadnolen: 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:49dnolenBronsa: if you want to hold it up for that no big deal
14:49technomancyjohann: just `lein uberjar`
14:49dnolenBronsa: there's a few other things I'd like to get into CLJS before the next release as well
14:50arrdemhyPiRion: I almost lost it at "swearjure in production"
14:50johanntechnomancy: after that i assumed that i have to set the :uberjar-name property in the project.clj right?
14:50technomancyjohann: maybe you should start at the top. =) :uberjar-name in project.clj should be enough on its own.
14:51Bronsadnolen: 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:51hyPiRionarrdem: yeah, I love it
14:51arrdemhyPiRion: what part did you play in this madness?
14:52hyPiRion~quicksort
14:52clojurebotquicksort is https://www.refheap.com/paste/284a0552a6b69c6037faa2db5
14:52hyPiRionand hello swearjure, of course
14:52hyPiRion$google hello swearjure
14:52lazybot[hyPiRion/hello-swearjure · GitHub] https://github.com/hyPiRion/hello-swearjure
14:53technomancyI wonder if swearjure is limited enough for genetic algorithms to operate on it sensibly
14:54dnolenBronsa: k
14:54arrdemI 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:54Bronsadnolen: 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:55technomancywhoa bronsa is into swearjure too?
14:55technomancy=)
14:55hyPiRiontechnomancy: yeah, he's secretly making an analyzer for it
14:56coventryWhat the heck is going on with ##(#('%& '%& '%&)) ?
14:56lazybot⇒ rest__28561#
14:57arrdemcoventry: it's a gensym. somehow.
14:57BronsahyPiRion: ssssh don't tell them
14:57dnolenBronsa: hm, that seems useful - not sure where we'd use that in the compiler, but it does seems neat for user macros?
14:57coventryarrdem: Yeah, I meant how is that producing the gensym?
14:57technomancyhyPiRion: do swearjure programs typically depend on the order of compilation via actual gensym values?
14:57dnolenBronsa: what was the use case aredington had in mind?
14:58bitemyappYou people will use Swearjure but Haskell is a bridge too far? Weirdos.
14:58arrdem(inc bitemyapp)
14:58lazybot⇒ 5
14:58gfrederickswhat my swearjure presentation is online?
14:58mdrogalisWatching the Swearjure talk. Pretty funny. :)
14:58Bronsadnolen: he said he's working on a static analyzer, I think he needs to map back to the original clojure source
14:58coventrybitemyapp: I've been reading John Hughes lately. He makes an interesting case for monads.
14:58hyPiRiontechnomancy: no, not generally. My quicksort used one to check if I was at the end of a list
14:59hyPiRionBut I don't think it's common practice. I've used few in production at least.
14:59dnolenBronsa: interesting, though it seems a bit strange to want to do that at the level of forms?
14:59seangrove(inc gfredericks) ; good fun!
14:59lazybot⇒ 32
14:59Bronsacoventry: ##'#(%&)
14:59lazybot⇒ (fn* [& rest__28573#] (rest__28573#))
14:59bitemyappcoventry: 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:00hyPiRion,'#('%& '%& '%&)
15:00clojurebot(fn* [& rest__29#] ((quote rest__29#) (quote rest__29#) (quote rest__29#)))
15:00bitemyappcoventry: 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:00bitemyappcoventry: maintaining the useful "boxing" of monadic results in a dyn-lang is a matter of discipline rather than tooling at the moment.
15:00hyPiRionReads as: Call the symbol on the same symbol, and return the symbol if the symbol doesn't contain the symbol.
15:01technomancyhyPiRion: I'd expect that to need `%& though
15:01coventryhyPiRion, Bronsa: Oh, it was the default argument part I was missing. Thanks.
15:02coventrybitemyapp: Yeah, I can see how that would be a problem.
15:02hyPiRiontechnomancy: heh, to avoid naming collisions?
15:03bitemyappcoventry: it gets worse when you start getting into things like Monad Transformers.
15:03bitemyappcoventry: keeping the monad stack in your head and figuring when to lift and when to send a functor through would be insane
15:03technomancyhyPiRion: oh, it's expanded by the #() reader macro; I see now
15:03bitemyappI'm way too fucking lazy for that. I'd rather the compiler tell me I'm stupid.
15:03technomancyI was confused because plain '%& doesn't expand
15:03Bronsadnolen: 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:04hyPiRiontechnomancy: ah, yeah. It has to be done inside a function literal
15:05dnolenBronsa: sorry was busy w/ something else and didn't read closely, yes that makes sense.
15:05coventryInteresting that the function literal process gets a crack at them before their quoted.
15:06TimMccoventry: It doesn't, though.
15:06arrdembitemyapp: and does it do so often?
15:06Bronsacoventry: quoting happens after read-time
15:07TimMcWhat? Quoting is part of reading.
15:07bitemyapparrdem: of course - I'm stupid and the compiler is never wrong.
15:07BronsaTimMc: no, 'foo -> (quote foo) is part of reading
15:07bitemyapparrdem: I find GHC very very helpful when I'm writing Haskell code - especially in unfamiliar territory.
15:08TimMcgfredericks: It's weird to hear someone I've never met in person speak my name in a video. :-D
15:08BronsaTimMc: 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:09technomancybitemyapp: offloading some of the cognitive ovehread to your exocortex, as it were
15:09bitemyapptechnomancy: that's precisely it.
15:09arrdemclojurebot: GHC is an exocortex
15:09clojurebotOk.
15:10technomancy"Computer, it's late. Tell me if this makes any sense."
15:10bitemyapparrdem: good call.
15:10gfredericksTimMc: I just put your face on infoq
15:10bitemyapptechnomancy: since I didn't have the experience of writing grench, how good of a job did OCaml do of catching you?
15:11technomancybitemyapp: it was extremely helpful
15:11technomancybitemyapp: I thought that OCaml wouldn't be as good at separating side-effects because it doesn't have the IO monad
15:11gfrederickshyPiRion: 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:11technomancyturns out returning unit gets you 80% of the way there
15:11technomancyor 80% of where I imagine "there" to be, having never been there myself
15:11hyPiRiongfredericks: no. All I know is that it works inside a let.
15:12bitemyapptechnomancy: 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:12gfrederickshyPiRion: as in (let [x @v] ...)?
15:13bitemyapptechnomancy: 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:13hyPiRiongfredericks: as in (let [v (doto (clojure.lang.Var/create ...))] ...)
15:13bitemyapptechnomancy: 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:13technomancyclojurebot: typed clojure is http://p.hagelb.org/typed-clojure.jpg
15:13clojurebotYou don't have to tell me twice.
15:14bitemyapptechnomancy: I like the Hotel California in the background. That's where they trap the bugs so they can never leave.
15:14technomancybitemyapp: there was one place where I wanted to use Option monadically and I would have had to pull in a 3rd-party lib
15:15technomancybut 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:15marcopolo2technomancy: hovercars and punchcards, that an interesting view of the future
15:16bitemyapptechnomancy: 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:16bitemyappthe features play off each other nicely.
15:16bitemyappthe STM containers in Haskell aren't nearly as "clean" or uniform as Clojure though.
15:16dnolencemerick: (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:16seangrove~typed clojure
15:16clojurebottyped clojure is http://p.hagelb.org/typed-clojure.jpg
15:16technomancybitemyapp: yeah, I wouldn't use OCaml for somewhere concurrency mattered
15:17marcopolo2dnolen: what about wrong arg count?
15:17gfrederickshyPiRion: oh I see; hmm
15:18cemerickdnolen: Seems like differing use cases really do want/need fine-grained control
15:18dnolenmarcopolo2: this is just getting rid of useless knobs - there won't be less warnings
15:18gfrederickshyPiRion: 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:18TimMcgfredericks: That was a good talk! :-D
15:18marcopolo2dnolen: ok
15:18dnolencemerick: ok sure, I'm also fine to leave it as is. Just wasn't obvious to me that anybody actually used these knobs.
15:19hyPiRiongfredericks: Can't explain it either :x. I'd guess it inlines the var reference inside the let for some reason?
15:19bitemyapptechnomancy: also strange is Clojure's lack of retry.
15:19bitemyappno orElse either.
15:20cemerickdnolen: 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:20seangrovednolen: What knobs currently exist?
15:20gfredericksTimMc: phew
15:20TimMcI like all the nervous laughter in the audience.
15:21TimMcAt least one person is thinking "Should I be taking notes? Oh no, what if my code isn't swearjure-compatible!"
15:21technomancyhahaha
15:21arrdemmore 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:21gfrederickstechnomancy's tweet afterwards was the best comment that has ever been made about anything I've done
15:22technomancyI don't even remember
15:22dnolenseangrove: :undeclared, :redef, :dynamic, :fn-var, :fn-arity, :fn-deprecated, :protocol-deprecated
15:22TimMc50 years from now, engineers will stand by the water cooler and complain about the swearjure-implemented financial software they have to maintain.
15:23gfrederickstechnomancy: you said it was "surprisingly G-rated", which is a reaction I've been trying to duplicate ever since
15:23TimMchaha nice
15:23technomancyoh right; hehe
15:23seangrovednolen: Thanks, would love to have cljsbuild fail on some of these
15:23seangrovecemerick: I haven't worked on cljsbuild at all, would it be a breaking change, or something that could be in a point release?
15:24TimMcgfredericks: Speak to me of this var within a var; it sounds naughty and I am intrigued.
15:24dnolenseangrove: 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:25gfredericksTimMc: https://www.refheap.com/20137
15:25gfredericksI'm just trying to get a thread-localable reference type
15:25gfredericksthat works correctly with bound-fn and friends
15:25gfredericksbut without being interned in a namespace
15:25seangrovednolen: I could work on that sometime next week
15:26seangroveAny existing design doc?
15:26stuartsierragfredericks: Not sure exactly what you're trying to do, but maybe with-local-vars would help.
15:27TimMcgfredericks: Oh huh.
15:28gfredericksstuartsierra: I tried that but the var seems to quit existing at the end of the scope? or something like that
15:28TimMctechnomancy: The "bug-free world" thing, when was that produced?
15:28dnolenseangrove: 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:28stuartsierragfredericks: yes
15:29seangrovednolen: Got it, will take a look.
15:29TimMcIf it's any time within the last 30 years I need to smack someone.
15:29technomancyTimMc: wish I had a source, sorry
15:29gfredericksstuartsierra: 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:29gfredericks(for testing)
15:29Bronsagfredericks: putting the push-thread-bindings inside the try seems to work
15:29gfrederickswaaat
15:29gfrederickseverything about this is weird
15:30stuartsierragfredericks: "hidden dynamic var" - three words that I never wanted to hear together ;)
15:31gfredericksstuartsierra: the use case is being able to safely parallelize tests that stub functions
15:31pepijndevosWhat is a good introductory piece on datomic?
15:31tbaldridgepepijndevos: theory or practical use?
15:31bitemyapppepijndevos: well datalog would be learndatalogtoday.com - Datomic? Maybe the Day of Datomic repo.
15:32bitemyappCraig Andera had a nifty presentation on some aspects of Datomic not long ago.
15:32pepijndevostbaldridge, something that would exaplin what datalog is well to someone from a more traditional background
15:32pepijndevosbitemyapp, link doesn;t work
15:33tbaldridgeRich's talks are pretty good: http://www.infoq.com/presentations/datomic-functional-database
15:33bitemyappBAH
15:33bitemyapppepijndevos: http://www.learndatalogtoday.org
15:33Bronsadnolen, cemerick: released 0.7.10
15:33tbaldridgepepijndevos: and in that one Rich actually pulls out Emacs in the middle of a talk...I thought I'd never see the day.
15:33cemerickyeah, it'll be a breaking v2 change
15:33gfredericksrich was using emacs at the first clojure conj
15:33dnolenBronsa: sweet
15:34tbaldridgepepijndevos: I've also heard good things about http://www.youtube.com/watch?v=ao7xEwCjrWQ but I haven't watched all of it yet.
15:34bitemyappOddly, he's using Aquamacs in the presentation.
15:34cemerickBronsa: thanks much; I'll tweak up the cljs patch once dnolen gives it a look
15:34pepijndevoshttp://www.learndatalogtoday.org
15:34bitemyapppepijndevos: yes.
15:35pepijndevoshttp://webchat.freenode.net
15:35technomancybitemyapp: 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:35pepijndevosoops
15:35bitemyapptechnomancy: the man probably uses hammocks more than Emacs :)
15:36pepijndevosbitemyapp, tbaldridge , thanks
15:36technomancybitemyapp: 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:37mdrogalistechnomancy: Hah
15:37sjltechnomancy: https://twitter.com/stevelosh/status/310487495198523393
15:37technomancynice; thanks
15:40marcopolo2(inc sjl)
15:40lazybot⇒ 1
15:41technomancysjl: been a while. still doing much clojure these days?
15:41sjltechnomancy: right now mostly scala at work
15:41bitemyappI'm actually pretty curious how much of Simple's stack is Scala/Clojure/JRuby.
15:41dnolencemerick: Bronsa: patch looks good, lets go w/ NO_SOURCE_FILE as in Clojure
15:41sjlwe do use some clojure though so I'll be getting back into it at some point
15:41sjlgotta do something now though, back in a bit
15:41technomancysjl: ah, well hope it happens sooner rather than later =)
15:42cemerickdnolen: sounds good, I'll revisit tonight or tomorrow. Do you have any idea re: the orphaned require-macros expression? Just vestigial?
15:42dnolencemerick: parse 'ns is a monstrosity, I barely understand any of it.
15:43cemerickheh, fair enough
15:43dnolencemerick: likely vestigial.
15:43cemerickI'll fix up that misspelling as well
15:43dnolencemerick: sounds good
15:43cemerickCould use some typed-clojure action in there :-P
15:45akurilinIs 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:46bitemyappakurilin: any side effect unless it's super obvious.
15:46bitemyappa family of logging fns probably don't need it. they're for logging. that's a side effect.
15:46akurilinIn 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:46bitemyappBut, "transfer-money" if it's side-effecting should get a !
15:46bitemyappdoesn't matter
15:46bitemyappthat's not what I said.
15:47bitemyappthe ! is to prevent anybody from being surprised by side effects.
15:47akurilinbitemyapp, I know, I like your approach.
15:47bitemyappIt's not a hungarian notation for return values.
15:47bitemyappif you want to note return values, annotate the var with core.typed.
15:47akurilingot it.
15:47bitemyappprinciple of least surprise and all that.
15:47tbaldridgeakurilin: technically the ! means it's not STM safe. Hence why send doesn't have one. It's side effecting, but still transaction safe.
15:47akurilinbitemyapp, yeah I like that.
15:48TimMcgfredericks: The trouble in implementing the SKI combinator calculus in Swearjure is K, right? That would be like implementing clojure.core/constantly
15:48bitemyappakurilin: tbaldridge's approach is stricter but also valid.
15:48bitemyappI don't think any expects a logging fn to be STM safe.
15:48bitemyappanybody*
15:49akurilinspeaking 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:49bitemyappit wouldn't really verify much for you. Just that you're getting request, params, etc?
15:49bitemyappakurilin: it wouldn't really verify much for you. Just that you're getting request, params, etc?
15:50akurilinbitemyapp, I'm more interested in schema / type verification of the param map I'm getting.
15:50akurilinany way I can declaratively constrain that?
15:50bitemyappakurilin: that's runtime bro.
15:50bitemyappakurilin: clj-schema
15:50technomancyTimMc: K is constantly, right
15:50bitemyappor mississippi
15:51akurilinbitemyapp, so clojure.typed is more of a hinting system?
15:51bitemyappakurilin: I don't think you're understanding the difference between a type system and runtime schema enforcement.
15:51bitemyappakurilin: a type system cannot enforce/prevent things that happen at runtime from user input.
15:52bitemyappit 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:52bitemyappbut it can't spew error messages at users at runtime.
15:52bitemyapptype 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:54akurilinI'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:55bitemyappcore.typed doesn't cast anything or change your code, it enforces the correctness of your types.
15:55bitemyappyou 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:55gfredericksTimMc: 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:55gfredericksi.e., lots of non-objectionable details
15:56technomancyat one point I decided I was going to implement SKI in terms of lein tasks
15:56technomancyI never did, and if anyone else wants to beat me to it I'd be tickled
15:56akurilinbitemyapp, I'd have to look more in depth into it when I have time to better relate to what you're saying.
15:57bitemyappakurilin: 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:57bitemyappformer: core.typed latter: clj-schema/mississippi/etc
15:58bitemyappwell, "compile" time.
15:58TimMcOh well, back to the URL mines.
15:58bitemyappI wonder who had the job of making an HTML parser that works everywhere at Google?
15:58bitemyappand are they still alive?
15:59akurilinbitemyapp, ok thanks for clarifying the distinction, again, I'll have to look further into this before I can appreciate it.
15:59dmi3yHello, can someone advice please how to make ajax call passing basic authentication parameters using ClojureScript ?
16:00TimMcbitemyapp: 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:00coventryIf the JVM SecurityManager disallows getStackTrace, does that mean all exceptions come without stack traces?
16:01akurilinIs 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:01akurilinSo that to me is a DAL as far as I can tell.
16:03bitemyappakurilin: possibly.
16:03bitemyappOne doesn't really want to be spending a lot of time on CRUD, generaly.
16:03bitemyappgenerally*
16:03akurilinI would indeed prefer not to.
16:05gfredericksokay I got this var thing going I think
16:07gfrederickshttps://gist.github.com/fredericksgary/7143494
16:09gfredericks^ clojure stubbing for the paranoid
16:09gfredericksoops it has a borg
16:10tbaldridgeresistance is futile
16:11hiredmantechnomancy: remember the job is one third done, because SK give you I
16:11gfredericksborg eliminated
16:11bitemyappgfredericks: is there a parallel runner for Clojure?
16:11gfredericksbitemyapp: I have no idea :)
16:11bitemyappwell this is relevant to my interests :)
16:11gfredericksPHEW
16:12gfredericksI didn't mean that ironically that's actually how I react to most things
16:15scopedTVI'm looking for a std library function that applies a function to the values of a map. Is there such a function?
16:16tsdhscopedTV: And what should it return? The map with transformed values?
16:16seangroveAny way to get emacs in I-search to show me "match 2 / 50" as I'm banging C-s?
16:16scopedTVtsdh: Yes.
16:16manutterscopedTV: check out https://github.com/weavejester/medley
16:17manutterspecifically the map-vals fn
16:17tsdhThis should also do: (apply hash-map (mapcat (fn [k v] [k (transform v)]) my-map))
16:18scopedTVyeah I figured something like that out, but thought there must be a better method.
16:18scopedTVThanks!
16:18hyPiRiontsdh: only if you want to use hash maps. Sorted maps go boom with that one
16:18bitemyappseangrove: hook + count-matches + output to sub-bar.
16:19bitemyappthe 2 out of X part would be a little tricker, still doable.
16:19tsdhhyPiRion: Uh, then use (apply sorted-map ...), no?
16:20hyPiRiontsdh: yeah, I'm just nitpicking. It's just good to be aware of the subtle details
16:20seangrovebitemyapp: The obvious worry being that the size of the buffer may be too big an kill the search
16:23tsdhhyPiRion, 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:23hyPiRionyeah, medley has a good version of it
16:24tsdhhyPiRion: Indeed, nice.
16:28arrdembitemyapp: 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:28bitemyapptechnomancy: and to balance out the nice things I said earlier: http://www.yesodweb.com/blog/2013/10/pipes-resource-problems
16:28bitemyapparrdem: the do monad is just sugar for bind
16:28bitemyapparrdem: if you want to learn why monads are useful, it's best to just write Haskell programs.
16:29bitemyapparrdem: also: http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/
16:29TimMcgfredericks: Man what I don't
16:29arrdembitemyapp: I may wind up doing just that... lets hope I pass GHC's IQ stat check
16:29TimMcI don't have brain for vars today, I guess.
16:31bitemyapparrdem: I wouldn't sweat it, I'm an idiot.
16:32gfredericksTimMc: yeah it's a littel hairy
16:33gfredericksTimMc: mostly it's just jumping through hoops to make sure there's only one dynamic hidden var created at a time
16:34xuserbitemyapp: you don't like doing CRUD apps in clojure or in general?
16:34bitemyappProgrammers should automate away boring tasks.
16:35bitemyappThat's our purpose for existence.
16:35coventryarrdem: 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:36coventryAlso section 3.1 "On Category Theory." But I totally don't buy that.
16:36TimMcgfredericks: I'll stare at that on the subway sometime.
16:39mdrogalisHm, where the heck is BigDecimal?
16:39mdrogalis,clojure.lang.BigInt
16:39clojurebotclojure.lang.BigInt
16:39mdrogalis,clojure.lang.BigDecimal
16:39clojurebot#<CompilerException java.lang.ClassNotFoundException: clojure.lang.BigDecimal, compiling:(NO_SOURCE_PATH:0:0)>
16:39arrdemcoventry: thanks, I'll throw that on the reading list.
16:39mdrogalisOh, it's Java's BigDecimal.
16:41bitemyappcoventry: the point is reliable abstractions which you can reason about at a high level.
16:41bitemyappif 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:41noncomhi, i have a little question about macros: https://www.refheap.com/20142
16:41bitemyappcoventry: are you familiar with PG's essay that mentions "blub programmers"?
16:42coventrybitemyapp: Yes, but that's the point of any serious program.
16:42bitemyappwhat point, what program?
16:42arrdemnoncom: ~@
16:42coventrybitemyapp: "the point is reliable abstractions etc. etc."
16:43bitemyappcoventry: not long ago programmers were complaining about how procedures were too declarative and restrictive compared to their gotos.
16:43arrdemnoncom: that's our sequence insert operator.
16:43bitemyappcoventry: I'm talking about something more universal and important than any one program.
16:43arrdemnoncom: so (let [foo [1 2 3 4]] `(~@foo)) -> '(1 2 3 4)
16:43bitemyappcoventry: I'm talking about continually advancing the state of the art by enabling ourselves to build up reusable, composable, reliable abstractions.
16:44arrdemcoventry: can I get the title of that paper? my browser isn't loving your link.
16:44bitemyappCategory theory happens to provide some nice faculties for discussing computational models at a high level.
16:45coventryarrdem: Sorry must be cookie-linked. "Generalising Monads to Arrows", John Hughes, 1998.
16:45arrdemcoventry: no worries, thanks!
16:46noncomarrdem: hmm, i try and get an error, look the update: https://www.refheap.com/20142
16:46coventrybitemyapp: We've had this discussion. I don't think anything's changed, although my perspective's a little broader.
16:47arrdemnoncom: that's because you aren't in a quoted form...
16:47coventrynoncom: ,(macroexpand '(defmacro k [& body] ~@body))
16:47coventry,(macroexpand '(defmacro k [& body] ~@body))
16:47clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
16:47noncombut the second try in the refheap uses quote
16:47bitemyappcoventry: 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:47coventryBah. Anyway, when something mysterious happens in a macro, macroexpand is the first tool to reach for.
16:48bitemyappWe're not going to keep making houses with mud forever.
16:48arrdemnoncom: http://en.wikibooks.org/wiki/Learning_Clojure/Macros
16:49arrdemnoncom: 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:49arrdemnoncom: you can insert values into a backquoted form via ~<expr>
16:49noncomarrdem: but the second try in the refheap is (defmacro k [& body] `(~@body)) and still gives an error..
16:50arrdemnoncom: probably... because you need do as the first element of that spliced list
16:50noncomi can't find a difference from the example from the wikibook that you referenced
16:50noncomoh that, wait i try
16:51noncomtrue that was about the (do) thing!
16:51noncomthanks!
16:51arrdemnoncom: np
16:55coventrynoncom: Sorry, that was a bad example. (macroexpand '(k (+ 1 2) (- 2 1))) would have been informative.
16:56noncomcoventry: cool! i have tried like (macroexpand k) before and it failed, but now i'm starting to see things..
16:58coventrybitemyapp: Obviously, that's preaching to the choir. :-)
16:59arrdembitemyapp: but I like playing with mud...
16:59bitemyapparrdem: off to the Fortran mines with you then!
16:59arrdemI suppose clouds would be more fun...
16:59coventryOne day, we will build a ball of mud which will build balls of mud for us.
16:59arrdemcoventry: the power <strike>set</strike> ball of mud?
17:00noncommight turn out to be something like that: http://filer.case.edu/dts8/thelastq.htm
17:01arrdembitemyapp: no thanks, that's where they send the grad students
17:10avishaiquestion
17:10arrdem~answer
17:10clojurebotExcuse me?
17:10arrdemdang.
17:10avishaii want to issue a few parallel actions and have a timeout for the entire operation
17:11avishaii can do this with futures
17:11avishaibut
17:11avishaiit's damn ugly
17:11bitemyappavishai: core.async, alts, timeout.
17:11bitemyappavishai: you're welcome.
17:11avishaicore.async ain't good since it's blocking
17:12bitemyappavishai: could've fooled me, I think it has async in the name bro.
17:12avishaino,
17:12avishaithe operations i'm using are
17:12bitemyappso...change...them?
17:12avishaican't
17:12avishaithey're plugins
17:12avishaiexternal
17:13bitemyappand it's impossible to wrap these operations?
17:13avishaiwith future or threads
17:13avishaiit's possible
17:13znDuffwell, there you are.
17:13brehautavishai: jsut make an alternative to future that wraps up a future and a chan
17:14avishaithen use select
17:14avishaigood idea
17:14avishaiany alternative without core.async?
17:14brehautavishai: making new bits out of existing bits is what this FP is about
17:15avishaiok
17:15avishaibrehaut, thank you very much
17:16brehautavishai: its worth keeping in mind that in clojure all the different primatives for this stuff are largely intended to be used together
17:16brehauttheres no 'one true model'
17:17avishaiyes
17:17tbaldridgeavishai: 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:17avishaithe problem is i'm still very young clojurer
17:18avishaii find it a bit confusing at this point to jump from blocking to non-blocking code in the same project
17:18brehautavishai: its only a problem if you arent willing to learn. so looks like not a problem
17:19avishaino, it's not a problem; if anything it's a challenge!
17:19avishaithanks a lot. you people are awesome!
17:24brehautavishai: 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:24rasmustoi 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:26brehautrasmusto: its possible that core.cache has something for that?
17:27arrdemrasmusto: what clojure version are you using?
17:27rasmustoarrdem: 1.5.1
17:27brehautrasmusto: although thats surprising as memoize is jsut using an atom and swap!
17:27arrdemrasmusto: yeah... that should work just fine...
17:27coventryrasmusto: 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:28rasmustocoventry: that's what I was thinking, yeah
17:29rasmustomy 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:30rasmustoso 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:30arrdemrasmusto: yeah. this won't do any blocking on a parallel computation.
17:31coventryrasmusto: Is pmap smart enough to fire up more computations if a current thread is blocking?
17:31rasmustocoventry: I'm not sure
17:31arrdemcoventry: if the current thread is blocking then it should yield to other green/real threads and life will be good.
17:31rasmustoarrdem: could I write a similar function to memoize that updates an argument map with values in a future?
17:32coventryrasmusto: pmap only runs (+ 2 (.. Runtime getRuntime availableProcessors)) processors.
17:32arrdemrasmusto: totally. I was just about to.
17:32rasmustocoventry: hmm, ok. What impact does that have in this case?
17:33coventryrasmusto: If more than two threads block, there will be fallow resources.
17:33rasmustocoventry: ah, gotcha
17:34coventryrasmusto: My impression is that reducers are supposed to be smarter about this kind of thing.
17:34coventryrasmusto: But I could be wrong. I have only read / heard about them, not played with them.
17:35rasmustocoventry: same here, I might have to explore them more now that I have a potential application
17:38arrdemrasmusto: https://www.refheap.com/20143 is what I'd do.
17:38arrdemoops.
17:38arrdembug: the trailing ret needs an @
17:39arrdem(doall)ing that sequence could be worthwhile depending on your application.
17:39coventryarrdem: 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:40rasmustowas going to say something ;p
17:40arrdemcoventry: no so this does do locking
17:40arrdemunless I'm totally crazy.
17:40rasmustothis will spin up futures for each call, then swap them out when each call completes, yea?
17:40arrdemcoventry: because I swap! in the ref returned by the future.
17:41arrdemrasmusto: no.
17:41arrdemso here's my understanding of what this will do.
17:41arrdemfor every element of the args, check to see if it's in mem
17:41arrdemmem is _only_ refs, or nil. if the ref exists, deref it (this is blocking)
17:42arrdemif the value is nil, swap! in a new future and yield the deref of the future.
17:42rasmustoohh, wow. My eyes totally missed the map part
17:42arrdemyeah. so this is sequential on the args, which is why it'll work.
17:42arrdembut it's parallel on the computation.
17:42arrdempotentially.
17:42rasmustohrm, okay.
17:43rasmustoI'm not sure if I want something that requires a map in its implementation
17:43rasmustoI think I just want a drop-in replacement for memoize
17:44rasmustoarrdem: I will have to think about how yours works a bit
17:44arrdemYou could refactor the fn out and use it instead of memoize. Thanks to the atomicity gurantee of swap! it should Just Work (TM)
17:44rasmustoah okay, so this is something that I'd call at a higher level.
17:45rasmustomy code is a bit nested though, and I'm concerned with a function call that's a few layers deep
17:45rasmustonot something that I can easily pull out and map across
17:45rasmusto(this is an issue on my end)
17:47arrdemI mean... the straight memoize is also trivial... https://www.refheap.com/20146
17:51arrdemherm... so how does swap! effect the order semantics of an atom... isn't it essentially a (with-lock <atom> (set! <atom> (apply ... )))?
17:53arrdembecause 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:54rasmustohmm
17:54arrdemthen the return value is just (deref (get .. args)), which expression is guranteed to be blocking :D
17:56arrdemthe 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:56arrdems/case/behavior/
17:56coventryarrdem: 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:57turbofailarrdem: not necessarily even that weird. it should happen fairly often
17:57coventry(Just take out the (user/starbreak) line. It's a convenience function of mine.
17:58arrdemcoventry: hum... weird! time to start testing my own snippets before pasting :D
17:59coventryWell, it's what I would expect from reading the code, as I described in my earlier question with the map question.
17:59coventrys/map question/map version/ :-)
18:00turbofailyeah, 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:01arrdemok ok trying my (swap!) is atomic version.. lets see what happens..
18:01arrdemL31K A BAu5
18:01arrdemcoventry: this version totally works.
18:01arrdemhttps://www.refheap.com/20149
18:02arrdemassuming that swap! never has to retry at any rate.
18:02hyPiRionYou could've made it a promise too
18:03hyPiRiondoesn't use a new thread for the computation that way
18:04rasmustowhy is fact always 1
18:05arrdemrasmusto: because I suck? :P
18:05rasmustoit looks right to me...
18:05rasmustoI guess I suck too?
18:05turbofailif 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:06arrdemturbofail: oooh cute...
18:06turbofailand rest assured, swap probably will retry if you call the memoized function from multiple threads
18:07rasmustofact needs to multiply x and (fact (dec x))
18:07rasmustootherwise it keeps recursing and then hits 1 * 1
18:08arrdemrasmusto: lol looks like I mixed fib and factorial to no effect :P
18:09rasmustofactonachi sequence
18:09rasmustofibotorial
18:09rasmustoarrdem: haha, that's cracking me up. You're 100% right
18:10arrdemMckenzie Labs: wasting stack frames for multiplying 1 since 1992 :D
18:11turbofailwell 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:12arrdemso 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:12turbofailright, that
18:12arrdemo/
18:13turbofailso a promise is probably what you actually want
18:13arrdemor 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:14turbofailwell you want to only call the partial if the swap! succeeds
18:14turbofailwhich is not something you can really do
18:15arrdemoh yeah I see what you're saying.
18:15turbofaili think what you actually want is (delay (apply f args))
18:16turbofailor something to that effect
18:16arrdemyeah delay is perfect.
18:16marcopolo2What's that lein config called that lets you reference a dependency you are working on, instead of having it in the dependencies vector
18:17technomancymarcopolo2: checkouts?
18:17arrdemexcept that it kills all possibility for parallelism in the evaluation..
18:18mtpyogthos‘ away-nicks are unnecessary. thanks for your understanding.
18:18marcopolo2technomancy: that's it, thanks!
18:19technomancynp
18:19turbofailarrdem: 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:19rasmustoturbofail: that's correct. In my case I want it to block same-argument stuff
18:20rasmustoif 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:22arrdemok cool! turbofail: good catches :D
18:23rasmustoarrdem: 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:24turbofailrasmusto: dunno. for all i know core.cache might already have this
18:24turbofaili haven't looked
18:26arrdemI doubt this fits in core.cache, just because that's several cache implementations with no use cases.
18:27arrdemwould probably fit in the flatland toolkit or some other snippets lib.
18:27arrdemhttps://github.com/flatland/useful perfect fit.
18:30rasmustoarrdem: 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:30arrdemrasmusto: nope.
18:31arrdemthat (future) needs to be a (delay)
18:31arrdemotherwise ok.
18:31rasmustoarrdem: ah, alright. you're awesome :)
18:31turbofailer. also needs to use the non-overwriting swap function
18:32arrdemhttps://www.refheap.com/20152
18:42kovasdnolen: u alive?
18:43dnolenkovas: yep
18:43rasmustoarrdem: performance numbers (idk how applicable the test case is) https://www.refheap.com/20153
18:43kovasdnolen: having trouble loading core.match
18:43kovasgetting FileNotFoundException Could not locate clojure/core/match__init.class or clojure/core/match.clj on classpath: clojure.lang.RT.load (RT.java:443)
18:43arrdemturbofail, rasmusto: PR'd to flatland/useful
18:43kovaswith [org.clojure/core.match "0.2.0"]
18:43rasmustoarrdem: awesome :)
18:44kovasalso tried [match "0.2.0-SNAPSHOT"]
18:44kovasha
18:44kovaswell, just tried again and it works
18:45kovasheisenbug
18:45arrdemrasmusto: yeah that really isn't to surprising. for lightweight fns the coordination overhead of the atom is gonna really kill performance
18:45dnolenkovas: heh
18:45seangrovetechnomancy: No idea how you manage to even idle in emacs. I can barely glance without eyes glazing over.
18:45kovasdamn state
18:45dnolenkovas: I've seen a few projects using it and I haven't heard complaints
18:45muhoowhat's the difference between find and get? why would you use find instead of get or vice versa?
18:46akurilinMan, nrepl is the coolest thing ever. Running tasks from production straight from the app, reusing all of the existing code.
18:46dnolenmuhoo: 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:46akurilinOn 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:47muhoodnolen: thanks
18:50rasmustoarrdem: I hope to get some real numbers from my horribly inefficient code sometime this week, I'll let you know what happens
18:51brehautLexicon PSA: From now on, any bug caused by using when in place of if is now known as a Hagelbug
18:52arrdem~lexicon
18:52clojurebotI don't understand.
18:52arrdemthat should be a wiki page somewhere...
18:52brehautyou'll have to use your on-board memory
18:55arrdemeh I'll just mmap in a markdown file...
19:04akurilinbbl
19:07johanntechnomancy: got it to work! thanks for your responsiveness earlier :)
19:07technomancyjohann: cool. anything confusing or unclear about the docs?
19:09johanntechomancy: i probably was such in an ansy that i didn't slow down and understand the whole $PORT variable thing
19:09johanntechomancy: but that probably lends to my ability to focus than the docs themselves :P
19:20CreapI 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:21arohner_Creap: I dont use with-test because I don't like the indention, and I like my src and tests separate
19:21coventryCreap: It hasnt't seen much use because people find it breaks up the flow of reading the code.
19:22arrdemCreap: I'd rather see docstrings or margalina docs than tests inline... tests would be kinda weird. maybe one in the docstring. maybe.
19:23dnolencemerick: Bronsa: patch landed! a very nice one thanks.
19:24Creapok, makes sense.. but wouldn't another benefit be to be able to test private functions?
19:26coventryCreap: Personally, I would find using (#'fully.qualified/name args) in the test file less disruptive.
19:26arrdemcoventry: wouldn't that be a access error for a private fn?
19:27arrdemwow it isn't...
19:29coventryBe sure to use this power only for good. :-)
19:29Creap:)
19:30brehautarrdem: theres not really any such thing as a private function.
19:31technomancybrehaut: well, closures =)
19:31brehauttechnomancy: not so much private as just local right?
19:31arrdembrehaut: I knew that private was really metadata, but I thought that it did do something in aot.
19:31arrdems/ato/gen-class/
19:31technomancybrehaut: not sure the difference is meaningful
19:32brehauttechnomancy: probably true
19:32technomancywell, it's different from ^:private, just not "what you think of as the english definition of private"
19:35brehauttechnomancy: if it were stateful things it might matter more
19:37bitemyapparrdem: nope.
19:37bitemyapparrdem: vars are vars, regardless of when compilation happens.
19:39bitemyapparrdem: how many communication media can we spread our converations across? Time to fire up SC2 and talk on B.Net too?
19:40MrJones98i'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:40MrJones98does anyone have helpful links for me to learn more about any nuances that are related?
19:42bitemyappMrJones98: 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:43hiredmanthe nuances are "libraries that use alter-var-root should be avoided"
19:43bitemyappthat's like half of my libraries. I'm going to choose to take pride in this.
19:43MrJones98here's a link to the library that i'm trying to use
19:43MrJones98https://github.com/clojurewerkz/archimedes/blob/master/src/archimedes/core.clj
19:44bitemyapphahahaha, I fucking knew this was going to be a clojurewerkz library.
19:45MrJones98i'm still too new to this community to have any idea if i should be laughing or crying
19:45coventryMrJones98: What test is failing?
19:45MrJones98but… transact!* on line 13 is what's causing me problems
19:45coventryIn what context?
19:46MrJones98so 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:46MrJones98and in the process, pointing titanium to the latest version of archimedes
19:47bitemyappJenga Tower library usage.
19:47MrJones98and every test within titanium is failing, appearing as if transact!* is not being bound to something else
19:47bitemyapp"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:47MrJones98bitemyapp: it sort of feels that way
19:47bitemyappMrJones98: so...stop that.
19:48MrJones98i've been considering just starting over with just the parts i need to interact with ttian
19:48coventryWow the titanium dependencies are pretty stupendous.
19:48bitemyappMrJones98: throwing stuff away is almost always a good idea.
19:49MrJones98i'm still very new to clojure… so slowly learning which libraries are a good idea or not
19:49MrJones98i started with titanium… then saw that it built on top of archimedes and ogre
19:50bitemyappI 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:51MrJones98any recommendations of "good" libraries i can take a look at to compare with?
19:51coventryMrJones98: Why do you want bleeding-edge archimedes?
19:52MrJones98i don't want bleeding edge archimedes necessarily… i'm looking for bleeding edge titan
19:52coventrybleeding-edge titanium works with the specified archimedes dependency.
19:53coventry(In my hands.)
19:53coventryFails with bleeding-edge archimedes as you describe, though.
19:53MrJones98bleeding 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:54MrJones98and titan 0.4.0 runs with blueprints 2.4.0… so then i decided to look at the latest archimedes
19:54MrJones98and then started building my jenga tower
19:55bitemyappMrJones98: do you need to be using Titan specifically?
19:56MrJones98bitemyapp: 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:57bitemyappMrJones98: there's also the option of using Titan directly.
19:57bitemyappwhich is just Java
19:57MrJones98bitemyapp: 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:57MrJones98figured it might be a good clojure learning experienc3e
19:57MrJones98i have some decent experience working with titan/faunus directly from groovy
19:58bitemyappMrJones98: did you try what coventry described?
19:58bitemyappnative Clojure libraries are generally nicer.
19:58nopromptbitemyapp: sketch, refine, repeat.
20:00MrJones98bitemyapp: i'm thinking it's easiest to just roll my own "library" to interact with titan directly
20:00bitemyappnoprompt: wut
20:00nopromptbitemyapp: about throwing stuff away.
20:01bitemyappnoprompt: ah, yes.
20:01bitemyappMrJones98: if you make a nice micro-library please put it on github.
20:01MrJones98bitemyapp: will do
20:01MrJones98are you working with graph dbs?
20:02bjais tools.logging supposed to clobber pr/prn/print/println?
20:02bjaor rather, it clobber print
20:02bja*clobbers print
20:02bjabut not pr and prn
20:03nopromptbitemyapp: although i feel programming is more like working with clay.
20:03nopromptor mudd.
20:03noprompt:)
20:03technomancynoprompt: https://mobile.twitter.com/tangentialism/status/379996890366238720?p=v
20:04noprompttechnomancy: lol.
20:05MrJones98general 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:05MrJones98i've seen how clojurewerkz does it with monger and titanium...
20:06bitemyappMrJones98: make the connection a value. bucket of state for talking to the database and retaining results/dispatching queries
20:07bitemyappMrJones98: then just pass it around.
20:07bitemyappBe a lazy ass about this at your own peril.
20:07noprompts/"proper" clojure\(way\)/\1 in which others will not give me "shit"
20:07nopromptdamn forgot a space. :/
20:07coventryMrJones98: Why do you want bleeding-edge titan, out of curiosity?
20:08bitemyappMrJones98: make the rest of the API as pure as possible.
20:12MrJones98noprompt: i generally assume that i will always get shit from someone
20:12MrJones98bitemyapp: i'm not sure i even know what "being lazy" means when it comes to clojure
20:12nopromptMrJones98: you have won at least half the battle.
20:14MrJones98coventry: 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:15nopromptwow.
20:15bitemyappMrJones98: proliferating statefulness throughout the API unnecessarily.
20:15MrJones98otherwise, all of my other development to date has been on titan 0.3.2
20:16MrJones98bitemyapp: makes sense… i've become a big believer of not having state if at all possible
20:16MrJones98frees up my brain to worry about other stuff
20:21noprompti don't think i actually grok what i'm doing with this lein plugin.
20:25noprompti just want to watch some files at a path, load a file, grab the value of a var and something with it.
20:26arrdembitemyapp: -E_BAD_CONTEXT
20:26arrdemoh. right. the ^private thing.
20:33nopromptomfg. clean. i just needed to clean.
20:35seangrovednolen: What patch was that?
20:50Bronsaseangrove: http://dev.clojure.org/jira/browse/CLJS-632
20:56seangroveBronsa: Very nice
21:17nopromptok. 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:18technomancynoprompt: just use your repl
21:20noprompttechnomancy: i'm trying to automate a compilation function. ie. something that writes to a file.
21:21noprompttechnomancy: the changes could be in a directory.
21:21technomancyoh gotcha, so not for general dev use
21:21technomancythere's a ring middleware you could try
21:23noprompttechnomancy: 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:24nopromptdo note, i understand my grammar is awful.
21:24Raynesnoprompt: I'm gonna need you to head on down to LA now and visit me.
21:25nopromptRaynes: iz that so?
21:25RaynesIz
21:25nopromptRaynes: :)
21:25nopromptRaynes: what's the score?
21:25Raynesnoprompt: wat
21:25nopromptRaynes: as in "what's happening"
21:27Raynesnoprompt: Nothing. That's why you should be here.
21:27RaynesWe could make things happen.
21:27nopromptah, indeed.
21:27nopromptwell i was supposed to visit bitemyapp/callen next weekend.
21:27RaynesDamn him.
21:27RaynesWhy is he special?
21:27nopromptyes.
21:27RaynesAm I not good enough for you?
21:27seangrovednolen: 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:27RaynesDon't answer that. I get it.
21:27nopromptyou are worth.
21:27noprompt*worth
21:28nopromptugggh WORTHY
21:28RaynesThat wasn't a word.
21:28nopromptno wait!
21:28nopromptsrsly i need lol halp.
21:28Raynes:P
21:28fakedrakehello
21:29fakedrakewhere does lein download packages it pulls as dependencies?
21:29noprompti've been at this for like an hour now.
21:29nopromptfakedrake: ~/.m2/repository
21:30fakedrakenoprompt: yay! thanx
21:30nopromptRaynes: do you get what i'm trying to do?
21:30RaynesOh, I didn't actually look.
21:30nopromptRaynes: and perhaps know of how i could do it?
21:31Raynesnoprompt: I imagine that lein-prism is probably a good starting point.
21:32nopromptRaynes: well now i have more source to read.
21:32RaynesI'm sorry.
21:33nopromptRaynes: nah it's all good.
21:33nopromptRaynes: good ol watch/load-file do something wasn't working right.
21:36nopromptoh snap it's almost lunchtime :)
21:39nopromptwelp better go eat
21:42fakedrakelein repl doesnt seem to find clojure.contrib
21:42fakedrakehow do I get that?
21:43technomancyclojurebot: what happened to contrib?
21:43clojurebotWell... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go
21:45fakedrakeso what is the best way to get pwd from the repl?
21:45technomancyshould be (System/getProperty "user.dir")
21:47fakedrakeaha
21:47fakedrakeis that also the best way to do that from an actual app?
21:48technomancysure
21:48technomancynote that you can't actually change the current directory of the jvm
21:49technomancyso it's really "what directory did I start in"
21:49fakedrakehmm
21:49fakedrakeallrighty then
21:50fakedrakeso the repl is not like eshell then
21:55llasramIn what way is a raven like a writing desk?
21:58fakedrakewell eshell is sort of a repl for elisp, and ipython is an interpreter that can be used as a shell to some extent
21:58fakedrakei kind of assumed clojure repl would be something like that
22:00llasramThat's fair
22:00llasramBut the JVM is a strange beast
22:01fakedrakellasram: indeed it is
22:07technomancyfakedrake: it's more like M-x ielm than M-x eshell
22:08technomancyI don't know anything that's like eshell
22:09technomancyexcept erlang's interactive prompt has the same name, but that's about as far as the similarities go
22:09hyPiRionno, that's just erl
22:12l1xhey guys
22:13l1xhow 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:14llasraml1x: First, why do you want to ahead-of-time compile the files?
22:16l1xllasram: 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:17l1xi would like to have all of the namescpaces available in lein repl
22:17l1xmakes sense?
22:17llasramWell, what you want makes sense, but there's some degree of mismatch
22:18llasramCompilation is a deployment optimization, and is only generally necessary if you're using `gen-class`
22:18llasramIf you just want stuff in a REPL, you definitely shouldn't need to `compile`
22:18llasramIf 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:19llasramThe `project.namespace1` namespaces should be in a `project/namespace1.clj` file under a source path (default just `src`)
22:19l1xi see
22:20l1xso i cant really have a logical source code management when the db layer is in the db directory?
22:21llasramWell, 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:21l1xor i can still do project.function.namespace1 and project/function/namespace1.clj?
22:21llasramthat's fine
22:21l1xgreat
22:21l1xthis is what i am going to do
22:22llasramCool beans
22:22l1xthanks a million llasram
22:22llasramnp
22:22l1xclj community <3
22:22technomancyl1x: you can set :init-ns in :repl-options of project.clj, and `lein repl` will start off with that ns loaded
22:22technomancyso if you put a bunch of :requires in that ns it con be convenient
22:23coventryl1x: 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:33ddellacostaanything 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:33seangrovepartition-by?
23:34ddellacostaseangrove: right, that is a good avenue to look down...thanks!
23:34seangrove,(partition-by even? (range 0 10))
23:34clojurebot((0) (1) (2) (3) (4) ...)
23:34seangroveAh, no, that's wrong...
23:34seangrovegroup-by?
23:34ddellacostahmm, that's not was I was hoping for
23:34ddellacostayeah, I mean, it's definitely something in this family
23:35ddellacostayep, perfect
23:35ddellacosta,(group-by #(= (:a %) "foo") [{:a "foo"} {:a "bar"}])
23:35clojurebot{true [{:a "foo"}], false [{:a "bar"}]}
23:35ddellacostaseangrove: excellent, thanks again
23:36seangroveddellacosta: No problem, I just looked at the coded where I used partition-by and I sort the collection first
23:36ddellacostaseangrove: ah, I see
23:42bitemyappddellacosta: comp?
23:42bitemyappddellacosta: you could do it with reduce.
23:42ddellacostabitemyapp: didn't try comp
23:43bitemyapp,((comp (partial filter even?) (partial remove string?)) (range 10))
23:43clojurebot(0 2 4 6 8)
23:43ddellacostabitemyapp: 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:43bitemyappddellacosta: ^^
23:43bitemyappoh, okay, well if that works.
23:43ddellacostabitemyapp: the thing is, comp is just giving me one set of results, isn't it? I need both the matches and non-matches
23:44ddellacostabitemyapp: which is why I was thinking of something in that family, but didn't quite know until seangrove suggested group-by
23:45bitemyappddellacosta: yeah when you said filter and remove I assumed that was literally what you wanted
23:45ddellacostahmm, bummer that I can't use a boolean like a keyword with a hash though.
23:45bitemyappit does sound like group-by is what you want
23:45ddellacostabitemyapp: yeah, it's pretty perfect for this specific scenario.
23:45ddellacostabitemyapp: in general I think I use filter/remove too much actually
23:46`cbp:-o
23:46ddellacostashould start grabbing comp more off the bat, I'm less comfortable with it
23:46seangrovejuxt?
23:46clojurebotjuxt is the bestest option though if it doesn't weird you out
23:46ddellacostahaha
23:46seangroveI don't think juxt is appropriate, but it always seems to come up right about now
23:46ddellacostayeah, I still feel like I don't know what the hell I'm doing when I use juxt
23:46ddellacostaI really need to practice more
23:47seangroveThere's always 4clojure
23:47seangroveI'd like to see some of the medley stuff move into core
23:47ddellacostaseangrove: you know, I got through the first 50 or so when I started learning clojure, and haven't gone back
23:47seangroveEspecially mapping a function over a map's keys/values and getting a modified map back
23:47ddellacostaseangrove: I really should--I've learned so much since then
23:47ddellacostaseangrove: what's medley?
23:47ddellacostanow my curiosity is piqued
23:48ddellacostaah, this? https://github.com/weavejester/medley
23:48ddellacostaneat
23:49ddellacostaoh, yeah, some awesome stuff there
23:49ddellacostadissoc-in seems like a no-brainer, for example
23:49ddellacostafilter-keys/-vals too would be pretty natural to include in core methinks
23:49ddellacostaneat
23:50seangroveWell, prismatic's plumbing has some similar functions
23:51seangroveddellacosta: If you haven't started using dommy, well, now's a good time to look ;)
23:51seangroveThoroughly impressed with it
23:51ddellacostaseangrove: 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:51clojurebot[1 [3 2 4]]
23:51ddellacostaseangrove: that said, really not happy with it, I wish dommy had been more mature when I started
23:51ddellacostaor rather, that I'd known about it
23:52seangroveddellacosta: Probably a mechanical-ish transformation. But if domina works for you (it barely did for us), then there's no worries
23:52ddellacostafor example, hear the crickets chirping: https://github.com/levand/domina/issues/60
23:53ddellacostaseangrove: it works, mostly...but the problem is, I think, that wrapping Google Closure is fundamentally problematic. It really uses a different paradigm.
23:53ddellacostaseangrove: and domina doesn't make great choices at many points, AND the response from the dev team is painfully slow.
23:54seangroveddellacosta: 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:54ddellacostaanyways, enough griping, I'll look into dommy.
23:54ddellacostaseangrove: yeah, that sounds nice, and is the direction we're heading in anyways. Will definitely be investigating it further.
23:55seangroveddellacosta: What company/product are you working on again?
23:56seangrovebitemyapp: Saw you popup on the nunjuks hn thread, but selmer isn't client-side, right?