@@ -899,58 +899,51 @@ express that `f` requires no explicit `return`, as if it returns
899
899
control to the caller, it returns a value (true because it never returns
900
900
control).
901
901
902
- #### Predicate functions
902
+ #### Pure functions
903
903
904
- Any pure boolean function is called a * predicate function* , and may be used in
905
- a [ constraint] ( #constraints ) , as part of the static [ typestate
906
- system] ( #typestate-system ) . A predicate declaration is identical to a function
907
- declaration, except that it is declared with the additional keyword ` pure ` . In
908
- addition, the typechecker checks the body of a predicate with a restricted set
909
- of typechecking rules. A predicate
904
+ A pure function declaration is identical to a function declaration, except that
905
+ it is declared with the additional keyword ` pure ` . In addition, the typechecker
906
+ checks the body of a pure function with a restricted set of typechecking rules.
907
+ A pure function
910
908
911
909
* may not contain an assignment or self-call expression; and
912
- * may only call other predicates , not general functions.
910
+ * may only call other pure functions , not general functions.
913
911
914
- An example of a predicate :
912
+ An example of a pure function :
915
913
916
914
~~~~
917
915
pure fn lt_42(x: int) -> bool {
918
916
return (x < 42);
919
917
}
920
918
~~~~
921
919
922
- A non-boolean function may also be declared with ` pure fn ` . This allows
923
- predicates to call non-boolean functions as long as they are pure. For example:
920
+ Pure functions may call other pure functions:
924
921
925
922
~~~~ {.xfail-test}
926
923
pure fn pure_length<T>(ls: list<T>) -> uint { /* ... */ }
927
924
928
925
pure fn nonempty_list<T>(ls: list<T>) -> bool { pure_length(ls) > 0u }
929
926
~~~~
930
927
931
- In this example, ` nonempty_list ` is a predicate---it can be used in a
932
- typestate constraint---but the auxiliary function ` pure_length ` is
933
- not.
934
-
935
928
* TODO:* should actually define referential transparency.
936
929
937
930
The effect checking rules previously enumerated are a restricted set of
938
931
typechecking rules meant to approximate the universe of observably
939
932
referentially transparent Rust procedures conservatively. Sometimes, these
940
933
rules are * too* restrictive. Rust allows programmers to violate these rules by
941
- writing predicates that the compiler cannot prove to be referentially
934
+ writing pure functions that the compiler cannot prove to be referentially
942
935
transparent, using an escape-hatch feature called "unchecked blocks". When
943
936
writing code that uses unchecked blocks, programmers should always be aware
944
937
that they have an obligation to show that the code * behaves* referentially
945
938
transparently at all times, even if the compiler cannot * prove* automatically
946
939
that the code is referentially transparent. In the presence of unchecked
947
940
blocks, the compiler provides no static guarantee that the code will behave as
948
941
expected at runtime. Rather, the programmer has an independent obligation to
949
- verify the semantics of the predicates they write.
942
+ verify the semantics of the pure functions they write.
950
943
951
944
* TODO:* last two sentences are vague.
952
945
953
- An example of a predicate that uses an unchecked block:
946
+ An example of a pure function that uses an unchecked block:
954
947
955
948
~~~~
956
949
# import std::list::*;
@@ -972,7 +965,7 @@ pure fn pure_length<T>(ls: list<T>) -> uint {
972
965
973
966
Despite its name, ` pure_foldl ` is a ` fn ` , not a ` pure fn ` , because there is no
974
967
way in Rust to specify that the higher-order function argument ` f ` is a pure
975
- function. So, to use ` foldl ` in a pure list length function that a predicate
968
+ function. So, to use ` foldl ` in a pure list length function that a pure function
976
969
could then use, we must use an ` unchecked ` block wrapped around the call to
977
970
` pure_foldl ` in the definition of ` pure_length ` .
978
971
@@ -1136,8 +1129,8 @@ looks like:
1136
1129
1137
1130
The only exception is that the body of the class constructor begins
1138
1131
with all the class's fields uninitialized, and is allowed to -- in
1139
- fact, must -- initialize all the fields. A special case in the
1140
- typestate pass enforces this invariant.
1132
+ fact, must -- initialize all the fields. The compiler enforces this
1133
+ invariant.
1141
1134
1142
1135
Usually, the class constructor stores its argument or arguments in the
1143
1136
class's named fields. In this case, the ` file_descriptor ` 's data field
@@ -1306,7 +1299,7 @@ type.
1306
1299
1307
1300
~~~~
1308
1301
# trait shape { }
1309
- # impl of shape for int { }
1302
+ # impl int: shape { }
1310
1303
# let mycircle = 0;
1311
1304
1312
1305
let myshape: shape = mycircle as shape;
@@ -1332,7 +1325,7 @@ An _implementation item_ provides an implementation of a
1332
1325
1333
1326
type circle = {radius: float, center: point};
1334
1327
1335
- impl circle_shape of shape for circle {
1328
+ impl circle: shape {
1336
1329
fn draw(s: surface) { do_draw_circle(s, self); }
1337
1330
fn bounding_box() -> bounding_box {
1338
1331
let r = self.radius;
@@ -1370,10 +1363,10 @@ specified, after the `impl` keyword.
1370
1363
~~~~
1371
1364
# trait seq<T> { }
1372
1365
1373
- impl <T> of seq<T> for ~[T] {
1366
+ impl<T> ~[T]: seq<T> {
1374
1367
/* ... */
1375
1368
}
1376
- impl of seq<bool> for u32 {
1369
+ impl u32: seq<bool> {
1377
1370
/* Treat the integer as a sequence of bits */
1378
1371
}
1379
1372
~~~~
@@ -1934,13 +1927,15 @@ x <- copy y;
1934
1927
1935
1928
The former is just more terse and familiar.
1936
1929
1937
- #### Operator- assignment expressions
1930
+ #### Compound assignment expressions
1938
1931
1939
1932
The ` + ` , ` - ` , ` * ` , ` / ` , ` % ` , ` & ` , ` | ` , ` ^ ` , ` << ` , ` >> ` , and ` >>> `
1940
1933
operators may be composed with the ` = ` operator. The expression `lval
1941
1934
OP= val` is equivalent to ` lval = lval OP val` . For example, ` x = x +
1942
1935
1` may be written as ` x += 1`.
1943
1936
1937
+ Any such expression always has the [ ` nil ` ] ( #primitive-types ) type.
1938
+
1944
1939
#### Operator precedence
1945
1940
1946
1941
The precedence of Rust binary operators is ordered as follows, going
@@ -2074,31 +2069,6 @@ A `loop` expression denotes an infinite loop:
2074
2069
loop_expr : "loop" '{' block '}';
2075
2070
~~~~~~~~
2076
2071
2077
- For a block ` b ` , the expression ` loop b ` is semantically equivalent to
2078
- ` while true b ` . However, ` loop ` s differ from ` while ` loops in that the
2079
- typestate analysis pass takes into account that ` loop ` s are infinite.
2080
-
2081
- For example, the following (contrived) function uses a ` loop ` with a
2082
- ` return ` expression:
2083
-
2084
- ~~~~
2085
- fn count() -> bool {
2086
- let mut i = 0;
2087
- loop {
2088
- i += 1;
2089
- if i == 20 { return true; }
2090
- }
2091
- }
2092
- ~~~~
2093
-
2094
- This function compiles, because typestate recognizes that the ` loop `
2095
- never terminates (except non-locally, with ` return ` ), thus there is no
2096
- need to insert a spurious ` fail ` or ` return ` after the ` loop ` . If ` loop `
2097
- were replaced with ` while true ` , the function would be rejected
2098
- because from the compiler's perspective, there would be a control path
2099
- along which ` count ` does not return a value (that is, if the loop
2100
- condition is always false).
2101
-
2102
2072
### Break expressions
2103
2073
2104
2074
~~~~~~~~ {.ebnf .gram}
@@ -2540,7 +2510,7 @@ macro-generated and user-written code can cause unintentional capture.
2540
2510
Future versions of Rust will address these issues.
2541
2511
2542
2512
2543
- # Types and typestates
2513
+ # Type system
2544
2514
2545
2515
## Types
2546
2516
@@ -2758,7 +2728,7 @@ trait printable {
2758
2728
fn to_str() -> ~str;
2759
2729
}
2760
2730
2761
- impl of printable for ~str {
2731
+ impl ~str: printable {
2762
2732
fn to_str() -> ~str { self }
2763
2733
}
2764
2734
@@ -2805,7 +2775,7 @@ trait printable {
2805
2775
fn to_str() -> ~str;
2806
2776
}
2807
2777
2808
- impl of printable for ~str {
2778
+ impl ~str: printable {
2809
2779
fn to_str() -> ~str { self }
2810
2780
}
2811
2781
~~~~~~
@@ -2966,7 +2936,7 @@ Local variables are not initialized when allocated; the entire frame worth of
2966
2936
local variables are allocated at once, on frame-entry, in an uninitialized
2967
2937
state. Subsequent statements within a function may or may not initialize the
2968
2938
local variables. Local variables can be used only after they have been
2969
- initialized; this condition is guaranteed by the typestate system .
2939
+ initialized; this is enforced by the compiler .
2970
2940
2971
2941
References are created for function arguments. If the compiler can not prove
2972
2942
that the referred-to value will outlive the reference, it will try to set
0 commit comments