I propose adding the following two functions to the refs
and st
packages:
new' :: forall s. s -> Ref s
new' :: forall a r. a -> STRef r a
And then rewrite the current new
as new a = pure $ new' a
.
The proposal comes from extensive work with purescript-event
and finding myself often needing to create an event with a push function in a non-effectful context. The signature for create is currently create :: forall a. Effect (EventIO a)
, but the Effect
just exists so that Ref.new
can be called: otherwise, it could be written create :: forall a. Unit -> EventIO a
.
The effectful nature of new
creates a weird situation in the internals of the event
library, where unsafePerformEvent
is called in a pure function just to make an event. This usage of unsafePerformEvent
winds up being is necessary in other situations as well when working with purescript-events
. If new
were a pure function, on the other hand, event creation could be pure as well.
So that’s the upside of the proposed new'
. The downside is that it gets into murky waters of what a pure function is. If the definition of a pure function is that it must always return the same output for a given input, you can argue that new' :: a -> Ref a
is pure because the two references, at their moment of creation, are equal. At the same time, it doesn’t make sense for Ref a
to have an Eq
instance, so even though the function is conceptually pure, it is not demonstrably pure.
Back to the upside, this change would get rid of several unsafePerformEffect
-s spread over various libraries and web apps.
Thoughts?