On 2013-05-04 01:28:43, Huon Wilson wrote:
> Hi all,
> 
> Aatch, Kimundi and I (and maybe some others... sorry if I've forgotten
> you) came up with a bit of proposal on IRC for handling fmt!. It's
> possibly been considered already, but whatever, we'd like some
> comments on it.
> 
> 
> There would one trait for each format specifier (probably excluding
> `?'), e.g. FormatC for %c, FormatD for %d/%i, FormatF for %f, and
> format would just require that the value for each format specifier
> implements the correct trait. (Presumably this check can be done
> "automatically" by attempting to call the appropriate method and
> using the type checker.)
> 
> In code,
> 
> 
> trait FormatC {
>   fn format_c(&self, w: &Writer, flags: Flags);
> }
> 
> impl FormatC for char {
>   fn format_c(&self, w: &Writer, _: Flags) { w.write_char(*self) }
> }
> 
> struct MyChar(char);
> impl FormatC for MyChar {
>   fn format_c(&self, w: &Writer, _: Flags) { w.write_char(**self) }
> }
> 
> fmt!("%c%c%c", 'a', MyChar('a'), ~"str")
> 
> // becomes
> 
> 'a'.format_c(w, {});
> MyChar('a').format_c(w, {});
> ~"str".format_c(w, {});
> 
> 
> And the first two would resolve/type-check fine, but the last would
> not. (`Flags' would contain the width and precision specifiers and all
> that.)
> 
> 
> This could then be extended to have a dynamic formatter, which allows
> types to format for any specifier at runtime (i.e. get around compile
> time restrictions). Our thoughts were to add an extra flag to indicate
> this (e.g. !), so that it is entirely and explicitly opt-in. (Similar
> to Python's __format__ and Go's fmt (I think).)
> 
> 
> trait DynamicFormat {
>   fn format_dynamic(&self, w: &Writer, spec: FormatSpec);
> }
> 
> fmt!("%!s %!10.3f", a, b)
> 
> // becomes
> 
> a.format_dynamic(w, {flags: {}, type: 's'});
> w.write_str(" ");
> b.format_dynamic(w, {flags: {width: 10, prec: 3}, type: 'f'});
> 
> 
> (Presumably this could also have a lint mode, to give an error or
> warning if dynamic formatting is used.)
> 
> 
> There were also some other discussions about the fmt! syntax, e.g. it
> was suggested that the following could be equivalent to each other
> 
> fmt!("%{2}[0].[1]f %{2}e", 10, 3, 1.01);
> fmt!("%10.3f %e", 1.01, 1.01);
> 
> This is an explicit divergence from printf's slightly archane */'n$'
> placeholder syntax. One could use `[*]`  to just refer to the next
> argument, like * does by default. (Aatch has a format spec parser[1]
> in the works that supports this syntax.)
> 
> 
> Huon
> 
> [1]: https://gist.github.com/Aatch/fb94960ab770c7df5718
> _______________________________________________

Hi All,

Me and dbaupp have done some preliminary implementation[1] on the formatting 
side of things. During
discussion on IRC we have come up with a few extra details that should probably 
be mentioned.

Using a writer for format strings is useful for efficiency, especially when 
doing things like 
writing to the terminal or a file. So there are 3 syntax extensions that would 
be used in order to 
make this work and be nice:

* fmt! which is essentially the same as now, returns a ~str
* printf! which writes straight to stdout (effectively replacing 
`io::print(fmt!(...))`)
* writef! which would take an io::Writer as it's first argument

fmt! and printf! would simply be written in terms of writef! with pre-supplied 
Writers.

The actual format string has, unsurprisingly, created a lot of discussion 
mostly around it's 
relative power. The current placeholder format is as follows:

    % position flags width precision numeric_arg conversion_specifier

With all except the '%' and conversion specifier being optional. The specific 
format of the fields 
is detailed in the string parser.

Currently we have identified 4 conversion specifiers: 'd', 'f', 's' and '?'. 
These are interpreted 
as "convert as" specifiers so '%d' means "convert this argument as a number" 
and the argument type 
itself knows how to do this.

For flags, we have '0', '-', '=', ' ', '+' and '\'' which have the same meaning 
as standard printf 
(where they exist in standard printf).

* '0' means zero-pad
* '-' means left-justified in the field
* '=' means center in the field
* ' ' means that a blank should always be before a signed number
* '+' means that a '-' or '+' should always be placed before a signed number

Width and precision fields are similar to the standard printf fields, just with 
minor syntax 
changes in the case of using the next or a specific argument.

The numeric arg field is formatted like this: `<[0-9]+>` and is used for 
supplying a base to 'd' 
conversions, with the default being 10. This means that '%x', '%o' and '%t' can 
all be replaced 
with this format: '%<16>d', '%<8>d' and '%<2>d'. You could obviously specify 
other bases to print 
in up to 36.

I'm in favor of keeping printf-style strings. For one, they are what we already 
have, so in that 
sense it's merely not changing that. Also, I am struggling to see the objective 
advantages of other
implementations, while they aren't worse, I don't see a reason to use them over 
what we alrady 
have.

Many people want more power in the format strings, but I am reluctant to 
include it for a couple 
reasons.

* Turning format specifiers into a mini-language (more than it already is) 
seems to add too much 
complexity for not enough return. In practice I have rarely seen many of the 
complex features of 
other formatting systems be used, since they are often too simplistic for many 
cases, or the 
resulting string is too complex to be clear any more. This is the issue with 
regex, but without the 
advantages that regex gives you.

* Adding more power is the perfect way to introduce undefined or unspecified 
behaviour. It forces 
the definition of further syntax rules and then limitations. Eventually you 
either end up with 
something that is so complex nobody uses it, or so ham-strung that it isn't 
worth using.

I would much rather spend time implementing common features that are likely to 
be used (centering 
for example) than obscure features that only look good in examples.

So that's my update and opinion.

--
James Miller

[1]: https://github.com/Aatch/rust-fmt
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to