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

proposal: strings: string transformation functions for Builder #65338

Open
CAFxX opened this issue Jan 29, 2024 · 1 comment
Open

proposal: strings: string transformation functions for Builder #65338

CAFxX opened this issue Jan 29, 2024 · 1 comment

Comments

@CAFxX
Copy link
Contributor

CAFxX commented Jan 29, 2024

Proposal Details

There is currently no support for appending the result of any of the string transformation functions1 (Join, Replace(All)?, Repeat, Map, To(Title|Upper|Lower)(Special)?, ToValidUtf8) directly to a Builder, bypassing the intermediate temporary allocation:

// var b strings.Builder (assume that the backing buffer has been preallocated)
s := strings.Repeat(...) // intermediate temporary allocation
b.WriteString(s) // s dead here

The necessary presence of that temporary allocation partially defeats the purpose of Builder. I most recently ran into this while building SQL queries with varying number of placeholders (Repeat) and columns (Join).

Any of the following would address this issue, with different tradeoffs:

  1. somehow ensure that the compiler is able to elide that intermediate temporary allocation
  2. add variants of the transformation functions1 that target either a Builder (or more in general a io.Writer, but in this case we will still want to add special handling for the case in which the io.Writer is a Builder) -- e.g. for function Foo(...) string we would get something like AppendFoo(*Builder, ...) int or AppendFoo(io.Writer, ...) (int, error)2
  3. add a wrapper type in package strings that can be used to add all these string transformation methods1 to an existing io.Writer (again, with the case of the io.Writer being a Builder being handled specially) -- e.g. for function Foo(...) string we would get something like WriteWapper(io.Writer).Foo(...) (int, error)2

Option 1 would be possibly the best from a user perspective, as it would transparently apply to existing code and would not require new APIs (nor a full-blown proposal), but seems a bit tricky as it would involve teaching the compiler about some of these functions/types and/or significantly strengthening escape analysis.

Option 2 and 3 could be useful beyond strings.Builder, but they require duplicating a number of existing APIs.

Footnotes

  1. internally most of these strings transformation methods already instantiate an ephemeral Builder to accumulate the result of their work, so the existing methods could likely share their implementation with the ones being proposed 2 3

  2. the proposed names, AppendFoo and WriteWrapper, are currently just placeholders... suggestions welcome 2

@CAFxX CAFxX added the Proposal label Jan 29, 2024
@gopherbot gopherbot added this to the Proposal milestone Jan 29, 2024
@dolmen
Copy link
Contributor

dolmen commented Mar 25, 2024

We also commonly use functions from package strconv when assembling strings, so I think that the design should lead towards a solution for both packages. strconv functions don't have support for io.Writer.

(of course also bytes)

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

No branches or pull requests

4 participants