I have lately become enamored with explaining the Rust type system in
terms of *ownership*. Basically Rust types are either shared (co-owned),
uniquely owned, or borrowed.
The shared types all begin with the @ prefix: @T, @[], and @fn(). Each
reference to a shared value is an equal owner, which is another way of
saying that none of them are owners. Thus shared types can also be
thought of as a kind of co-ownership.
The uniquely owned types are either unique boxes, which begin with the ~
prefix: ~T, ~[], ~fn(), or value types (no prefix). Uniquely owned
values are freed as soon as the reference goes out of scope or is
reassigned.
Borrowed types begin with the & prefix: &T, &[], &fn(). Borrowed values
are neither owned nor co-owned: a borrowed pointer is always derived
(perhaps indirectly) from some owning reference on the call stack.
Owned types (@ or ~) can be converted to borrow values.
This is not, of course, incompatible with explaining @[] as a kind of
'second class' form of @T.
Niko
On 7/15/12 5:15 PM, Patrick Walton wrote:
Currently, we've gone back on the concept of dynamically-sized types.
I think that, while there were very good reasons for going back on
them in the implementation (namely, that we want a pointer to a vector
to be a fat pointer--one with start and length--internally, among
other obscure reasons relating to region bounds for functions), they
still possess an appealing amount of simplicity when describing the
language to newcomers.
One of the things that immediately strikes most as complex about Rust
is the large number of pointer types, vector types, and function
types. This has not really changed with the current proposals for
vector reform and function reform. However, the way we present it and
think about it *can* change, in order to conceptually simplify the
language.
Here is what I propose:
1. We have three (or four, if you count unsafe) types of pointers. @T
is a garbage-collected, task-local pointer, like shared_ptr; it can be
used anywhere within a single task. ~T is a unique pointer to the
exchange heap; it can be sent between tasks. &T is a safe reference
(borrowed) pointer to any allocation.
2. Function types, trait types, and vector types without a fixed size
are *second-class* types. Because their sizes aren't known to the
compiler, they can't be referred to in isolation; they can only be
referred to with a pointer. Any of the three pointer types will do.
Note that this rule is quite similar to C++; note the error that
occurs when you try to compile this program:
int foo(int x[]) {
int y[];
y = x;
return y[0];
}
$ g++ -o test test.cpp
test.cpp: In function ‘int foo(int*)’:
test.cpp:2:8: error: storage size of ‘y’ isn’t known
The only difference is that we prevent the programmer from referring
to the dynamically-sized type *at all* except through a pointer. In
C++ it is allowed in some situations, but automatic conversions happen
(from T[] to T *) to give it meaning. The Rust rule is simpler.
3. A pointer to a vector can be indexed, just like in C++. Unlike C++,
bounds checks are performed and the task fails if an out-of-bounds
access is attempted.
4. Again like C++, a pointer can be taken to any element of a vector,
and this pointer can be indexed just like a pointer to the head of the
vector. Because a pointer to just one element (which can't be indexed)
and a pointer to a subrange of the vector (which can be) have
different types, we need a special method for creating a pointer to a
subrange of a vector. This method is called "slice":
let x: &[int] = [ 1, 2, 3, 4, 5 ].slice(3, 5);
printf!("%d %d", x[0], x[1]); // prints 4 5
In this way, we can present Rust as a language with three basic
pointer types, one kind of vector type, one kind of function type
(modulo unsafe, pure, one-shot if we want to add it, etc), and one
kind of trait type. I think this could drastically decrease the
perceived complexity of the language for newcomers without having to
change anything in the language itself.
Thoughts?
Patrick
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev