-
Notifications
You must be signed in to change notification settings - Fork 23
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
Remove public let fields #59
Conversation
9c975e0
to
2125466
Compare
|
||
## Design Proposal | ||
|
||
This proposal suggest to remove the support for public `let` fields, and only support private (`priv`) `let` fields. |
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.
One potential point to note; the existing mutability restrictions also apply to var
fields; a pub var
array cannot be mutated outside of the enclosing composite. The only way to do that is to declare a pub(set) var
field. This may cause a slight inconsistency or point of confusion if our solution to this is to only support priv let
fields, as this does not solve the "problem" where you can mutate regular pub var
fields through references or functions. However we may simply decide this isn't actually an issue and move on.
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.
That's a good point! The two options I think we can take are:
- Like you've said, we can assume the problem/confusion is only with
let
fields, and assume users are more cautious of usingvar
fields with access controls - Or we can extend this to all
var
fields as well, by mergingpub
andpub(set)
into one and say anything that is public is also settable. i.e: Removingpub
and keeping onlypub(set)
(and maybe just call itpub
for syntax convenience), which is essentially what Dete proposed I think.
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 like the second option; pub(set)
seems like a very weird distinction to make.
2125466
to
c416422
Compare
Adding a Summary of the last meeting we had on 26/01/2023: Questions:
Solutions:During the meeting, it seemed there was clear preference towards the "removal/limiting of public Also, there were several variants of this solution was also proposed:
Action Items:
|
So I've been applying some of the suggested solutions, mainly the first two (because other solutions only solve the problem partially):
To me, it feels like if we go ahead with any of these solutions, we would end up making life harder for the majority (making the simple/common case difficult), and also may end up just moving the problem to a different place (e.g: returning a reference), or hiding/burying the problem inside the boilerplate code making it even far less obvious to tackle. Maybe we should just properly document the behavior and let it be (current documentation isn't quite accurate)? I'm curious about what everyone else thinks about this. |
I've said this in internal meetings, but I should put this down in a public place as well: I agree with basically all of what you've said here. I think a partial solution here is really only going to push the problem elsewhere or paper over it without really solving the core of the issue. IMO we should either implement the full solution (with mutability tracking, read-only references, etc) or just fix the bug with reference-field mutation and document the existing behavior and move on. |
All those actually can be Actually we would retire Returning reference has danger only for resource fields, but I think it is acceptable. You cannot return nested resource anyway. |
I agree it shouldn't be much of a problem for values returned from functions. However, I haven't been involved enough in writing smart contracts to have a strong say towards/against that. So I would trust you and everyone else who has more exposure to smart contracts use-cases than me (especially authors of these contracts) to have a better insight.
Yes, true. |
Returning references is possible even now, so there won't be a change in that. My only concern is if people start returning references as a way to avoid boiler-plate code, then that would undo all the effort we put to avoid accidental mutations. |
can you give an example? I don't see a possibility like this at first look but I am missing some case probably. is it something like: pub contract NodeManager{
priv var node: @NodeRecord
pub resource NodeRecord {
pub var tokensStaked: @FlowToken.Vault
pub var tokensCommitted: @FlowToken.Vault
}
pub fun getNodeRecord(): &NodeRecord{
return &self.node as & NodeRecord
}
}
|
This is a hypothetical example: Assuming all fields in (EDIT: basically yes, same as what you wrote above) |
in this example , entitlements will save us ( as mutations will be via function ), but in my example case problem remains. But it feels like it is a bit bad design anyway. |
@SupunS Today I participated in the meeting, and I would like to know if the understanding is correct so far. The discussion involved the proposal to remove support for public let fields and only allow private let fields (priv). The issue of mutations in pub var fields and the potential confusion between pub and pub(set) was also addressed. Options considered included addressing the problem with let fields only, extending the solution to var fields, or combining pub and pub(set) into a single access modifier. In addition, concerns were raised about how the solution would affect existing contracts and the possibility of merely moving the problem instead of solving it. During the meeting, there was a clear preference for removing/limiting public let fields rather than adding static checks to prevent mutations. However, when applying some of the suggested solutions, it was noted that many developers and users would end up returning references to internal fields to avoid writing additional code, which could provide full mutable access to the fields through a reference. The discussion led to the conclusion that a partial solution might only shift the problem or mask it without actually addressing the core issue. Some participants suggested properly documenting the current behavior and moving forward, while others discussed the possibility of implementing a comprehensive solution with mutability tracking and read-only references. |
Thanks, @diegofornalha for joining the discussion! What you posted is a good summary of the overall discussion so far about this FLIP and the alternative FLIP #58. In today's meeting, we mostly focused on the impact on existing contracts by the proposed changes (i.e pretty much continued this discussion), and also a possible third option of using Entitlements to restrict external mutability. |
Summary of the meeting on 20/04/2023Restricting
|
Work towards onflow/cadence#2273
An alternative solution for improving external mutability restrictions.