3 ms·
One reason is that "&" is nestable, but ownership is just ownership. Currently the types are: owned T T ref of T &T ref of ref
by justinpombrio 4y ago
One reason is that "&" is nestable, but ownership is just ownership.
Currently the types are:
owned T T
ref of T &T
ref of ref of T &&T
You're suggesting that instead you skip the "&" and write some sigil for owned types, say "@":
owned T @T
ref of T T
ref of ref of T ???
How do you write the type "ref of ref of T"?
On its own this isn't a super compelling argument, because "&&T" is an unusual type that one doesn't normally use. But it hints at the fact that "&" is a modifier. The stronger but less pithy version of this argument is that if you have a type parameter "T" it's essential that it can be instantiated as "T=&U" for some "U".
EDIT: come to think of it, you don't often write "&&T", but it is commonly used. If you `println!("{}", x)` where "x" is a reference, the "println!" macro also takes a reference and you get a "&&" type.
- unshavedyak 4y ago> come to think of it, you don't often write "&&T", but it is commonly used. If you `println!("{}", x)` where "x" is a reference, the "println!" macro also takes a reference and you get a "&&" type. Yup, i see them all the time in iterators too. Eg `foos.iter().filter(|t| ..` `t` is `&&Foo` in that example, iirc. Not that you usually see it though, due to closures obscuring types.
- BiteCode_dev 4y agoYou would use an explict "&", just that &T is implicit by default. I have to assume rust creators knew what they were doing since they are obviously way more experienced at this than me, but I still don't get it.
- justinpombrio 4y agoI suspect you're not imagining all the places this would touch the language. For example: - Does "i32" mean an integer or a reference to an integer? You almost always want it to be an integer, so maybe we carve out an exception for small primitive types, that they don't get an implicit "&". - Likewise some library-defined types like "Rc<T>". "Rc<T>" is the way you store a ref-counted T. So you usually want "Rc<T>" instead of "&Rc<T>". Is there an exception for this type, too, or do you always have to write "@Rc<T>"? It's defined in the standard library, so if it gets an exception than there has to be a language mechanism for "types that should not have an implicit &". - The ".next()" method on iterators has the type signature "next(&mut self) -> Option<T>", where "T" is the type of the iterator's elements. Under your proposal, you'd write "next(&mut self) -> Option<@T>". If "T=&str", then you're returning an "Option<@&str>". Which has to be equal to "Option<&str>" or else everything breaks, but that might not be super intuitive to programmers. That last one's the most important, though I don't know how to explain it clearly. If you have a type parameter "T", then "T" does not mean owned T. It means "T", whatever "T" is. If "T" is a reference, then it's a reference. And if you have a type parameter "T" then "&T" means a reference to "T" whatever "T" is. If "T" is itself a reference, then "&T" is a reference to a reference.
- ndyg 4y agoGosh, thanks for this explanation. This will help as my eyes protest the assault of '&'s.