From 30943ded71e123886291ad393e55bfb6aa837df3 Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Wed, 8 Jun 2022 02:28:37 -0600 Subject: BIG change: generic Var[T], txVar, etc. --- doc.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'doc.go') diff --git a/doc.go b/doc.go index db03501..748af80 100644 --- a/doc.go +++ b/doc.go @@ -10,14 +10,14 @@ it non-atomic). To begin, create an STM object that wraps the data you want to access concurrently. - x := stm.NewVar(3) + x := stm.NewVar[int](3) You can then use the Atomically method to atomically read and/or write the the data. This code atomically decrements x: stm.Atomically(func(tx *stm.Tx) { - cur := tx.Get(x).(int) - tx.Set(x, cur-1) + cur := x.Get(tx) + x.Set(tx, cur-1) }) An important part of STM transactions is retrying. At any point during the @@ -29,11 +29,11 @@ updated before the transaction will be rerun. As an example, this code will try to decrement x, but will block as long as x is zero: stm.Atomically(func(tx *stm.Tx) { - cur := tx.Get(x).(int) + cur := x.Get(tx) if cur == 0 { tx.Retry() } - tx.Set(x, cur-1) + x.Set(tx, cur-1) }) Internally, tx.Retry simply calls panic(stm.Retry). Panicking with any other @@ -47,13 +47,13 @@ retried. For example, this code implements the "decrement-if-nonzero" transaction above, but for two values. It will first try to decrement x, then y, and block if both values are zero. - func dec(v *stm.Var) { + func dec(v *stm.Var[int]) { return func(tx *stm.Tx) { - cur := tx.Get(v).(int) + cur := v.Get(tx) if cur == 0 { tx.Retry() } - tx.Set(v, cur-1) + v.Set(tx, cur-1) } } -- cgit v1.2.3 From ea580b2c20a5e26e68c8f1d111bbe3adfb3e54d9 Mon Sep 17 00:00:00 2001 From: Chris Wendt Date: Wed, 8 Jun 2022 03:15:50 -0600 Subject: update README --- README.md | 9 ++++----- doc.go | 10 ++++------ 2 files changed, 8 insertions(+), 11 deletions(-) (limited to 'doc.go') diff --git a/README.md b/README.md index 22dfdda..8073b9d 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,9 @@ composition will either deadlock or release the lock between functions (making it non-atomic). The `stm` API tries to mimic that of Haskell's [`Control.Concurrent.STM`](https://hackage.haskell.org/package/stm-2.4.4.1/docs/Control-Concurrent-STM.html), but -this is not entirely possible due to Go's type system; we are forced to use -`interface{}` and type assertions. Furthermore, Haskell can enforce at compile -time that STM variables are not modified outside the STM monad. This is not -possible in Go, so be especially careful when using pointers in your STM code. +Haskell can enforce at compile time that STM variables are not modified outside +the STM monad. This is not possible in Go, so be especially careful when using +pointers in your STM code. Remember: modifying a pointer is a side effect! Unlike Haskell, data in Go is not immutable by default, which means you have to be careful when using STM to manage pointers. If two goroutines have access @@ -31,7 +30,7 @@ applications in Go. If you find this package useful, please tell us about it! See the package examples in the Go package docs for examples of common operations. -See [example_santa_test.go](example_santa_test.go) for a more complex example. +See [cmd/santa-example/main.go](cmd/santa-example/main.go) for a more complex example. ## Pointers diff --git a/doc.go b/doc.go index 748af80..c704c33 100644 --- a/doc.go +++ b/doc.go @@ -69,11 +69,9 @@ behavior. One common way to get around this is to build up a list of impure operations inside the transaction, and then perform them after the transaction completes. -The stm API tries to mimic that of Haskell's Control.Concurrent.STM, but this -is not entirely possible due to Go's type system; we are forced to use -interface{} and type assertions. Furthermore, Haskell can enforce at compile -time that STM variables are not modified outside the STM monad. This is not -possible in Go, so be especially careful when using pointers in your STM code. -Remember: modifying a pointer is a side effect! +The stm API tries to mimic that of Haskell's Control.Concurrent.STM, but +Haskell can enforce at compile time that STM variables are not modified outside +the STM monad. This is not possible in Go, so be especially careful when using +pointers in your STM code. Remember: modifying a pointer is a side effect! */ package stm -- cgit v1.2.3