@eddyb

159 Followers
66 Following
23 Posts

Officially unemployed now after almost 5 years at aws working completely in the open on the Rust compiler.

With https://rustnl.org/fund/ and https://rustfoundation.org/media/announcing-the-rust-foundation-maintainers-fund/ both figuring out how to ensure maintainers are paid to do reviews, refactorings and mentoring, I'm optimistic I can continue doing my work in the future.

If your company uses Rust a lot and would like to support it and talk about how that support can either indirectly or directly benefit its Rust-writing employees, I'm happy to chat to explain both funds and make the connection to the right fund for you. Or just skip directly to one of the funds if you already know ppl there!

Rust Maintainers Fund - RustNL

RustNL - Stichting Rust Nederland

in a way, i am glad that it is unraveling: this whole system is biased towards granting basic rights to people who got lucky with their family. it is manifestly unjust and should not exist in its present form. anybody who cheats through university to get a blue card is justified in doing so

at the same time, i wish there were places i could go to where i could learn from people dedicated to their field, at my own pace and without going into debt

would be nice, wouldn't it

@cliffle now for a slighty hotter take:

C implementations could've, when adding threads, make all global state thread-local by default (w/ an opt-in for cross-thread sharing)

so C threads would default to being like processes sharing an address space

AFAIK, on (some?) RISC ABIs, globals and thread-locals each reserve one base register, and it's mainly register-starved CISC ABIs which treat them differently (also dynamic linking loves to make a mess of everything, but that's another story)

@cliffle it took me a while to even notice that JS (ECMAScript, to be more precise) is rare among dynlangs, to limit itself to single-threaded GC, comparable to Rust Rc+Cell

IME, most ways to split JS workloads across threads (whether in the browser or node.js/Deno etc.) still rely on inter-process-like mechanisms such as message passing

(and even `SharedArrayBuffer` is designed like cross-process shared memory! you need to combine it with wasm to simulate multi-threaded memory unsafety)

This is an old blog post of mine, but I still really appreciate this subtle feature of Rust: one of the ways it supports robust thread-safe concurrent code is by _not making everything thread-safe._ It's odd that this property is so rare in languages. Just like how clear boundaries are critical in relationships, being able to designate which parts of your program _can't_ be shared across threads is critical for ensuring that the shared parts are correct.

https://cliffle.com/blog/not-thread-safe/

#rustlang

Safely writing code that isn't thread-safe

An under-appreciated Rust feature

@cliffle now for a slighty hotter take:

C implementations could've, when adding threads, make all global state thread-local by default (w/ an opt-in for cross-thread sharing)

so C threads would default to being like processes sharing an address space

AFAIK, on (some?) RISC ABIs, globals and thread-locals each reserve one base register, and it's mainly register-starved CISC ABIs which treat them differently (also dynamic linking loves to make a mess of everything, but that's another story)

@cliffle it took me a while to even notice that JS (ECMAScript, to be more precise) is rare among dynlangs, to limit itself to single-threaded GC, comparable to Rust Rc+Cell

IME, most ways to split JS workloads across threads (whether in the browser or node.js/Deno etc.) still rely on inter-process-like mechanisms such as message passing

(and even `SharedArrayBuffer` is designed like cross-process shared memory! you need to combine it with wasm to simulate multi-threaded memory unsafety)

@whitequark @iximeow naively I was hoping for something more like e.g. https://mlir.llvm.org/docs/Dialects/IRDL/ and better interoperability even without FFI

but when you already have a hammer...

(also, even IRDL has e.g. a way to inject C++ code from a string: https://mlir.llvm.org/docs/Dialects/IRDL/#irdlc_pred-irdlcpredop)

'irdl' Dialect - MLIR

Multi-Level IR Compiler Framework

@iximeow @whitequark

was looking at MLIR as perhaps a less cursed way to e.g. ingest LLVM IR w/o FFI (plus ClangIR could give access to C/C++ information lost in LLVM IR)

then I found out that:
- MLIR heavily relies on TableGen
- MLIR dialects can invent arbitrary syntax for their constructs!
(through TableGen generating C++ code, AIUI)

(there's `-mlir-print-op-generic`, e.g.: https://godbolt.org/z/GhWMaWb5j but even that makes me wonder if the MLIR bytecode would be easier to work with instead...)

Compiler Explorer - C++ (x86-64 clang (clangir))

struct S { S(int); virtual void f(); }; struct T : S {}; S globalS(5); void mayThrow(); int doThings(S *s) { int retval = 1; try { if (T *t = dynamic_cast<T *>(s)) mayThrow(); } catch (int i) { retval = i; } catch (...) { retval = 0; } return retval; }

@whitequark guessing you need `&T` values to invoke the operator overloads because it's all DAGs on the stack, kinda like what I couldn't pull off ages ago (pre-temporary-lifetime-rules) and instead got me into rustc dev,,,

whereas sobek interns everything and uses Copy handles (at god knows what cost. I never benchmarked any of this shit, and also this specific iteration of decompiler brainworms got started during a certain DK64 livestream, hence MIPS as the first ISA implemented and the name)