This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-06-06
Channels
- # announcements (2)
- # babashka (22)
- # beginners (93)
- # calva (12)
- # cider (65)
- # clj-kondo (15)
- # cljdoc (5)
- # cljs-dev (4)
- # cljsrn (4)
- # clojure (65)
- # clojure-europe (2)
- # clojure-italy (1)
- # clojure-nl (1)
- # clojure-norway (1)
- # clojure-spec (40)
- # clojure-uk (7)
- # clojurescript (12)
- # conjure (1)
- # cursive (2)
- # data-science (13)
- # datomic (1)
- # dirac (12)
- # emacs (3)
- # figwheel-main (19)
- # ghostwheel (5)
- # helix (6)
- # kaocha (1)
- # leiningen (6)
- # news-and-articles (2)
- # off-topic (17)
- # pathom (5)
- # re-frame (59)
- # reitit (17)
- # restql (1)
- # shadow-cljs (31)
- # spacemacs (5)
- # spire (3)
- # sql (35)
i'm not sure since when but homebrew started giving this warning:
❯ brew update && brew upgrade
Already up-to-date.
Warning: Calling 'devel' blocks in formulae is deprecated! Use 'head' blocks or @-versioned formulae instead.
Please report this issue to the clojure/tools tap (not Homebrew/brew or Homebrew/core), or even better, submit a PR to fix it:
/usr/local/Homebrew/Library/Taps/clojure/homebrew-tools/Formula/clojure.rb:7
Just started happening today
Well, they’re suggesting removing the devel block, but we’re using that
And the suggested replacements are different things
No need to do anything, I’m thinking about the best way to address
Seems the brew
people are really opinionated about how the world should work... 😞
yes and i think they are learning it the hard way that the real world doesn’t work the way they think it should: https://github.com/Homebrew/homebrew-core/pull/51883 for various reasons like that, i switched to SDKMAN! for all other SDKs on the JVM and never looked back. i’m hoping to see Clojure CLI on it soon. 🙂
huh they removed lumo
formulae in that PR o_O https://github.com/Homebrew/homebrew-core/pull/51883/commits/a5c6280c5d42f71bfdcf4badb981a52598953b84
If anyone is interested, there are https://clojure.atlassian.net/browse/TDEPS-113 and https://clojure.atlassian.net/browse/TDEPS-36
I looked at sdkman again back when we made our own brew tap as another option. I’d have to go find my spreadsheet again for all my thinking on it but certainly it does not have the awareness or reach of brew
Seems like brew is pretty actively moving in ways I don’t like these days though
yeah, I hadn't heard of it before this thread and have been struggling with good cross-platform options.
It’s kind of jvm focused
yes, that’s one of the things i like about it: maintained by people who know a thing or two about the JVM and its ecosystem.
from my personal observations over the past 10 years, there are two types of developers with regard to how software should be installed on their computer: a) people who would like to have full control over it and thus don’t mind taking manual steps as far as manually downloading/placing JARs; b) people who just want things installed and don’t care how (and thus are not picky about what tools to use.) so if linux-install.sh
is made compatible with macOS (as a manual option) and we picked SDKMAN! (or anything less brittle, less opinionated, and friendlier to the SDKs on the JVM) for the automated installation/update then we should be at a sweet spot where we can cater to both kinds developers on ALL platforms (GNU/Linux, macOS, and WSL on Windows).
I think linux-install.sh is at least mostly compatible with Mac already (it’s already nearly identical to the install script invoked by brew)
right now I have my mac, and I'm also using WSL2 on my desktop and I'm using SDKMAN! now, plus the official clojure tap on both and it works great.
I just need to figure out (though Calva with VSCode WSL remote and Emacs are the options I'm using now) how to get Cursive working well with WSL2 and then I'm totally mirrored between the two, which helps when I need to jump over and take advantage of more RAM.
FYI, Atom/Chlorine on Windows understands Linux and Windows file paths so it will work with a Socket REPL started from either Powershell or WSL (because it assumes <drive>:\path\to\file.clj can be loaded on WSL as /mnt/<drive>/path/to/file.clj).
That's good to note. I still haven't gotten to the point where I'm comfortable (as it were) using Windows tools through Linux filepaths (or vice versa). I'm keeping the two worlds separate except for very specific tools (opening a browser, or ports), which may be me hobbling myself. I'm not really comfortable with Windows development-isms, but the combination has been great for me.
I use asdf and like it a lot. I don’t use it for Clojure because currently brew is officially supported, and I found asdf’s Clojure plug-in to be immature. https://github.com/asdf-community/asdf-clojure, https://github.com/asdf-vm/asdf
I looked at asdf back in Feb. I don't think it's a good match for what we're doing - brew has more reach and sdkman is a better ecosystem fit
Opinionated isn't always a bad thing. Else Clojure would not exist 🙂
I'm not here defending any choices of the Homebrew team -- I do not understand that situation well enough to have an opinion on it.
Hi people. Is there a threading operator that keeps threading until a non-nil result is produced? Kind of like reverse some->?
https://github.com/rplevy/swiss-arrows
have a look at
some-<>
Just in case - if you have a collection of functions, I would use some-fn
instead of any kind of threading.
@U0K064KQV Thanks, but or doesn't let me pass in a value to the expressions. I realise I could do a let binding but I think a threading operator would be more elegant.
@U04V4KLKC Yeah, I looked at those, but I don't see how they would let me return the first non-nil result? I might be missing something.
Because there's no built-in threading operator that does that, and some-fn
is both built-in and does exactly what you need (again, assuming you just have a collection of single-argument functions).
@p-himik I see your point. I think I can rework the expressions into single arg functions, so that might be the way to go.
Plain lambdas are fine:
(let [find-needle (some-fn single-arg-fn #(two-arg-fn % 1) #(three-arg-fn 1 % 2))]
(find-needle haystack))
Ah ya I see, you want a threaded or. Don't think there's a core way of doing that. But if you copy paste the code for the some-> macro it is probably trivial to modify it to check for nil? instead and write your own
Hello everyone, bringing in a discussion started by @p-himik in a thread, regarding benchmarking • What's a proper way to benchmark a function? • What makes benchmarks synthetic? • Is criterium sufficient for benchmarking functions? • How big should the input space we run benchmarks against be? Would love to hear your thoughts link to original discussion with lots of comments by Alex Miller https://clojurians.slack.com/archives/C8NUSGWG6/p1591453495326800
For the context: the discussion rose in comparing
(into {} (map (fn [[k v]] [k (f v)])) m)
and
(reduce-kv (fn [m k v] (assoc m k (f v))) {} m)
Based on some input from Alex, it seems that map entries are generated at iteration time, and that reduce-kv
doesn't generate overhead. There's also the cost paid for destructuring and allocation several times during the mapped function.
I’m really interested in the answers to this, I’ve been trying to work out how to write reasonably fast code without having to write java in clojure…
@U0JUM502E updated with link to original discussion, you might find Alex's comments interesting. You can also refer to my experiments with writing fast clojure in https://github.com/bsless/clj-fast
Just curious if you’ve seen specter? https://github.com/redplanetlabs/specter
It aims for a different level of abstraction, a downside in my eyes is that you have to restructure your code a bit to use it well, but on the other hand it’s not too complicated and gives quite nice performance benefits =)…
I always have a slight aversion towards introducing too many new language abstractions. a. they're not free b. I don't work alone. My teammates might feel less inclined to try out another one of my crazy ideas
Yes, that’s just it. Hence it’s nice, but not sufficient for me. At the moment I’m really trying to figure out ways of structuring looping across really large structures with as low a perf hit as possible without my code looking weird =)… Writing a sim, so larger numbers of agents means more scope to have interesting things happen… Also lots of group of X interacts with group of Y type stuff… It can end up really slow if I’m not careful.
I remember when someone popped in to the clojure subreddit with a version of Conways game of life which ended up with everyone golfing it for performance. Ended up writing alien code with arrays, but boy did it run fast https://gist.github.com/bsless/f2e98c8c512a2c015c6e9bce6a10a039
I missed that, tempted to write a simple broad strokes example of part of my sim and see what alternative ways people would shrink it by =)… Actually that might be fun, could double as a tutorial, not seen enough of those for this! Would be cool if more people started writing them.
@UK0810AQ2 First of all thanks for that post, it was an interesting read. I especially like the clear don't=>do paragraphs. As I have not seen this mentioned yet, regarding benchmarking I would say, you don't do it until you have a real world case with a real world problem Which usually is a programm / webapp / library running in production given certain inputs, load, latency and hardware requirements. And that's what you do benchmark. It's hardly useful (except for learning purposes) to benchmark single functions as you will never know how they are used in production. And then, when you find the culprit of your slowness, you will update it and again test the performance in your reproduction environment and not just the single thing alone.
Thank you @U0677JTQX
In general I tend to agree with what you say on benchmarking, but I think it can be qualified a bit. Isolated benchmarks can be indicative, if not definitive. We can see merge
performs badly, regardless of the environment it runs in. Similarly for transducers vs. lazy sequences, and reduce-kv vs map iterator.
I still hadn't seen a case where a "micro-benchmark" didn't match what I later saw "in the wild". I'd love to hear about a case where that happened
The thing is, I am not disagreeing wether merge performs worse than other options. What I mean is, just because you use merge in places x, y and z in your application, it does not mean that these code paths will be slow. What if they are called only once per user per registered lifetime? Would it make sense to use other options or prefer the more readable one? And now that you thought about that one place, can you answer the question about how your code is going to be used for every probable usecase? If in doubt I code for readability and being able to understand what's going on easily instead of perceived performance.
> Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil*. *Yet we should not pass up our opportunities in that critical 3%. (emphasis mine) First, even in the hypothetical you describe, you're neglecting taking into account system SLAs. Even in a one-off call, the code path might have to be optimal. Second, you sidestep the issue of recognizing the tight loop and optimizing that. It might be legitimate to write less readable code there, or creating a new library, to support that place in your code. Third, any performance optimization of software in the wild must come after profiling in my opinion. In that sense you are right, that "perceived" performance differences are irrelevant. This is why you profile, generate a pretty flame graph, and realize you spend 90% of your CPU doing something that can easily be avoided with nary a dent to the code's readability, but you have to measure first. I don't see the benefit in this sweeping generalization of readability > performance. Each have their place. But one important caveat is to measure things before starting to optimize them
If I understand you correctly we have the same take on that topic. You need to profile your running system and optimize the slow parts, if they hinder you staying within the bounds of your SLA. If you have one.
Hey guys, is there a way to mock, or globally re-def Java classes in tests? Currently, I can use with-redef
to mock clojure functions, but this does not work with java interop classes like say: java.util.Date
. I would like to mock Date to return a mocked string for my tests.
https://github.com/shaolang/cljito should be able to handle that, i've definitely mocked java.util.Date
with mockito-scala before.
Interesting. I was hoping to do this without importing a new lib, doesn't seem like its possible. I will check out your lib thanks