Skip to content

Technical nits: Misc #69

Closed
Closed
@QuineDot

Description

@QuineDot

You make a direct comparison between Rust and C++ references, but Rust references are more similar to pointers in many ways. I see people coming from C++ and being confused by this on the forums, so making the direct comparison may be counter-productive.


The compile time guarantees are guaranteed for safe Rust with sound dependencies. Worth pointing out since you have a section on unsafe. Most of them are UB if they do get compiled.

There are no NULL references, but there are NULL pointers.

(More a suggestion:) Although foot-noted, the memory leak seemed out-of-place to me in this list. Perhaps the Mutex lock too. Both, I guess, fall under RAII.


Here you say

you need a trait object if you want to return different values implementing a trait

But what you actually mean is "if you want to return different types implementing a trait".

The rest of this is suggestion territory, but here you should point out how different the argument position (APIT) and return position (RPIT) uses are.

  • APIT is basically a generic parameter on the function, but the type becomes opaque
    • You don't need APIT to accept unnameable types in generics, e.g. to be passed a closure
    • The caller can choose any type that meets the bounds
  • RPIT is opaque, but still a single type (for a given set of parameter inputs)
    • I.e. you can't return different types in an if/else
    • The function writer chooses the (single) type that gets returned

And then when you get to returning Box<dyn Trait> you can compare and contrast with RPIT.


You say

Rust enums are packed tightly,

But they're not really packed, it's more that the variants can share storage because it's a tagged union; only one variant is "active" at a time. (And repr(packed) is something else entirely.)

Also, the layout (size optimization) is only guaranteed in very specific circumstances. Perhaps mention in general that most Rust data structures have no layout guarantees. You mention niche optimization here too; that almost meets the guaranteed case (as far as I'm aware of it existing), but not quite. So the niche optimization is not guaranteed for the example.


You say

The Iterator trait simply says that you can call next until you get None back

First, there are 74 more other methods so far, so it says a lot more than that.

But also, there's nothing that keeps you from calling next after you get a None back. And unless your iterator is fused, nothing that says you'll never get a Some(_) after you see a None.


You say

There is always exactly one variable binding which owns a value.

But Rc and Arc are often referred to as "shared owneship". Even more nit-picky, a Vec (say) can be in a single variable binding, but owns multiple values.

I don't have a good suggestion on how to word all this while getting across your original point and not being confusing though.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions