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

Implement dynamic string interpolation #642

Open
steveklabnik opened this issue Jan 21, 2015 · 6 comments
Open

Implement dynamic string interpolation #642

steveklabnik opened this issue Jan 21, 2015 · 6 comments
Labels
T-libs-api Relevant to the library API team, which will review and decide on the RFC.

Comments

@steveklabnik
Copy link
Member

Issue by bstrie
Wednesday Nov 06, 2013 at 16:55 GMT

For earlier discussion, see rust-lang/rust#10318

This issue was labelled with: B-RFC in the Rust repository


In a perfect world, a minimal quine in Rust would look like this:

fn main(){let S="fn main(){let S={1}{0}{1};println!(S,S,'{1}')}";println!(S,S,'"')}

Sadly, this is impossible. Why? Because println! requires that the first argument not just be static; it must be a string literal.

There are other, non-contrived use cases for dynamic string interpolation; acrichto mentions internationalization as one example.

So what would be involved in implementing dynamic string interpolation?

acrichto mentions (https://botbot.me/mozilla/rust/msg/7556963/) that the current machinery used to parse strings for format! provides an interface that could be reused (std::fmt). But that's only part of the solution.

The first issue is that we can't guarantee type safety for dynamic interpolation (can we???), so the syntax for dynamic format strings might need to be rethought. For now we should probably assume that all arguments to dynamic string interpolation will implement ToStr and just ignore any format string options that aren't for positional or named arguments.

The second issue is that we can't just simply have anything like a simple .format() method on strings, like Python has, since we don't have variadic functions. We'd need to either do something like pass an array of trait objects:

"ab{1}d{0}".format(["e" as ~ToStr, "c" as ~ToStr]);  // gross
dyn_format!("ab{1}d{0}", "e", "c");  // maybe a little less gross

...or use method chaining and generics:

fn push<T: Any>(&mut self, x: T) { self.vec.push(~x as ~Any) }
"ab{1}d{0}".format().push("e").push("c").to_str()  // still kinda gross

(all code examples are just quick sketches, might be overlooking details (and don't worry about naming))

Any thoughts?

@mbrubeck
Copy link
Contributor

The runtime-fmt crate by @SpaceManiac implements versions of format! and other interpolation macros that allow dynamic formatting strings.

@strega-nil
Copy link

I would rather allow format_args! to take a constexpr string argument, which would come with better constexpr and less use of macros.

@eddyb
Copy link
Member

eddyb commented Apr 18, 2017

@ubsan You would at least need variadic generics to pull that off, and then you have the named arguments feature... which I suppose you can encode as Named::<"foo">(&expr) for foo = expr.

@strega-nil
Copy link

@eddyb :)

@strega-nil
Copy link

@eddyb you don't have to reveal my entire plan :)

@mbrubeck
Copy link
Contributor

See also #543.

@Centril Centril added the T-libs-api Relevant to the library API team, which will review and decide on the RFC. label Feb 23, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

6 participants