Skip to content

Commit ae06e79

Browse files
authored
Update docs (#31)
See also #23, #29 I thought about this a bit more, and I think the reasoning for why refs are effectful is more persuasive when viewed through the lens of purity rather than of referential transparency, so I've updated the docs accordingly. I am reluctant to include code examples illustrating why Refs are effectful here, because I think people may skim the page looking for code examples, and in the absence of code examples which describe the real API, I think code examples which illustrate a hypothetical version of the API which doesn't actually exist may do more harm than good. I am also leaning towards not including @natefaubion's example (where you can violate the type system by defining a reference with a polymorphic type and specializing it after the fact), since it's hard to illustrate without a code example, and I think it's unlikely to be useful to most people who just want to make use of the Ref API, which is the group I think we should be considering to be our target audience here.
1 parent 8ab49d5 commit ae06e79

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

src/Effect/Ref.purs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
1-
-- | This module defines actions for working with mutable value references.
1+
-- | This module defines the `Ref` type for mutable value references, as well
2+
-- | as actions for working with them.
23
-- |
3-
-- | _Note_: `Control.Monad.ST` provides a _safe_ alternative to `Ref` when
4+
-- | You'll notice that all of the functions that operate on a `Ref` (e.g.
5+
-- | `new`, `read`, `write`) return their result wrapped in an `Effect`.
6+
-- | Working with mutable references is considered effectful in PureScript
7+
-- | because of the principle of purity: functions should not have side
8+
-- | effects, and should return the same result when called with the same
9+
-- | arguments. If a `Ref` could be written to without using `Effect`, that
10+
-- | would cause a side effect (the effect of changing the result of subsequent
11+
-- | reads for that `Ref`). If there were a function for reading the current
12+
-- | value of a `Ref` without the result being wrapped in `Effect`, the result
13+
-- | of calling that function would change each time a new value was written to
14+
-- | the `Ref`. Even creating a new `Ref` is effectful: if there were a
15+
-- | function for creating a new `Ref` with the type `forall s. s -> Ref s`,
16+
-- | then calling that function twice with the same argument would not give the
17+
-- | same result in each case, since you'd end up with two distinct references
18+
-- | which could be updated independently of each other.
19+
-- |
20+
-- | _Note_: `Control.Monad.ST` provides a pure alternative to `Ref` when
421
-- | mutation is restricted to a local scope.
522
module Effect.Ref
623
( Ref
@@ -25,7 +42,7 @@ type role Ref representational
2542
-- | Create a new mutable reference containing the specified value.
2643
foreign import new :: forall s. s -> Effect (Ref s)
2744

28-
-- | Read the current value of a mutable reference
45+
-- | Read the current value of a mutable reference.
2946
foreign import read :: forall s. Ref s -> Effect s
3047

3148
-- | Update the value of a mutable reference by applying a function
@@ -40,6 +57,7 @@ foreign import modifyImpl :: forall s b. (s -> { state :: s, value :: b }) -> Re
4057
modify :: forall s. (s -> s) -> Ref s -> Effect s
4158
modify f = modify' \s -> let s' = f s in { state: s', value: s' }
4259

60+
-- | A version of `modify` which does not return the updated value.
4361
modify_ :: forall s. (s -> s) -> Ref s -> Effect Unit
4462
modify_ f s = void $ modify f s
4563

0 commit comments

Comments
 (0)