#clojure logs

2016-02-26

00:15seanirbyis there a way i can associate an nrepl server with a clojure app
00:18seanirbywait nvm, i may be confused
03:44akonring\list
07:48freddy_hi friends
09:04kungiCan I limit the number of threads to 1 while running my tests on the JVM?
09:58nicola1did cider-refresh stop working for anyone else here in the past couple of days?
09:59nicola1i can't seem to load any module in the repl anymore more than once
10:11kwladykanicola1 maybe you need a licence?
10:11kwladykanicola1 trial end?
10:13kwladykanicola1 restart intellij? update?
10:14nicola1this cider https://github.com/clojure-emacs/cider
10:17nicola1i think upgrading the package broke something, but pinning (from cask) the git version of cider won't work at all (cider fails to load some "cider-test" file, even if i specify cider's latest commit on which melpa's version is based on)
10:20hexaanyone ever tried to cider-jack-in with a lein-exec script ?
10:37kwladykanicola1 i use cider with intellij, so i don't know situation in eamcs
10:55sdegutisIsn't this sufficient for turning Clojure rows into a CSV string? https://gist.github.com/sdegutis/55febb1065df0a85208e
10:56sdegutisOf course, the two "," instances could be replaced with an optional variable as well as the "\n" instance. But even then, it's, like, complete. Right?
11:00TimMckungi: You mean limit the total number of threads in the JVM, or change whether your tests are multi-threaded?
11:05kungiTimMc: I was asking the wrong question
11:05kungiTimMc: I found my bug an d have to think about it for the weekend
11:11TimMc:-)
11:18justin_smithnicola1: CIDER emacs upgrading in place *always* breaks
11:19justin_smithnicola1: the two things that typically fix it are deleting all .elc files related to clojure stuff (including things like clojure mode that aren't strictly CIDER), and deleting everything clojure related entirely then installing the version you want
11:20justin_smithpersonally I opted out of using a tool that breaks when upgraded, but that's a personal decision of course
11:24nicola1justin_smith: i've had it break a few times but it's usually resolved quickly; i'd be happy using an older version (that's why in my cask setup i specify the git commit to pull from) but in that case it fails to even start
11:24justin_smithnicola1: no it's not about using an older version
11:24nicola1btw i'm erasing the whole .cask directory when reinstalling, no success though
11:25justin_smithit's that updating without deleting first breaks it
11:25sdegutisjustin_smith: I have not had problems upgrading CIDER
11:25justin_smithoh
11:25justin_smithsdegutis: congratulations
11:25sdegutisjustin_smith: I've had to find the right version numbers but that's about it
11:25justin_smithhow often do you upgrade?
11:25sdegutisLike twice a year at this rate
11:25sdegutisThat's about how often Cider comes out with new versions tho
11:25justin_smithsdegutis: that's why it is OK, it breaks when you upgrade
11:25sdegutiswhat breaks?
11:25justin_smithCIDER
11:25justin_smithrandom crap
11:25justin_smitheverywhere
11:26justin_smithsdegutis: normally, in emacs, when a package has a new version you can just pull it in
11:26sdegutisok
11:26sdegutisjustin_smith: sorry you've had bad experiences with it :(
11:26sdegutisjustin_smith: i normally delete the old version and pull in the new version for upgrades
11:27justin_smithsdegutis: I had a coworker who would turn .cljc files into clj / cljs files because he did not have a CIDER new enough to work with cljc properly and refused to update because it would break :(
11:27sdegutisjustin_smith: that would be frustrating indeed
11:29TimMcjustin_smith: o_o
11:29TimMcI feel like as long as you have paredit, further editor support is not really all that necessary.
11:30sdegutisso, unrelated: i'm getting closer this week to finally using component in our whole app!
11:30sdegutisI'm still trying to figure out how to make the router be able to be a component.
11:30justin_smithTimMc: that's my take as well - though auto-indent that behaves properly is also very nice
11:30sdegutisI like the idea of the router and the route-handler being separate components. That's how duct does it right?
11:31justin_smithsdegutis: the way I would do that next time is passing a hash-map containing all the handlers in the system (each component adding to it as needed) and then finally having the router pull out the functions and middlewares it uses from that map
11:32justin_smithI don't know duct though
11:32sdegutisjustin_smith: hmmm interesting to have each component have its own handlers
11:32justin_smithor middlewares
11:33justin_smitheach stateful thing probably has the ability to offer its state to another handler, or a handler that accesses its state (if not both)
11:33sdegutisjustin_smith: ignore the duct comment, I just meant that's how weavejester's ring-component lib works, it allows the ring-jetty-adapter to be wrapped in a component which can take another component as the handler
11:33justin_smithgot it
11:34justin_smithyeah, you could make one component that contains the http-adaptor and another that constructs the handler, or combine them. The former would be a small thing without the handler / middlware definitions.
11:37sdegutishmm
11:37sdegutisman, so many options
11:37sdegutisarg
11:38justin_smithsdegutis: clearly we need to get 1250 people to try each option, and then tabulate the total complexity and error rate of each resulting codebase and then we can calculate the objective best choice
11:39sdegutisagreed
11:40justin_smithsdegutis: my analog watch only allows setting in the forward direction, and is 15 seconds fast, and this makes me angy
11:40justin_smith*angry
11:40sdegutis*hangry?
11:40justin_smithI need to spin it almost 12 whole times to get it right and even then what are the chances I get it perfect that time
11:41justin_smithsdegutis: also I am permanently hangry, because I decided to lose weight. This is a seperate topic and completely off topic.
11:42sdegutisjustin_smith: why does your time need to be so accurate? are you a train conductor for a living?
11:43justin_smithsdegutis: wait I thought I was an engineer
11:43sdegutishahahaha i get your joke
11:43justin_smithOK different kind of engineer my bad and maybe I should not even use that term because we are not certified and I did not go to engineering school
11:43justin_smithwell, that's a load of my mind, thanks
11:44justin_smithsdegutis: realistically my watch could be 10 minutes off and nobody at work would never notice
11:45sdegutisjustin_smith: all the clocks in our house are off from each other by many minutes and seconds
11:45justin_smithI'm gonna get a watch that just blinks 12:00 all the time
11:46sdegutiswell its always 12:00 somewhere!
11:48justin_smithsdegutis: blinking 12:00 is a totem, capturing the spiritual energy of all misconfigured devices and software everywhere.
11:53sdegutis:D
11:53sdegutishi
11:55sdegutisTIL you shouldn't use anonymous functions for things so much because they don't have metadata
11:55sdegutis,(meta (fn []))
11:55clojurebotnil
11:55sdegutisLiterally impossible to determine its arglists.
11:55justin_smithbut hey you could put meta on it
11:55sdegutisOh right lol
11:59justin_smith,(defn has-arity [f n] (try (apply f (repeat n nil)) true (catch clojure.lang.ArityException _ nil) (catch Throwable t true)))
11:59clojurebotjustin_smith: Excuse me?
11:59justin_smithhaha
11:59justin_smithsdegutis: the above thing is an abomination, but it correctly tells you whether a function has a given arity
11:59justin_smithI probably should have named it has-arity?-lol-don't-use-this
12:00sdegutisActually
12:00sdegutisgot an idea brb
12:00justin_smithoh no I gave sdegutis an idea I'm scared
12:01sdegutisyou will regret it
12:03Bronsasdegutis: no function has arglist metadata
12:03Bronsait's been that way since 1.3.0
12:04sdegutisIT WORKS
12:05justin_smithsdegutis: how about a fn-with-arglists macro?
12:05sdegutishttps://gist.github.com/sdegutis/62f0b4177f01cf331218
12:05sdegutisjustin_smith: even better
12:05justin_smithoh, man...
12:06sdegutisit's like pretty legit kinda!
12:06Bronsathere's with-local-vars for that
12:06justin_smithsdegutis: instead of the let / gensym you could just do (let [v# (defn x# ~@stuff ...)] ...)
12:06justin_smithBronsa: with-local-vars attaches the kind of metadata defn would?
12:06sdegutisjustin_smith: oh right!
12:07sdegutisI forgot x# does gensym for me
12:07Bronsajustin_smith: no, right
12:07justin_smithsdegutis: I MEAN YOU WERE USING IT RIGHT THERE ALREADY COME ON
12:07justin_smithget it together, man
12:08sdegutisupdated
12:08sdegutishttps://gist.github.com/sdegutis/62f0b4177f01cf331218
12:09sdegutisthis is probably the cleverst thing ill ever accomplish in clojure
12:10justin_smithsdegutis: (defmacro fn+ [& stuff] `(doto (defn n# ~@stuff) (partial ns-unmap *ns*)))
12:10justin_smithsdegutis: tested in my repl, works
12:10sdegutisoh man
12:10sdegutisI was just about to type "i kinda wanna find out how to use doto on this thing)
12:10justin_smithnow you know!
12:11TimMcThat partial doesn't need an extra set of parens?
12:11justin_smithTimMc: nope
12:11justin_smitherr...
12:11TimMcyou sure?
12:11justin_smithTimMc: you are correct!
12:12justin_smithTimMc: the ns-unmap silently misbehaved
12:12sdegutisjustin_smith: wait doesnt that require comp meta :name too?
12:12sdegutisor are you able to just give that a var?
12:12sdegutiscuz it says 'sym' in the docstring
12:12sdegutis(doc ns-unmap)
12:12clojurebot"([ns sym]); Removes the mappings for the symbol from the namespace."
12:12justin_smithsdegutis: I think it does
12:12justin_smithsdegutis: yes, fixing
12:12sdegutisyeah so that shuldnt work and doesnt work here
12:13sdegutisi trieda comp version but i think i got it wrong cuz it no worky
12:14sdegutisdang this tricky
12:15justin_smithdefmacro fn+ [& stuff] `(doto (defn n# ~@stuff) (->> meta :name (ns-unmap *ns*)))) ; TimMc sdegutis fixed
12:16justin_smiththanks for the quality QA
12:16sdegutisoh man so smart
12:16sdegutisjustin_smith: wins
12:18sdegutisjustin_smith: https://gist.github.com/sdegutis/62f0b4177f01cf331218
12:18sdegutisthis is just terrible
12:18sdegutiswhy would you contribute to such a terrible invention justin_smith
12:18sdegutisand TimMc
12:18sdegutishow terrible of a macro
12:18sdegutismy goodness
12:19sdegutisso awesome
12:21justin_smithsdegutis: it would be nice if instead the thing that attached metadata was a separate composible function
12:21justin_smithso instead of making a var just for the side effect of getting the metadata we want, we could pull that metadata-generator in
12:21justin_smithkind of like how destructure is just a function you can call in your macro if you want it
12:22sdegutisjustin_smith: that would be impossible tho unless your fn was quoted
12:22sdegutisunless..
12:23justin_smithsdegutis: look at the source to defn, most of the code is just building the metadata map
12:23justin_smithsdegutis: if that happened in a separate function, we could use it
12:23TimMcopen a jira ;-)
12:23justin_smithTimMc: seriously considering it!
12:24sdegutisjustin_smith: i feel 100% confident everyone will be against the idea
12:24justin_smithsdegutis: oh I know it, but it's the principle of the thing!
12:25sdegutisjustin_smith: ok well if you post it then link me ill +1 it
12:25sdegutisalthough itll probably be canceled out by amalloy's -1'ing it
12:26justin_smithsdegutis: he has a bot that just -1s anything you +1
12:29Bronsacaveat is that it'll only do that on bad ideas
12:32sdegutisBronsa: like he said
12:39sdegutisI like how nicely assoc works with defrecord.
12:39sdegutisNice job guys.
12:47sdegutisWhy is this?
12:47sdegutis,(do (definterface Bar) (defrecord Foo [quux] Bar) ((juxt identity type) (dissoc (Foo. 2) :quux)))
12:47clojurebot[{} clojure.lang.PersistentArrayMap]
12:47sdegutisThat's unexpected to me. I'd assume it would try to retain the type.
12:48sdegutisEven this:
12:48sdegutis,(do (definterface Bar) (defrecord Foo [quux zappa] Bar) ((juxt identity type) (dissoc (Foo. 2 3) :quux)))
12:48clojurebot[{:zappa 3} clojure.lang.PersistentArrayMap]
12:48TimMcWhen you remove a basis key on a record, it stops being a record.
12:49justin_smithsdegutis: yeah, that's been the expected behavior for a while now - I'm thinking at least since 1.5? maybe before that even?
12:49sdegutisIs that desired behavior?
12:49TimMc"expected"
12:49justin_smithdefinitely explicit - I remember it changing
12:49BronsaBar is completely useless to your example
12:49sdegutisYeah I carefully avoided using the word "expected" in my last question.
12:49sdegutisIt has disparity with assoc:
12:50Bronsajustin_smith: I think that's actually always been the case, not a 1.5 change
12:50sdegutis,(do (definterface Bar) (defrecord Foo [quux] Bar) ((juxt identity type) (assoc (Foo. 2) :quux nil)))
12:50clojurebot[#sandbox.Foo{:quux nil} sandbox.Foo]
12:50Bronsasdegutis: rationale is that by being X + something else you're still X, by being X - parts of X you're no longer X
12:50sdegutisBronsa: hmm I can see that
12:51sdegutisstill, it feels wrong
12:51Bronsasome would argue not behaving this way feels wrong
12:51TimMcWhere it gets gross is when you want to break apart a map and reconstruct it.
12:51TimMc(into (empty m) (for [[k v] m] ...)) works great to preserve type for most maps, but not for records
12:51Bronsawhere it gets gross is when (empty some-record) throws but (dissoc some-record record-key) doesn't
12:52justin_smith(assoc instance :field :temporarily/removed)
12:52justin_smithhaha
12:52TimMcAw man, empty throws on records? Didn't know that.
12:52Bronsayeah
12:52TimMcyuck yuck yuck
12:52Bronsait feels really wrong that empty doesn't behave like reduce dissoc (keys record)
12:52sdegutisTimMc: that makes more sense though, because you're reconstructing a map from only the fields of a record, without "re-attaching" the metadata
12:53sdegutisTimMc: whereas dissoc seems more like removing a field while preserving the rest of the thing
12:53BronsaI'd rather have either both dissoc/empty throw or have them both fallback on normal maps
12:53Bronsathere's no good reason why (defrecord X []) (empty (X.)) shouldn't work
12:53sdegutisnaturally its far too late to make any changes like that since it would break every clojure app ever
12:54BronsaDon't think so
12:54Bronsaif something hasn't worked, making it work shouldn't break anything
12:55Bronsaand if you're depending on (f x) throwing an UnsupportedOperationException, your code deserves to be broken
12:55justin_smithBronsa: unless someone was intentionally throwing errors as flow control, and if they did that, they deserve broken code.
12:55justin_smithright, right
12:55Bronsajustin_smith: they deserve more than that
12:55Bronsaunless they're doing that as an optimization :P
12:56Bronsabut in that case, you're still not going to throw an UOE
12:56Bronsajustin_smith: IIRC core.match uses exceptions as flow control for non-local returns
12:57justin_smithick
12:57sdegutisBronsa: you planning to file a jira ticket?
12:57Bronsano
12:57sdegutisok i might then
12:57Bronsajustin_smith: it's surprisingly fast
12:57justin_smithBronsa: I'm sure it was a perf improvement over the sane option, but still, ick
12:58Bronsajustin_smith: you're either going to use recursion or exceptions if you want to backtrack in clojure
12:58Bronsasince there's no goto
12:58Bronsaor explicit return
12:58Bronsa(both or which exist in java)
12:59Bronsa(both of which are incredibly useful for this kind of stuff)
12:59justin_smiththat's true
13:00justin_smithand also sad, it would be nice to have a cleaner thing like continuations
13:00Bronsa¯_(ツ)_/¯
13:00BronsaI honestly don't think continuations are much cleaner thatn gotos
13:00Bronsathan*
13:01justin_smithwell, they are first class, but I guess it's not so hard to make a goto first class and juggle lexical environments to go with them...
13:03sdegutisBronsa: what about the continuation monad?
13:19gfredericksif you were using test.check's recursive generator
13:20gfredericks(gen/recursive-gen some-collection-generator-fn some-scalar-generator)
13:20gfrederickswould you expect it to ever generate pure scalars, or only collections of varying depths?
13:23gfredericksalso does anybody use freenode from erc and how can I get past that weird auth thing it does now.
13:25hiredmangfredericks: well, only generating collections of various depths would make it weird that you passed in a scalar generator
13:25gfrederickshiredman: I mean for (gen/recursive-gen gen/vector gen/boolean), it could generate [true [false false]] but never true or false
13:25hiredmanright
13:25gfredericksso the scalar generator does get used either way
13:26hiredmanif you are have a tree generator, would you ever generate just a leaf
13:26gfredericksyeah, same question
13:27gfredericksI'm hoping there'll be a compelling example of some sort :)
13:27gfredericksI think it's relatively easier to get one from the other
13:27gfrederickss/easier/easy/
13:28gfrederickshttp://dev.clojure.org/jira/browse/TCHECK-83
13:28gfredericksI think I created this when I was making a json generator and got surprised when it didn't generate any scalars; but on the other hand in some json contexts pure scalars are considered invalid I think
13:29hiredmanif you where testing some kind of recursive tree traversal, depending on the traversal code, you might want to test hitting a leaf
13:32hiredmanalthough, if you are thinking of it as a tree kind of data structure, a lot of those have lots of rules associated with their structure, so you can't just generate them recursively willy nilly
13:33gfredericksrules that are only valid at the root in particular?
13:34gfredericksit might make sense to restrict this to use cases where you can generate things recursively willy nilly
13:34gfredericksgiven the signature of the function
13:36hiredmana tree structure I might want to test would be, I dunno, a red black tree, but those have rules about what nodes can be children of other nodes, and are restricture to two children per node
13:36hiredmanyeah, only things willy nilly
13:36gfredericksyeah, I think that would require something more general/customizable
13:36hiredmanso like json or edn
13:36gfredericksright
13:37gfredericksspeaking of trees it is Bronsa
13:37hiredmanan edn generator I would definitely expect to hit leaves
13:38gfredericksyou could also argue that including leaves is better for test.check uses in particular to avoid accidentally undertesting
13:38gfredericksI think adapting it to not do leaves is as simple as calling (collection-gen-fn (gen/recursive-gen collection-gen-fn scalar-gen))
13:42gfredericksokay I'm convinced
13:42gfrederickseverybody brace for minor breaking changes
13:42hiredmana clojure code generator that did included generating type hints would be nice
13:42gfredericksis that related?
13:43hiredmannot really
13:43gfredericksokay cool just checking
13:43gfredericksthought I was missing something
13:43gfrederickshas somebody written a general code generator somewhere?
13:47amalloyjustin_smith: never fear, your has-arity? is in fact not correct
13:47justin_smithamalloy: awesome, what's the mistake?
13:48amalloytry it on (fn [] (inc 1 2 3 4))
13:48amalloyit'll claim not to have arity 0, but of course the problem is that in lacks arity 4
13:48justin_smithoh, of course
13:48justin_smithcool, I feel much better now
13:49sdegutisSome aspects of Component really confuse me. Is this normal?
13:49amalloyit's the same reason you get bogus errors for stuff like (defmacro fo [] (inc 1 2 3 4))
13:49amalloy,(defmacro foo [] (inc 1 2 3 4))
13:49clojurebot#error {\n :cause "Wrong number of args (4) passed to: core/inc--inliner--4489"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "clojure.lang.ArityException: Wrong number of args (4) passed to: core/inc--inliner--4489, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyzeSeq "Compiler.java" 6875]}\n {:type clojure.lang.ArityException\n :message "Wrong numb...
13:50amalloywell, apparently inc is smarter now
13:50amalloy,(defmacro foo [] (seq 1 2 3 4))
13:50clojurebot#'sandbox/foo
13:50amalloy,(foo)
13:50clojurebot#error {\n :cause "Wrong number of args (2) passed to: core/seq--4357"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (2) passed to: core/seq--4357"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6781]}]\n :trace\n [[clojure.lang.Compiler macroexpand1 "Compiler.java" 6781]\n [clojure.lang.Compiler macroexpand "Compiler.java" 6837]\n [clojure.lang.Com...
13:50justin_smithhaha
13:50amalloy,(defmacro foo [] (seq))
13:50clojurebot#'sandbox/foo
13:50amalloy,(foo)
13:50clojurebot#error {\n :cause "Wrong number of args (-2) passed to: core/seq--4357"\n :via\n [{:type clojure.lang.ArityException\n :message "Wrong number of args (-2) passed to: core/seq--4357"\n :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6781]}]\n :trace\n [[clojure.lang.Compiler macroexpand1 "Compiler.java" 6781]\n [clojure.lang.Compiler macroexpand "Compiler.java" 6837]\n [clojure.lang.C...
13:52gfredericksI got to write a function called random-psuedofactoring: https://www.refheap.com/115236
13:53cfleming{blake} TEttinger3: Sorry for the problems. I haven't had time to reproduce with that project.clj yet, but generally you have to add the deps to the project.clj, and then use the Refresh Leiningen Projects action, which you can either search for or use the lein toolwindow.
13:54amalloygfredericks: returns, not generates? that makes it sound to me like it just keeps one collection lying around forever, and always gives that one
13:54{blake}cfleming: I did not know there was a lein toolwindow! Cool!
13:54gfredericksamalloy: well it's in the context of test.check generators, so hopefully that means the more natural interpretation is that it doesn't return a generator
13:54gfredericksbut that there might be a better wording
13:55gfredericksI think a lot of docstrings for functions that return generators just say "Generates ..."
13:55amalloyit seems like this could be a generator if you wanted it to, right? am i wrong, or is there a reason not to do that?
13:56gfredericksamalloy: yeah it could be one that's just not what I needed it for
13:57sdegutisim back
13:57amalloyi understand you owe me a link to something so i can downvote it, sdegutis
13:57sdegutisamalloy: oh yeah hold on
13:57sdegutisamalloy: https://gist.github.com/sdegutis/62f0b4177f01cf331218
13:58sdegutisamalloy: its not yet turned into a mailing list discussion but justin_smith had toyed around with the idea of extracting the metadata-generating code from defn and turning it into a stand-alone function (which defn then uses) so it can be used independently similar to how 'destructure' works
13:58sdegutisamalloy: anyway please downvote my gist
13:59amalloyoh. you mean like clojure.tools.macro.name)with-attributes?
13:59sdegutisamalloy: justin_smith /cc
13:59sdegutisamalloy: not quite, cuz fn+ here generates :arglists for you
14:00sdegutisamalloy: that was the main reason i invented fn+ today
14:01amalloywell, it's a cute trick anyway
14:02sdegutisthanks!
14:02amalloygithub doesn't have downvotes, so i forked and deleted it
14:02sdegutisamalloy: haha or yu could comment with -1
14:02sdegutis:-1: technically
14:03sdegutiswow u wasnt kiddin https://gist.github.com/amalloy/05b64a9418fd318b7916/revisions
14:04sdegutisamalloy: actually your revision should just contain `(meta (fn [x] (inc x)))` so its made clear that your fork results in less functionality than the thing you forked
14:04sdegutis:D
14:06justin_smithamalloy: my thought was that it would be nice to be able to generate the same metadata properties that defn would, or that def would, without having to call def/defn, so the specific metadata generation could be refactored into a function - name-with-attributes is nice but doesn't do all the metadata defn does, and would need to be manually updated for each change to core's defn
14:08sdegutisjustin_smith: what would such an api look like in action?
14:09sdegutisjustin_smith: (let [f (fn [])] (generate-metadata f)) ?
14:09sdegutisjustin_smith: or (generate-metadata (fn [])) ?
14:11justin_smithsdegutis: maybe something like (defmacro fn+ [& body] `(with-meta (fn ~@body) ~(gen-meta body)))
14:11justin_smithsdegutis: but I realized the annoying thing about making a function that defn would use to generate its macro - you can't use defn to define that helper :)
14:13amalloyor syntax-quote
14:13justin_smithamalloy: oh yes, of course
14:14justin_smiththat would also be an annoyance
14:16{blake}I have a vector of vectors I'm using to make my web-page, and now (using React) I have to update a value in that vector of vectors.
14:17{blake}[[{stuff}{stuff}{stuff :control {:cell-name "target" :value "changethis"}}][next row...]]
14:18justin_smith{blake}: are you using react directly or with some clojurescript wrapper?
14:18{blake}justin_smith: reagent
14:18amalloydon't use vectors to store stuff you want to look up indexed by some key
14:18justin_smith{blake}: don't change the vector, use a function call to generate the vector
14:18{blake}amalloy: Well, I didn't know I was going to have to.
14:18amalloyinstead of searching through a bunch of vectors, wouldn't it be lovely to have a map? {"target" ...}
14:19justin_smithamalloy: this is hiccup
14:19justin_smithso generate the hiccup, instead of using a literal
14:19amalloyif it were hiccup you would have a seq of vectors, perhaps. never a vector of vectors
14:19justin_smith{blake}: or do you mean some source data? if so, yeah do what amalloy says
14:19{blake}OK, so, yeah, I've thought of "change it to a map" and "regenerate the vector". Just seems like a lot of work.
14:20justin_smith{blake}: less work than arbitrary updates in a vector I'd think
14:21{blake}So, the deal is, my server sends me data that I used to make an entry page for the user, including pre-populating some of those values.
14:21{blake}(At the user's request.)
14:21{blake}I'd been putting those in "defaultValue".
14:21{blake}Only to discover that reagent only uses defaultValue first time out.
14:21{blake}When the component is first rendered. So I put it in value.
14:22{blake}But if I put it in value, all my components gotta be "controlled".
14:22{blake}And to make them "controlled", I gotta be able to update that structure the server sends.
14:22{blake}So.
14:22{blake}Crap.
14:24justin_smith{blake}: send the data from the server in a form you can easily access, and generate the structure you need on the frontend from that
14:25justin_smithso yeah, a map instead of vector, like amalloy said
14:25{blake}Or...
14:25{blake}Maybe send two structures. Since the only thing that's going to change is a small subset of controls->values, keep one for the structure of the whole page, and a little part for the react stuff.
14:26justin_smithbut it's easier to generate the right vector from a map than it is to update a vector correctly
14:26justin_smithif you need a vector, make it out of maps
14:28rhg135Juxt is useful for that
14:28justin_smithindeed!
14:31gfredericks~juxt
14:31clojurebotjuxt is usually the right answer
14:31gfredericks~juxt
14:31clojurebotjuxt is a little hard to grok but it's the best thing ever
14:31gfredericks~juxt
14:31clojurebotjuxt is usually the right answer
14:32{blake}Lotta juxt propaganda goin' on.
14:32tcrayford_____juxt shut up already
14:34{blake}I have a nice thing on the server where it's going through the cells of the spreadsheet and creating a vector.
14:35{blake}A vector of vectors. Rows and columns. Then I just go through this on the client side, same way.
14:35{blake}I guess I could key it as [col row] and make a flat map.
14:35sdegutisjust and comp are cool
14:36sdegutisjust don't expect them to notice rebound vars unless you explicitly pass vars
14:36sdegutis(comp foo/bar foo/quux) ;; redefine #'foo/bar or #'foo/quux and it will never notice
14:36sdegutis(comp #'foo/bar #'foo/quux) ;; this will though
14:36sdegutisThis works because you can call vars as functions if you try hard enough.
15:04sdegutisHello.
15:04sdegutisWhat's your recommended way of sharing many common immutable parameters between a group of functions?
15:05sdegutisThe way I'm currently using is to have each of them take a map as its first parameter with each of these values at common keys.
15:50rhg135But then you can't compose them elegantly, I guess it's not as bad
16:25justin_smithclearly what we need is some crazy hack using metadata to imitate monads
16:25justin_smith(that was in response to rhg135 but it's universally true as well, of course)
16:56{blake}Who doesn't love crazy hacks?
16:56justin_smithin fact I sometimes suspect I *am* a crazy hack
16:58amalloyisn't using metadata to imitate monads like using...noodle soup to imitate 4chan? they are just totally disjoint separate things
16:59CaptainLex_Well that's what makes the hack /crazy/
17:00justin_smithamalloy: in the sense that a monad can track a separate immutable value implicitly carried forward in each call, which could hackily be a metadata passed along on values
17:00justin_smithor maybe I'm just talking nonsense again
17:15rhg135justin_smith: I just pass everything in one mega map, maybe a magic monad is better
17:21gfredericksoh man; I have a memory perf test in test.check that runs fine on the jvm but blows the stack (?) in cljs
17:21gfredericks#object[RangeError RangeError: Maximum call stack size exceeded]
17:22gfredericksI guess either nodejs has a smaller default stack than the jvm or cljs uses more stack frames than clj or both?
17:27CaptainLex_gfredericks: The former wouldn't surprise me one bit
17:28gfredericksthis shouldn't even be a particularly stacky usage :/
17:28gfredericksstill trying to get a proper stack trace
17:30gfredericksthe internet says that e.stack is something useful but for me it's undefined :/
17:30gfredericksso I'm not sure how to figure out what's so stacky about this
18:04rhg135that would be the reader monad now that I think it
18:45srrubyI want to do something like: lein ring server -env=testing To indicate that the server is running in a testing environment. Thanks, John
18:46CaptainLex_srruby: I don't know about any special ring stuff, but can't you just pass environment variables to the JVM like normal?
18:46CaptainLex_Which I don't have any real experience with either
18:53srrubyCaptainLex_ : I guess I'll use (export FOO=bar; lein ring server)
18:54CaptainLex_Or you could ($FOO=bar lein ring server) if you didn't want to mess with your normal environment
18:54CaptainLex_Or you could even write a shell script to launch lein with the variables set according to arguments, if the syntax annoyed you
19:17srrubyHow can I change a string into a "reader" object ?
19:19CaptainLex_srruby: What are you trying to do?
19:20srrubyCaptainLex: I have some code that reads from a file and processes the data. I want to test the code with a string.
19:21amalloywith-in-str
19:21srrubySomething like new Reader(new stringBuffer("test data")
19:21srrubyamalloy: Thanks
19:25srrubyO
19:44srrubyOK. This is what I came up with.
19:44srruby(defn reader-from-string[s]
19:44srruby (new java.io.BufferedReader (new java.io.InputStreamReader (new java.io.ByteArrayInputStream (.getBytes s)))))
19:44srruby(slurp (reader-from-string "a,b,c,d"))
19:45srrubyseems clumsy
19:46rhg135StringReader exists
19:50srrubyOK. This works. (with-in-str "hello" (parse-data (clojure.java.io/reader *in*)))
19:50srrubyThat is what I was looking for.
19:53srruby(parse-data (new java.io.StringReader "a,b,c,d")))
19:54srrubyrhg135: Thanks. (new java.io.StringReader "foo") was what I was looking for.
19:54rhg135np
19:55amalloywas there something wrong with (with-in-str "a,b,c,d" (parse-data *in*))?
19:56rhg135,(class *in*)
19:56clojurebotclojure.lang.LineNumberingPushbackReader
19:56rhg135oh
19:57amalloy,(with-in-str "a,b,c,d" (class *in*))
19:57clojurebotclojure.lang.LineNumberingPushbackReader
19:58rhg135I assumed it'd be a inputstream given his code
20:01amalloy,(class System/in)
20:01clojurebotjava.io.BufferedInputStream
20:01rhg135hmm
20:45n0n3suchhey
22:22hodwikAre LISPs hard to read because I'm not used to them, or are they just harder to read?
22:23tolstoyI find them easier to read, but I suspect Clojure's use of brackets, and syntax highlighting improve that significantly.
22:25hodwikI guess I find it easier to get a sense of what the code is doing at a fine-grained level
22:25hodwikbut I'm having a hard time stepping back and seeing the big picture
22:25hodwikbecause all of the pieces are so low-level logically
22:26tolstoyComing from Java?
22:26hodwikPython & Java
22:28tolstoyA friend just went through a similar thing. For him, realizing that the functions were verbs seems to have helped a lot (his words not mine).
22:30hodwikHmm, I'm not sure I follow.
22:31tolstoyClojure functions, generally, take data as parameters and transform it into another form of data.
22:31tolstoySo, map, reduce, filter, etc.
22:31tolstoySo, just read the function names and get a sense of what they're doing.
22:33hodwikI've gotten that far
22:33hodwikI'm just not sure how to skim code, so to speak
22:33hodwikto get the big ideas
22:33hodwikEverything looks equally important, in a way
22:34TEttingerah, yeah. an interesting thing is that what would be a few lines in java, with a for loop for instance, is typically a one-line call in clojure to a collection-based fn
22:35hodwikSo then maybe skimming code is not the right strategy to read code in clojure?
22:35TEttingerlike map vs. creating a new ArrayList and appending to it in a for(Thing thing : myList) {} way
22:35tolstoyThat's what I do.
22:35TEttingerclojure code tends to be slightly wider and much less vertically stretched
22:35tolstoyBut I skim by first reading the names and then maybe glancing at the function body to see if there's filter, reduce, map, or something.
22:36TEttingeryeah, similar here
22:36tolstoyLike this: https://github.com/ring-clojure/ring/blob/master/ring-core/src/ring/middleware/params.clj
22:36tolstoyI start at the bottom and go up.
22:37hodwikInteresting, why read from the bottom?
22:37tolstoyThat's usually where the "main" function is, with all the ones above it in support position.
22:38TEttingerit is a big benefit to know if you're dealing with a many-to-many fn (map and mapcat are commonly used like this, filter usually), a many-to-one (usually reduce, not always), a one-to-many (iterate, certain uses of loop, for can be used something like this), etc.
22:38tolstoyThen I quickly scan up and see, assoc-query-params, where I can see he's parsing the querystring from the request (:query-string this or that).
22:39tolstoyI can see that he's parsing the query string into a key/value and associating it to the request as two keys. The rest the functions: *shrug*.
22:40tolstoyKeywords are pretty nice because you can kinda trace the transformation of data by scanning for them.
22:40hodwikOh, that
22:41hodwik's an interesting strategy.
22:41tolstoyI didn't know I had that strategy until looking at that code. ;)
22:44hodwikDo you find yourself using other people
22:44hodwik's code/libs less when writing in Clojure?
22:45tolstoySort of.
22:45tolstoyFor me, the biggest difference between Clojure and your avg Java/Python/C# approaches is the separation of data from functions.
22:46tolstoyFor instance, with that "ring" web stuff, you realize that it's just a wide variety of functions that take a "request" map and produce a "response" map (mainly).
22:47tolstoyOnce you get that, you can skim the code if, say, you wonder how it handles cookies, or query strings, or a response with a body of type "stream".
22:47tolstoySo, the "big idea" you mentioned is getting that main idea, the request map.
22:49tolstoyAnd given that the vast bulk of Clojure code is just maps and lists, you don't need to look for type names (like domain objects).
22:50tolstoySo, you don't look for things like User, but, instead, for functions that seem to operate on users, like, (auth? user) or (valid? db-conn email password) and so on.
22:50tolstoySo, yeah, from the point of view of OO, it can seem like undifferentiated soup. ;)
22:53hodwikSo with Python and Java, I find Python much more expressive. However, I also find it much more difficult to read my code 6 months later than with Java. As if, all that boilerplate just acts as a visual cue.
22:53hodwikMy concern is that Clojure is going to go farther in that direction.
22:54hodwikI take it that you do not experience that relationship between expressiveness and readibility, if you find clojure to be more readable?
22:56tolstoyClojure's the first language where, when I didn't understand a docstring, I clicked the "show source" link and that actually helped.
22:57tolstoyI do find it more readable, I think, because everything's in one place. With Java, I have to use Intellij so I can bop around because any given thing seems to involve dozens of objects.
23:02hodwikI was thinking it'd be pretty cool to have syntax highlighting that does every pair of parens a different color. Does such a thing exist?
23:03tolstoyrainbox delimiters
23:03tolstoyrainbow, sorry.
23:03hodwikAwesome. Is it useful/popular?
23:04tolstoyI think it's reasonably popular. What's your editor?
23:05hodwikWell, I've got Emacs setup, but I wouldn't call it my editor, but that's where I'm working on Clojure right now.
23:06tolstoyhttps://github.com/Fanael/rainbow-delimiters
23:06tolstoyAlas, no pictures on that page.
23:07hodwikThanks
23:07hodwikI'm checking out some screenshots, it looks a bit more distracting than I thought it would
23:08tolstoyI find it so.
23:08amalloyhodwik: ideally you should be paying attention to the indentation, not the parens
23:08hodwikIs focusing on the parens the wrong way to go about it. That is, do you read the "verbs" more than the parens?
23:08tolstoyYeah, I dim my parens, actually.
23:08tolstoyAnd use paredit to manage them.
23:08amalloyparens are for the computer
23:09tolstoyAnyone happen to know how to query specific network adapters via command line on windows?
23:09hodwikAh, I think stanislav datskovskiy told me that
23:09hodwikI had forgotten
23:24macroliciousI'm getting a FileNotFoundException: Could not locate seesaw/core__init.class or seesaw/core.clj on classpath in spite of having :dependencies [[org.clojure/clojure "1.5.1"]
23:25hiredmanseesaw is not part of clojure
23:25hiredmanso saying you depend on clojure doesn't mean you get seesaw
23:51totalnes`hiredman: oops, I meant to say I had: :dependencies [[org.clojure/clojure "1.5.1"] [seesaw "1.4.4"]])
23:51totalnes`last line didn't paste
23:51totalnes`in my src directory I have seesaw.
23:58hiredmantotalnes`: what do you mean by "in my src directory I have seesaw." ?
23:59hiredmanin the interest of short circuiting this, you likely added the dep to project.clj and didn't restart your repl