Pin
Scope of Pin and &mut in Rust
- Several commenters note that
&mutis “too powerful”: it allows moving viamem::swap,mem::replace,Option::take, etc. - Some argue that if moving through
&mutwere restricted (or those functions wereunsafe), self‑referential values could be safe withoutPin. - Others counter this would be a non‑starter: it would break large amounts of existing code and there are many move‑via‑reference patterns in the wild.
Move semantics, !Move, and alternative designs
- Proposed alternative: a language‑level
Movetrait (analogous toCopy) or split traits for trivial vs custom moves, enabling self‑referential types and richer movement semantics. - Some see this as a cleaner long‑term design that could avoid
Pin; others argue move constructors would be even more complex for users thanPin. - There is interest in “languages after Rust” that keep Rust’s safety but redesign moves, async, and comptime.
Async Rust, Pin, and ergonomics
- Many see
Pinas tightly tied to async/await and futures; some feel Rust’s async story is “half‑baked” and comparatively painful versus other languages. - Others insist that with macros (
pin!, pin‑project) and idioms,Pinisn’t that hard in everyday async code. - A common pattern is “I add
Pinwhere the compiler complains until it compiles,” reflecting weak intuition about when it’s needed.
Why Pin feels confusing
Pinalone doesn’t define what is allowed; its meaning depends on whether the inner type isUnpinand on custom APIs built around it.- Documentation is criticized as technically accurate but opaque, especially for
Unpinand its double‑negative feel. - Users struggle with action‑at‑a‑distance: changes far from the error site can suddenly introduce
Unpinconstraints. - Suggestions include more practical, “systems‑engineering” docs and better teaching analogies (Velcro/smooth, magnets/non‑magnetic, stapling vs hooks).
Unpin and typestate
- Clarified view:
Pinis a state of a pointer, not a property of the data.- For most types (those that are
Unpin),Pin<T>is effectively a no‑op. - Only types that rely on their address (e.g., self‑referential, some futures) truly care about pinning.
- Pinning vs non‑transitive pinning of fields (via projection) is acknowledged as necessary but confusing accidental complexity.
Use cases beyond async
- Reported non‑async uses:
- FFI where a C API gives a raw pointer that must not move.
- OS or system types (e.g., mutex/futex implementations) whose docs require stable addresses across their lifetime.
Async vs threads and broader concurrency debate
- One camp argues all async is a workaround for inefficient OS threads; “fix threads” and much complexity (including
Pin) disappears. - Others respond that:
- OS‑level fixes are unrealistic or outside language designers’ control.
- Async offers benefits such as cancellation, fine‑grained control, and embedded/no‑alloc scenarios.
- Thread APIs and context‑switch costs still limit simple “just use threads” answers.
- Go’s model is cited both positively (no explicit async) and negatively (composability, context management, hidden overhead).
HN‑specific meta: titles and moderation
- Many dislike the bare title “Pin” as uninformative or clickbaity; some want language tags like “[Rust] Pin”.
- Others note HN guidelines favor original titles but are applied with varying strictness; debate centers on balancing fidelity vs clarity.