about summary refs log tree commit diff
path: root/doc/tutorial/data.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/tutorial/data.md')
-rw-r--r--doc/tutorial/data.md334
1 files changed, 0 insertions, 334 deletions
diff --git a/doc/tutorial/data.md b/doc/tutorial/data.md
deleted file mode 100644
index 79a0cb85ac5..00000000000
--- a/doc/tutorial/data.md
+++ /dev/null
@@ -1,334 +0,0 @@
-# Datatypes
-
-Rust datatypes are, by default, immutable. The core datatypes of Rust
-are structural records and 'enums' (tagged unions, algebraic data
-types).
-
-    type point = {x: float, y: float};
-    enum shape {
-        circle(point, float);
-        rectangle(point, point);
-    }
-    let my_shape = circle({x: 0.0, y: 0.0}, 10.0);
-
-## Records
-
-Rust record types are written `{field1: TYPE, field2: TYPE [, ...]}`,
-and record literals are written in the same way, but with expressions
-instead of types. They are quite similar to C structs, and even laid
-out the same way in memory (so you can read from a Rust struct in C,
-and vice-versa).
-
-The dot operator is used to access record fields (`mypoint.x`).
-
-Fields that you want to mutate must be explicitly marked as such. For
-example...
-
-    type stack = {content: [int], mutable head: uint};
-
-With such a type, you can do `mystack.head += 1u`. If `mutable` were
-omitted from the type, such an assignment would result in a type
-error.
-
-To 'update' an immutable record, you use functional record update
-syntax, by ending a record literal with the keyword `with`:
-
-    let oldpoint = {x: 10f, y: 20f};
-    let newpoint = {x: 0f with oldpoint};
-    assert newpoint == {x: 0f, y: 20f};
-
-This will create a new struct, copying all the fields from `oldpoint`
-into it, except for the ones that are explicitly set in the literal.
-
-Rust record types are *structural*. This means that `{x: float, y:
-float}` is not just a way to define a new type, but is the actual name
-of the type. Record types can be used without first defining them. If
-module A defines `type point = {x: float, y: float}`, and module B,
-without knowing anything about A, defines a function that returns an
-`{x: float, y: float}`, you can use that return value as a `point` in
-module A. (Remember that `type` defines an additional name for a type,
-not an actual new type.)
-
-## Record patterns
-
-Records can be destructured on in `alt` patterns. The basic syntax is
-`{fieldname: pattern, ...}`, but the pattern for a field can be
-omitted as a shorthand for simply binding the variable with the same
-name as the field.
-
-    # let mypoint = {x: 0f, y: 0f};
-    alt mypoint {
-        {x: 0f, y: y_name} { /* Provide sub-patterns for fields */ }
-        {x, y}             { /* Simply bind the fields */ }
-    }
-
-The field names of a record do not have to appear in a pattern in the
-same order they appear in the type. When you are not interested in all
-the fields of a record, a record pattern may end with `, _` (as in
-`{field1, _}`) to indicate that you're ignoring all other fields.
-
-## Enums
-
-Enums are datatypes that have several different representations. For
-example, the type shown earlier:
-
-    # type point = {x: float, y: float};
-    enum shape {
-        circle(point, float);
-        rectangle(point, point);
-    }
-
-A value of this type is either a circle¸ in which case it contains a
-point record and a float, or a rectangle, in which case it contains
-two point records. The run-time representation of such a value
-includes an identifier of the actual form that it holds, much like the
-'tagged union' pattern in C, but with better ergonomics.
-
-The above declaration will define a type `shape` that can be used to
-refer to such shapes, and two functions, `circle` and `rectangle`,
-which can be used to construct values of the type (taking arguments of
-the specified types). So `circle({x: 0f, y: 0f}, 10f)` is the way to
-create a new circle.
-
-Enum variants do not have to have parameters. This, for example, is
-equivalent to a C enum:
-
-    enum direction {
-        north;
-        east;
-        south;
-        west;
-    }
-
-This will define `north`, `east`, `south`, and `west` as constants,
-all of which have type `direction`.
-
-When the enum is C like, that is none of the variants have parameters,
-it is possible to explicitly set the discriminator values to an integer
-value:
-
-    enum color {
-      red = 0xff0000;
-      green = 0x00ff00;
-      blue = 0x0000ff;
-    }
-
-If an explicit discriminator is not specified for a variant, the value
-defaults to the value of the previous variant plus one.  If the first
-variant does not have a discriminator, it defaults to 0.  For example,
-the value of `north` is 0, `east` is 1, etc.
-
-When an enum is C-like the `as` cast operator can be used to get the
-discriminator's value.
-
-<a name="single_variant_enum"></a>
-
-There is a special case for enums with a single variant. These are
-used to define new types in such a way that the new name is not just a
-synonym for an existing type, but its own distinct type. If you say:
-
-    enum gizmo_id = int;
-
-That is a shorthand for this:
-
-    enum gizmo_id { gizmo_id(int); }
-
-Enum types like this can have their content extracted with the
-dereference (`*`) unary operator:
-
-    # enum gizmo_id = int;
-    let my_gizmo_id = gizmo_id(10);
-    let id_int: int = *my_gizmo_id;
-
-## Enum patterns
-
-For enum types with multiple variants, destructuring is the only way to
-get at their contents. All variant constructors can be used as
-patterns, as in this definition of `area`:
-
-    # type point = {x: float, y: float};
-    # enum shape { circle(point, float); rectangle(point, point); }
-    fn area(sh: shape) -> float {
-        alt sh {
-            circle(_, size) { float::consts::pi * size * size }
-            rectangle({x, y}, {x: x2, y: y2}) { (x2 - x) * (y2 - y) }
-        }
-    }
-
-Another example:
-
-    # type point = {x: float, y: float};
-    # enum direction { north; east; south; west; }
-    fn point_from_direction(dir: direction) -> point {
-        alt dir {
-            north { {x:  0f, y:  1f} }
-            east  { {x:  1f, y:  0f} }
-            south { {x:  0f, y: -1f} }
-            west  { {x: -1f, y:  0f} }
-        }
-    }
-
-## Tuples
-
-Tuples in Rust behave exactly like records, except that their fields
-do not have names (and can thus not be accessed with dot notation).
-Tuples can have any arity except for 0 or 1 (though you may see nil,
-`()`, as the empty tuple if you like).
-
-    let mytup: (int, int, float) = (10, 20, 30.0);
-    alt mytup {
-      (a, b, c) { log(info, a + b + (c as int)); }
-    }
-
-## Pointers
-
-In contrast to a lot of modern languages, record and enum types in
-Rust are not represented as pointers to allocated memory. They are,
-like in C and C++, represented directly. This means that if you `let x
-= {x: 1f, y: 1f};`, you are creating a record on the stack. If you
-then copy it into a data structure, the whole record is copied, not
-just a pointer.
-
-For small records like `point`, this is usually more efficient than
-allocating memory and going through a pointer. But for big records, or
-records with mutable fields, it can be useful to have a single copy on
-the heap, and refer to that through a pointer.
-
-Rust supports several types of pointers. The simplest is the unsafe
-pointer, written `*TYPE`, which is a completely unchecked pointer
-type only used in unsafe code (and thus, in typical Rust code, very
-rarely). The safe pointer types are `@TYPE` for shared,
-reference-counted boxes, and `~TYPE`, for uniquely-owned pointers.
-
-All pointer types can be dereferenced with the `*` unary operator.
-
-### Shared boxes
-
-<a name="shared-box"></a>
-
-Shared boxes are pointers to heap-allocated, reference counted memory.
-A cycle collector ensures that circular references do not result in
-memory leaks.
-
-Creating a shared box is done by simply applying the unary `@`
-operator to an expression. The result of the expression will be boxed,
-resulting in a box of the right type. For example:
-
-    let x = @10; // New box, refcount of 1
-    let y = x; // Copy the pointer, increase refcount
-    // When x and y go out of scope, refcount goes to 0, box is freed
-
-NOTE: We may in the future switch to garbage collection, rather than
-reference counting, for shared boxes.
-
-Shared boxes never cross task boundaries.
-
-### Unique boxes
-
-<a name="unique-box"></a>
-
-In contrast to shared boxes, unique boxes are not reference counted.
-Instead, it is statically guaranteed that only a single owner of the
-box exists at any time.
-
-    let x = ~10;
-    let y <- x;
-
-This is where the 'move' (`<-`) operator comes in. It is similar to
-`=`, but it de-initializes its source. Thus, the unique box can move
-from `x` to `y`, without violating the constraint that it only has a
-single owner (if you used assignment instead of the move operator, the
-box would, in principle, be copied).
-
-Unique boxes, when they do not contain any shared boxes, can be sent
-to other tasks. The sending task will give up ownership of the box,
-and won't be able to access it afterwards. The receiving task will
-become the sole owner of the box.
-
-### Mutability
-
-All pointer types have a mutable variant, written `@mutable TYPE` or
-`~mutable TYPE`. Given such a pointer, you can write to its contents
-by combining the dereference operator with a mutating action.
-
-    fn increase_contents(pt: @mutable int) {
-        *pt += 1;
-    }
-
-## Vectors
-
-Rust vectors are always heap-allocated and unique. A value of type
-`[TYPE]` is represented by a pointer to a section of heap memory
-containing any number of `TYPE` values.
-
-NOTE: This uniqueness is turning out to be quite awkward in practice,
-and might change in the future.
-
-Vector literals are enclosed in square brackets. Dereferencing is done
-with square brackets (zero-based):
-
-    let myvec = [true, false, true, false];
-    if myvec[1] { std::io::println("boom"); }
-
-By default, vectors are immutable—you can not replace their elements.
-The type written as `[mutable TYPE]` is a vector with mutable
-elements. Mutable vector literals are written `[mutable]` (empty) or
-`[mutable 1, 2, 3]` (with elements).
-
-The `+` operator means concatenation when applied to vector types.
-Growing a vector in Rust is not as inefficient as it looks :
-
-    let myvec = [], i = 0;
-    while i < 100 {
-        myvec += [i];
-        i += 1;
-    }
-
-Because a vector is unique, replacing it with a longer one (which is
-what `+= [i]` does) is indistinguishable from appending to it
-in-place. Vector representations are optimized to grow
-logarithmically, so the above code generates about the same amount of
-copying and reallocation as `push` implementations in most other
-languages.
-
-## Strings
-
-The `str` type in Rust is represented exactly the same way as a vector
-of bytes (`[u8]`), except that it is guaranteed to have a trailing
-null byte (for interoperability with C APIs).
-
-This sequence of bytes is interpreted as an UTF-8 encoded sequence of
-characters. This has the advantage that UTF-8 encoded I/O (which
-should really be the default for modern systems) is very fast, and
-that strings have, for most intents and purposes, a nicely compact
-representation. It has the disadvantage that you only get
-constant-time access by byte, not by character.
-
-A lot of algorithms don't need constant-time indexed access (they
-iterate over all characters, which `str::chars` helps with), and
-for those that do, many don't need actual characters, and can operate
-on bytes. For algorithms that do really need to index by character,
-there's the option to convert your string to a character vector (using
-`str::to_chars`).
-
-Like vectors, strings are always unique. You can wrap them in a shared
-box to share them. Unlike vectors, there is no mutable variant of
-strings. They are always immutable.
-
-## Resources
-
-Resources are data types that have a destructor associated with them.
-
-    # fn close_file_desc(x: int) {}
-    resource file_desc(fd: int) {
-        close_file_desc(fd);
-    }
-
-This defines a type `file_desc` and a constructor of the same name,
-which takes an integer. Values of such a type can not be copied, and
-when they are destroyed (by going out of scope, or, when boxed, when
-their box is cleaned up), their body runs. In the example above, this
-would cause the given file descriptor to be closed.
-
-NOTE: We're considering alternative approaches for data types with
-destructors. Resources might go away in the future.