Everything else you mentioned is out there, although I didn't love the websocket experience the one time I needed them for something.
1,005 karma · joined March 31, 2020
Everything else you mentioned is out there, although I didn't love the websocket experience the one time I needed them for something.
Just recently I had a need for a fairly simple webapp. Whipped up the back end in Rust in, like, an hour; only had to bolt on a couple tests for the single complex bit of business logic, because I have a high degree of confidence that the compiler has me covered for everything else.
Now it sits there quietly using 4.9 MiB of physical memory and 1.5 millicores on two of my servers, primarily serving a k8s healthcheck every couple seconds.
Honestly, this is a really good way to put it, and that one minute rule sounds like a pretty good rule (ignoring cases where performance requirements led to profiling, which pointed you at some specific piece that you need to optimize, obviously)
I don't really care whether or not nukes are cheap when they're the only reliable low-carbon energy source we have, and when they're the safest energy source we have. Some things are more fundamentally important than economics.
This isn't really consistent with my experience. Compared to writing other languages with varying levels of strictness (C, Python, Go to name a few), Rust's compiler saves me a lot of time writing tests and finding bugs.
It doesn't save me the work of fixing them, but in my experience, bugs that are hard to find and easy to fix drastically outnumber bugs that are easy to find and hard to fix.
That said, I haven't tried Zig. It's on my radar, but just haven't had a new project to start lately.
Each of these copies requires space for the instructions...this means a larger binary on disk, more memory required when it runs, and more pressure on the CPU's caches, especially precious L1I.
The cache pressure issue is typically the big one worth thinking about, although binary size itself can be an issue for some cases - I've primarily got embedded use cases in mind, but I'm sure there are others I'm not thinking of.
Anyway, back to cache pressure. If there are a whole bunch of different monomorphizations of a given function, and they're all called frequently, that could mean that the CPU will frequently need to refer to slower L2$, or much slower L3$ (or much much slower RAM) to load instructions. That's no bueno from a performance standpoint.
Because of this, there are cases when dynamic dispatch can outperform monomorphization - it's definitely not as simple as "vtable slower, monomorphization faster" across the board, even if that is an OK rule of thumb.
Just to put an extra-fine point on this...the backup generators are typically fossil fuel fired, so the unpaid externalities apply to those as well.
Generics aren't going to improve this situation - at least not the current iteration of generics :(
I'm guessing you already know this, but for anybody else reading - this isn't entirely accurate; Result::Err doesn't auto bubble up like an exception, you have to manually bubble it up. The "special sauce" comes from (A) the compiler forcing you to notice this and do something about it, and (B) the `?` syntactic sugar to make that super easy.
It does occur to me as I'm typing this that you might be talking about panics, though, in which case yeah that's entirely accurate.
This isn't true for almost any language to the extent it's true for Go, and for many compiled languages it isn't really true at all.
> Try building a significant Python project on anything except a recent version of RHEL, Debian, MacOS, or Windows. For example, try getting your Python project running on something like a scratch Docker container. Or try packaging a Python package (which depends even transitively on a C library, especially one which isn't already packaged for Nix) with Nix.
While these are legitimate theoretical problems, none of them are really problems in practice. Containers don't need to be scratch, and if you're building a Python project, you're already not running a scratch container, so the addition of FFI doesn't change that. Nix is not an environment I've ever seen a requirement to support, let alone had a requirement.
It really seems to me that you like Go and you like Go's design decisions, but "I like this" is not the same as "this is better than that". I'm not particularly interested in rehashing the same conversation over and over again.
As with many things, there's nothing stopping you from just sticking with pure Go if you don't like C toolchains. While C build issues are a valid theoretical concern, in practice I've never had any Python package fail to install because of a C dependency problem that wasn't trivially resolved, nor any Rust project fail to compile because of a C dependency problem at all.
Lots of garbage-collected languages make FFI not only easy but plenty fast. Go does neither.
Maybe I'm just too dumb for Go, but this is not consistent with my experience at all. Go's insistence on pretending that complexity doesn't exist would get in my way all the time. Go's extreme hostility toward FFI calls got in my way several times.
Whether or not you can read everything on the screen at one time is missing the point entirely. The point is that context matters, and the more frequently you have to scroll to find it is more cognitive burden.
> It's not likely that it will continue with corrupt data because you can't use the return value without explicitly ignoring the error.
It is far too easy to accidentally do the wrong thing with an error in Go. In Rust, for example, no matter what you want to do with the result of a fallible call, you have to do it explicitly. If you want to crash on error, you `.unwrap()`; if you want to bubble it up, you `?`; if you want to continue with a default value, you `.unwrap_or()` or one of its variants.
> in practice, Go seems to have fewer error handling bugs than exception-based languages
This is based on?
I'd take exceptions any day of the week over Go's solution. I'd much rather the program crash by default than attempt to continue with corrupt data by default. I'd rather have concise, explicit, compiler-required error handling than exceptions, though.