[1]: https://pingcap.com/blog/rust-compilation-model-calamity
[1]: https://pingcap.com/blog/rust-compilation-model-calamity
They are awesome but they make compile-time arbitrarily bad. The D compiler is roughly as fast as the Go one. However, D has macros though and that makes it very slow to compile sometimes.
The alternative to macros are code generators. Works fine for bigger stuff like a parser generator but not for smaller stuff like a regex.
It's possible that Zig's approach helps here -- since the metalanguage is just the language, you can take some of your intuition about performance along to compile time. And the macro language is not weirdly restricted, so you can write something you're more used to, with similar idioms.
In the limit this is clear: I'm using several Python code generators C++ in https://www.oilshell.org, and it's easy to reason about the performance of Python. Doing the same in C++ metaprogramming would almost certainly be a lot slower. It would also give me less indication of code bloat; right now I simply count the lines of output to test whether my code generator is "reasonable".
e.g. I generate ~90K lines of code now, which is reasonable, but if I had 1M or 10M lines of code, that wouldn't be. But there's not that much of a sanity check on macros (except binary size).
I think of one as metaprogramming with the parser and the other as metaprogramming with an interpreter. (And the C preprocessor is metaprogramming with only a lexer. Code generation is the kind of metaprogramming that every language supports :) )
Although maybe you're saying Zig doesn't have the functionality of Rust macros, and that could be true; I haven't played with it enough.
However I do think there is overlap as Zig implements printf with compile-time evaluation and Rust does it with macros:
https://ziglang.org/documentation/master/#Case-Study-printf-...
https://andrewkelley.me/post/zig-programming-language-blurs-...
Anyway if you want to know why your compile time is slow in a given zig project, you can probably get pretty far by grepping for calls to that builtin.
The question is whether you do the meta programming/code generation within the language or as external tool. Code bloat is an issue in both cases.
Macros make it easy to write code which generates code which generates code which... This enables some wonderful use cases, often around generating type declarations. If done with an isomorphic language, you can also reuse the same code for compile time and runtime implementations with just thin wrappers.
External code generators however will build faster because the build system takes care of reusing the intermediate code.
Not according to this benchmark:
https://github.com/nordlow/compiler-benchmark
dmd performed around 1.5x to 4x faster than go.
My only experience with Rust so far has been trying to learn it by writing applications in it and also use 3rd party CLIs, but quickly loosing interest because the "change <> try out change" cycle has been too slow and cumbersome, and installing/compiling dependencies take fucking forever, even on a i9-9900K.
[1] https://bevyengine.org/learn/book/getting-started/setup/#ena...
Maybe you're comparing apples to oranges here. I've worked professionally with both Rust and Go for years now on a variety of real world projects, and I've never seen a similarly-sized Go codebase that compiles slower than a Rust one. If you're comparing incremental Rust compilation to first-time Go compilation, maybe they could be competitive, but... Rust is incredibly slow at compilation, even incremental compilation.
Yes, using lld can speed up Rust compilation because a lot of the time is often spent in the linker stage, but... that's not enough to make it as fast as Go.
YMMV, of course, but... my anecdotal experience would consider it disingenuous to say that Rust compile times are an advantage compared to Go, and I'm skeptical that Rust compile times are even an advantage compared to the notoriously slow webpack environments.
Rust is good at many things, but compilation speed is not one of them. Not even close, sadly. "cargo check" is tolerable most of the time, but since you can't run your tests that way, that's not actually compilation.
It is absolutely apples to oranges, but if you just care about the everyday local workflow and ability to iterate and test, it's close enough most of the time to not be much of a problem in either case.
I'm sure this experience isn't guaranteed for all codebases, and it certainly helps that I make heavy use of crates, which would minimize the work required during incremental compilation. Though I'm not actively going out of my way to optimize for incremental compilation really, beyond the config linked above.
Plus, Kubernetes is sitting at 5 million lines of Go code, by my count. Try compiling a 5 million LoC Rust code base... I won't wait around.
I would assume that a controller written in Rust bypasses all the complex legacy of the Kubernetes code base, and that's why it can compile faster. If someone made a similar project in Go[0] to write Kubernetes controllers in Go without depending on the mega-Kubernetes code base, I'm sure it would be incredibly faster at compiling than the Rust version.
Beyond that, I've heard that the Kubernetes codebase is internally just a nightmare of basically untyped `interface{}` stuff floating around everywhere, which would make the development experience subpar. I don't know how much this is exposed to custom controllers.
So, if Kubernetes is your only experience with Go... I'm sorry you've had to experience that. It's a product that people seem to agree is functional and works most of the time, but I can't remember hearing any positive experience from people working on it. From what I understand, it was originally prototyped in Java, and then hastily rewritten into Go before public release, and I'm sure that didn't help things.
[0]: conceptually, maybe something like this? https://github.com/ericchiang/k8s or an updated fork of it like this: https://github.com/karlmutch/k8s No idea how well either works, if at all.
An important thing though, if you aren't doing this already, is to not wait for a full build to know if your types check out. You can use cargo-check if you prefer (https://doc.rust-lang.org/cargo/commands/cargo-check.html), but really I recommend using an editor with immediate feedback if at all possible. rust-analyzer (an LSP) is one of the best, and should be available even if you're on Vim or something.
Using Rust without snappy editor hints is fairly miserable because of how interactive the error feedback loop tends to be. If you don't rely on a full build for errors - just for actual testing - I find the build times to be perfectly livable (at least in the smallish projects I've done).
On the other hand iterative development with rust analyzer going and all the dependencies already built is pretty painless. By the time you run your tests or program, it's likely to take only a few seconds to build.
That said you can write terribly long to compile rust. Usually there's some trades you can make to weigh compile time as more important than flexibility or static code paths.
I've written a sizeable ad server in rust with maybe 25kloc. Where I was the sole developer and sys ops person, it cost me a little upfront time but saved me many more hours in operations work.
About on par with C/C++ and Go. In that you don't have one and don't want for one. REPL driven development is difficult with languages like Rust, both to implement and use.
I think there are some projects floating around out there, but I personally don't see a purpose for one. It's not python or matlab.
Notebooks work better than raw REPL's for a language that's so heavily based on static typing, but they're idiomatically quite similar.
I was thinking of a REPL in the sense of common Clojure usage (https://vvvvalvalval.github.io/posts/what-makes-a-good-repl....) not the basic "write lines into a separate program and then copy-paste it into your source code" that Python offers.
In my experience, you write some code, the rust analyzer (which is easily embedded in an IDE like VSCode or IntelliJ - which has its own "analyzer" I think) gives you immediate feedback, so you know immediately if things compile or not (there are a few edge cases the analyzer might miss, so when you actually run "rustc" something doesn't compile, but it's pretty rare)... you then write a little test , and Rust has many ways of letting you do that (unit tests right into the same file as the code being tested, integration tests which let you use the code as if from another crate, and even doctests, which are like unit tests but embedded in the documentation of your code)... running the tests is a matter of pressing a button and waiting a few seconds (compilation + test runtime) normally, unless you change dependencies between runs as that requires downloading/compiling your code AND the dependencies, which can be very slow (dozens of seconds)... which is the same problem as with a fresh build, which will almost certainly run in the minutes because of the necessary local compilation of all dependencies... but the experience is not very different from something like Java or Kotlin IMO (but definitely a slower cycle than Go, for example).