I don’t think I like RefUnsafePointer, since I would assume that would represent something like a reference to an UnsafePointer or an UnsafePointer to a reference (which I don’t think exists in Mojo). I think that we need to choose whether the mut and read versions of types are treated as specializations or whether some other option (read/var) is the default. I can see arguments for both, especially since ref by default for functions would be very confusing, var by default will cause a lot of moves which isn’t great, and I think mut by default will cause borrow checker headaches as soon as we have lambdas. read by default also has its issues since it doesn’t really match anyone’s expectations (rust is var, c++ is mut) and I keep seeing people surprised by it.
Immutable by default does have some nice properties for compilers as far as not needing to prove not mutations occur to de-duplicate reads. Right now, I don’t think that Mojo has the same noalias for every mutable reference as Rust has due to external origins and the ability to have some shared mutability.
I do like the idea of using const, since that usage of const carries similar meaning as it does in other languages. The only issue I see is that Mojo doesn’t really imply “deep immutability”. You can have a read Span with a mutable origin and still mutate the items inside of the span. This is similar to how C and C++ use const (ex: const**T for a pointer you can’t mutate to one you can mutate to a T), which is probably fine, although Rust is a bit more restrictive in the name of making borrow checking nicer.
I also agree that we need a way to make an immutable variable, and const seems like a good way to do that.