rust-lang / rust-lang/rfcs

Implement dynamic string interpolation

Open
#642 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

T-libs
Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

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

For earlier discussion, see https://github.com/rust-lang/rust/issues/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?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the earlier discussion in issue 10318 and the existing std::fmt machinery mentioned here. The design must settle dynamic format-string syntax, type-safety constraints, and how arguments are passed without variadic functions; done would be a resolved proposal rather than a localized code change.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.