degree of separation from C: 0 * Nim: this function might be unsafe, it's declared with an importc pragma * Rust: (nothing)
degree of separation from C: 1 * Nim: (nothing) * Rust: this function might be unsafe, it uses an internal unsafe block to call a 0-degree function degree of separation from C: >=2 * Nim: (nothing) * Rust: (nothing) And what do you tend to call? * Nim: 0-degree functions directly, because with the more ergonomic FFI with nice cstring conversions and such, your job is done with the importc * Rust: 1-degree functions, because you want to laboriously get rid of C FFI types immediately, and you want to use an unsafe block so that the chore of unsafe tracking is over immediately So the functions that are _actually called_ are actually at the same level of being auditable as unsafe. Example: * Nim: <https://github.com/jrfondren/chrestomathy/blob/master/pwcheck/nim/src/pwcheck.nim#L18> \-- crypt() is an actually useful function * Rust: <https://github.com/jrfondren/chrestomathy/blob/master/pwcheck/rust/src/main.rs> \-- crypt() needs this wrapper to be actually useful. The wrapper doesn't need an unsafe block. The wrapper actually led to segfaults in actual use because I didn't realize that crypt() returns NULL given an invalid hash. (In Nim the desired behavior of a failed comparison happens with cstring.) So a change that is only a small change to the compiler already doesn't seem to be worth it. It's actually cargo-culting: Rust has this safety-obsessed culture that stigmatizes unsafe blocks and harasses devs that are revealed as not sharing these feelings, and a consequence is that great care is taken to make the libraries actually safer. Nim lacks this. OK, give Nim an unsafe block so that the planes will start landing again. What would be the result? It would be: `import wow_easy`, giving you a pragma that you use instead of importc which automatically wraps your FFI with procs having internal unsafe blocks.