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

FLIP 293: StructStringer interface #294

Merged
merged 8 commits into from
Oct 30, 2024

Conversation

RZhang05
Copy link
Contributor

Flip #293 working towards onflow/cadence#3579.

@SupunS
Copy link
Member

SupunS commented Oct 22, 2024

[Just cross-referencing] There were some concerns raised before, over having a user-defined toString functions for composites:

Copy link
Member

@turbolent turbolent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Adding a built-in interface, implementing it for built-in types that support it, and allowing Cadence developers to implement the interface for their types, makes a lot of sense 👍

cadence/20241010-stringer-interface.md Outdated Show resolved Hide resolved
cadence/20241010-stringer-interface.md Outdated Show resolved Hide resolved
cadence/20241010-stringer-interface.md Outdated Show resolved Hide resolved

### Alternatives Considered

An alternative is to have `AnyStruct` itself implement a `toString` function. As a native function there is no longer any risk of malicious code and it still solves the first goal. Additionally, it still allows for more powerful string formatting. The downside of this approach is in limiting customizability for developers.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be infeasible, given that not all values of AnyStruct are stringable.

cadence/20241010-stringer-interface.md Show resolved Hide resolved
cadence/20241010-stringer-interface.md Outdated Show resolved Hide resolved
Copy link
Member

@SupunS SupunS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 from me

@bluesign
Copy link
Collaborator

I had some concerns in the beginning but after thinking a bit more on it, this is great 👍

  • Is 'string' also 'Stringer'?
  • should some standard library functions change 'string' parameters to 'Stringer'?

@RZhang05
Copy link
Contributor Author

Is 'string' also 'Stringer'?

Yes it would be, this is the case in Swift with their CustomStringConvertible.

@turbolent
Copy link
Member

should some standard library functions change 'string' parameters to 'Stringer'?

That should not be necessary and would just complicate and slow down the functions, because they would all have to first call toString on the argument, even though in most cases it would just be a string.

This is also uncommon in the standard library or in "user code" of other languages. For example, Go's standard library functions work with strings as inputs, not fmt.Stringer.

@turbolent
Copy link
Member

One thing I realized in the discussion above is that we should probably clarify what the result of the toString function should be. Not all, but quite a few other languages make the distinction between a "human-readable representation", and a "debug representation". The former is used for display purposes to show to the user using the application, while the latter is meant to be helpful for the developer of the application.

For example

  • In Python there are the __str__ and __repr__ functions
  • In Swift there are the CustomStringConvertible and CustomDebugStringConvertible interfaces, with description and debugDescription properties
  • In Rust there are the Display and Debug traits

It might be good to clarify this in the proposal and note that the purpose of the proposed stringer interface is the former, providing a "human-readable representation".

I'm noting this, because currently we actually have the latter, the "debug representation", which makes sense for the log debugging function. For example, log("foo") logs "foo" (note the quotes), not foo (similar to how Swift "foo".debugDescription produces "foo").

When we're implementing this proposal we need to make sure to implement a new set of string functions and use it for the built-in types. Concretely, e.g. interpreter.StringValue.String() currently quotes. We might want to rename this e.g. DebugString, Representation, etc.

@turbolent turbolent changed the title Flip 293: Stringer interface FLIP 293: Stringer interface Oct 23, 2024
@turbolent turbolent changed the title FLIP 293: Stringer interface FLIP 293: StructStringer interface Oct 23, 2024
@turbolent
Copy link
Member

We discussed this FLIP in yesterdays working group call. Attendees liked the proposal and there were no concerns, so this FLIP is accepted 🎉

As always, thank you everyone for reviewing proposals and providing valuable feedback 🙏

@turbolent turbolent merged commit 6db6f3b into onflow:main Oct 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants