[rust-dev] Suggestions

Masklinn masklinn at masklinn.net
Mon Feb 6 00:07:04 PST 2012


On 2012-02-04, at 22:14 , Brian Anderson wrote:
> 
> I would be interested in seeing an extension that explores other ways to do string formatting. I think #fmt uses a printf style because it is well-known and was an obvious early approach to take. It is a bit unwieldy though and other languages have done this in a nicer way.

These ways may or may not work in Rust though, not sure.

String formatting approaches I know of:

= printf-style (most C-derived languages, numerous others as well)
    "this is a string %s", interpolated
  + well known
  + pretty simple
  + can be statically verified
  - positional interpolation only (annoying for e.g. translations where the order of interpolated terms could be changed)
  - formatting string is unclear and unwieldy as it becomes big
  - formatting mini-language is pretty horrible

 == printf-style extensions: keyword (Python)
     "this is a string %(interpolated)s", {'interpolated': somevar}
   + in-band name can be different (and more descriptive for the new context) than the variable name
   + when interpolating multiple values, values can easily be moved around, also allows for easily interpolating the same value in multiple places
   + can ignore some of the values provided for interpolation if desired/desirable
   + can be statically verified when using structures/records
   - redundancy between the format string and the map/structure provided, Python can also pick the local environment as a dict (`locals()`) but that brings other risks.

= Direct variable interpolation (Perl, PHP, shells)
    "this is a string $interpolated"
  + simple and (usually) obvious
  - harder to statically check
  - needs a standard conversion protocol or interface (a -> String)

 == extensions: expressions (PHP, Ruby)
    "this is a string {$interpolated}"
    "this is a string #{interpolated}"

  In this case, the format string contains an expression shim, which fully evaluates its expressions in the context of the surrounding code. It's possible to call any expression construct in the format string.
  + interpolated values can be formatted using standard language functions and methods
  - untrusted formatting input are code injection vectors (hard to use for e.g. translations)

= C#-string formatting (C#, Python >= 2.6, preferred to printf-style in Python 3)
    "this is a string {}", interpolated
    "this is a string {0}", interpolated
    "this is a string {interpolated}", {'interpolated': somevar}

  + terseness even superior to printf-style
  + more flexibility (e.g. moving positional arguments around by providing an integer index to `{}`)
  + can easily be extended with things like attributes or index access (as Python does)
  - formatting mini-language just as bad as printf-style
  - also requires a standard protocol or interface (à la Show) to convert values to strings

= Common-lisp's format
    you probably don't want to know


More information about the Rust-dev mailing list