Fork me on GitHub

I've only played this once, but I suspect I will become addicted:


Hmm. I made a ton of guesses, with a couple of words in the 1000 list and a lot in the sub-1 list. And when I gave up and learned the right word, it didn't make a lot of sense.


That ending. 😄

👍 1
Martynas M08:02:32

Why did he end on the solo. He almost had me converting already!


Any recommendations for a book on understanding the JVM better as a platform? Performance is one consideration, but I'm also interested in how it all fits together from a design/architecture point of view.

🙏 3
Alex Miller (Clojure team)16:02:40

I don't know that there are a lot of great books on the jvm specifically. I think Java Concurrency in Practice is an incredibly useful read for anyone.

☝️ 4
👀 1
Alex Miller (Clojure team)16:02:41

the jvm spec is online and I use it as a reference regularly, but it's not really a "curl up in a hammock" kind of thing :)

😅 3
Alex Miller (Clojure team)16:02:37

I've heard "Optimizing Java" is good, but don't have it

Ben Sless19:02:54

talks by JVM architects and experts also help (Brian Goetz, Guy Steele, Gil Tene, etc)

👍 4
💯 2

@UK0810AQ2 might I ask if you have some personal favorites in talks? (I've watched every Guy Steele talk I've found)

Ben Sless04:02:04

@U3X7174KS nothing specific unfortunately. I mostly gathered it by osmosis and trying to understand performance issues. Don't think I would have heard of stuff like TLAB otherwise

👍 1

I agree with the jvm spec being quite useful

Richard Bowen18:02:31

What practices do you partake in to keep your programming skills very sharp?

Alex Miller (Clojure team)18:02:46

Writing lots of programs

☝️ 4
👍 2
😄 1
Richard Bowen19:02:06

Simple but the best answer so far. Thanks.

Alex Miller (Clojure team)20:02:22

to be slightly less flip about it, the important thing is that practice does not make perfect, it makes permanent. improvement comes from intentional work and criticism of that work (ideally from an outside observer). opportunities to have multiple solve the same problem, then compare their results can be valuable in jogging you out of a local optimal answer.

👍 3
thanks3 1
💯 1
🔥 2

Taking on goals/tasks that I don't yet know how to accomplish and using techniques that I don't yet know to solve them. (e.g. "I need to parse this file that has a complex structure, so I will learn how to write a grammar for a parser generator")

👍 4

Working with people who are smarter and more skilled than me

👍 3

One thing I do to keep my skills sharp is to learn a new programming language that is distinctively different from what I know. Haskell was eye-opening as were prolog, rust, etc. In general, finding approaches to software that disagree with your own views and really deeply understanding them, then practicing them is a great way to learn.

👍 3

☝️:skin-tone-2: Yeah, "The Pragmatic Programmer" book recommends trying to learn a new language every year and I think that's a good stretch goal. I end up learning a new one about every two years and have spent time with Go, Rust, Elm, Kotlin, and a few others in the last decade that I've been doing Clojure. APL, Haskell, and Prolog are all languages I suggest folks try learning.

💯 1
Richard Bowen21:02:03

@seancorfield, do you observe "carry over" from other languages a lot? I.e, concepts/approaches you learned from one language that you've applied to others you're more familiar with.


I find that languages with different idioms and practices help me think of alternative solutions in other languages -- but I think you need to have learned several very different languages for that to work. If you learn several similar languages, that's going to reinforce that style of thinking, and that makes it harder to "think around problems". That's why the first three languages I normally recommend are APL, Haskell, and Prolog -- wildly different ways to solve problems.

👍 1

I think the first Seven Languages in Seven Weeks book is great in that respect (the second one, not so much).

💯 1
Cora (she/her)21:02:35

I find that I usually end up going against the grain quite a bit when I carry over heavily

Richard Bowen21:02:27

Against the grain meaning against the common approaches used by your favored programming language's community?

Richard Bowen21:02:17

This is valuable: Just remembered about it after reading one of the replies here.

Cora (she/her)21:02:18

some things just fit better in different environments. like trying to make ruby into clojure is just not going to work out well. you can add a ton of things to get closer to clojure but it ends up painfully at odds with the language and the community.


> trying to make ruby into clojure is just not going to work out Believe me, I tried 😄. More about this

Cora (she/her)21:02:49

but some things aren't as painful and have more concrete benefits

Cora (she/her)21:02:02

in the ruby example, for instance, making more functions be pure has a ton of benefits


High performance bit-manipulation operations struggle a bit in Clojure. You can certainly do it, but it’s not ideal


I guess if you want you could use the new Foreign Function (JVM 17) and use something like C++/Rust for that part. As long as bit manipulation is not the core thing of the app it might be viable.


But then it's another language. Which is making my point


Yes, but you can still write all the other stuff in Clojure.

Martynas M12:02:11

Why go down the levels? Why not up? 😄 Somebody should implement a compiler from C/ASM to Clojure. Because this way they could do their bit operations fast and then call Clojure when they need to use Datalog or something similar.


Yes, making a Clojure like thing on Rust crossed my mind. It's a hell lot of work through, not sure about repl experience either.


Ferret attempts this. Personally, I want to see ClojureScript targeting WASM instead of JavaScript. The main impediment right now is the lack of GC. Then again, reference counting would have a lot of benefits… I’ve just never tried to implement a reference counted lisp

👀 1
Martynas M16:02:21

I wasn't thinking about ferret. I was thinking what could it be. Without even referring to computing. But yes, it could be something like Ferret.


Rereading what I wrote… I should reword it. I meant that I’d like to see an option for ClojureScript to target WASM rather than JS. I don’t want to get rid of the JS-targeting version


though, maybe if it could be written to an LLVM backend, that would be ideal

👍 1
Martynas M16:02:08

LLVM could mean golang (I have no idea what this means but I know that golang is compiled via LLVM)


I think an implementation could just wrap everything in ARC all the time, and let the 'gc' be handled by the code itself, instead of having it natively in WASM?


@U028ART884X LLVM is a compilation framework which has an intermediate representation that can then be targeted to various platforms. Golang is a language that can be compiled to that intermediate representation, as is C, Rust, and so on. Once in that representation, the next steps of the compiler can target the various platforms, including x86, M1, and WASM.


the main thing about porting clojure to bare metal (or re-implimenting a vm -- llvm isn't really one) - clojure puts a lot of pressure on the gc short-term allocator. it turns out the JVM has exceptional performance for this use case, but replicating it would be a huge undertaking

👀 1

if you write code that actually looks / feels like idiomatic clojure, a gc other than the jvm hurts perf more than your low level target improves it


there's a lot of common lisp lore about "cons free programming" - what they called writing your hot loop so it doesn't comtain allocation. but it is much easier to write code like that in C (or even java for that matter)

Martynas M17:02:49

What about C# VM? Do they do the same? JS?


there are clojure ports to those targets, but they don't have the performance of jvm clojure (relevant because the reason people talked about bare metal ports here was improved perf)


actually I'm less sure about C# - that port hasn't taken off (at least in the worlds of tooling and open source)


when I first tried clojure-clr I was blown away by the speed - then I realized it was just fast startup from not using leiningen


My understanding is that reference counting is slower, but it also doesn’t have the pauses that GCs typically have


right, you trade better latency (no stop-the-world pauses) for worse throughput (everything that allocates is slower, you fragment the heap which degrades performance over time) btw. this is related to some gc languages needing periodic restarts for perf reasons, while jvm can run for years without perf degrading


and the way we use immutable data structures in clojure leads to large numbers of small short lived allocations in idiomatic code, which is a worst case scenario for reference counting

👍 2

but even most mark-and-sweep gcs (the main alternative to refernece counting iirc) are not as performant as the jvm gc


Well… the latest JVM gcs.


When I’ve worked with GCs, it was done as mark-and-sweep. (I’m thinking of Gherkin here)

Joshua Suskalo13:02:12

I mean you could make a/b copy gcs and that gets you most of the way there, and if you make a/b configurable it'd make it pretty easy to make a generational collector which is what makes the jvm good for clojure, and if you make all the mutable elements (atom, ref, agent, volatile) live in a special memory arena all their own with reference counting then you can make the GC dead simple because objects are only able to reference things older than themselves and have no cycles.

Martynas M18:02:20

What if we don't do it for Haskell and we have transients in Clojure?