Skip to content
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

Need a way get a dereferenced copy from a reference #2803

Closed
SupunS opened this issue Sep 21, 2023 · 8 comments · Fixed by #2982
Closed

Need a way get a dereferenced copy from a reference #2803

SupunS opened this issue Sep 21, 2023 · 8 comments · Fixed by #2982

Comments

@SupunS
Copy link
Member

SupunS commented Sep 21, 2023

Issue to be solved

Sometimes it is useful to be able to get a dereferenced-copy from a reference.

For e.g. assume a large dictionary is in storage, and one would need to get a copy of just one entry of that dictionary. In the latest released version, this is possible by:

  • First, borrowing a reference to the dictionary (say dictionaryRef)
  • Accessing the entry using index-access dictionaryRef[key], which would return a copy of the value at the key.

However, with stable cadence, given the index syntax dictionaryRef[key] also returns another reference, the above approach no longer works. Instead, they would need to

  • Take a "copy" of the entire dictionary first (say dictionaryCopy)
  • Then, get a copy of the value using the index-access dictionaryCopy[key].
    The downside of this is now they would need to copy the entire outer dictionary which could be a very expensive operation.

Suggested Solution

It would be nice to have a way to get a dereferenced copy from a reference (say a built-in method dereference()), so that they can get a copy from the reference itself.
i.e:

let elementRef = dictionaryRef[key]

let elementCopy = dereference(elementRef)

Some suggestions for the name of the built-in method:

  • dereference()
  • dereferenceCopy()
  • Could also use the c-like dereference operator- asterisk (*), but I personally prefer one of the above, because they are verbose.
@SupunS
Copy link
Member Author

SupunS commented Sep 21, 2023

An example use-case is FlowEpoch.getEpochMetadata: onflow/flow-core-contracts#384

@j1010001
Copy link
Member

Important to prevent regressions + Quality-of life improvement for Stable Cadence

@bluesign
Copy link
Contributor

bluesign commented Sep 25, 2023

I think this is only needed when accession container types (or structs) inside container types. Maybe adding a copy/clonemethod to them would be sufficient.

let elementRef = dictionaryRef[key]
let elementCopy = elementRef.copy()

@SupunS
Copy link
Member Author

SupunS commented Sep 25, 2023

I personally prefer a different name other than copy because, a 'copy' on a reference could be misinterpreted/misunderstood as copying the reference itself (not the referenced value).

But a good point on that this could be a method on the value (elementRef.something()) rather than a global function (something(elementRef))

@bluesign
Copy link
Contributor

yeah copy/clone has that meaning, you are right @SupunS . My concern was if we make it global, people will try to use it on all kind of references. ( maybe elementRef.derefence() ? ) only things developer can can dereference

@SupunS
Copy link
Member Author

SupunS commented Sep 25, 2023

My concern was if we make it global, people will try to use it on all kind of references. ( maybe elementRef.derefence() ? ) only things developer can can dereference

That would be no harm, correct? e.g: dereferencing an &String type to get the String.
I agree there is no reason for someone to do so, and also if the dictionary's value type is String then accessing the element dictionaryRef[key] would give a String (and not a `&String), so there's little value.
But I don't see any specific reason to limit it to just container-typed references.

@bluesign
Copy link
Contributor

bluesign commented Sep 25, 2023

That would be no harm, correct? e.g: dereferencing an &String type to get the String

Yeah I was more thinking in line with dereferencing resources etc. That's why I think some generic dereference method on &AnyStruct can work better. ( yeah my comment on Container type was wrong, it is useful on &String etc too for sure if we limit to &AnyStruct )

@SupunS
Copy link
Member Author

SupunS commented Sep 25, 2023

oh yes, you are correct, it definitely has to be supported only for the subtypes of &AnyStruct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants