Fork me on GitHub

Anyone know where in intelliJ I can change the styling of teh box that it puts around matching parens, like shown in the image below. I want to either remove it make it much much lighter


It puts the same stupid box around matching text too, e.g.:


Found it Editor > Color Scheme > General > Code > Matched BRace and turn off bordered or make it a dimmer colour


@qmstuart Glad you figured it out - there's a #cursive channel which should be helpful.

Ben Sless08:02:57

We have at work some services which do a ton of IO and ser/de. the GC improvements from just migrating to Java 15 (from 8 ) are massive. It's very nice to see young generation time take a nose dive


yeah I heard so :) is the described scenario pure-java or do you also have some clj benefiting from this?

Ben Sless10:02:55

Clojure services, although almost all CPU is jsonista (i.e. jackson) and gzip in Kafka

👀 3
Ben Sless10:02:55

Another interesting tidbit I found relating to GC is that direct linking gives an improvement

👍 3

interesting that the CPU bottleneck is non-clojure JVM code ^^

Ben Sless13:02:21

It's a pretty simple IO service that handles a large amount of traffic, so serialization dominates the CPU. In a sense we do pay a price for the Clojure code because building up maps and vectors, even transients, is probably slower then allocating objects


Yes it's well plausible that immutable objects are more expensive than mutable ones. Probably Clojure relies heavily on JVM's GC as a basis for good performance, which generally works but GC isn't magic either Things aren't necessarily better in Java either, where "zero-allocation" techniques can be needed There's also the nuance that Clojure, not unlike Java, is a general-purpose language. Certain kinds of workloads beyond that "general-purpose" can benefit from lower-level platforms/languages


clojure maps are Objects, but they contain a lot more data (and a set of internal objects) than the naiive equivalent object, the difference in performance is about the larger number of allocations to create one, and the number of allocations done on each field update. when you update an object field, you do a simple reset of a value, to update a clojure map you do N allocations for each update where N is at least one


@UK0810AQ2 Which GC are you using with 15? We've been using G1 for a long time (we're on JDK 11 in production/QA and a mix of 14 and 15 in development).

Ben Sless17:02:24

I'll test the performance of other algorithms in the next weeks


I'll be interested in those results -- were you using G1 with JDK 8 as well? (I can't remember when it was introduced/became the default)

Ben Sless18:02:49

G1 became the default on JDK9. The default on 8 is ParallelGC

Ben Sless18:02:08

AKA throughput collector

Ben Sless18:02:31

On JDK8 I found that services which churn a lot of data (kafka to kafka) indeed have better throughput with ParallelGC

Ben Sless18:02:38

I'll need to rerun those tests with JDK15


We were mostly using G1 on JDK 8 because it gave better latency on interactive services (like web apps). I think our background processes were using ParallelGC back then. Everything is using G1 now at work (even our legacy JDK 8 processes).

Ben Sless18:02:18

This is slightly OT of this thread, but do you version control the commands you use to run your services?

Ben Sless18:02:31

Interactive services should use G1 from what I read, but it seems that at scale when responsiveness isn't an issue ParallelGC still has an opportunity to shine


Yes, all the scripts for building, deploying, and running services at work are under git (bitbucket). Server-specific configuration is the only thing we don't version control (passwords and sensitive API keys etc).

Idan Melamed17:02:21

Hi, Anyone wanna join @pradeep.bishnoi, @pithyless, and me for a session of mob programming? Tuesday at 12:00 UTC. This is the first session, so we'll do the PM me if you want to join :-)

Thomas Moerman19:02:58

On the topic of naming things nicely, following The Clojure Way (spoken with a Mandalorian accent): how would you call a boolean variable that means: this task is ignored for the completion of the parent Project.

Thomas Moerman19:02:27

:muted?, :ignored?, :transient?... something like that


I personally dislike keywords with ? on them -- I only use ? for strictly Boolean predicate functions.


aren’t keywords with ? also considered boolean predicate functions? 😁

😅 3

Edge case: passing a predicate in a map:

{:odd? odd?}


I have considered making this an opinionated linter in clj-kondo, since I also dislike question-marked keywords, but when actually using it, I found it too strict to make sense, because of these edge cases.


Yeah, it's def. one of those grey areas for me -- and I've gone back and forth on it a lot over the decade I've been doing Clojure. I believe nothing in clojure.core uses keywords ending in ? (although the implementation of has an internal :changed? flag and the implementation of print-method for reader literals has :splicing?)


I have no strong feelings, but the general consensus seems to be with you (ie. avoid ? suffixes for keywords , but allow edge cases like borkdude’s example)

Thomas Moerman20:02:13

ok, the misplaced doc-string linter is a reason by itself to try clj-kondo I'm still getting bitten by that one due to python muscle memory 😅


?-suffixed keywords can make slightly more expressive APIs when used as keyword arguments (i.e. code). For all other usages (data) they seem more dubious since it's plausible that that data can end up serialized to e.g. json later.


On the parent have a set of ignored sub tasks so it’s just membership check with respect to the parent.


I’m assuming there’s context info somewhere floating around

Thomas Moerman19:02:41

that's a possibility, indeed has a stronger link with the semantic context


Yeah it’s only meaningful with respect to the parent. So it’s nested where it’s unambiguous

Thomas Moerman19:02:43

although it is a memberof the parent, but its completion is ignored for the completion of the Parent

Thomas Moerman19:02:18

kind of a flag to indicate that this task is e.g. a Training task instance, not an Official task effort.


don't know your specifics. but if you walk a tree of subtasks for a parent you can mark them as don't run and then your task runner doesn't have to care about why they aren't run. or have the task runner consult the parent for which tasks aren't mean to run

Thomas Moerman19:02:31

Thinking about it, I could as well reify the relationship and qualify it with a relationship type, would make more sense but more work to retrofit

Thomas Moerman19:02:43

anyhow thanks for the input


there are designs where you make a graph of dependent tasks, and only execute the ones across your desired path


eg. what make(1) does - you specify a target to execute, and every target defines its prerequisites


I think that's off topic of your off topic question 😄

Thomas Moerman20:02:39

slightly 😉 it's also off-mark but that's because i didn't properly explain the design problem 😅

Thomas Moerman20:02:38

Rubberducking the question here already helped me think about it 😉

Thomas Moerman20:02:50

I have to call it quits for the day, otherwise i'll be dreaming in Parens again