Conversation

if only i had a dollar for every time a rust dev fails to realize that wrapping everything in Arc makes their “fearless concurrency” async code run like dogshit on many-core x86 systems because all the atomic refcounting keeps invalidating cache lines and the CPU is too busy managing cache coherence and store buffer flushing to do any real work cirnosaddest

2
0
5
@mia "Noooo garbage collectors are too slow" *ends up using the least efficient garbage collection algorithm by accident*

I generally like Rust quite a bit but the whole borrow checker thing just feels like a bizarre gimmick
2
0
4
@scathach @mia i think you're meant to avoid using arc boxes. i only used them for gui stuff in my brief tour of early rust (where its really awkward to not have them.)
1
0
1

@icedquinn @scathach the rust book only has a brief warning before it proceeds to tell you about Arc and mutexes:

Consider this part of the slogan from the Go language documentation again: “Do not communicate by sharing memory.”

it never explains why

3
0
2
@mia @scathach at the time i just wanted a weak reference box. cause a lot of guis dont' really need arc, they just own their children, but you want a non-owning pointer back upwards a lot of the time, which is a pattern that is a little derpy to do in rust.
1
0
0

@scathach @icedquinn it also never mentions the performance penalty of atomic refcounting or where it comes from, and neither do 3rd party sources

0
0
0

@icedquinn @scathach i just consider it the result of mathbrained blindness to real world computing where for a lot of code lifetimes simply cannot be statically verified at compile time. afaict async in rust is a joke at the expense of the programmer who spends more time trying to appease the borrow checker than getting anything done

2
0
6
@mia @scathach it does an ok job but my impression was they are collectively praying for that sufficiently smart compiler.

stuff like austral was trying to make the rules simple with the linear type mechanics.

i remember fighting with the borrow checking because "in this exact module" there was no race condition or issue with the mutable borrows, but then i shrugged that this might not always be true if someone were to come by and patch on threading or start adding hooks. its basically paying up front now to make the static analyzer happy vs maybe dealing with a heisenbug.

though the build speed can get so bad that you've tested it ten times already in go before you've sat through one rust build
1
0
3
@mia @icedquinn @scathach Having to make everything work with borrow checking seems like a pain. It's nice in c# because it's limited to actually passing references down the stack and you don't end up managing complicated lifetimes i think, but that only works if you have good ways to manage memory on the heap too as a fallback and not just reference counting
1
0
0
@mia @scathach @icedquinn Reminds me of the situation around `.unwrap`. The documentation puts a small warning about what it does and why it shouldn't be used in production code, bit everybody still does that.
1
0
1
@icedquinn @mia @scathach
> they are collectively praying for that sufficiently smart compiler
One word. Itanium.
0
0
1
@snacks @mia @scathach my problem with the borrow checker is the spec for it is more of a research paper on github somewhere and its like 80+ pages if i recall.

it should be a plain list of rules in the spec, like effect systems and linear typing are in the languages which have it.

how do effects work? if a function is manually tagged as a fox, or calls a function tagged as a fox, then the function stack is foxed, and if a function somewhere says foxes aren't allowed in database code then it may never call something foxed. congrats, you're done (though it is annoying in that they tend to lack a way to strip tags which would be useful for string tainting, but this would also make it easy to shim in a bypass for IO bans, idk.)

austral linear types are pretty much a one paragraph spec: all references are copies or moves, you must consume or return a value if you have it, therefore all things must be spoken for in the control flow in some way. done.

all safety checks are going to be at adds with people cowboying shit anywhere they feel like. the social contract is to not do that in exchange for some nice return somewhere (ex. static lifetime traces guaranteeing that if you obey the rules you won't shoot yourself, even if some of those revolvers look really nice)
0
1
4

@icedquinn @scathach @phnt i think a problem here is that rust does a bunch of experimental things while masquerading as production-ready, and the way its tools and ecosystem work makes it more of a resumeslop-focused silicon valley industry skill than a language to write free software in. with all the new challenges that rust introduces, that’s absolutely not an environment that produces good design practice.

2
0
4
@mia @scathach @phnt it was meant to be a life support system for a web browser and then everyone was fired. cirno_sip
0
0
1
@mia @icedquinn @scathach I feel with unwrap it's kind of like. We have this error handling we stole from somewhere else, did it our own way, and we give you a really convenient function to get the result with the side-effect of it being a footgun. Idea is great, execution is horrible. It feels that the thought process didn't really finish.
2
0
0
@phnt @mia @scathach i was going to say ours in nim just throws an error but i'm reminded araqs latest hairbraned idea was to start replacing exceptions with panics ("defects.")
1
0
0
@phnt @mia @scathach in the past i would have pointed to nim's option type has 'unsafe_get' which i feel like should have the unsafe tag (but for some reason stdlib doesn't use effects tracking.) c#'s notion of unsafe blocks is actually fine and good, esp. since in the phabricator days you could simply put a warden in that says if any file is changed with an unsafe keyword block the push and demand auditor approval.

nowadays idk. phabricator is dead, i don't think forgejo has audit/signoff, and the concept of "bringing the system down with no survivors belongs behind this obvious footgun {...} fence" didn't catch on.

sometimes microsoft gets it right
0
0
0

@phnt @scathach @icedquinn this is why i brought up async in particular. rust wants to know the lifetimes of everything in advance, but async/await futures are fundamentally at odds with that and you get to deal with the consequences in a recursive fashion because async functions must be async all the way down the call stack

1
0
1
@mia @phnt @scathach async hell is basically a consequence of comp sci refusing to adopt delineated continuations properly.

true continuations are powerful but a nightmare to compile around for this exact reason. delineated continuations aren't, though, because they still exist as a call stack and are quite reasonable. (most languages have them as 'generators', because why do anything right.)

in the case of delineated, the continuation itself does have a rather ordinary lifetime, so propagating a restrictive scope downward is entirely fine to do.
1
0
0
@mia @phnt @scathach its been a while since i wrote rust but i remember distinctly having some of these problems and after writing an inklecate interpreter in it, walked away noting that stuff like lifetime tracing and mutable borrows really aren't the horrors people make them out to be.

i think my biggest annoyance at the time was that it wouldn't let me factor out a bigger function to smaller ones without having to re-borrow mutable values. i'm not sure if that paid a runtime cost (its possible that they were inlined away) but it annoyed me because i knew it was safe.

that being said, i kind of get that the pattern i used could very very easily have somebody drive by and patch in something that violated that, and the borrow checker's mindering was preventing the potential of a future heisenbug, things that i *have* had in nim because pointer twizzling is inevitably going to result in a derpy dereference.
1
0
0
@mia @phnt @scathach the annoying-ness of deep match arms all the time kind of pushed me to pre-processing the shitty json assembly format they used in to a much flatter set of opcodes, so i think overall the pain points actually did a reasonably good job of encouraging that module to be more well factored (ex. a flat array of position->opcodes, instead of the shitty nesting inklecate uses natively), so i suspect a lot of rust pain in practice is people doing cowboy shit that was enabled for a long time by other languages that maybe weren't actually good ideas.

like nim's lack of deep class trees seems limiting at first, but has lead to reading about ECS systems and composition, which is an entirely valid approach to software design that have basically been entirely ignored to decades of java.

so, idk. i do have complaints (unwrap should be behind an unsafe fence, sure) but i think a lot of them are maybe more indicative of other problems (lamport talked about people struggling to test binary searches and quicksort in TLA+ because people were so used to copy/pasting the recursive C version that they struggle bussed the fact you can also just do it with lists and tuples.)

most of my rust complaints are cultural, i think. they might be overly scared of pinning down concrete answers that should be pinned down out of fear that the rust spec will become c++ again, but maybe we should embrace the refactoring browser concepts from the 80s smalltalk and just let languages use semver and break.)
0
0
0