flips
flips copied to clipboard
Flip 288: Simple String Interpolation
Flip #288 addresses https://github.com/onflow/cadence/issues/3579.
I really like the concept.
maybe little off topic but quick note on string interpolated strings vs printf; they are used for different needs; it is not one or the other. ( interpolation is better DX, but limited comparing to printf ( you cannot have dynamic templates etc ) ) So having both is a bit benefit. I think thinking with printf and building over it can be better option.
I am more into prefix or backtick to indicate interpolation personally, I think it is also easier to analyze statically. ( also by using a new prefix or backtick we can have multiline strings as additional benefit)
Something like this:
var s = `hello, ${getUsername(userId)};
you have ${getUserBalance(userId)} tokens.
`
maybe little off topic but quick note on string interpolated strings vs printf; they are used for different needs; it is not one or the other. ( interpolation is better DX, but limited comparing to printf ( you cannot have dynamic templates etc ) )
Regarding the limitation of not having dynamic templates: when do you ever need to dynamically construct the template? From my experience, that is almost never the case.
We might still want to also provide a string formatting facility, but we should promote the safer alternative (string interpolation). Given the benefits of string interpolation, static checking, we should prioritize it over string formatting.
Regarding the limitation of not having dynamic templates: when do you ever need to dynamically construct the template? From my experience, that is almost never the case.
Sorry it is a bit lack of my English; when I said dynamic templates, I meant format string stored somewhere and can be changed ( vs storing in code ) ( something like https://github.com/onflow/flow-evm-bridge/blob/main/cadence/contracts/templates/mainnet/EVMBridgedNFTTemplate.cdc )
Given the benefits of string interpolation, static checking, we should prioritize it over string formatting.
100% agree here
This would be a great feature!
Though I do agree with @bluesign that being able to use this in the context of stored strings would also be useful. As another example, the recent FlowRewards contracts (FlowRewardsMetadataViews#L106) uses an SVG template stored within a struct, rendered by joining values with the contained string chunks.
It would be much easier to simply store the whole template (rather than splitting before storing) and render using native interpolation.
e.g. In practice, we currently need to so something like
access(all)
struct Template {
access(all) let chunks: [String]
init(_ template: [String]) { self.chunks = template }
access(all)
fun render(param1: Int, param2: Int): String {
return self.chunks[0].concat(param1.toString())
.concat(self.chunks[2]).concat(param2.toString()
}
}
Where it would be much nicer to do something like
access(all)
struct Template {
access(all) let template: String
init(_ template: String) { self.template = template }
access(all)
fun render(param1: Int, param2: Int): String {
// where template == "First parameter: \(param1) | Second parameter: \(param2)"
return printf(`self.template`, param1, param2) // or some variation
}
}
Though perhaps the above is a separate issue entirely or is at least not mutually exclusive with this FLIP as proposed.
That's a good point on dynamic string formatting @bluesign and @sisyphusSmiling! Totally agree that it could be useful to have that as well. But at the same time, I think, as you pointed out as well, it could be another separate feature (can propose it as a new FLIP), and shouldn't really block us from having the static string templates/interpolations.
As discussed in the last working group session, this FLIP has been accepted 🎉
Checking in on this again. Is this in the latest Cadence release and available on the latest emulator?
This is in the latest Cadence release v1.3.0, but some of the downstream dependencies (e.g: emulator) are not yet updated to this version. Emulator still uses v1.2.1. I think Bastian already started updating the downstream dependencies (flow-go-sdk is already updated https://github.com/onflow/flow-go-sdk/pull/799), not sure what's the current status is, but guess it probably just need to get to the remaining ones.