In other posts you actually argue that GCs help you reduce complexity because manual memory management is too much of a hassle.
May be immutable is not the correct term - persistent data structures is what I like support for: that is my use-case.
I think you can have efficient persistent data structures without a GC, but that requires fast reference counting and in turn, that requires a lot of work to be competitive with the JVM.
I also understand that my use-case is not Julia's focus. That's perfectly fine.
Java sacrifices some performance for having this "one paradigm" of all objects, and then heavily invested in the GC, but in many cases like writing a BLAS it still just will not give performance exactly matching a highly tuned code, where as in Julia for example you can write really fast BLAS codes like Octavian.jl.
Julia is multi-paradigm in a way that is purposely designed for how these features compose. I think it's important to appreciate that design choice, in both its pros and cons.
Octavian uses stack-allocated temporaries when "packing" left matrix ("A" in "A*B"). These temporaries can have tens of thousands of elements, so that's a non-trivial stack allocation (the memory is mutable to boot). No heap allocations or GC activity needed (just a GC.@preserve to mark its lifetime). If I understand correctly, this isn't something that'd be possible in Java?
To be fair, you can also just use preallocated global memory for your temporaries, since the maximum amount of memory needed is known ahead of time.
Indeed, it is always about design choices and trade-offs. I can see why BLAS code is important and why Julia is an optimal choice for computation heavy problems.
It is entirely possible to design a garbage collected language that doesn't generate so goddamned much garbage — and this works much, much better because a relatively simple GC can easily keep up. Julia and Go are good examples of this. Julia uses immutable types extensively and by default, while Go uses value semantics, which has a similar effect on garbage (but has other issues). With a language design that doesn't spew so much garbage, if you only care about throughput, a relatively simple generational mark-and-sweep collector is totally fine. This is what Julia has. If you also want to minimize GC pause latency, then you need to get fancier like Go (I think they have a concurrent collector that can be paused when it's time slice is up and resumed later).
Persistent data structures are a whole different question that I haven't really spent much time thinking about. Clojure seems to be the state of the art there but I have no idea if that's because of the JVM or despite it.
How possible would it be for Julia to add this? I keep thinking Julia would be great for graphical environments and gaming, but high GC latency won't work there.
Unfortunately, persistent data structures tend to produce (short-lived) garbage which the JVM is very good at collecting!
So yes, Clojure benefits immensely from the JVM.
It is also an interesting research topic whether (optimised) reference counting would be a better approach.
Regarding objects, there is also a "middle ground" to consider:
Split big (immutable) arrays in smaller ones, connect them with some pointers in between, and you are still cache friendly.
Also, you can do a lot on the application level to reduce garbage, and most Java programmers don't care for that exactly because of JVM.
Not anymore. That future is here. Java is getting "flattenable" types not because of GC, but because of iteration.