FAQ
Yes. I'd be interested. Any code on a github repo?
On Monday, April 26, 2010 11:25:03 AM UTC-7, Peter Thatcher wrote:

I agree that immutable data structures are a missing piece of the
concurrency story in Go. But I think we need to look beyond just
structs that can't be changed. We need vectors, maps, structs, etc,
that are not only immutable but are easily "changed" in the sense that
a new value is created in an efficient way.

I think Clojure (http://clojure.org/) is really leading the way in
this regard with a very impressive implementation of immutable
(technically, "persistent") vectors and maps using hashed array mapped
tries (http://en.wikipedia.org/wiki/Hash_array_mapped_trie). I would
really like to see an implementation of HAMT-based vectors and maps
for Go. In fact, I started one based on the Clojure one, but haven't
had the time to make much progress on it. Is anyone else interested?

On Apr 23, 2:45 pm, Esko Luontola wrote:
Since Go is meant for writing concurrent programs, it would IMO
benefit greatly from supporting compiler-enforced immutability,
because concurrent access to immutable objects does not need to be
synchronized. For example you can send a reference to an immutable
object over a channel and be guaranteed that there will be no
concurrency bugs because of concurrent modification. For more
information, seehttp://en.wikipedia.org/wiki/Immutable_object

The goal of this thread is to make a proposal for structs which can
not be modified after they have been constructed. In particular, this
does not include the immutability of local variables (as discussed
inhttp://groups.google.com/group/golang-nuts/browse_thread/thread/ba388...),
nor is this the same read-only references to mutable objects (as
discussed inhttp://
groups.google.com/group/golang-nuts/browse_thread/thread/aa8d6...).
(Although this might expand on the ideas in the latter thread by
making the rules for immutable references more strict.)

I have one idea that how immutable objects could be added to the
language. Please point out any cases where this proposal fails to
guarantee immutability, or makes writing code too hard. Constructive
criticism and improvements are welcome.

Proposal:

(1) If a struct type has been labeled as immutable, then an object of
that type can be mutated only in the method where the object is
allocated, before the object is returned from the method or passed as
a parameter to any other method (calling the object's methods is the
same as passing it as a parameter to a method). Everywhere else, any
attempt to modify the object's fields is disallowed by the compiler.

(2) Types which are labeled immutable may contain only other types
which are labeled immutable. There needs to be special handling for
the built-in types (slices, arrays, maps) which makes them immutable
when they are members of an immutable object.

The syntax for labeling things immutable is something that is not yet
considered, until the semantics have been fully thought out. In the
following examples I've used the keyword "immutable".

Some examples of rule (1):

type A immutable struct {
X int

}

func NewA() *A {
a = new(A)
a.X = 1 // allowed, because done in the same method where the
object was allocated (you may even assign it many times if you like)
someOtherMethod(a)
//a.X = 2 // would not be allowed, because the object was already
passed to some other method, and this method is not anymore guaranteed
to have the only reference to the object
return a

}

func (a *A) Foo() {
//a.X = 3 // would not be allowed, because not in the same method
where the object was allocated

}

func Bar() {
a = NewA()
//a.X = 4 // would not be allowed, because not in the same method
where the object was allocated

}

The rule (2) says that immutable objects are fully immutable. If an
object contains a slice, array or map, there needs to be some special
handling which prevents mutating it. I have not yet fully thought it
through, that what all those rules are. Maybe something similar to
rule (1), so that a slice which is labeled immutable may be mutated
only in the method where it is allocated, before it is returned or
passes to any other method.

Some examples of rule (2):

type B immutable struct {
Y *A // allowed, because A is immutable
Z immutable []int // allowed
//W []int // not allowed, because []int is a mutable slice

}

func NewB(values []int) *B {
return &B{NewA(), immutableCopyOf(values)}

}

func immutableCopyOf(values []int) immutable []int {
copy := make([]int, len(values))
for i, v := range values {
copy[i] = v
}
return copy // converting "[]int" to "immutable []int" is allowed
here, because this method is guaranteed to be the only one having a
reference to the slice

}

Similarly also arrays and maps can be made immutable.

It is not yet clear that how interfaces relate to this. For example,
is it allowed for an immutable type to contain interfaces or not.
Maybe if the interface type is labeled immutable ("type Foo immutable
interface {...}") then an immutable struct could contain it. Only
immutable structs may be accessed through immutable interfaces.
Accessing immutable structs through a regular interface is safe,
because the compiler has already enforced that none of the immutable
struct's methods modify itself.

Your thoughts?
--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedOct 23, '14 at 9:56a
activeOct 23, '14 at 9:56a
posts1
users1
websitegolang.org

1 user in discussion

Matt LeVeck: 1 post

People

Translate

site design / logo © 2022 Grokbase