#clojure logs

2017-06-27

07:13RovanionDoes a symbol reference a value or is there a more correct term than references one can use?
07:13dysfuna symbol names a value
07:14dysfunpossibly
07:14dysfuna symbol may or may not name a var which contains a value
07:14dysfunoh, but that doesn't cover local bindings
07:14RovanionAre functions held in vars?
07:15dysfunif it's a value accessible through the namespace, it's a var
07:15RovanionBut local bindings made with let are not vars?
07:16dysfuni don't think so, but i couldn't tell you what they are
07:16dysfunthe point of vars is that they provide a thread safe mechanism for changing the value of something
07:17dysfunand there's no need for thread safety for locals
07:17RovanionWhile namespaced things can be adressed and potentially mutated from anywhere in the program?
07:18dysfunexactly
07:18dysfunwhereas a binding isn't updateable, so no worries
07:18dysfun(with the exception of dynamic binding, obviously)
07:18Rovanion:D
07:19dysfunthose i am afraid i do know about, but you'll forgive me for not wanting to talk about how they work
07:21RovanionI've not needed dynamic binding thus far so I'm absolutely fine being ignorant about how they work right now.
07:21dysfunwhen you need it, you really need it
07:21dysfunnaturally it plays terribly with lazy sequences
07:22dysfunin general, a great way to add confusion to your codebase
09:50RovanionWhat is the difference between a form and an expression?
09:51justin_smithin a language without statements (like clojure), there is none
09:52justin_smithin other languages a form could be a statement
09:53RovanionThank you!
11:05tallpantsHi
11:05dysfunhello
11:07tallpantsIs it normal to feel skullfucked when you're starting off learning >_>
11:07dysfunutterly
11:09tallpantsHow long did it take for you to get over the hump?
11:09tallpantsNot to get good, just to get to "not utterly incomprehensible wtf is happening"
11:10dysfunit starts to fade fairly quickly, but i don't know i felt properly comfortable in clojure for at least a year
11:36dnolenClojureScript 1.9.660 released https://clojurescript.org/news/2017-06-27-faster-compilation-runtime-and-spec-caching-fixes
12:11osfabibisigah, how annoying that < doesn't work for all compare'able things
12:12osfabibisicolleagues have written #(< (compare %1 %2) 0) instead, which seems less pleasant than it ought to be
12:12technomancy(comp neg? compare)
12:13osfabibisiyeah, that's still pretty horrid though
12:13technomancysure
12:26technomancywhich is nicer? (mapcat (comp file-seq io/file) src-paths) vs (for [p src-paths f (file-seq (io/file p))] f)
12:27technomancyI feel like this is one place where `for' making you choose a name for the intermediate seqs isn't helpful
12:39technomancy(.lastModified (java.io.File. "does not exist")) ; -> 0
12:39technomancyugh
13:01justin_smithtechnomancy: it's Borges' Library of Babel - every possible file with every possible name existed on january 1st 1970
13:02justin_smith"Despite—indeed, because of—this glut of information, all books are totally useless to the reader, leaving the librarians in a state of suicidal despair."
13:03justin_smithsounds a lot like the Internet actually
13:04technomancyah man I really need to read that
13:05justin_smithwow, Quine wrote about it https://en.wikipedia.org/wiki/The_Library_of_Babel#Quine.27s_reduction
13:05dysfuntechnomancy: i would be interested to see your 'fur' macro which is like for but removes the need to assign names
13:09technomancydysfun: oh, I just meant mapcat
13:20wickedshellDoes anyone have any recommendations on parsing an input stream into a lazy sequence? The best I've been able to find is https://github.com/jpalmucci/clj-yield looks quite reasonable for what I want to do, but I notice it hasn't been updated in 6 years (still works as expected in the REPL) I'm just curious if there is a more idiomatic way to transform an input stream into a lazy sequence
13:23hiredmana lazy sequence of what?
13:24wickedshellmaps (each message that was encoded in the file essentially)
13:25hiredmandon't use clj-yield
13:25amalloyclj-yield is a weird idea
13:26hiredmanyou may want to checkout https://github.com/ztellman/byte-streams
13:26amalloyit's very easy to just write a recursive function that uses lazy-seq and cons
13:27wickedshellI've never messed around with lazy-seq, but I was struggling on paper to see how to maintain the locally needed state for the input stream to build the next cell (probably missing something obvious on it, but thats where I ended up last night)
13:28justin_smith(lazy-seq (cons (f input-source) (self-call input-source)))
13:31wickedshellhmm will play with that a bit then, see if I can make sense out of it in the REPL
13:31wickedshellThanks
13:53wickedshellWith the above calls how do you manage the with-open context? I succesfully cooerced the code into justin_smith's recommendation (was easier then expected), however it has the downside I had to remove the with-open inside my function that was creating it's own DataInputStream
13:54justin_smithright, you need to embed the ability to close and clean up the stream into f (and only conditionally do the self-call if the stream is still open)
13:55justin_smithwith-open and laziness are not compatible
13:56hiredmanhttps://ce2144dc-f7c9-4f54-8fb6-7321a4c318db.s3.amazonaws.com/reducers.html
13:56wickedshell... right, thats actually obvious in hindsight and something I think I had realized last night, and now spaced today...
13:58justin_smithreducers, as hiredman linked, seem like they could be an interesting alternative to a lazy-seq here, but I can't say anything about using them
13:58justin_smithI should try them out one of these months
14:00amalloywell, with-open is *sorta* compatible with laziness. you can produce a sequence lazily inside of a with-open, so long as you fully consume it before leaving the scope of that with-open. laziness is still a useful way to reduce coupling
14:00wickedshellThe current target for why I was pursuing laziness was to allow working with a moving window over a large file (on the assumption that if I don't hold onto the head I won't blow up memory) I could be wrong on that, but the files I'm poking at are just to large to hold the entire represenation in memory, but I still want to be able to play with external use of filter/look into transducers
14:00wickedshellI could be chasing this the wrong way, but it's been intresting thus far :)
17:52Rick77Hi, does anyone knows how to start leiningen with a specific version of clojure (I have to work around CLJ-1743 and I use a patched jar)?
17:54TEttingeryou mean the version of clojure that lein itself uses, not your project?
17:55Rick77TEttinger, I guess I can change the clojure in my project easily enough with project.clj (correct me if I'm wrong), so I'd say the one leiningen uses
17:56TEttingermaybe this? https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md#replacing-default-repl-dependencies
17:57TEttingerI don't know what CLJ-1743 is off the top of my head. I mean I don't even know where the JIRA is...
17:57amalloyTEttinger: it is very easy to find if you just type CLJ-1743 into google
17:58amalloyRick77: i think you should figure out whether you need to replace the one lein uses or the one your project uses, not just assume you want to do the harder one of those
17:58amalloyi doubt the version of clojure used by lein matters to you at all, in the context of CLJ-1743
17:58amalloyi would expect it to do AOT compilation inside of a JVM that's in your project context, not lein context
17:59Rick77amalloy, that's *very* helpful, thanks
17:59amalloymy guess would be, make sure the patched version of clojure you need is published in a maven repo somewhere, and then depend on that in your project
17:59Rick77since we are at it, is there any way to reference a jar in a leiningen project without maven? I'm doing a quick company hackaton, and the dependencies are messy...
18:00Rick77amalloy, also a very good suggestion: thanks
18:00TEttingerif it's a public git repo, you can use jitpack
18:00Rick77no, it's a naked jar I have in a dir somewhere. Don't ask ;D
18:00Rick77(or better, a dozen of them...)
18:01amalloynormally when publishing a fork you'd do it under a different artifact id, but since you want to override the version of clojure seen by the whole universe, i'd publish it to a maven repo (preferably a private one you own) under the name "org.clojure/clojure" but with a weird version number that nobody else will ever try to use, like "rick77-1.9-alpha500"
18:02Rick77amalloy, I'll follow the way of the slacker(Tm) and look for one around first ;-)
18:05Rick77is there any leiningen plugin that allows referencing a "naked" jar anyway?
18:05amalloynaked jars are a recipe for sadness
18:07Rick77amalloy, agreed, and I have already installed all the jars I need in my local repo with custom names, but still it would be nice to be able to do that, if else for quick tests...
18:07TEttingerif the bug has been fixed in Clojure but hasn't yet been released, this gets the latest commit as it is built by JitPack https://jitpack.io/#clojure/clojure/d7e92e5d71 (lein is an option)
18:08TEttingerif it has been fixed by someone else, use their repo instead of clojure/clojure
18:08Rick77Thanks TEttinger: I'll check it out!
18:08TEttingercommit could be broken, but that seeems to be a release
18:08amalloyTEttinger: the problem with that is, if you use something other than org.clojure/clojure, you end up pulling in both the patched clojure and normal clojure
18:08Rick77also, no custom repo: there is a patch, and I'm applying and compiling right now
18:09amalloythe same thing would happen if you added a local naked jar to the classpath: you'd get its stuff, but lein would still also pull in org.clojure/clojure for you, as other stuff depends on it transitively
18:09TEttingeramalloy: would that still have issues with AOT compilation then?
18:09amalloymaybe you could make it work, but i would not want to deal with the issues caused by having two clojures in the same jvm
18:09amalloyi dunno, maybe, maybe not
18:09TEttingermaybe you should google it
18:09Rick77the jar inclusion was for something else, actually, not necessarily the clojure jar itself
18:10Rick77but that's good to know, thanks
18:13Rick77wait... I didn't check whether 1.9 already has the patch!
18:13Rick77nope ;(
18:16lxsameerwhich name do you prefer for a function which is responsible for fetch a value of a key from a config file ? 1) fetch-config 2) <-config 3) suggestion
18:16lumacoming from enterprisey java background, get-property
18:16technomancy"fetch" implies over a network to me
18:16jeayeAgreed with technomancy.
18:16jeayeAlso, sounds like that function is doing a lot.
18:17jeayeConsider separating the slurp from the pure key lookup.
18:18TEttingergood point for composability, jeaye
18:18lxsameerjeaye: that function implemented by smaller functions
18:20jeayeSo why not just have a fn which gets you the config and you can do the key lookup like you would normally?
18:20amalloyjeaye: yes, but having done that be careful not to write something like [(:k (get-config)), (:q (get-config)) ...]
18:20jeaye(::meow (kitty/config)) ; for example
18:21lxsameerjeaye: basically that's the implementation of that function. and if i do that in every place in my code it going to violate the DRY rule
18:21amalloythat is, it's great to split up, but this imposes on you the extra burden of tracking already-loaded configs to avoid lots of pointless re-lookups
18:21jeayeamalloy: What I tend to do is (def config (slurp ...)) and then just treat it like a map.
18:22amalloyfine, but now you've made a global singleton
18:22jeayeAny "redundancy" is in the syntax of looking up a key, which is the the majority of code.
18:22lxsameerjeaye: let's say you need to provide a default value for missing keys
18:22technomancythere's nothing wrong with a global singleton of immutable data
18:22amalloyand introduced weird compile-time vs runtime dependencies: you're slurping that at compile time
18:22technomancyyou merge in the defaults at boot
18:22jeayelxsameer: clojure.core/get does that.
18:22lxsameerjeaye: now, you spread your default values in your code
18:22jeayetechnomancy: Agreed, immutable globals ar eno problem.
18:23jeayelxsameer: If you're using defaults quite often, I can see that as causing an issue.
18:23technomancyit's not a problem; merge them when you def
18:23amalloythey're less of a problem, but i disagree that they are no problem at all. it means you can't have two copies of your thing in the JVM at once, because they have an implicit dependency on this global
18:24amalloyoften this is fine, but it's not so rare that a thing you thought you would only need one of suddenly turns into something you want more of
18:24jeayelxsameer: I almost never do, so it didn't come to mind. In that case, consider get-config
18:24technomancyamalloy: it's not a good pattern for libraries, granted
18:24amalloyheh, i would say the same thing but emphasized differently: it's excusable for apps
18:24lxsameerjeaye: ;) thanks
18:26amalloyeven for apps i prefer not to do that, but it is the expedient path and usually causes little harm. component is a good way to avoid global singletons while still keeping the convenience of not having to wire stuff together yourself
18:26technomancywe have our config managed using mount in one of our services and it's really stupid
18:26technomancybecause it means you can't repl in without having mount started =\
18:27technomancybecause the repl port is a config value
18:27amalloyas someone who only hears about mount when someone is having enough trouble with it to ask for help in irc, i conclude that mount always causes a great deal of trouble
18:27technomancyamalloy: that's exactly how I feel about component
18:28{blake}Is it possible to capture stdout globally? Such that all the output that would normally appear on the command-line (I guess that might include stderr) would be saved as a string?
18:28technomancy(they're both annoying to me)
18:28technomancyamalloy: but this problem would be just as bad with component
18:29amalloytechnomancy: well, so long as you and i both recognize that we have biased perspectives based on where we hear about it. that's why i prefaced my statement with the obvious reasons it's a bad observatoin
18:30technomancyI'm sure component solves problems for people
18:31jeaye{blake}: Wrap your main in with-out-str?
18:31jeayeHonestly, the easiest way would probably be in the shell, not in Clojure.
18:32{blake}Yeah. My issue is that I can't control anything outside the code and I'm not allowed to see the logs. =)
18:32jeayejava -jar my-app.jar 2>&1 | tee my-saved-output
18:32jeayeAh.
18:38{blake}And the log tool I have access to shows each line of the stack trace as a single, clickable entity... Whee!
18:42Rick77amalloy, building a custom jar, slapping it in the local repo and just changing the dependency worked (no need to mess with the profiles): thank you! :)
18:59Rick77thank you all for the help, always a pleasure to be here! Bye.
21:52kenrestivojar in repo? hmm.
21:53kenrestivoi am always deeply suspicious of compiled objects in repos
21:54amalloykenrestivo: i think you are confused about what is meant by repo there. clojars.org is a repo with loads of jars; the earlier discussion was about maven repos, not git repos
21:57kenrestivoaye