Correct the claim that dependencies are a different kind of problem
I had been calling the dependency closure a different problem from the language, and that was wrong: another crate is just more Rust. rustnim already takes many files and flattens modules, so a dependency's sources are simply more of them. Tested directly rather than argued -- a crate with `mod mathlib;` fails alone, succeeds when mathlib.rs is passed alongside, and the output matches rustc's. So the wall is two other things, and only one of them is qualitative. Scale is quantitative: libcosmic resolves to 741 crates, every one of them Rust, each needing its own blocker stack cleared. That is the same problem 741 times rather than a different problem. The floor is not Rust at all, and this is the part that actually matters. Proc macros are compile-time programs -- 37 of the 400 sampled crates are proc-macro = true, and syn, quote and proc-macro2 have 155 dependents between them in libcosmic's tree. They bottom out in proc_macro::TokenStream, which the compiler provides and which exists as no crate in the registry: there is nothing to transpile, they have to be run, and what they emit is the Rust you would then translate. libc is 129,594 lines holding 121 function bodies, with the rest declarations binding to the C library; wgpu, winit and the *-sys crates have the same shape. Then SIMD and the parts of core the compiler implements directly. DESIGN.md now says this instead of the vaguer claim it had. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
effd8a3 parent: ba4c4ab modified
DESIGN.md +34 -0 | @@ -417,6 +417,40 @@ transpiled. At that point "files produce a translation" would measure nothing | ||
| 417 | 417 | at all. The honest reading is narrower and still worth something — the |
| 418 | 418 | *language* is no longer what stops it. |
| 419 | 419 | |
| 420 | +### "But another crate is just more Rust" | |
| 421 | + | |
| 422 | +It is, and an earlier draft of this section was wrong to imply otherwise. A | |
| 423 | +dependency is not a different kind of input: rustnim already takes many files | |
| 424 | +and flattens modules, so a dependency's sources are just more of them. Tested | |
| 425 | +directly — a crate calling `mod mathlib;` fails alone and succeeds when | |
| 426 | +`mathlib.rs` is passed alongside, with output identical to rustc's. | |
| 427 | + | |
| 428 | +So the wall is not "dependencies". It is two other things, and only one of | |
| 429 | +them is qualitative: | |
| 430 | + | |
| 431 | +**Scale, which is quantitative.** `libcosmic` resolves to 741 crates. Every | |
| 432 | +one is Rust and each would need its own blocker stack cleared — the same | |
| 433 | +problem 741 times, not a different one. | |
| 434 | + | |
| 435 | +**The floor, which is not Rust at all.** The graph terminates in things that | |
| 436 | +have no Rust source to translate: | |
| 437 | + | |
| 438 | +- **Proc macros** — 37 of the 400 sampled crates are `proc-macro = true`. | |
| 439 | + These are *compile-time programs*: `syn`, `quote` and `proc-macro2` have 155 | |
| 440 | + dependents between them in `libcosmic`'s tree. They bottom out in | |
| 441 | + `proc_macro::TokenStream`, which the compiler provides and which exists as | |
| 442 | + no crate in the registry. There is nothing to transpile — they have to be | |
| 443 | + *run*, and what they emit is the Rust you would then translate. | |
| 444 | +- **FFI** — `libc` is 129,594 lines holding 121 function bodies; the rest is | |
| 445 | + declarations binding to the C library. `wgpu`, `winit` and the `*-sys` | |
| 446 | + crates are the same shape. | |
| 447 | +- **Intrinsics** — SIMD and the parts of `core` the compiler implements | |
| 448 | + directly. | |
| 449 | + | |
| 450 | +That is the real answer to "isn't it just Rust?": yes, all the way down until | |
| 451 | +it stops being Rust, and the stopping points are where the interesting | |
| 452 | +dependencies live. | |
| 453 | + | |
| 420 | 454 | ### The blocker survey, and what it says about roadmaps |
| 421 | 455 | |
| 422 | 456 | 400 crates from the local registry (under 4,000 lines each), all their module |
| @@ -417,6 +417,40 @@ transpiled. At that point "files produce a translation" would measure nothing | |||
| 417 | at all. The honest reading is narrower and still worth something — the | 417 | at all. The honest reading is narrower and still worth something — the |
| 418 | *language* is no longer what stops it. | 418 | *language* is no longer what stops it. |
| 419 | 419 | ||
| 420 | +### "But another crate is just more Rust" | ||
| 421 | + | ||
| 422 | +It is, and an earlier draft of this section was wrong to imply otherwise. A | ||
| 423 | +dependency is not a different kind of input: rustnim already takes many files | ||
| 424 | +and flattens modules, so a dependency's sources are just more of them. Tested | ||
| 425 | +directly — a crate calling `mod mathlib;` fails alone and succeeds when | ||
| 426 | +`mathlib.rs` is passed alongside, with output identical to rustc's. | ||
| 427 | + | ||
| 428 | +So the wall is not "dependencies". It is two other things, and only one of | ||
| 429 | +them is qualitative: | ||
| 430 | + | ||
| 431 | +**Scale, which is quantitative.** `libcosmic` resolves to 741 crates. Every | ||
| 432 | +one is Rust and each would need its own blocker stack cleared — the same | ||
| 433 | +problem 741 times, not a different one. | ||
| 434 | + | ||
| 435 | +**The floor, which is not Rust at all.** The graph terminates in things that | ||
| 436 | +have no Rust source to translate: | ||
| 437 | + | ||
| 438 | +- **Proc macros** — 37 of the 400 sampled crates are `proc-macro = true`. | ||
| 439 | + These are *compile-time programs*: `syn`, `quote` and `proc-macro2` have 155 | ||
| 440 | + dependents between them in `libcosmic`'s tree. They bottom out in | ||
| 441 | + `proc_macro::TokenStream`, which the compiler provides and which exists as | ||
| 442 | + no crate in the registry. There is nothing to transpile — they have to be | ||
| 443 | + *run*, and what they emit is the Rust you would then translate. | ||
| 444 | +- **FFI** — `libc` is 129,594 lines holding 121 function bodies; the rest is | ||
| 445 | + declarations binding to the C library. `wgpu`, `winit` and the `*-sys` | ||
| 446 | + crates are the same shape. | ||
| 447 | +- **Intrinsics** — SIMD and the parts of `core` the compiler implements | ||
| 448 | + directly. | ||
| 449 | + | ||
| 450 | +That is the real answer to "isn't it just Rust?": yes, all the way down until | ||
| 451 | +it stops being Rust, and the stopping points are where the interesting | ||
| 452 | +dependencies live. | ||
| 453 | + | ||
| 420 | ### The blocker survey, and what it says about roadmaps | 454 | ### The blocker survey, and what it says about roadmaps |
| 421 | 455 | ||
| 422 | 400 crates from the local registry (under 4,000 lines each), all their module | 456 | 400 crates from the local registry (under 4,000 lines each), all their module |