#clojure logs

2014-10-19

00:04MrJones98how would one apply #’ via map/mapv?
00:04MrJones98in other words, i have a seq of symbols
00:04MrJones98and would like to that into vars
00:07justin_smithMrJones98: var is a macro, you can't map with it
00:07justin_smithyou probably want resolve
00:08justin_smith,(map resolve '[+ - *])
00:08clojurebot(#'clojure.core/+ #'clojure.core/- #'clojure.core/*)
00:09MrJones98justin_smith: hmm… that makes sense
00:09MrJones98now i just need to figure out why resolve is returning nil
00:10justin_smithwhat are you trying to resolve?
00:10MrJones98playing around with a lein plugin
00:10MrJones98so basically… i’m using lein-ring and when it starts the nrepl server, it ignores :nrepl-middleware
00:10justin_smithI mean, is the thing you are trying to resolve in a namespace you have loaded? are you sure that namespace is loaded, etc.
00:10MrJones98my guess is the namespace isn’t loaded
00:11MrJones98what’s the proper way for loading a namespace at runtime?
00:12justin_smithrequire
00:12MrJones98is a (require ..)
00:12MrJones98hahaha, ok
00:12MrJones98thanks
00:12justin_smith(doc require)
00:12clojurebot"([& args]); Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of
00:12justin_smithit's similar to the :require block in an ns form, but not identical
00:13justin_smithand actually, you should be putting anything you need in the :require block of the ns, using require directly is just for the repl, or weird meta stuff
00:13MrJones98problem is these middlewares are specified in project.clj
00:14justin_smithright
00:14MrJones98so i need to requre them then resolve them, i think
00:14MrJones98would this be safe for the fn to pass to map: (fn [s] (require (namespace s)) (resolve s))
00:14MrJones98(trying it now)
00:14justin_smithso you are trying to manually parse something in project.clj?
00:15justin_smiththere has to be a sane way to do this, and that is not it...
00:15MrJones98effectively, yeah… extract it out of project.clj and pass it off to a handler
00:15MrJones98it doesn’t feel right
00:15MrJones98but i’m trying to make the various components play nice
00:15MrJones98letting them all do what they originally attempt
00:15MrJones98our project uses lein-ring and i’m trying to get simple-brepl working with it
00:15justin_smithyou don't actually need lein-ring you know
00:16MrJones98justin_smith: interesting...
00:16MrJones98that might make my life easier
00:16justin_smithit will likely be easier to just directly create and start a ring handler, and then let the regular lein stuff work like normal
00:16MrJones98ok
00:16MrJones98i’ll look into that now
00:17MrJones98my current efforts just feel like i’m trying to squish a square peg into a round hole
00:17justin_smithright
00:17eggheadyay, just pushed a small clj project to the docker registry
00:20MrJones98justin_smith: is it realy as simple as (run-jetty handler {:port 3000})
00:22pdmcthow do I apply a list of functions to a single set? eg (??? [:a :b] {:a 1 :b 2 :c 3}) --> [1 2]
00:23justin_smithMrJones98: that is pretty much it, yeah
00:23eggheadpdmct: juxt
00:23justin_smithMrJones98: that's why accepting any inconvenience from lein-ring is kind of silly
00:23MrJones98justin_smith: no kidding
00:24eggheadpdmct: ,((juxt :a :b) {:a 1 :b 2 :c 3})
00:24pdmctegghead: thanks
00:24justin_smithMrJones98: the difference being also that you need the jetty handler (or some other standalone handler) explicitly in your deps, and lein ring kind of abstracts over running an embedded server vs. running in a container, but it's not a huge thing
00:25MrJones98so we’re running it in immutant in production
00:25MrJones98i just checked the immutant docs though… seems we can still have the :ring{} options in project.clj
00:25MrJones98but not necessarily use lein-ring
00:27justin_smithyeah, there is a little bit of env specific config to sort out, but it's not as big as "hacking together middleware that should just work"
00:27MrJones98justin_smith: agreed
00:28MrJones98now i’m hoping adding an nrepl is as easy as getting jetty up
00:29MrJones98looks simple enough
00:43justin_smithalso you could just run lein repl and start up the jetty server from the repl
01:28dysfun_how does clojure rewrite unicode names?
01:28dysfun_are the translation rules written down anywhere?
01:28justin_smith,(munge "☃") ; often it doesn't at all
01:28clojurebot"☃"
01:28justin_smithmunge
01:28justin_smith(doc munge)
01:28clojurebot"([s]); "
01:28justin_smithugh
01:28justin_smith$source munge
01:28lazybotmunge is http://is.gd/OckYZt
01:29dysfun_so if i generate a java class, it's got a unicode-named funciton?
01:29justin_smithright, which is legal in java
01:29justin_smithmunge guarantees it's a valid java name
01:29dysfun_ah. right
01:29dysfun_ah right, thanks
01:29justin_smith,(munge "my-ns")
01:29clojurebot"my_ns"
01:29justin_smiththat's what it's really about
01:29justin_smith,(munge "this->that")
01:29clojurebot"this__GT_that"
01:30dysfun_and of course ? -> _q
01:30justin_smithyup
01:30dysfun_that one is a particularly nice touch
01:30justin_smith,(munge "really?!?!")
01:30clojurebot"really_QMARK__BANG__QMARK__BANG_"
01:30justin_smith,(munge "!!!on the door baby love shack")
01:30clojurebot"_BANG__BANG__BANG_on the door baby love shack"
01:31dysfun_,(munge "really?")
01:31clojurebot"really_QMARK_"
01:31justin_smithheh
01:31justin_smithfunny that it leaves spaces- since they don't make much sense in clojure either I guess
01:32dysfun_*sigh* i wish i could find an actual definition of what characters are valid in a symbol. the reader allows invalid symbols that will fail to compile
01:32dysfun_or invalid patterns
01:32dysfun_isn't there a handy regex somewhere?
01:38justin_smith,(symbol "hey, the reader don't care")
01:38clojurebothey, the reader don't care
01:38dysfun_yes, sadly i care in this case
01:40justin_smithhttp://clojure.org/reader
01:40dysfun_that's totally inaccurate
01:40dysfun_reading the source fared much better
01:40justin_smith"Symbols begin with a non-numeric character and can contain alphanumeric characters and *, +, !, -, _, and ?"
01:40justin_smiththat's what's *officially* supported
01:41dysfun_right, except we all use characters like > automatically because we use records
01:41dysfun_not to mention threading
01:41justin_smithright, that documentation is a bit odd
01:41dysfun_and > and <
01:41justin_smithand ' definitely gets used when people want to get mathy
01:41justin_smithx, x', x''
01:42dysfun_yup
01:54amalloyjustin_smith: that documentation was invalid when it was written
01:54amalloy>= is a function in clojure.core, for example
01:57justin_smithyeah
01:57justin_smithsilly me for thinking it would be helpful :)
01:59andyfdysfun_: justin_smith: If you care about getting it fixed, I?d recommend voting on this ticket: http://dev.clojure.org/jira/browse/CLJ-1527
01:59andyfIt can make a difference in how soon such things are addressed.
02:00dysfun_voted
02:13justin_smithandyf: thanks
02:15justin_smithvoted
02:19arrdemandyf: voted. thanks.
03:00Jaoodwhat version of Java is used to develop Clojure?
03:03Jaoodlooks like Java 6
03:04knosysClojure requires only Java 1.6 or greater, plus the Clojure JAR file itself.
03:04knosyspasted from clojure.org
03:08Jaoodknosys: yeah, I was more curious about what version/api is used develop clojure as opposed to what runtime is required
03:08dysfun_,(munge "a'") ; really ?!
03:08clojurebot"a_SINGLEQUOTE_"
03:08dysfun_that's verbose as hell
03:10dysfun_well to support java 1.6, you have to use java 1.6
03:10dysfun_otherwise you can't be sure
03:10Jaooddysfun_: won't java 1.5 bytecode run on java 1.6?
03:10knosysAaahh sorry Jaood!
03:11dysfun_Jaood: yes, but how can you be sure that your code will run on 1.5 if you've got 1.6 available?
03:11dysfun_or at least some step that runs tests has to have 1.6 available
03:12dysfun_you could do it on newer java and religiously check every time you import something new, i suppose
03:13dysfun_anyway, having multiple copies of the jvm lying around isn't terribly difficult
03:14Jaooddysfun_: sure, I was nitpicking there, does clojure uses any java 1.6 features? the changelog only mentions that clojure now builds with java 1.6
03:14dysfun_i don't honestly know. i try to avoid reading java as a rule. sadly i did have to dive into the code the other day to figure something out
03:15Jaoodk
03:15Jaoodgood rule ;)
03:15dysfun_java is never going to make me happy
03:17Jaoodis good to know java to appreciate just how simple clojure makes things
03:17dysfun_i didn't say i don't know java, merely that it won't make me happy :)
03:17Jaoodoh I didn't imply that, just saying
03:19dysfun_it's all just syntax. and annoying restrictions in the case of java.
03:20Jaoodto much rules also
03:23dysfun_i mostly hate the verbosity
03:23dysfun_i don't like IDEs and a lot of java seems to involve pressing buttons in IDEs
03:24dysfun_also the attitude is different. in the java world, it's all about heavyweight design patterns. clojure is quite the opposite.
03:25JaoodI partly know java but yeah, clojure is way more slick :)
03:28Jaooddysfun_: but still, for non-java people like me, you have to get familiar with java.lang, java.util and java.io for practical reasons
03:40dysfun_not really. there are nice clojure wrappers for most things
03:42dysfun_however if you want to experience the true nature of hell, simply try programming javafx in clojure and trying to follow the javadocs
03:43Jaooddysfun_: why are you doing that?
03:43dysfun_i wanted a webkit control
03:44dysfun_but it's so tedious that i put that idea on hold. i got my webkit, but the next steps are harder
03:45Jaoodcould you not build your UI in cljs?
03:46dysfun_a) i want to program clojure, not cljs b) no, cljs would not be suitable for either of those projects
03:47dysfun_especially the one where i wanted to manipulate the dom from clojure specifically
03:48Jaooddysfun_: manipulating the dom sever side?
03:49dysfun_indeed
03:49dysfun_although in this case i wanted a webkit to paint my UI in and control it from the clojure side
03:50dysfun_of course there are lots of cljs libraries for dealing with the dom and not many clojure libraries...
03:52dysfun_anyway, the idea tickles me because it's basically bringing visual basic levels of 'GTD' without the horror that is visual basic as the base language
05:02hellofunkany Om users in here at the moment?
05:03hellofunkis it acceptable to use om/update! in a function that is not a component, but is called from a component and receives the "app" var from the component (but no "owner")?
05:35the-kennyyes.
05:36the-kennyhellofunk: ^
05:37hellofunkthe-kenny thanks
05:37hellofunklots of things work find in Om even if they are not advised.
05:37the-kennyhellofunk: there's no magic going on. `app' is a cursor which you can pass around just like any other data structure. You only need to be careful when using its value (there's a difference inside and outside of a render phase)
05:37hellofunk*fine
05:39SagiCZ1what is om for? im having trouble googling it
05:39SagiCZ1just wondering..
05:39dysfun_it's a facebook react wrapper for cljs
05:39SagiCZ1thanks, cool
05:39dysfun_but it's been made somewhat more clojurey
05:40the-kennyNot really a wrapper - it uses React as its backend. It brings nice stuff by itself
05:41hellofunkOm is a library that uses React but actually does quite a bit more.
05:41the-kennySagiCZ1: In general it's a clojurescript library allowing you to write UIs in a functional way. You don't need to handle all the stateful stuff in the DOM itself. You just write fuctions/component and om/react handles updating the dom (and much other stuff) for you.
05:41dysfun_okay, a library for react
05:42hellofunkIt's worth noting that Om adds the efficiency of persistant data structures to the React pipeline, and some tests show it triples the performance of React because of these cljs features
05:43SagiCZ1the-kenny: wait what? your description isnt mentionnig facebook?
05:43the-kennyhaha :D
05:43hellofunkSagCZ1 React is officially a FB library but I think it was born out of the Instagram team
05:43SagiCZ1alright i missed that..
05:43SagiCZ1so it would be for web apps?
05:43hellofunkSagiCZ1 yes
05:43the-kennyYes. For the UI layer.
05:44SagiCZ1cool
05:44hellofunkIt cleverly solves some weakness in how browsers render pages by taking matters into its own hands before the browser gets any information about what to render
05:44SagiCZ1i only have experience with javas vaadin, and with swing, in clojure seesaw..
05:48the-kennyIt's really nice - and 0.8.0 solves another weakness by supporting a non-tree component/data structure :)
05:49hellofunkthe-kenny can you elaborate?
05:49the-kennyhellofunk: https://github.com/swannodette/om/wiki/Advanced-Tutorial#reference-cursors
05:49hellofunkI'm using 0.7.1
05:51hellofunkthe-kenny have you studied the techniques used in the undo feature of the ToDo demo?
05:51the-kennyhellofunk: I haven't used it in my projects yet, but I'm aware of the technique
05:52hellofunki haven't studied it, but in a nutshell how is this done and is this what "time travel" refers to?
05:53hellofunkmy guess is that you just make changes to the app state and conj them onto a vector of all past app states, each item in the vector has a minor change, then you can cycle through them if desired. but this may be totally wrong.
05:53the-kennyThat's exactly how it is
05:53hellofunkoh wow
05:54the-kennyOm/React doesn't care how big the difference is - you can swap between two totally different application states without any issues
05:54hellofunkand it is because of the persistent data engineering that makes this efficient, even though it would appear that the vector is storing multiple copies, actually it is not under the hood
05:54the-kennyyup
05:55hellofunkin other words, if you have an app state A like {..bunch of stuff...} and then you have B which is (assoc A :new :stuff) then your overall app state of [A B] is actually not much larger than just [A] or for that matter [A B C...]
05:55the-kennyThat's a property of the persistent data structures, yes.
05:55hellofunkFascinating. The undo example just allows you to pop off items then from this app state vector?
05:57the-kennyhellofunk: In a nutshell: https://swannodette.github.io/2013/12/31/time-travel/
05:57hellofunkthis is a perfect example of what Om can bring to the React world that React does not do on its own
06:01the-kennyIt's also harder to do in plain React as it encourages component-local state way more than om, right? (I have no experience with plain react)
06:02hellofunki have little experience with JS directly. React uses more component-local state? that's interesting.
06:02the-kennySomeone else might know more - that was just my impression by skimming over it
06:11pkkmis there a variant of reduce in the standard library that always calls the reducing function with 2 arguments (`reduce' appears to initially call it with 0 arguments)?
06:12jkjpkkm: you can give reduce the initial form
06:12jkjpkkm: thus it doesn't have to determine it by 0-arg call
06:12pkkmthanks jkj
06:14hellofunkjkj pkkm: whether you give it an initial form or not, isn't it always calling with 2 args?
06:15pkkmhellofunk: it appears to call with 0 args if I don't give the initial form.
06:15hellofunkpkkm example?
06:15hellofunkif you don't give it an initial form, it uses the first 2 items in your collection as args
06:15hellofunkif you *do* give it an initial form, it uses that form and the first item as its 2 args
06:15hellofunk2 args either way, right?
06:16jkjoh it does that
06:16hellofunkthere are no zero arg calls for the reduce fn
06:17pkkmthen it must be a weird error in my code, sorry for the confusion.
06:17hellofunkpkkm feel free to share your code if you want more specific help
06:20pkkmthanks, I will if I won't be able to figure this out
06:22SagiCZ1yesterday i was in a programming competition and couldnt get one problem to work.. i had no idea what was wrong with it.. after a long time a realized java arrays are mutable.. what an evil thing.. i was passing an array and not its copy :X .. thats what i get for getting used to clojure
06:22hellofunktrue dat
06:23SagiCZ1immutability now just seems so natural i cant believe i could code without it
06:24the-kennyYup, that's a bad effect of Clojure: You stop thinking about side effects
06:26jkjSagiCZ1: many hit that even without first spoiling them with immutability. in some contexts it requires being extra careful to always think about moving pointers around
06:41hellofunkthe-kenny I suppose a key reason why channels are used in Om click handlers is that the native om/update! and transact! don't work in an onClick since that is outside the render phase, right? Therefore, using channels communicates these clicks to a place that watches and then acts using update! or transact!
06:41the-kennyhellofunk: no! transact! and update! work fine
06:42hellofunkthe-kenny you often get errors like "cannot manipulate a cursor outside render phase" or something like that when you use om/update! in an onClick
06:42the-kennyIt's only accessing the cursor as a *value* that's forbidden outside of a render-phase (as there is no 'consistent' view of the state in that situation)
06:42the-kennyhellofunk: you need to deref cursors outside of render phases
06:42the-kennyWhile rendering, cursors behave like values. Outside of render phases, they behave like atoms
06:42hellofunkso you are saying that om/update! can be used on a @app-state deref inside an :onClick?
06:43the-kennyNo, @app-state will give you the value. You need to call update! or transact! on the cursor itself
06:43the-kennyForbidden: (do (println my-cursor) (update! my-cursor ...)), ok: (do (println @my-cursor) (update! my-cursor ...))
06:43hellofunkit seems that often causes an error to direclty use om/update! app-state in an :onClick
06:44the-kennyMaybe when doing (update! (:foo my-cursor) ...)?
06:45the-kennyyou need to use update-in or assoc-in in that case, as :foo counts as 'accessing' too
06:45hellofunki see, so the (:foo cursor) is requiring a read of the cursor's value
06:46the-kennyyup
06:46hellofunkbut if i used update-in i would need to de-ref first, right?
06:46the-kennyno!
06:46hellofunkbut doesn't update-in return the value of the cursor?
06:46the-kennyupdate! or transact! always work on cursors. Deref will get you the value the cursor points to
06:47the-kenny(om/transact! cursor (fn [v] (assoc-in v [:foo] 42))) is how you would do it
06:47hellofunkinteresting, i shall try.
06:48the-kennyYou need to think of cursors outside of render phases just like atoms.
06:48hellofunki didn't realize that you could manipulate a cursor outside render phase as long as you weren't reading it also.
06:48the-kenny,(swap! @(atom 42) inc)
06:48clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.Atom>
06:48the-kenny(swap! (atom 42) inc)
06:48the-kenny,(swap! (atom 42) inc)
06:48clojurebot43
06:48hellofunkin other words, think of update! and transact! as operating on atoms like swap! or reset!
06:49the-kennyyes
06:50hellofunkthat's a big help
06:50hellofunk(inc the-kenny)
06:50lazybot⇒ 2
06:50hellofunk(inc the-kenny)
06:50lazybot⇒ 3
06:50hellofunkhee hee
06:50the-kennyhaha
06:50the-kennyhey, you're cheating
06:51the-kenny(dec the-kenny)
06:51lazybotYou can't adjust your own karma.
06:51the-kennynot even down?!
06:51hellofunkyou answered 2 questions, so you were aptly rewarded
06:51the-kennyok :)
06:52dysfun_what's the easiest way to repeat a character n times?
06:52hellofunkthe-kenny: I suppose it is acceptable to pass korks outside render phase though also?
06:53dysfun_and get back a string, i mean
06:53hellofunkdysfun_ (take 5 (cycle "a"))
06:53hellofunk,(take 5 (cycle "a"))
06:53clojurebot(\a \a \a \a \a)
06:53hellofunk,(apply str (take 5 (cycle "a"))
06:53clojurebot#<RuntimeException java.lang.RuntimeException: EOF while reading>
06:54hellofunk,(apply str (take 5 (cycle "a")))
06:54clojurebot"aaaaa"
06:54dysfun_aha, apply, that's what i was missing
06:54dysfun_thanks
06:54hellofunknp
06:55the-kennythere's also StringUtils.repeat - might be more performant for bigger strings
06:55dysfun_that's not liable to be an issue here
06:56the-kennyYup, just mentioning it
06:56dysfun_:)
07:08the-kennyhellofunk: Sorry, missed your questions. I'm not sure what you're meaning by korks though.
07:08the-kennyhellofunk: ohh to transact! and update!. Yes! That's totally ok - and I totally forgot about that
07:08the-kennyhellofunk: (om/transact! cursor :foo inc) is totally fine
07:10hellofunkthe-kenny this line: (om/update! omstate/data :popup popup) is giving me this error: "No protocol method ITransact.-transact! defined for type cljs.core/Atom" when I use this in an onClick
07:11schmeeanyone here using Vinyasa?
07:11the-kennyhellofunk: omstate/data isn't a cursor.
07:11hellofunkthe-kenny well, it's the atom that holds the app state
07:11the-kennyYup, that's not a cursor ;) Are you updating that from inside a component or from a totally different part of the application?
07:11the-kenny(inside a component, maybe via some other function)
07:12hellofunkthat line above is running as a fn inside an :onClick that is in a component
07:12hellofunkso a "cursor" is only something inside the atom, not the atom itself? components often have the parameter "app" (along with "owner") that is the entire atom
07:12the-kennyhellofunk: Then you need to access it via the cursor passed to the component. Or, if you need a root-cursor, via `om/root-cursor' from om-0.8.0-alpha1
07:13hellofunkahh, i see. i'm directly accessing the atom itself rather than the cursor that points to the whole atom
07:13the-kennyA cursor is its own data type. You pass the atom to `om/root' and it will build a cursor around it.
07:13hellofunkgot it. i shall try momentarily.
07:13the-kennys/its own/a different/
07:14the-kennyhellofunk: In general, a component can only access data from the cursor it was passed and downward. If you pass (:foo app) to om/build, the component built can't access app itself.
07:14the-kenny(true before 0.8.0)
07:17hellofunkthe-kenny beautiful man, got that working by passing down the cursor. awesome.
07:17the-kennyhellofunk: it's in general good style to pass "just" the data a component needs. The less it knows the better. In terms of code-simplicity and performance.
07:17hellofunkall year i have been relying on channels only because i didn't realize that onClick handlers could do this outside render phase
07:19noncomis anyone here using quil recently ?
07:30engblomIs anyone aware of any minimal tutorial teaching a subset of clojure? I am looking for something ready made rather than writing myself one. I will have some clojure workshops with elementary school kids. The total time I will have (including exercises) is 10 weeks with 2x45 minutes each week.
07:45luxbockengblom: I don't know about tutorial but you could ask @thattommyhall, I think he mentioned having taught kids with Clojure in his EuroClojure talk
07:45luxbockhis talk was about DSL's
07:46luxbockhttp://vimeo.com/100425264
07:46luxbockthis is the talk
08:00schmeegaaah, can someone please help me with this?
08:00Bronsaschmee: with what?
08:01jaltesting.core=> (let [{:as orig} (range 20)] orig)
08:01jal{0 1, 4 5, 6 7, 12 13, 2 3, 14 15, 16 17, 10 11, 18 19, 8 9}
08:01jalwhy is there no 1 key in there?
08:01schmeeI want two functions automatically available in a new REPL: `pp`, to alias `clojure.pprint/pprint`, and `p` to alias `println`
08:01schmeeit seems easy enough, but I can't get it to work
08:01Bronsaschmee: you can use :injections in your user lein profile
08:02schmeeI've been mucking around with Vinyasa, Lein injections but there seems to be some conflict cause clojure.pprint is loaded in to the repl by default
08:02Bronsajal: you're destructuring a seq as a map, that'll turn '(1 2 3 4) into {1 2, 3 4}
08:02schmeeand `pp` is already defined in clojure.pprint
08:02Bronsaschmee: use ns-unmap
08:02jalah
08:03schmeeBronsa: in lein :injections?
08:04Bronsaschmee: yeah put something like [(ns-unmap *ns* 'pp) (def pp c.p/pprint) (def p println)]
08:07schmeeBronsa: here's my user.clj and what happens when I try your suggestion: https://gist.github.com/schmee/662a1444754141b721d1
08:07schmeeseems very close, but no cigar
08:10Bronsaschmee: I'm out of my league here, you'll have to wait for some lein wizards
08:11schmeeBronsa: haha, I feel the same way :P Thanks for your help!
08:41arnaudsjdoes anybody know what type of pattern to use to build a lazy seq based on back-end api calls?
08:44luxbockschmee: you have to require vinyasa as well and then use vinyasa.inject/in add whatever you wish to have available in clojure.core
08:47luxbockschmee: see https://gist.github.com/luxbock/59f0abf4217ee54932c3
08:48luxbockI think you need to leiningen dependency in there as well, at least for something, I forgot which
08:52schmeeluxbock: thanks for the code example! How can I rename a function when importing it with Vinyasa? In particular, can I rename `pprint` to `pp` without causing trouble (since it is already defined)?
08:52luxbockyes, see the thing I do with the macroexpands
08:52luxbockuse a vector
08:53luxbock[namespace [old-name new-name]]
08:56schmeeluxbock: hmm... that's what I tried at first. But it doesn't work for me at least, see here: https://gist.github.com/schmee/12af069cdfd8b6204e7a
08:59luxbockschmee: maybe just use a different alias so they won't get overwritten
09:00luxbockclojure.pprint/pp pretty prints the last thing that was output so it's pretty convenient as well
09:01schmeeluxbock: yeah, I should probably just do that, I hate the feeling of being defeated by my own tools though... I'm sure it's possible, I'm just to stupid to figure it out
09:02luxbockare you requiring clojure.pprint with :refer :all at any point?
09:07schmeeluxbock: no, but I think it gets loaded in the user namespace by default in the REPL
09:15pkkmcould you help me a bit with debugging? I've written a simple calculator with a recursive descent parser, <https://gist.github.com/pkkm/3a61ff7061803bf7020a&gt;, in which there are 2 mutually recursive functions (lines 139, 157): `factor' and `expression' (defined in that order with `def'). it works when `expression' calls `factor', but not the other way around, despite `expression' being forward-declared. the
09:15pkkmerror is: "Attempting to call unbound fn: #'modulo-calculator.core/expression".
09:21squeedeepkkm you can use declare
09:21squeedeedunno how to use this bot
09:21squeedee,declare
09:21clojurebot#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/declare, compiling:(NO_SOURCE_PATH:0:0)>
09:22squeedeeits not that
09:22the-kennyit is declared.
09:22squeedee(doc declare)
09:22clojurebot"([& names]); defs the supplied var names with no bindings, useful for making forward declarations."
09:22squeedeeoh
09:22pkkm(the error can be triggered by launching the calculator, inputting any intereger >= 2, and when the ">>> " prompt appears, and then inputting some expression with parens, for example "2+(3*1)".)
09:23squeedeei missed that completely
09:34pkkmI found a hack that makes it work: (declare expression) (defn expression-caller [& args] (apply expression args)) and replace `expression' with `expression-caller' in the body of `factor'.
09:34squeedeepkkm: the issue occurs higher up in parser_concat, so i thought maybe you needed to declare expression even earlier
09:35squeedeehah
09:36pkkmmoving `declare' to the top doesn't work unfortunately.
09:37pkkmdo you have any idea why this `expression-caller' hack works?
09:39pkkm(replacing `expression' with (fn [& args] (apply expression args)) works too.)
09:39squeedeeno
09:40squeedeeBut i think its worth producing a cut down replication and sharing it with the group
09:40pkkmwhich group? I'm new, this is my first clojure program.
09:41squeedeeclojure goolge group
09:41squeedeegoogle
09:41pkkmah, ok.
09:41squeedeeim really green too. but this looks like a bug, possibly because of a non-idiomatic approach?
09:42squeedeeeither way, you might get some insight
09:43squeedeei woulda stayed in school if my homework was this interesting
09:43jonhhehe
09:43squeedeeI'm feeling a little green about some code i wrote: https://github.com/squeedee/mapper/blob/master/src/mapper/core.clj#L20
09:44squeedeeI have a 'Map' that carries with it a higher order function which, when asked for the content of a cell, returns it. The map is also bound. So when i treat it as a seq, i get a flat seq of the entire map.
09:45Bronsasqueedee: a minor unrelated, code style complain. in a ns decl usually we put :refer-clojure, :require, :import in this order
09:45squeedeeWhat feels wrong here, is i assume that idiomatically, someone would expect the seq to return something representing the fields [x y fn]
09:45squeedeeBronsa: ta, I'm still very confused about my (ns)
09:45r4viif I want a function that when called returns the next integer how should I go about it? return a function from a closure with an atom for the value? (defn make-incr ...[] (let [count (atom )] (fn [] (swap! count inc))
09:46squeedeeBronsa the import was placed there by cursive-clojure auto-import! tch
09:47Bronsasqueedee: also, you can replace (.map-fn this) with map-fn
09:47squeedeeoh neat
09:47squeedeethis is lexically scoped?
09:47Bronsayes
09:48Bronsadeftypes inject their fields in the lexical scope of the inline methods decls
09:48hellofunkr4vi you are creating a new atom every time the fn is called in your example
09:48hellofunkput the let above the defn as one alternative
09:48Bronsa(defrecords too)
09:48Bronsasqueedee: so you can replace (:width this) with width too
09:48hellofunkunless you are calling the make-incr only once, r4vi
09:48squeedeeline 26 shows that i knew this
09:49squeedeeeven if it was subconcious
09:49r4vihellofunk: yep calling make-incr once to get the anon function, then keep calling that
09:49r4viis there a better way
09:49r4viwithout the closure
09:50hellofunkwell, you are talking about some form of stateful persistence so I would expect an atom to be in there somewhere.
09:50squeedeeBronsa, what you think about making the sequable interface return something other than the fields
09:51hellofunkr4vi you could also do something without an atom by using core.async channels. but that would be overkill in your case.
09:51Bronsasqueedee: I don't see a problem with that
09:51r4vihellofunk: yes bingo
09:51r4vihellofunk: I like that
09:51hellofunkr4vi just put a list of integers onto a channel. every time you pull from the channel, you get the next integer
09:51Bronsasqueedee: a Range seq would do that too, for example
09:51squeedeetrue.
09:51r4vir4vi: well I've trivialised the case here but in my actual case a core async channel would be cool
09:52r4vijust put (range) on one side of the channel then consume one every time
09:52squeedeeBronsa because i had to change it from a defrecord to deftype to do what i needed, i wondered if that was some kind of smell
09:52myguidingstarweavejester, codox can't find metadata for protocols in a Clojurescript project of mine
09:53hellofunkr4vi you could also just add a new integer to the channel only when you have first pulled an integer, and then just add the inc of the integer that was pulled. start with only the number 1 on the chan and you're done
09:53myguidingstarso I tried codox.example in codox source, and it failed to generate doc for protocols, too
09:53weavejestermyguidingstar: ClojureScript is missing metadata for a few things. I think protocols are one of them.
09:53myguidingstarokay
09:54myguidingstarI just wanted to know if there's a previous version of codox/clojurescript that worked
10:48abx_freenodewhat is discussed?
10:49borkdudeI filed an issue in jira of a project I was working on this week at my company. I'm starting to realize what I reported may be is just the way people program OO: a class for every kind of thing. It felt so wrong to me.
10:52winkbonus points if they do something like class Thing extends Object
10:53winkit's like customising the generic object to your domain ;)
11:06borkdudewink why would you extend Object? that happens automatically?
11:07winkspeaking of java, yes. was more meant in a universal sense
11:10gfredericksborkdude: an issue for what?
11:10borkdudegfredericks using a class for every new thing (a thing being something that needed to be converted from json and persisted to database with an aweful intransparent ORM framework)
11:11gfredericks"thing" == "domain object"?
11:12borkdudegfredericks well, an enumeration of options with certain questions etc
11:12borkdudegfredericks and their translations... a new class for every ThingTranslation of course
11:12gfredericks["Mother's maiden name" "Childhood pet's name" "Favorite pants"]
11:17borkdudejust found a song that expresses my feelings with this subject https://www.youtube.com/watch?v=fCLQEkpZy1A
11:20myguidingstar,(defprotocol MyProtocol "a docstring")
11:20clojurebotMyProtocol
11:20myguidingstar,(meta MyProtocol)
11:20clojurebotnil
11:20sveriHi, I usually construct my maps like this (let [a b c d...] {:a a :c c} Now, I wonder if what the idiomatic way is to put something into a map only if a predicate is true, something like (some? d)? I know there is merge, but that looks somewhat ugly to have several merge statements
11:20myguidingstar,(:doc MyProtocol)
11:20clojurebot"a docstring"
11:20gfredericks,(meta #'MyProtocol)
11:20clojurebot{:doc "a docstring", :ns #<Namespace sandbox>, :name MyProtocol, :file "NO_SOURCE_PATH", :column 0, ...}
11:21myguidingstaroh, thanks gfredericks
11:21gfrederickssveri: you want to add the key/val only if the val is truthy?
11:22sverigfredericks: No, not only, an empty string "" is truthy too, but then the key/val should not be part of the map
11:22myguidingstarhmm, I saw people type `(inc some-irc-nick)` here. what does that mean?
11:22gfrederickssveri: okay, I'd use cond-> I suppose
11:22sverigfredericks: cond->? with maps? Hm, haven't seen that, do you have an example please?
11:23gfredericksmyguidingstar: lazybot tracks karma; it's a slightly more measurable way of saying thanks
11:23myguidingstarawesome
11:23gfredericks,(let [a "yep" b ""] (cond-> {} (seq a) (assoc :a a) (seq b) (assoc :b b)))
11:23clojurebot{:a "yep"}
11:23myguidingstar(inc gfredericks)
11:23lazybot⇒ 94
11:23gfrederickssveri: ^
11:24gfrederickssveri: I like it as it seems to be the most succinct way of maybe-modifying something
11:24sverigfredericks: I see, looks nice too, a more intentional way then merge I think, thank you :-)
11:24gfredericksnp
11:25sveri,(inc gfredericks)
11:25clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: gfredericks in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:25sveri(inc gfredericks)
11:25lazybot⇒ 95
11:25sveriah :-)
11:28myguidingstar@gfredericks
11:29gfredericksyes?
11:29myguidingstaris there anyway to check someone's karma?
11:29myguidingstarI tried to `deref` yours ;)
11:30ustunozgurfor those of you who switch bt. emacs and intellij during work, this could be helpful: https://github.com/ustun/emacs-friends
11:30borkdudeanyone here uses sente? I want to see the uid of the event that the client sent
11:30borkdudecurrently I see :client-uuid 5-75035d91, but I only need 5
11:30gfredericks$karma gfredericks
11:30lazybotgfredericks has karma 95.
11:30gfredericksmyguidingstar: ^
11:30myguidingstargot it
11:31myguidingstar(inc gfredericks)
11:31lazybot⇒ 96
11:31gfredericks$juxt
11:31gfredericks$karma juxt
11:31lazybotjuxt has karma 14.
11:31myguidingstarhmm, it's not very lispy to do so
11:33justin_smithborkdude: that's a weird value for a uuid
11:33borkdudejustin_smith it's not even a uuid, but I use incremental values for the clients
11:33justin_smith,(java.util.UUID/randomUUID)
11:33clojurebot#uuid "665601a3-5e78-4e68-a2fa-c510fac771d4"
11:33borkdudejustin_smith sente appends something though
11:33justin_smithoh, I saw uuid in the name and was confused
11:34borkdudejustin_smith yeh, sente appends something uuid-ish
11:34gfredericksNVUID
11:35justin_smithPUID - Potentially Unique IDentifier
11:35gfredericksthe uniqueness of this ID cannot be ruled out on purely logical grounds
11:36borkdudeunique enough for me
11:36justin_smiththere exists at least one timeline in which this ID will be unique
11:36pyrtsa"Randomly unique identifier"
11:37myguidingstarhow do I lookup metadata of a protocol in Clojurescript?
11:37borkdudejustin_smith but does there exist a unique such a timeline?
11:38squeedeewow im having a hard time with protocols. I have a 'Map' type which carries three fields, width, height and a fn(x y) to obtain the value at a location
11:39gfredericksfun fact: you can efficiently tell if a positive integer is a nontrivial power (e.g. p^k for k>1)
11:39squeedeethen Map.seq returns a seq of fn(x y) for all of widths in all of heights.
11:40squeedeeIm thinking that my sequencing function doesnt need to be forced to using the Map type.
11:41gfrederickssqueedee: I for one cannot yet tell what exactly the trouble you're having is
11:41squeedeei could alternatively just have map-seq which accepts different args
11:41squeedeeor leave it smple (defn map-seq [width height fn[)
11:41justin_smithsqueedee: sounds very OO
11:42squeedeewhich seems less painful
11:42squeedeei know right?
11:42justin_smithwhy can't this just be a map?
11:43justin_smithor a defrecord (that you can use as you would a map)
11:43bbloomand a function that uses a for comprehension
11:44squeedeei dont want a map
11:44bbloom,(let [m {:width 3 :height 2 :f vector}] (for [y (range (:height m)) x (range (:width y))] (f x y)))
11:44clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: f in this context, compiling:(NO_SOURCE_PATH:0:0)>
11:44squeedeei want composable functions that lazily describe a map
11:45bbloom,(let [m {:width 3 :height 2 :f vector}] (for [y (range (:height m)) x (range (:width y))] ((:f m) x y))); i was so close
11:45clojurebot#<NullPointerException java.lang.NullPointerException>
11:45bbloomblah
11:45squeedeejustin_smith: but you confirmed my feelings about my tactic being 'OO"
11:46bbloom,(let [m {:width 3 :height 2 :f vector}] (for [y (range (:height m)) x (range (:width m))] ((:f m) x y))); irc coding never works
11:46clojurebot([0 0] [1 0] [2 0] [0 1] [1 1] ...)
11:53pgmcgeeis there an equality function that will return true for two atoms holding the same content? ex: (= (atom 1) (atom 1)) => true
11:53pyrtsaThat sounds very data-racy.
11:53pgmcgeei suppose i could write (= @(atom 1) @(atom 1))
11:54pgmcgeebut i'm looking for something recursive... perhaps i have to write it myself
11:54bbloompgmcgee: yeah, it's easy to do, but pyrtsa is right: that looks like a data race
11:54pyrtsaYes. And you should note that there's no guarantee that anyone else would see the same equality hold.
11:54justin_smithand that says "there was one moment in time where these values {were,were-not} equal"
11:54pgmcgeethis is for writing a test
11:54bbloompgmcgee: unless you know you're single threaded
11:54pyrtsajustin_smith: There might even be a thread for which they never were equal at the same time.
11:54justin_smithpgmcgee: if you are confident they are not changing, why not a promise or delay?
11:55bbloompgmcgee: you have recursive atoms? ie atoms within atoms that you want checked for equality?
11:55justin_smithpyrtsa: note the were-not option
11:55justin_smithpyrtsa: it makes one of those claims
11:55pyrtsaHaha, gotcha. :)
11:55bbloompgmcgee: there is *definitely* not any prebaked predicate for that b/c it's definitely a design problem
11:55pyrtsaThat.
11:55pgmcgeejustin_smith: i'm not familiar with promises or delays, perhaps this is my problem
11:56bbloom(doc future)
11:56clojurebot"([& body]); Takes a body of expressions and yields a future object that will invoke the body in another thread, and will cache the result and return it on all subsequent calls to deref/@. If the computation has not yet finished, calls to deref/@ will block, unless the variant of deref with timeout is used. See also - realized?."
11:56bbloom(doc delay)
11:56clojurebot"([& body]); Takes a body of expressions and yields a Delay object that will invoke the body only the first time it is forced (with force or deref/@), and will cache the result and return it on all subsequent force calls. See also - realized?"
11:56pgmcgeebbloom: yeah, i'm writing a tree structure for maps that i want to be able to update just certain nodes without locking
11:56bbloompgmcgee: now you're familiar with them :-)
11:56bbloompgmcgee: swap! on the root won't lock, it will spin compare and swap
11:56justin_smithpgmcgee: short version: a promise is created but does not have a value yet, anyone can fulfill the value, a delay is initialized with some function that is not called until the value is asked for
11:57bbloompgmcgee: how many threads are accessing your atom? what operations are they doing to it?
11:57bbloomif the number of threads if not huge or the cost of atomic operations given to swap is cheap, then it's a good idea to just use swap plus update-in
11:58bbloomif you're not sure, you should still just use swap! & update-in, then profile your application to see if contention is hurting you
11:58bbloomand only then figure out how to optimize it
11:58pgmcgeebbloom: basic structure looks like (atom {:a (atom {:b nil :c (atom {:d nil})}) :e nil})
11:58pgmcgeebbloom: good advice
11:59pgmcgeejustin_smith: thanks for the advice to check out promise and future
11:59bbloomhomogenous use of atoms basically always requires justification
11:59bbloomyou shouldn't have N atoms where N varies at runtime, you should have M where M varies with architecture
12:00bbloomobviously that's not always true, but it's a reasonable starting principal
12:01pgmcgeebbloom: time to go rework the algo a bit, thanks
12:10justin_smithpgmcgee: I suggested delay and promise on the off chance you were not using the atoms for arbitrary mutation, but since you are, - the base case is to use a map with keys pointing to all your atomic values (this simplifies things, and works for most people), if performance is hurt because of parallel modifications within that structure, don't jump to multiple atoms, use refs - this is the exact (and rare) use case they are designed f
12:10bbloomjustin_smith: pgmcgee: but before you use refs, come back here and explain to us your architecture so we can explain to you how to do it even simpler and faster w/o refs :-)
12:10justin_smithheh :)
12:11pgmcgee:)
12:11pgmcgeebasically, i'm practicing my clojure by implementing suffix trees
12:12pgmcgeetrying to wrap my head around all this stuff in a real-ish world use case
12:12justin_smithif you are not heavily mutating the tree in parallels, a single atom holding a hash-map should suffice
12:12pgmcgeei think i was thinking atom-in-atom, because when i think recursive i think "update in place" which you need an atom for
12:13pgmcgeebut, that's not very clojure-ish i'm guessing
12:13justin_smithright, but you don't need an atom inside an atom for update in place
12:13bbloom,(let [a (atom {:x {:y {:z 1}}})] (swap! a update-in [:x :y :z] inc))
12:13clojurebot{:x {:y {:z 2}}}
12:14bbloompgmcgee: ^^
12:14justin_smith,(swap! {:a {:b {:c []}}} update-in [:a :b :c] conj 0)
12:14clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentArrayMap cannot be cast to clojure.lang.Atom>
12:14justin_smith,(swap! (atom {:a {:b {:c []}}}) update-in [:a :b :c] conj 0)
12:14clojurebot{:a {:b {:c [0]}}}
12:14justin_smithbbloom beat me to it anyway
12:14pgmcgeeseems like rather than calling my function recursively with (f (:keyword node) new-value) i should be calling (f node (conj loc :keyword) new-value) and then using update-in, yeah?
12:14justin_smithyeah
12:15pgmcgeedifferent recursive pattern to get used to when using trees
12:47quickezedI'm using sqlkorma but am struggling with the syntax for a query which adds two columns together.
12:47quickezedI can't figure out the correct what to use the + operator.
12:48quickezedAnyone familiar with this?
12:53bbloomquickezed: may i suggest https://github.com/krisajenkins/yesql ?
12:56quickezedbbloom: you certainly can :)
12:56quickezedbbloom: this looks like my preferred route, thanks for the suggestion.
12:57bbloomquickezed: yeah, korma is just more of the same old bad ideas
12:57bbloomi can't speak for ibdknox but i wouldn't be surprised if he'd agree with that statement :-)
12:57bbloom(now, at least)
12:58quickezedbbloom: hehe, yeh, i'm used to writing sql. i've always struggled with orm and dsl type layers.
12:58bbloomquickezed: that struggle should be a hint, but apparently nobody can take a hint
12:59quickezedbbloom: i've tried to broach the topic at work but people think i'm mad haha
12:59quickezedI can tell you now we'll be struggling to optimise queries in the future.
12:59bbloomquickezed: clojure can undo brains of poison
12:59quickezedhahahaha
13:00quickezedbbloom: i'll have to stick with it then!
13:00bbloomi meant "years of brain poison" but i like the way it came out too heh
13:04quickezedbbloom: what would you recommend for database migrations? I'm currently using ragtime.
13:05bbloomquickezed: i don't know about any of the tools out there for clojure, I usually avoid complex migration systems
13:05gfredericksclojurebot: clojure |can undo| brains of poison
13:05clojurebotRoger.
13:05bbloomi have some faith in weavejester, so that lib may be good
13:06bbloomactually, looking at it now
13:06bbloomit seems like it *is* good
13:06bbloommigrations as sql files? yes, please.
13:07quickezedbbloom: hehe yeh, that's exactly why I decided to give it a shot.
13:07quickezedbbloom: I'm actually authoring the migrations in sql. It just handles the migrate and rollback.
13:08bbloomlooking at it, it looks like the stuff i usually hack up with bash
13:08bbloom+1
13:10bbloom(inc bash) ; while i'm at it
13:10lazybot⇒ 1
13:13sveriAnyone knows a ring middleware that trims all params?
13:15justin_smithsveri: as in remove leading and trailing whitespace?
13:17gfredericks(defn wrap-trimmings [handler] #(-> % (update :params (partial map-vals clojure.string/trim)) (handler)))
13:18gfredericksor so
13:19justin_smithgfredericks: would need a walk for json params I guess
13:19gfredericksyeah the requirements are a bit ambiguous so far :)
13:21sverijustin_smith: exactly
13:23martinklepschcan anyone point me to a library that provides compojure/ring routes? I want to write one but I'm uncertain how to design the API. Some ring handler you could just plug in at a certain route sounds good to me
13:25sverigfredericks: justin_smith well, I guess before some json / transit / edn middleware converts them they exist just as plain params, so it would be nice to trim these params before they get converted, which might be easy by placing the middleware before the other middlewares
13:25mr-Does anyone know some good learning material for somebody who doesn't speak any lisp dialect but is fine with e.g. Haskell?
13:27justin_smithsveri: so trim the json string before it gets parsed? or trim the values in the json before passing them on?
13:29sverijustin_smith: trimming them before they are passed on
13:32justin_smithsveri: yeah, clojure.walk/post-walk with somethig like #(if (string? %) (string/trim %) %)
13:32justin_smithto get all the nested stuff
13:32sverijustin_smith: ah, postwalk, that looks good, :-) thank you
13:34martinklepschasking again: whats the best way to provide a route/handler to be used in someone's ring app via a library? examples would be perfect! :)
13:37kenrestivowhy does lein have to go out on the network and complain if an artifact isn't in clojars or maven central, when it's already installed in ~/.m2/repository ?
13:37kenrestivoi'd expect it'd check the net only iff it didn't find the artifact locally.
13:38kenrestivoah, nevermind. it does exactly that.
13:39justin_smithmartinklepsch: a handler is a function, for bonus points you can provide a "factory" that takes some configuration parameters and returns a handler function
13:52corecodehi
13:53corecodehow would i use split-with while also limiting the maximum elements i take?
13:54justin_smith(doc take)
13:54clojurebot"([n] [n coll]); Returns a lazy sequence of the first n items in coll, or all items if there are fewer than n. Returns a stateful transducer when no collection is provided."
13:54justin_smitheither (take n (split-with ...)) or (map #(take n %) (split-with ...))
13:57corecodewell, i'm trying to take a maximum of 2 digits, while not holding on to the head, but retaining the rest
13:58quickezedbbloom: I'm giving yesql a shot and am trying to run a query which has no parameters and I get the following error: "clojure.lang.ArityException Wrong number of args (1) passed to: query/test-query"
13:58corecodejustin_smith: so take alone won't work
13:58quickezedbbloom: Any ideas? I'm hoping this is very obvious.
13:59bbloomquickezed: are you using defquery?
13:59bbloomor defqueries?
13:59quickezedbbloom: yeh
13:59quickezeddefquery
13:59bbloomdid you try (clojure.repl/doc test-query) like the readme shows?
14:00bbloomwhat does it say your parameters are?
14:00corecodemaybe something like (let [digits (take 2 (take-while is-digit seq)) rest (drop (count digits) seq)] ...)?
14:00quickezedbbloom: I've just got into the repl now. I'll let you know. Thanks.
14:00corecodebut that is extremely ugly
14:03quickezedbbloom: I see what's happening. I have some hardcoded timestamps in my where clause in the sql and due to the colons in the timestamp yesql thinks they are params.
14:03quickezedbbloom: at least i think that's what's happening.
14:04bbloomquickezed: yeash. i'd say that seems like a yesql bug
14:04quickezedxfd.query/test ... ([db 00 59]) ... A test query
14:04quickezedThe dots are new lines
14:04bbloomhaha yeah that's what that looks like
14:04bbloomanyway, seems like a harmless bug at least
14:05bbloommight want to report that issue though, not sure how much of the parsing business yesql wants to be in
14:05quickezedbbloom: Yeh, I am going to parameterise these timestamps anyway, I just hardcoded them for now because I thought it'd be quicker to test.
14:40csd_How can I execute a statement in the REPL and have it return to me a thread ID so that I can terminate the thread if it's nonresponsive?
14:40justin_smithcsd_: you can explicitly create a thread
14:41justin_smith,(Thread.)
14:41clojurebot#<SecurityException java.lang.SecurityException: no threads please>
14:41justin_smiththen tell it to run your function
14:41justin_smithor, use a future, you can use that handle
14:41csd_will that cause a problem if the statement is itself spawning threads using pmap?
14:41justin_smithcsd_: pmap is usually useless
14:41justin_smithbtw
14:41csd_how so
14:42justin_smith~pmap
14:42clojurebotpmap is not what you want
14:42csd_lol
14:42justin_smiththanks clojurebot
14:42justin_smithI thought there was a better factoid...
14:42justin_smith~pmap
14:42clojurebotpmap is not what you want
14:44csd_can i bind to future using let
14:45justin_smithcsd_: if you are afraid of pmap getting lost in a worthless calculation, you should embed a signal of some sort that tells the function to exit, that the function explicitly checks. For example a promise, and you bail out if the promise has been realized (this is nice because a promise can only be fulfilled once and isn't an arbitrary mutable thing)
14:45justin_smithcsd_: you can bind the return value of a future, yes
14:46justin_smithbut future-cancel is not so clean as it seems - unless your function checks (.isInterrupted (Thread/currentThread)) it doesn't do much
14:46justin_smith(checks it and acts on it that is)
14:46csd_i want a function to scrape data from n pages and return a list of the results.. in that case what datatype would you use?
14:46csd_eval is stalling during the scraping and it's difficult to debug because the REPL hangs
14:47corecodeif i am parsing a (string) sequence, would it be more idiomatic to use an atom to mutate the state (current position), or would it be better to carry the rest of the sequence around?
14:48justin_smithcsd_: you could just put the whole scraping thing in its own future, that checks isCancelled (or a custom atom or promise or whatever) before each recursion
14:48the-kennycorecode: I strongly prefer carrying the rest of the sequence. Mutation is seldom the answer.
14:49justin_smithcorecode: something like (lazy-seq (parse (firt-token input)) (recur (rest-tokens input)))
14:49csd_justin_smith: right how i have a list of urls and fn scrape-from-url and pmap scrape fn across the urls. guessing that's the wrong way then
14:49justin_smithcsd_: the issue with pmap is it does unexpected things with chunking, and is optimized for CPU bound taskes (scraping web pages is not CPU bound)
14:50csd_is there a version of doseq that executes concurrently?
14:52RaynesGood morning folks
14:52justin_smithcsd_: what about a queue on which you place URLs to scrape, and a pool of worker threads that each run (loop (when-not (should-bail?) (let [page (.take queue)] (process (slurp page)))))
14:52corecodejustin_smith: i thought about that, but i'm trying to do a recursive descent parser
14:53justin_smithcorecode: than instead of running parse on the tail, you map parse across the tail
14:53justin_smithlazy seqs can contain elements that are lazy seqs
14:53corecodesorry, beginner here, don't know how i could do that
14:54justin_smithcsd_: where of course process would end up putting each URL it finds onto the queue etc.
14:54justin_smithcorecode: yeah, it takes a little while to realize all the implications of our tools :)
14:54csd_justin_smith: makes sense
14:54justin_smithit's less about know whether something is possible, and more about figuring out which ones in practice are effective :)
14:55corecodeyea, that's why i'm asking
14:56corecodethe problem is that depending on what i'm matching, i need to consume more or fewer characters
14:56justin_smithcorecode: this can be solved by using a proper parsing lib maybe :)
14:57corecodei tried instaparse
14:57corecodetakes 8s to parse 8000 lines
14:57corecodeso i thought, maybe write a parser myself, can learn me some clojure at the same time
14:58justin_smithI think that there is a single root cause of parsing taking so long and the difficulty of writing the parser by hand - a complex / difficult / perhaps badly designed language
14:58justin_smithpure speculation
14:58corecodeno
14:58corecodethis is a data exchange format from the 60ies
14:58arrdemjustin_smith: 8k lines indicates an existing dataset
14:59corecodeyou can parse it with almost no backtracking
14:59justin_smitharrdem: fair point
14:59corecodehttps://gist.github.com/corecode/58606f3178c4c301627a
15:00corecodethat's my instaparse grammar
15:00arrdemcorecode: did you try using sequenced choice?
15:00corecodeyes
15:00corecodea bit slower
15:00arrdeminteresting.
15:01arrdemmaybe try throwing this at fnparse or one of the other parser libraries for Clojure?
15:01arrdemthere's no reason that you should invent a parser engine for such an obvious grammar
15:01corecodeyes
15:02arrdemcgrand has a couple... I have two...
15:02corecodebut then i thought, maybe try to write a simple recursive parser, as an excercise
15:02arrdemsure
15:02corecodeexercise*
15:08RaynesTEttinger3: Yo.
15:11corecodebasically i need a way to consume a variable amount of characters while mapping over a string
15:16radsdnolen_: is there a short answer for why the transducers js library has transducers that operate on "transforms" rather than reducing functions?
15:16radsfrom what I've seen in the clojure implementation, transducers operate on regular functions, not objects
15:16arrdemrads: afaik dnolen_ is on a plane to Germany rn
15:17radsoh, good to know
15:17radsmaybe I'll figure it out by the time he gets off the plane ;)
15:17arrdem:P
15:17borkdudearrdem he just tweeted
15:18schmeeon the topic of transducers, what's the story of transducers vs reducers?
15:18schmeeare reducers completely superceded by transducers?
15:18Raynesborkdude discovers in-flight wifi
15:19radsschmee: it seems like transducers are replacing reducers
15:19arrdemschmee: yes, transducers are a more general structure than reducers
15:19arrdemschmee: not sure whether clojure.core.reducers will be removed or not however
15:19borkdudeRaynes we're still dealing with getting wifi to work properly on trains here in NL
15:20RaynesWell, we're still dealing with getting wifi to work properly in apartments in Los Angeles, so it's cool.
15:20schmeearrdem: it makes sense to remove them I think, just like the core.async map et al. got deprecated after transducers came about
15:20borkdudehehe
15:20arrdemyeah here in Texas Time Warner has no damn idea how to keep a DCHP server up so..
15:21arrdemschmee: yeah. we'll see. deprecation notices in 1.7 and removal in 1.8 would be nice but I'm not holding my breath
15:23borkdudeit's kind of funny how they have all sorts of luxuries in planes that aren't properly available on the ground sometimes, I once had good espresso on a plane for example
16:00SagiCZ1borkdude: while many people consider flights necessary evil, i enjoy the luxury of the transatlantic flights even in the economy class.. :)
16:01justin_smithcorecode: another random thought - being able to split something into groups of arbitrary size is a pattern mapcat is well suited for
16:24sveri(inc justin_smith)
16:24lazybot⇒ 96
16:25Raynes(inc sveri)
16:25lazybot⇒ 1
16:26justin_smithsveri: was that because the post-walk string trim thing worked?
16:28sverijustin_smith: I did not try it yet, evening time here, but you helped often already and I learned about the feature today, so I thought it was appropriate
16:29sveri*you helped me often
16:29squeedeegood point
16:29squeedee(inc justin_smith)
16:29lazybot⇒ 97
16:30Raynes(inc squeedee)
16:30lazybot⇒ 1
16:35justin_smith(inc karma)
16:35lazybot⇒ 1
16:41SagiCZ1how would i extend defrecord? lets say it has fields a b c, and i want a record with those field plus another 'd' field?
16:41bbloom,(defrecord NoFields [])
16:41clojurebotsandbox.NoFields
16:41bbloom,(assoc (NoFields.) :a-field 123)
16:41clojurebot#sandbox.NoFields{:a-field 123}
16:41bbloomSagiCZ1: ^^ they are already extensible
16:43justin_smithSagiCZ1: use protocols or multimethods, not inheritence
16:43SagiCZ1bbloom: not sure if thats good for me
16:43the-kennySagiCZ1: You likely want to move the common stuff to a protocol - or rethink your use of records
16:43SagiCZ1justin_smith: but both of these deal with functions, not fields
16:44justin_smithSagiCZ1: a function can be a field accessor
16:44SagiCZ1i read about both protocols and records in Clojure Programming, but now when I might need them I am not sure when to use what
16:45BronsaSagiCZ1: is there a reason why you can't use a plain map?
16:47SagiCZ1i am remaking this application written in Common Lisp from a book... they use defclass to define some type hierarchy which they later use..while using simple inheritence to inherit some core fields which the whole family of types uses.. i thought i would replace that by records.
16:48bbloomSagiCZ1: just use maps
16:48bbloomSagiCZ1: skip the inheritence, put a :type key in the map, use multimethods that dispatch by :type
16:48SagiCZ1sounds simple
16:49BronsaSagiCZ1: and if you really need inheritance, use a ns qualified keyword for :type and use derive to build the hierarchy
16:50SagiCZ1its just kinda scary.. what if i need two instances of one "type" .. if they are both simple maps, who is enforcing, that they both have the same fields?
16:50bbloomSagiCZ1: you are, with the help of immutability
16:50bbloomSagiCZ1: just make a factory function just like you would have made a constructor in the past
16:50SagiCZ1factory function!
16:50SagiCZ1of course
16:50SagiCZ1thanks, let me try that
17:03zand`newbie question for you guys:
17:03zand`how would one convert: ([false (1 3)] [true (6 8)])
17:03zand`into:
17:04zand`{false [1 3], true [6 8]}
17:04Bronsa,(into {} '([false (1 3)] [true (6 8)]))
17:04clojurebot{false (1 3), true (6 8)}
17:04Bronsayou can convert the lists into vectors before or after, if you care
17:05justin_smithzand`: depending where that came from ##(group-by even? (range 1 8))
17:05lazybot⇒ {false [1 3 5 7], true [2 4 6]}
17:05zand`cool thanks - I'm sure I tried that already... i'm not sure why that didn't work for me the first time.
17:06justin_smithzand`: maybe you mapped over it after group-by
17:06zand`it's a 4clojure question (#63) and it's comes from a for loop
17:06zand`the restriction is to not use "group-by"
17:07justin_smithaha
17:07justin_smith:)
17:20SagiCZ1bbloom: so if i have a map of fields, one of the fields could be function, and i could call it like this ((:method-name my-object) arguments), right? if i had extended some protocol, i could call it like this (method-name my-object arguments) .. is that correct?
17:22BronsaSagiCZ1: you can still call (method-name obj args) if you make method-name a multimethod dispatching on :type/:op/whatever
17:23BronsaSagiCZ1: silly example: (defn make-foo [x] {:op :foo :x x}) (defmulti method :op) (defmethod method :foo [_] 1) (method (make-foo :foo))
17:23SagiCZ1Bronsa: I see, so in that case i wouldnt have mutliple functions in the map, just one field called :type, and the functions would move to one multimethod where i would implement methods of all types i wanted
17:24qbgSagiCZ1: If you wanted to do something like ((:method-name my-object) arguments), you would probably want to do ((:method-name my-object) my-object arguments) instead
17:24BronsaSagiCZ1: yes, keeping the data and and the functions manipulating the data separate
17:25SagiCZ1Bronsa: interesting.. i was taught to keep the data and the functions manipulating them together
17:25SagiCZ1qbg: yeah thanks, that would probably be the right way
17:26justin_smithSagiCZ1: this is one of the most important differences between fp and oo
17:26justin_smithregarding keeping functions and data tied or independent
17:27SagiCZ1justin_smith: i guess i should embrace that then
17:27SagiCZ1my idea was that maybe my factory function could make an instance via reify, but it cant hold any data
17:27qbgIn OO you want to keep the functions with the data because the data is mutable
17:27qbgWith FP, that is less important
17:27justin_smithSagiCZ1: you shouldn't need to be reifying anything here...
17:28BronsaSagiCZ1: even when using a deftype w/ a protocol, the protocol fn are not tied to the type (if not for performance reasons that you should ignore now)
17:29SagiCZ1okay
17:29SagiCZ1thanks for pointing me in the right direction
17:29lodinqbg: You still need to assure that you don't break any conditions on the data though.
17:30Bronsalodin: you can use prismatic's schema for that
17:30SagiCZ1lodin: i guess when you are implementing one of the methods in the mutlimethod u know exactly what data you can work with, dont you?
17:30qbglodin: True, but it is harder to "accidently" break the invariants when the objects are immutable
17:33SagiCZ1one more question to the multimethods.. they group together the methods, but not the classes themselves, so if i wanted to add another class, i need to go through all the multimethods and add the methods there, right? i know i am not using the exact terms here but i hope you can catch my drift
17:34BronsaSagiCZ1: yes you have to extend the multimethods to whatever new dispatch value you're adding
17:35Bronsabut it's an open system so there's no problem doing that. you can (defmethod my-method :new-dispatch-value ..) at anytime
17:35SagiCZ1Bronsa: yes it does sound very flexible
17:36SagiCZ1Bronsa: its just something completely different from what i was used to work with
17:36zand`justin_smith: I'm running into another hurdle that I can't seem to figure out -> can you tell me why this results in an error? : (flatten ( ( true (6 8) ) (false (1 3)) ) )
17:36qbgzand`: You need to quote the list
17:37qbgOtherwise it'll try to evaluate it as code
17:37zand`well, there ya go! thanks :-)
17:45lodinqbg: Depends on the invariant I guess. If you have a structure holding two maps, one being the inverse of the other, then that's an invariant that immutability doesn't help you with (especially if you use e.g. assoc-in).
17:48qbgThe structure can't change behind your back though, so you just have to ensure that you preserve the invariants that you care about
17:50lodinqbg: Ah, ok. Yes, I took that part for granted. :-)
17:59SagiCZ1does backwards partial exist?
18:00gfredericksjust in utility libs
18:00SagiCZ1#(foo % arg1 arg2 arg3)
18:01gfredericksthough that there is more of a "skip-the-first-arg-partial"
18:01gfrederickswhich I think would be nice sometimes
18:02SagiCZ1i guess i can write a macro
18:02SagiCZ1except that i cant
18:02qbgSagiCZ1: A function would do here
18:02SagiCZ1true
18:02SagiCZ1one should resort to macros only if a function cant do, right?
18:02qbgcorrect
18:04gfredericksand only after reconsidering whether you really need the thing or not
18:04qbg(inc gfredericks)
18:04lazybot⇒ 97
18:06johnwalkerwhy doesn't contains? work for transients?
18:06the-kenny,(let [x (transient {:foo 42})] (contains? x :foo))
18:06clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: contains? not supported on type: clojure.lang.PersistentArrayMap$TransientArrayMap>
18:07gfrederickstransients tend to be a bit primitive
18:07the-kennyWorks in ClojureScript
18:07johnwalkeroddly enough, .contains works for sets
18:08johnwalkerbut not maps
18:08gfredericks,(.contains (transient {}) 42)
18:08clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: contains for class clojure.lang.PersistentArrayMap$TransientArrayMap>
18:08gfredericks,(.contains (transient #{}) 42)
18:08clojurebotfalse
18:08johnwalkerand furthermore, contains? works in clojurescript for sets
18:09johnwalkerbut not in clojure
18:09the-kennyand maps too
18:09johnwalkerbrowsing the source. yeah, it looks like you're right the-kenny
18:09gfredericksI'm having trouble figuring that one out
18:10SagiCZ1,(repeat 5 (rand))
18:10clojurebot(0.5837106342374121 0.5837106342374121 0.5837106342374121 0.5837106342374121 0.5837106342374121)
18:10SagiCZ1i thought it would call the function 5 times?
18:10justin_smith,(repeatedly 5 rand)
18:10the-kennyYou want repeatedly
18:10clojurebot(0.3072787760975273 0.44169036150361773 0.29816617155704184 0.3742460514682746 0.6341255615995526)
18:10the-kennySagiCZ1: repeat is a function. It gets passed two values: 5, and the result of (rand)
18:11SagiCZ1but repeatedly takes a function of no args
18:11the-kennyyes
18:11SagiCZ1what if i want to repeatedly call a function with some args?
18:11gfredericksthe same args?
18:12the-kennySame args: Use #(rand ...), different: Use `map'
18:12justin_smith,(repeatedly 5 #(rand-int 5))
18:12clojurebot(1 2 4 2 1)
18:12SagiCZ1thank you
18:12gfredericks,(pr-str (repeatedly 20 #(rand-nth '(boom waka waka))))
18:12clojurebot"(waka waka waka boom boom ...)"
18:12SagiCZ1:>
18:12justin_smithhiphop generator
18:13gfredericks,(clojure.string/join " " (repeatedly 20 #(rand-nth '(boom waka waka))))
18:13clojurebot"waka boom waka waka waka waka boom waka waka waka waka boom waka waka boom waka waka waka boom waka"
18:13justin_smith(inc gfredericks)
18:13lazybot⇒ 98
18:15gfrederickswhat on earth is a TransactionalHashMap
18:15gfredericksis that for the refs?
18:16bbloomgfredericks: i think it's effectively dead code
18:16gfredericksI had just come to that conclusion
18:18kenrestivo,(pr-str (repeatedly 20 (constantly "OONTZ"))) ;; techno generator
18:18clojurebot"(\"OONTZ\" \"OONTZ\" \"OONTZ\" \"OONTZ\" \"OONTZ\" ...)"
18:18bbloom(doc repeat) ; kenrestivo
18:18clojurebot"([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."
18:19the-kennyClassic (for ClojureScript): (str (clojure.string/join "" (repeat 10 (- "wat" 1))) " Batman!")
18:19johnwalkerhaha nice
18:22kenrestivobbloom: indeed, that's more efficient, but the uglier version contains the adjectives "repeatedly" and "constantly" which are kind of appropriate for that variety of music
18:23gfrederickseffectively using clojure.core function names to disparage music genres for dummies
18:27johnwalkerok, it's a bug. transients are broken
18:27johnwalkerhttp://dev.clojure.org/jira/browse/CLJ-700
18:28arrdemI need a meme for jira hell...
18:29johnwalkerwell, can't really blame jira
18:29the-kennyhttp://www.quickmeme.com/img/d6/d6d1b31fed4c49fdc2ac502b9c68a0092f37f92590630b03a235025a5cfe0e8d.jpg
18:30arrdemMFW: Obvious bug fix vetted, two years old
19:01bbloomarrdem: it's even fixed by a alex redington at relevance
19:09johnwalkerbbloom: puredanger suggested that it was an incomplete fix
19:09arrdemI suspect but am too tired to prove that bbloom was joking
19:09gfredericksI tried to fix a different transient issue once with a similar assessment
19:10gfredericksit was more of "aw man this class hierarchy is all borked; what are we gonna do."
19:10bbloomargh.
19:10johnwalkerwelp
19:12gfredericksit was wrt ##(subvec (transient [1 2 3]) 1 2) I think
19:12lazybotjava.lang.ClassCastException: clojure.lang.PersistentVector$TransientVector cannot be cast to clojure.lang.IPersistentVector
19:12gfredericksno the other way around
19:12gfredericks&(transient (subvec [1 2 3] 1 2))
19:12lazybotjava.lang.ClassCastException: clojure.lang.APersistentVector$SubVector cannot be cast to clojure.lang.IEditableCollection
19:12johnwalkeryes, i recently voted on that issue
19:23arrdem&'#(+ x %1)
19:23lazybot⇒ (fn* [p1__11656#] (+ x p1__11656#))
19:28johnwalkerso why is a raven like a writing desk ?
19:30justin_smithjohnwalker: one is a pest for wrens, the other is a rest for pens
19:32johnwalkerlol http://www.quora.com/Why-is-a-raven-like-a-writing-desk
19:33gfredericks"Because there's a b in both, and because there's an n in neither."
19:39arrdemjustin_smith: http://stackoverflow.com/questions/26456524/clojure-using-map-to-store-results-and-parameters easy pickings
19:41justin_smitharrdem: there's a few doses of wat in that question to be sure, but yes, very easy to answer
19:42johnwalker,((juxt #(apply min %) identity) [1 2 3])
19:42clojurebot[1 [1 2 3]]
19:42johnwalkeractually nevermind. i'm not sure what he's asking
19:43johnwalkeroh he wants additive inverses
19:44johnwalker,(map (juxt identity -) [1 2 3])
19:44clojurebot([1 -1] [2 -2] [3 -3])
19:44gfrederickshuh speaking of which
19:44gfredericks,(+ Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)
19:44clojurebotNaN
19:44johnwalkerahahahhaha
19:44arrdemwhich makes perfect sense
19:44gfredericksI guess that's the best you can do
19:45johnwalkeris there a destroy all software talk coming up for clojure ?
19:46gfredericksis that a confusion of me with gary bernhardt?
19:47johnwalkerno, but i bet you could get away with it
19:48gfredericks,(* Double/NEGATIVE_INFINITY -1e-10)
19:48clojurebotInfinity
19:52johnwalkerhow long has he been joining clojure and promptly quitting?
19:57arrdemjohnwalker: dude just ignore joins and parts. seriously. #emacs et all are unlurkable otherwise.
20:01johnwalker"/ignore -channels #emacs,#clojure * JOINS PARTS QUITS NICKS"
20:01arrdem:+1:
20:02gfredericksI still get nicks; it is 99% noise and 1% clears up an otherwise confusing mention
20:03justin_smithit would be nice to have that data togglable - like with a switch it would disappear entirely (default) or appear, in chronological contex (when turned on to resolve some ambiguity)
20:03gfredericksah yeah
20:03johnwalkeror take a spam filter approach
20:03gfredericksit's at least pretty low noise
20:13johnwalker,(count (transient {}))
20:13clojurebot0
20:13johnwalker,(empty? (transient {}))
20:13clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.PersistentArrayMap$TransientArrayMap>
20:13johnwalker,(transient (hash-map))
20:13clojurebot#<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@7a1e34>
21:06papachanhello
21:07papachanif i want to test my project in suite test my project use ring, i must lein run first and lein specs
21:14justin_smithpapachan: you could also decompose the logic of your code into pure functions, and test those without booting up ring
21:15justin_smithpapachan: but anyway, you can start up ring without lein run
21:15papachanthanks
21:15papachanoh yeah certainly
21:15justin_smithmaybe I didn't understand what you were saying
21:16justin_smithoh, you are running the lein spec plugin
21:17papachanyeah i was trying with speclj first
21:17justin_smithanyway, there are a few options, you can manually run your specs from inside a repl / lein run, or you can start up the server from within the testing code, or, as I mentioned, move all the logic into a pure function, such that you can test its return value for the known input(s) without the server running
21:18justin_smithfunctional code + immutible values can simplify testing quite a bit
21:19papachani had take a look at kerodon, pretty good project
21:24squeedeeunit testing at whatever level under the skin is important, but so too is acceptance testing. Side effects are going to happen because there are places for mutable state, such as the db, and external services.
21:24justin_smithsqueedee: sure, integration tests
21:24justin_smithbut if it touches the db it isn't strictly a unit test
21:24squeedeethats not what i was saying
21:25justin_smithOK
21:25squeedeeJust that I don't think you can safely do without either
21:26squeedeehow is everyone tonight?
21:26squeedeeI took a break from second guessing myself about how i code clojure, reminded myself that I dont have to learn everything in one go, so now I'm going to make my autogenerated maps work dangit.
21:39squeedeeHmm any way to get compiler warnings about locals shadowing?
21:42squeedeeOr a lint anyone recommends?
21:44oskarkvsqueedee https://github.com/jonase/eastwood is the only one I've heard about.
21:46justin_smiththere's lein-bikeshed and lein-kibit
21:46squeedeesorry i typed in "giving it a whirl now" but it went into my browser search bar by mistake :P
21:46ddellacostaI'd like to hear other folks' opinions on this: https://github.com/ddellacosta/friend-oauth2/issues/27
21:47squeedeeyes, there are those two. I remembered looking at options last week and thinking i should ask in here for opinions
21:47ddellacostawould love to know how others would respond
21:48squeedeesame guy wrote kibit so i guess they are very much compimentary
21:49squeedeeddellacosta: thats totally reasonable
21:49ddellacostasqueedee: what is?
21:49squeedeesupport for 'quirks' is also a reasonable thought
21:49squeedeeyour position
21:50mdeboardIn the core.async doc, it lists several functions map<, filter<., etc as being deprecated and to use transformers instead. What's meant by this?
21:50ddellacostasqueedee: yeah, I guess I should clarify--I don't even want to add an option that my lessen security, especially if it's just because some providers don't follow the spec. Is that unreasonable?
21:50ddellacosta*that may lessen
21:51squeedeedoes setting 'assume-state' cause a potential security flaw?
21:51squeedeeI think it might be a little unreasonable
21:52squeedeeproviding an option thats clearly dangerous means you've done your bit, but not made life maddening for the consumer.
21:52squeedeethey could always maintain a fork, but that too becomes madenning
21:52squeedeethat said, I still understand where you're coming from
21:53ddellacostasqueedee: hmm. Again, why should we be adding features to a library to circumvent security because providers have not properly followed the RFC? I still feel like the "circumventing security by default" part is more important here than "making things more inconvenient for the consumer." I'm trying to see if there's a good counter-argument.
21:53squeedeeif it were { :quirks { :dangerous { :assume-state "suckitup" }}} ?
21:54ddellacosta...or maybe just don't use a service that isn't secure?
21:54ddellacostaor rather, fork it if you really need to. I dunno, I'm really not sure on this one.
21:55ddellacostaif it were some other non-security-related thing I think I'd be more open
21:55ddellacostabut it's not like OAuth2's security is that great to begin with
21:56ddellacostawell, thanks squeedee for your feedback, I'll give it a bit more thought. Maybe I'm overthinking it
21:56SqueeDsorry, hospital wifi is tragic
21:56ddellacostaah, hahaha
21:57SqueeDso.. you cant make business domain decisions for your consumers
21:57SqueeDyou can help them heaps
21:57SqueeDand in helping them heaps, your product gains favour
21:57SqueeDthats my 2cents
21:58SqueeDi may use crippled oauth to a service simply because: 1. I must, i am not in a position to change the dictatorial attitude of some PM or the company as a whole
21:58SqueeD2. It's a good stop gap to keep development moving
21:59SqueeD3. I honestly dont care, I just want the convenience oauth provides to let my users enter their details quicker.
21:59SqueeDIm arguing here, for your sake. Im not worried how you take it :D
22:01ddellacostasqueedee: no, this is what I wanted to hear, definitely
22:01ddellacostasqueedee: thanks, I'll think about it. I tend to go all out on the security side, and I realize that it's a balanced between convenience and security, and maybe I'm going to far here. Will think on it further--thanks a lot!
22:01squeedeeI'm just pleased its not a clojure question, so i can actually offer something :P
22:01ddellacostaah, haha
22:01squeedeewelcome
22:02ddellacostaedits: *it's a balance , *going too far ...typing too fast. :-/
22:02squeedeeMeh, it's IRC
22:03squeedeeI find it funny that people get annoyed at sloppy written communications in IRC.
22:03squeedeeHow well do they fare when chatting with people at meetups who use broken english or slang
22:04squeedeehello rubygeek :D
22:05squeedeeCan anyone tell I'm desperate for company?
22:07ddellacostasqueedee: haha. Yeah, I like to try to write well in every medium, if I can.
22:07ddellacostapersonal point of pride is all, I don't actually care that much how other people write, mostly.
22:08squeedeeThats cool :D
22:09squeedeeI was a tech writer for years
22:09squeedeeand when i was chilling in IRC in the evenings, i got murderous when people brought me up on my grammar and typos.
22:10arrdemhehe yeah nothing like someone pointing out a typo you missed in that shiney new post :P
22:10squeedeeAdmittedly i was younger, back when i got murderous about really deranged things.
22:11squeedeeI don't mind that so much if it's done politely. But a post is not conversational.
22:11squeedeein chat i'm more interested in conveying my thoughts than perfecting my written craft. If you're actually confused by something i said in chat, you can just say 'wait.. i didnt understand that'
22:12squeedeecontext is everything
22:12squeedeeor a huge amount thereof
22:12ddellacostayeah, agreed.
22:16squeedeeddellacosta are you producing clojure web apps professionally yourself?
22:16ddellacostasqueedee: well, as part of a team
22:16squeedeewhere at?
22:16ddellacostasqueedee: https://diligenceengine.com
22:17squeedeenew york?
22:20squeedeeddellacosta: hah says tokyo on your github account. is that where you're at?
22:22andrewhrmdeboard: you question got unaswered or a miss something? anyway.. that doc means that you should use 1.7’s tranducers
22:22andrewhrthat’s the new way to go
22:23ddellacostasqueedee: yep!
22:23ddellacostasqueedee: but working remotely
22:30squeedeeddellacosta: i work at pivotal labs in NY, (remotely from virginia)
22:31ddellacostasqueedee: really! I wonder if you know my buddy Jon there
22:31squeedeeddellacosta: i wish we would do some clojure projects
22:31squeedeeberger?
22:31ddellacostasqueedee: yeah, Jon Berger
22:31squeedeesure do
22:31ddellacostasqueedee: yeah, I thought you guys were doing some ClojureScript
22:31squeedeeThat guy gets around
22:31squeedeenone that i've seen
22:31squeedeenot in NY anyway.
22:32squeedeeI'll be moving to the Cloud Foundry organisational arm of Pivotal soon, so probably even less chance.
22:32ddellacostawhoops
22:32squeedeeTho I'm going to try and subsume one of the community clojure buildpacks and champion that
22:45andrewhrsqueedee: nice!
22:46squeedeeandrew do you ever deploy CLJ to heroku/cf ?
22:48andrewhrunfornutally, no. I still trying to squeeze some clj on my daily work (consultacy, primary ruby)
22:49squeedeei feel ya
22:49andrewhrmy current project I’m using clojurescript, but that’s because they leaved me alone with all the toys
22:49andrewhr:P
22:50andrewhranyway, will be nice to add support to clojure on CF since it’s another-platform-to-deploy
22:52squeedeeIt's big sell is you can get your clients to use it behind the firewall, makes them feel safe :P
22:52squeedeeI personally love CF, or i wouldnt have asked to transfer there from Labs.
22:56andrewhrCF works like a run-on-your-machine-paas? I’m not so familiar with it
23:05squeedeeandrewhr CF is a run-your-own paas. you can run it on your own machine in a vm but thats not exactly prod ready
23:06squeedeenormally you pick your IaaS. the current onprem solution most people use is vsphere
23:06squeedeetheres openstack support too
23:06squeedeetheres an abstraction layer designed to make it run on any IaaS
23:13andrewhrsorry squeedee, I’m accidentally disconnected :/
23:13andrewhrbut thank you for the explanation :)
23:14andrewhroh, freenode logs save the day
23:15andrewhrthank you guys, but need to go. bedtime. Seeya!
23:49rritochHi, does anyone know how to alter a root binding at runtime? I have a dynamic variable (def ^:dynamic *somevar*) that I need to set the root of at runtime so every thread defaults to an assigned root binding.