Return arbitrary value from upd
@baslijns and I were discussing the case where you want to do an upd
and return the old value of the share. For example, you have some [a]
of which you want to retrieve all values and set the value to []
. It is my understanding that with a get
followed by a set
you might lose data and due to the type of upd
(which always returns the new value) you cannot get the old value.
Assuming the current library indeed does not provide an easy way to do this, we would propose to change the type of upd
from
upd :: !(r -> w) !(sds () r w) -> Task w | TC r & TC w & RWShared sds
to
upd :: !(r -> (a, Maybe w)) !(sds () r w) -> Task a | TC r & TC w & RWShared sds
where the share is only written when a Just
is returned.
The old upd f
can be expressed as upd (\old -> let new = f old in (new, Just new))
, and get
can be expressed as upd (flip tuple Nothing)
.
This has two advantages:
- You can return any
a
(e.g. the original value in the example above); -
upd
can choose depending on the current value whether a new value should be written.
Problem: naming. Assuming that we want this function, do we want to change the current upd
(our preference) or introduce a new name (and which)? upd
is used 143 times in iTasks (examples included) and 7 times in VIIA.
Cases where the new upd
should be used: