-
Notifications
You must be signed in to change notification settings - Fork 21
Explain why Ref functions return Effect (Ref s)
rather than Ref s
#30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Can I get an approval here? |
-- | (e.g. `new`, `modify`, `modify_`, `read`) return an `Effect (Ref s)` | ||
-- | and not a `Ref s`. Here's what would happe if the `Ref s` was not | ||
-- | wrapped in an `Effect`: | ||
-- | 1. In some situations, one could violate referential transparency. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think putting it this way downplays the importance of Effect to retain referential transparency here; I'd argue that a Ref which could be read or written outside of Effect would end up violating referential transparency in almost all situations, since every time you write a new value to a ref, you change the result of reading from it. I also think we could do more to explain what referential transparency is, as if the reader isn't already familiar with the term, these docs probably won't make a lot of sense (and if they are familiar with it, they likely understand why reading or writing a Ref is effecful already anyway).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think putting it this way downplays the importance of Effect to retain referential transparency here
So... change the wording to "In all situations, one will violate referential transparency" ?
I also think we could do more to explain what referential transparency is
Odd. Usually you want docs to explain less and have readers look up terms elsewhere. Why the change here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change the wording to “in all situations...”?
Well, that’s not quite accurate either - it’s definitely possible that a Ref is initialised and then never written to, in which case all of the reads would return the same value and you wouldn’t observe a violation.
Why the change here?
I want docs to only address things that are directly relevant to the topic at hand; in this case, referential transparency is directly relevant to why refs are effectful. I also expect that it only needs a sentence or two; if it needed more than that, I’d agree that it should go elsewhere. If you can point to an example where you think I’m being inconsistent I’m happy to reconsider.
src/Effect/Ref.purs
Outdated
-- | referential transparency. However, `first` holds the same reference twice | ||
-- | whereas `second` holds two different references. Thus, it invalidates | ||
-- | referential transparency. By making `Ref.new` return an `Effect`, a | ||
-- | new separate reference is created each time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is quite accurate. Making Ref.new
return an Effect
means that Ref.new x
returns an action which represents creating a mutable reference and setting its initial value to x
. A new separate reference is only created each time that action is executed, not each time we call Ref.new
. The point is that by having it return an Effect, we ensure that Ref.new x
means the same thing wherever it occurs in the program.
-- | and not a `Ref s`. Here's what would happe if the `Ref s` was not | ||
-- | wrapped in an `Effect`: | ||
-- | 1. In some situations, one could violate referential transparency. | ||
-- | 2. One can violate the type system by giving a `Ref` a polymorphic type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reflecting on this a bit more, I think this particular point is specific to Ref.new
, and is probably best documented there (sorry).
-- | 2. One can violate the type system by giving a `Ref` a polymorphic type | ||
-- | and then specializing it after the fact. | ||
-- | | ||
-- | In regards to the first, consider the below example: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the topic of why using Refs is effectful in general, I think it will probably be more persuasive to use a simpler example where a Ref is created, read from, written to, and then read from again: that's likely to be easier to understand than this example, which is a bit more subtle.
Would you mind thinking through this more and then decide what should be written? I thought this would be as simple as just copying your and Nate's comments over. |
Yes, I’m happy to do that. |
Superceded by #31 |
Fixes #23