summaryrefslogtreecommitdiff
path: root/chapter17/README.md
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2024-11-13 13:41:18 -0800
committerCliff Click <cliffc@acm.org>2024-11-23 09:03:20 -0800
commit68cd11f31dd4ba7f089d1a15de5a36ec67043da6 (patch)
tree19adb6cee02232eba346c6aed2d56081556302f2 /chapter17/README.md
parent82fb275502f84e17228fc587385eeb76f195a09e (diff)
downloadSimple-68cd11f31dd4ba7f089d1a15de5a36ec67043da6.tar.gz
Simple-68cd11f31dd4ba7f089d1a15de5a36ec67043da6.zip
Final? pass of finals
Add a least-upper-bound to set Phis to their respective Top while preserving final fields. Requires a ReadOnly node to "cast-away-writable". Series of isFinal/makeRO in all Types. Changes tests to match r/w intent.
Diffstat (limited to 'chapter17/README.md')
-rw-r--r--chapter17/README.md103
1 files changed, 46 insertions, 57 deletions
diff --git a/chapter17/README.md b/chapter17/README.md
index b7a1afd6..bf998ab8 100644
--- a/chapter17/README.md
+++ b/chapter17/README.md
@@ -15,7 +15,7 @@ Allow pre-increment for identifiers only, for now: `--pc`.
## var & val
`var` can be used in the `type` position to indicate a "variable" (mutable
-value), whose type will be inferred from the initalizing expression.
+value), whose type will be inferred from the required initalizing expression.
`val` is the same as `var`, except it is a "value" (not mutable).
@@ -30,78 +30,68 @@ infers as
`S s? = new S;`
-## Initialized fields are immutable by default
+## Mutability
-Typed field declarations with an initializer are immutable by default, and can
-be made mutable with a leading `!`. `var` and `val` keep their current sense.
-Fields are immutable at the end of either constructor, but can be changed
-during construction.
+Typed primitive fields are always mutable. Typed reference fields without an
+initializer must be mutable to get a value. References with an initializer are
+immutable by default and can be made mutable with a leading `!`. `var` and
+`val` keep their current sense and can be used to make any field mutable or
+immutable. Fields are always mutable during construction, but will become
+immutable at the end of either constructor.
+`int x; x=3; x++; // OK, primitive so mutable`
+`int x =3; x++; // Ok, primitive so mutable, despite initializer`
-Examples:
+Assume in the next examples this struct exists:
+`struct S { int x; };`
+Then:
+`S s; s = new S ; s.x++; // OK, no initializer so s.x is mutable`
+`S s; s = new S{x=3}; s.x++; // OK, no initializer so s.x is mutable`
+`S s = new S ; s.x++; // Error, initializer so s.x is immutable`
+`S s = new S{x=3}; s.x++; // Error, initializer so s.x is immutable`
-```java
-struct Point { int x,y; }; // Fields x and y are not initialized, mutable
-Point p = new Point;
-p.x++; // Mutate is ok
-return p.x;
-```
+Leading `!` makes mutable:
+`S !s = new S; s.x++; // Ok, has '!' so mutable`
-```java
-struct Point { int x=3,y=4; }; // Fields x and y are initialized, immutable
-Point p = new Point;
-p.x++; // Error!
-return p.x;
-```
+'var' is variable:
+`var s = new S; s.x++; // Ok, has var so mutable`
-```java
-struct Point { int x=3,y=4; }; // Fields x and y are initialized, immutable
-Point p = new Point { x=x*x; y=y*y; }; // Ok to mutate in the constructor
-p.x++; // Error!
-return p.x;
-```
+'val' is a "value": not mutable through this reference, but may be mutable
+through other references.
+`val s = new S; s.x++; // Error, val so s.x is immutable`
-```java
-struct Point { int !x=3, !y=4; }; // Fields x and y are initialized, mutable
-Point p = new Point;
-p.x++; // Mutate is OK
-return p.x;
-```
-```java
-struct Point { var x,y; }; // Error, var and val require an initializer
-Point p = new Point;
-p.x++;
-return p.x;
-```
-```java
-struct Point { var x=3,y=4; }; // Fields x and y are mutable
-Point p = new Point;
-p.x++; // Mutate is OK
-return p.x;
-```
+### References with an initializer are deeply immutable
-```java
-struct Point { val x=3,y=4; }; // Fields x and y are immutable
-Point p = new Point;
-p.x++; // Error!
-return p.x;
-```
+References with an initializer are deeply immutable, but a mutable version of
+the same reference can exist. This works for `var` and normal type
+declarations: `var s = new S;` and `S s = new S` both make `s` an
+immutable reference to a `struct S`.
-## Deep Immutability (proposal)
-
```cpp
-struct Bar { int x; };
-Bar b = new Bar; /* b = new Bar; *//* b.x++; */ // immutable & deep immutable
-Bar !b = new Bar; b = new Bar; b.x++; // mutable & deep mutable
-val b = new Bar; /* b = new Bar; *//* b.x++; */ // immutable & deep immutable
-var b = new Bar; b = new Bar; b.x++; // mutable & inherits deep mutability from RHS
+struct Bar { int x; }
+Bar !bar = new Bar;
+bar.x = 3; // Ok, bar is mutable
+
+struct Foo { Bar !bar; int y; }
+Foo !foo = new Foo;
+foo.bar = barl // Ok bar is mutable
+foo.bar.x++; // Ok foo and foo.bar and foo.bar.x are all mutable
+
+val xfoo = foo; // Throw away mutability
+xfoo.bar.x++; // Error, cannot mutate through xfoo
+
+print(xfoo.bar.x); // Ok to read through xfoo, prints 4
+foo.bar.x++; // Bumps to 5
+print(xfoo.bar.x); // Ok to read through xfoo, prints 5
```
+
+
## Trinary
Allow `pred ? e_true : e_false`. Also allow `pred ? e_true`, where the false result
@@ -138,7 +128,6 @@ return i; // ERROR: Undefined name 'i'
finalize final
oper-assign +=, -=
TODO
-for-interator
switch