Skip to content

Commit

Permalink
v9.a
Browse files Browse the repository at this point in the history
  • Loading branch information
zigo101 committed May 25, 2019
1 parent a6b6a42 commit b66b412
Show file tree
Hide file tree
Showing 11 changed files with 1,393 additions and 940 deletions.
6 changes: 1 addition & 5 deletions README-v2.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
# A Go immutable values proposal

Old versions:
* [the propsoal thread](https://github.com/golang/go/issues/29422).
* [the `var:N` version](README-v1.md)

The new syntax is not Go 1 compatible,
please read the last section of this proposal for incompatible cases.

Expand Down Expand Up @@ -155,7 +151,7 @@ Short value declaration examples:
{
newA, newB, oldC := (var.fixed)(va), vb, vc
newA, newB, oldC := va.(fixed), vb, vc // equivalent to the above line

newX, newY, oldZ := (Tx.fixed)(va), (Ty)(vb), vc
newX, newY, oldZ := (Tx)(va).(fixed), (Ty)(vb), vc // equivalent to the above line
}
Expand Down
11 changes: 3 additions & 8 deletions README-v3.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
# A Go immutable types/values proposal

Old versions:
* [the propsoal thread](https://github.com/golang/go/issues/29422).
* [the `var:N` version](README-v1.md)
* [the pure-immutable-value interpretation version](README-v2.md)

This proposal introduces a notation `T.fixed` to represent the immutable version of type `T`,
where `fixed` is new introduced keyword, which makes this proposal not Go 1 compatible.
Please read the last section of this proposal for incompatible cases.
Expand Down Expand Up @@ -101,7 +96,7 @@ Those rules are much straightforward and anticipated.
Please note, the immutability semantics in this proposal is different from the `const` semantics in C/C++.
For example, a value declared as `var.fixed p ***int` in this proposal is
like a variable decalared as `int const * const * const * p` in C/C++.
In C/C++, we can declare a variable as `int * const * const * x`,
In C/C++, we can declare a variable as `int * const * const * x`,
in this proposal, no ways to declare variables with the similar immutabilities.

Another example, the following C code are valid.
Expand Down Expand Up @@ -182,7 +177,7 @@ Short value declaration examples:
newA, newB, oldC := (var.fixed)(va), vb, vc
newA, newB, oldC := (?.fixed)(va), vb, vc
newA, newB, oldC := va.(fixed), vb, vc // equivalent to the above two lines

newX, newY, oldZ := (Tx.fixed)(va), (Ty)(vb), vc
newX, newY, oldZ := (Tx)(va).(fixed), (Ty)(vb), vc // equivalent to the above line
}
Expand Down Expand Up @@ -381,7 +376,7 @@ The immutable version of a type may have a different method set from the type.
The new keyword `fixed` is one cause why this proposal is not Go 1 compatible.
Assume a source file imports a package as `T` and if there is a type named `fixed` in the imported package,
although a smart compiler will not mistake the `fixed` in `T.fixed` as a keyword, the `T.fixed` really hurts code readibilty.

Using the old `const` keyword instead of the new `fixed` keyword can avoid these problems,
however it would make people be confused with the current constant things.
(Maybe, it is an acceptable solution.)
Expand Down
7 changes: 0 additions & 7 deletions README-v4.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
# A Go immutable types/values proposal

Old versions:
* [the proposal thread](https://github.com/golang/go/issues/29422).
* [the `var:N` version](README-v1.md)
* [the pure-immutable-value interpretation version](README-v2.md)
* [the immutable-type interpretation version](README-v3.md)


This proposal not Go 1 compatible. Please read the last section of this proposal for incompatible cases.

Any criticisms and improvement ideas are welcome, for
Expand Down
8 changes: 0 additions & 8 deletions README-v5.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
# A Go immutable types/values proposal

Old versions:
* [the proposal thread](https://github.com/golang/go/issues/29422).
* [the `var:N` version](README-v1.md)
* [the pure-immutable-value interpretation version](README-v2.md)
* [the immutable-type interpretation version](README-v3.md)
* [the immutable-type/value interpretation version: const.fixed](README-v4.md)


This proposal not Go 1 compatible. Please read the last section of this proposal for incompatible cases.

Any criticisms and improvement ideas are welcome, for
Expand Down
24 changes: 7 additions & 17 deletions README-v6.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
# A proposal to support read-only and immutable values in Go

Old versions:
* [the proposal thread](https://github.com/golang/go/issues/29422)
* [the initial proposal](README-v0.md)
* [the `var:N` version](README-v1.md)
* [the pure-immutable-value interpretation version](README-v2.md)
* [the immutable-type interpretation version](README-v3.md)
* [the immutable-type/value interpretation version: const.fixed](README-v4.md)
* [the immutable-type/value interpretation version: final.fixed. With interface design flaw](README-v5.md)


This proposal is not Go 1 compatible.
Please read the last section of this proposal for incompatible cases.

Expand Down Expand Up @@ -206,7 +196,7 @@ The current design may be not perfect, so any improvemnt ideas are welcome.
Some examples of the full value declaration form:
```golang
// A true immutable value which can't be modified in any (safe) way.
final FileNotExist = errors.New("file not exist").fixed
final FileNotExist = errors.New("file not exist").fixed

// The following two declarations are equivalent.
// Note, the elements of "a" are all true immutable values.
Expand Down Expand Up @@ -334,19 +324,19 @@ func foo() {
z := x[:1] // z is var.fxied value (of type []T.fixed)
x = nil // ok
y = T{} // ok
final w = x // w is a final.fixed value
u := w[:] // w[:] is a final.fixed value, but
// u is deduced as a var.fixed value.
// v is a final.normal value.
final v = []T{{123, nil}, {789, new(int)}}
v = nil // error: v is a final value
v[1] = T{} // ok
_ = append(u, T{}) // error: can't append to fixed slices
_ = append(v, T{}) // ok
...
}
```
Expand Down Expand Up @@ -403,7 +393,7 @@ func bar(v map[string]T.fixed) { // v is a var.fixed value
*v["foo"].b = 789 // error: v["foo"].b is a fixed value
v["foo"] = T{} // error: v["foo"] is a fixed map
v["baz"] = T{} // error: v["foo"] is a fixed map

// m will be deduced as a var.fixed value.
// That means as long as one element or one key is fixed
// in a map literal, then the map value is a fixed value.
Expand All @@ -415,7 +405,7 @@ func bar(v map[string]T.fixed) { // v is a var.fixed value
for a, b := range m {
// a and b are both var.fixed values.
// Their types are *int.fixed.

*a = 123 // error: a is a fixed value
*b = 789 // error: b is a fixed value
}
Expand Down
25 changes: 7 additions & 18 deletions README-v7.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
# A proposal to support read-only and immutable values in Go

Old versions:
* [the proposal thread](https://github.com/golang/go/issues/29422)
* [the initial proposal](README-v0.md)
* [the `var:N` version](README-v1.md)
* [the pure-immutable-value interpretation version](README-v2.md)
* [the immutable-type interpretation version](README-v3.md)
* [the immutable-type/value interpretation version: const.fixed](README-v4.md)
* [the immutable-type/value interpretation version: final.fixed. With interface design flaw](README-v5.md)
* [the immutable-type/value interpretation version: final.fixed. Without partial read-only](README-v6.md)


This proposal is not Go 1 compatible.
Please read the last section of this proposal for incompatible cases.

Expand Down Expand Up @@ -220,7 +209,7 @@ The current design may be not perfect, so any improvemnt ideas are welcome.
Some examples of the full value declaration form:
```golang
// A true immutable value which can't be modified in any (safe) way.
final FileNotExist = errors.New("file not exist").fixed
final FileNotExist = errors.New("file not exist").fixed

// The following two declarations are equivalent.
// Note, the elements of "a" are all true immutable values.
Expand Down Expand Up @@ -340,19 +329,19 @@ func foo() {
z := x[:1] // z is var.fxied value (of type []T.fixed)
x = nil // ok
y = T{} // ok

final w = x // w is a final.fixed value
u := w[:] // w[:] is a final.fixed value, but
// u is deduced as a var.fixed value.

// v is a final.normal value.
final v = []T{{123, nil}, {789, new(int)}}
v = nil // error: v is a final value
v[1] = T{} // ok

_ = append(u, T{}) // error: can't append to fixed slices
_ = append(v, T{}) // ok

...
}
```
Expand Down Expand Up @@ -409,7 +398,7 @@ func bar(v map[string]T.fixed) { // v is a var.fixed value
*v["foo"].b = 789 // error: v["foo"].b is a fixed value
v["foo"] = T{} // error: v["foo"] is a fixed map
v["baz"] = T{} // error: v["foo"] is a fixed map

// m will be deduced as a var.fixed value.
// That means as long as one element or one key is fixed
// in a map literal, then the map value is a fixed value.
Expand All @@ -421,7 +410,7 @@ func bar(v map[string]T.fixed) { // v is a var.fixed value
for a, b := range m {
// a and b are both var.fixed values.
// Their types are *int.fixed.

*a = 123 // error: a is a fixed value
*b = 789 // error: b is a fixed value
}
Expand Down
50 changes: 19 additions & 31 deletions README-v8.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
# A proposal to support read-only and immutable values in Go

Old versions:
* [the proposal thread](https://github.com/golang/go/issues/29422), and the [golang-dev thread](https://groups.google.com/forum/#!topic/golang-dev/5M9F09S_k0g)
* [the initial proposal](README-v0.md)
* [the `var:N` version](README-v1.md)
* [the pure-immutable-value interpretation version](README-v2.md)
* [the immutable-type interpretation version](README-v3.md)
* [the immutable-type/value interpretation version: const+fixed](README-v4.md)
* [the immutable-type/value interpretation version: final+fixed. With interface design flaw](README-v5.md)
* [final+fixed. Without partial read-only](README-v6.md)
* [final+fixed. With partial read-only](README-v7.md)
* const + reader/writer roles. Partial read-only removed. (v8, the currrent version)
# A proposal to support read-only and practical immutable values in Go

_(Comparing to the last revision v7, this revision removes partial read-only,
for partial read-only will bring many complexities and cause some design flaws.)_
Expand Down Expand Up @@ -114,9 +102,9 @@ local variable/constants, and function parameter/result variables.
But it can't be used to specifiy struct field types.
Fields of a struct value will inherit the roles from the struct value.

There is not the `T:writer` notation.
There is not the `T:writer` notation.
The *writer role* concept does exist.
The raw `T` notation means a writer type (in non-struct-field declarations).
The raw `T` notation means a writer type (in non-struct-field declarations).

Thw word `reader` can be either a keyword or not.
If it is designed as not, then it can be viewed as a predeclared role.
Expand Down Expand Up @@ -187,23 +175,23 @@ An example:
const y = x // y is a writer constant
var z []*int:reader = x // z is a reader variable
const w = y:reader // w is a reader constant
// x, y, z and w share elements.
x[0] = new(int); *x[0] = 123 // ok
x = nil // ok
println(*z[0]) // 123
y[0] = new(int); *y[0] = 789 // ok
y = nil // error: y is a constant
println(*w[0]) // 789
*z[0] = 555; z[0] = new(int) // error: z[0] and *z[0] are read-only
z = nil // ok
*w[0] = 555; w[0] = new(int) // error: w[0] and *w[0] are read-only
w = nil // error: w is a constant
x = z // error: reader value z can't be assigned to writer value x
}
```
Expand All @@ -214,7 +202,7 @@ However, in the following example, the slice elements are immutable.
{
var s = []int{1, 2, 3}:reader
s[0] = 9 // error: s[0] is read-only
// S and its elements are both immutable.
const S = []int{1, 2, 3}:reader
}
Expand Down Expand Up @@ -280,7 +268,7 @@ func foo() {
w := x // w is deduced as a writer variable of type []int.
z[0] = 9 // error: z[0] is read-only.
u := &z // u is like y.
p1 := &x[1] // p1 is a writer pointer variable.
p2 := &z[1] // p2 is a reader pointer variable.
...
Expand Down Expand Up @@ -343,18 +331,18 @@ func foo() {
z := x[:1] // liek x, z is reader slice.
x = nil // ok
y = T{} // ok
const w = x // w is a reader constant.
u := w[:] // u is a reader slice variable.
// v is a writer slice constant.
const v = []T{{123, nil}, {789, new(int)}}
v = nil // error: v is a constant
v[1] = T{} // ok
_ = append(u, T{}) // error: can't append to reader slices
_ = append(v, T{}) // ok
...
}
```
Expand Down Expand Up @@ -420,7 +408,7 @@ func bar(v map[string]T:reader) { // v is a reader variable
*v["foo"].b = 789 // error: v["foo"].b is read-only
v["foo"] = T{} // error: v is a reader map
v["baz"] = T{} // error: v is a reader map
// m will be deduced as a reader map variable.
// That means as long as one element or one key is a reader
// value in a map literal, then the map is also a reader value.
Expand All @@ -431,7 +419,7 @@ func bar(v map[string]T:reader) { // v is a reader variable
}
for a, b := range m {
// a and b are both reader values of type *int:reader.
*a = 123 // error: *a is read-only
*b = 789 // error: *b is read-only
}
Expand Down Expand Up @@ -503,7 +491,7 @@ Use the `Split` function.
var x = []byte{"aaa/bbb/ccc/ddd"}
_ = Split(x, []byte("/")) // call the writer version
_ = Split(x:reader, []byte("/")) // call the reader version
// Use Split function as values.
var fw = Split{r: writer} // I haven't got better syntax yet.
var fr = Split{r: reader}
Expand Down Expand Up @@ -803,6 +791,6 @@ To support partial read-only, the following rules need to be added:

Another simpler rule design is to forbid the conversions mentioned in the 2nd and 3rd rules.

This means, the addressable constant feature and the partial read-only feature are mutually exclusive.
This means, the addressable constant feature and the partial read-only feature are mutually exclusive.


Loading

0 comments on commit b66b412

Please sign in to comment.