I think we can learn something here.
I think we can learn something here.
After a few rounds of this though it might end up seeming like it's not worth the hassle and it's easier to build the whole application in Rust.
For example,
- A field in a struct cannot borrow another field so now you'd have to create two structs. I guess you could write an impl to borrow that field instead of storing the borrow.
- In simulation software I wrote I found that mimalloc does just as good as bumpalo (within 5%) so carrying a bump everywhere was useless. Not really a rust issue but rather a loss of faith in manual memory management for me.
- Eventually over time you start adding Arc<Fn(Blah)->Foo> everywhere and Box, Arc and friends start coming in. But you can't have cyclical references there so you have to use Weak. And you have to use OnceCell or LazyCell or LazyLock for things that should run at start time.
Rust is really great for the crates, but ...
For applications which are not absolutely performance critical and cannot* be stated pretty easily in linear logic + clone + drop you can get away with Haskell
I don't see much point in choosing a language just to bypass it's features.
Given the issues involved in mixing languages, there can be cases where sticking with one "good enough" GC'd language and having to write a few performance-sensitive parts in very unidiomatic form to minimize/eliminate GC work is preferable.
The OP article here is nice because it allows selective enforcement of allocation free code. If you have code that has some discipline about heap allocation such as having all small allocations then you are OK on the fragmentation front.
Yet one still needs to account with processes like MISRA to account for safety.
Even ESP32 is much better than any MS-DOS PC, we have to update our understanding of embedded platforms, not everyone is writing Assembly or C dialects to PIC like microcontrollers.
It feels quite similar to using C++ on .NET via C++/CLI.
There is some cargo cult against CGO, I could not care less.
One of Go's major selling points is cross-compilation to other OSes and architectures is incredibly simple and fast, and _the same short build command works across every OS._
I maintain a CGO app that targets Windows macOS and multiple Linuxes and oh boy the build system is probably more complex than the app itself at this point.
I also have developed C and C++ native libraries for Tcl, Python, .NET, Java JVM/ART (JNI), Node.js.
`GOOS=windows go build ./...` versus all the jank you have to do with C is just not at all comaprable
Yes it is super easy, in a few selected workflows of Linux, BSD, Windows, macOS, everything else is just as "complicated" as regular C cross compilation.
Yes, marshaling has a visible impact, hence why one should think how to actually make it happen, not much different from using FFI in any other programming language, there is always an impact over staying in the same programming language.
Compilation being harder, only if the developer is not acquainted with C, which seems to be something harder to learn nowadays.
Signal handling is a mess even in pure C, especially since all UNIX implementations added threading support.
Also, I also agree that people optimize without proper testing and profiling. If there's a real bottleneck here, trying to optimize it is the right call. OTOH, optimizing without profiling opens a lot of unnecessary cans.
Lastly, Go doesn't like constant allocation and deallocation of variables, that's true, but I believe knowing this and optimizing hot-loops for that goes a very long way as a start.
"Why we chose Java for our High-Frequency Trading application"
https://medium.com/@jadsarmo/why-we-chose-java-for-our-high-...
The point being that it does not need to be a black and white approach, one language to rule them all, as many tend to advocate for.
Like everything else in Go, its designers have decided to ignore learnings in GC systems languages.
You're making two mistakes here:
1. Confusing "no allocation" with "avoiding the garbage collector". In non-GC languages like Rust or C there are instances you want to avoid allocation too.
2. Being oblivious that in the past many GC'd languages also had mechanisms for circunventing the garbage collector. Since long, long, long ago. Common Lisp for example (1981-). This is not a modern "realization" or "revelation".
Go/GC are mostly fine for medium frequency medium scale mid stack problems.
It’s bad for high frequency computing. It’s bad for very small targets, for very large targets, and by association software that lives at the very bottom of the stack.
Go is a high efficiency framework for writing mid sized servers, not a systems language. The runtimes hard opinions and closed interface are the reason for this enclosing definition and the GC is one part of that.