www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - writef, positional arguments, and array formatting

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
I don't want to divert anyone's attention from more important issues, 
but I'm running into a few little problems here with writef and friends.

1. Printing only some arguments

Currently writef insist on formatting all arguments, even those that 
don't have a format spec allocated. This creates problem in an app of 
mine that takes a format string as a command-line argument and 
selectively prints stuff. For example:

./kernelize --format='%1$s %2$s'

The call is:

uint id1, id2;
float value;
...
writefln(format, id1, id2, value);

I need:

12 23

But instead I get:

12 230.34

I wonder how this could be addressed. Should presence of positional 
parameters suppress the "print'em all" approach?

2. Formatting arrays

This has been an ongoing problem with formatting functions: there's no 
proper formatting for arrays beyound writing %s and formatting the 
entire array with [e0 e1 ... en]. I was thinking of improving that like 
this:

int[] a = [ 42, 1, 2 ];
writefln("%(s, )", a); // prints "42, 1, 2"

"%(" opens a spec that will be applied to each element of the array. For 
the last element, only the format part of the spec applies, not the 
trailing string (in the example above ", "). One nice thing is that the 
specs can be nested, so:

int[][] a = [ [ 42, 1, 2 ], [ 3, 4 ] ];
writefln("%((s, )\n)", a); // prints "42, 1, 2"

will print:

42, 1, 2
3, 4

that is, one subarray per line with elements separated with commas and 
spaces.

Is this something you'd use?


Andrei
Oct 09 2008
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Andrei Alexandrescu wrote:
 writefln("%((s, )\n)", a); // prints "42, 1, 2"

Cut and paste strikes again. Please ignore the comment. Andrei
Oct 09 2008
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
I don't want to divert anyone's attention from more important issues, but 
I'm running into a few little problems here with writef and friends.

 1. Printing only some arguments

 Currently writef insist on formatting all arguments, even those that don't 
 have a format spec allocated. This creates problem in an app of mine that 
 takes a format string as a command-line argument and selectively prints 
 stuff. For example:

 ./kernelize --format='%1$s %2$s'

 The call is:

 uint id1, id2;
 float value;
 ...
 writefln(format, id1, id2, value);

 I need:

 12 23

 But instead I get:

 12 230.34

 I wonder how this could be addressed. Should presence of positional 
 parameters suppress the "print'em all" approach?

It is this way in Tango AFAIK. You could write a wrapper for it (in pseudocode): writefln2(string format, ...) { x = count % in format; return writefln(format, varargs[0..x]); }
 2. Formatting arrays

 This has been an ongoing problem with formatting functions: there's no 
 proper formatting for arrays beyound writing %s and formatting the entire 
 array with [e0 e1 ... en]. I was thinking of improving that like this:

 int[] a = [ 42, 1, 2 ];
 writefln("%(s, )", a); // prints "42, 1, 2"

 "%(" opens a spec that will be applied to each element of the array. For 
 the last element, only the format part of the spec applies, not the 
 trailing string (in the example above ", "). One nice thing is that the 
 specs can be nested, so:

 int[][] a = [ [ 42, 1, 2 ], [ 3, 4 ] ];
 writefln("%((s, )\n)", a); // prints "42, 1, 2"

 will print:

 42, 1, 2
 3, 4

 that is, one subarray per line with elements separated with commas and 
 spaces.

 Is this something you'd use?

That is a very good idea! Tango is the same way, in fact, tango got ability to print arrays fairly recently. If I used Phobos, I'd certainly use it. How many times I wanted to print an array of ints as hexadecimal, but was forced to do some stupid loop thing... I'll propose something similar on Tango as well. -Steve
Oct 09 2008
prev sibling next sibling parent reply Max Samukha <samukha voliacable.com.removethis> writes:
On Thu, 09 Oct 2008 09:55:53 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

I don't want to divert anyone's attention from more important issues, 
but I'm running into a few little problems here with writef and friends.

1. Printing only some arguments

Currently writef insist on formatting all arguments, even those that 
don't have a format spec allocated. This creates problem in an app of 
mine that takes a format string as a command-line argument and 
selectively prints stuff. For example:

./kernelize --format='%1$s %2$s'

The call is:

uint id1, id2;
float value;
...
writefln(format, id1, id2, value);

I need:

12 23

But instead I get:

12 230.34

I wonder how this could be addressed. Should presence of positional 
parameters suppress the "print'em all" approach?

Positional formatting would be great. Maybe make it zero-based? Would it conflict with the '0' flag then? Or $ is enough to disambiguate? What about making %1 a shortcut for %1$s?
2. Formatting arrays

This has been an ongoing problem with formatting functions: there's no 
proper formatting for arrays beyound writing %s and formatting the 
entire array with [e0 e1 ... en]. I was thinking of improving that like 
this:

int[] a = [ 42, 1, 2 ];
writefln("%(s, )", a); // prints "42, 1, 2"

"%(" opens a spec that will be applied to each element of the array. For 
the last element, only the format part of the spec applies, not the 
trailing string (in the example above ", "). One nice thing is that the 
specs can be nested, so:

int[][] a = [ [ 42, 1, 2 ], [ 3, 4 ] ];
writefln("%((s, )\n)", a); // prints "42, 1, 2"

will print:

42, 1, 2
3, 4

that is, one subarray per line with elements separated with commas and 
spaces.

Is this something you'd use?

It is!
Andrei

Oct 09 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Max Samukha wrote:
 Positional formatting would be great. Maybe make it zero-based? Would
 it conflict with the '0' flag then? Or $ is enough to disambiguate?
 What about making %1 a shortcut for %1$s?

It's in already, just not very tested. I used the POSIX positional formatting syntax. Andrei
Oct 09 2008
parent reply Max Samukha <samukha voliacable.com.removethis> writes:
On Thu, 09 Oct 2008 10:55:34 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

Max Samukha wrote:
 Positional formatting would be great. Maybe make it zero-based? Would
 it conflict with the '0' flag then? Or $ is enough to disambiguate?
 What about making %1 a shortcut for %1$s?

It's in already, just not very tested. I used the POSIX positional formatting syntax.

Will you relieve the constraints that there must be no multiple % pointing to the same argument and positional and non-positional % must not be mixed?
Andrei

Oct 09 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
Max Samukha wrote:
 On Thu, 09 Oct 2008 10:55:34 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Max Samukha wrote:
 Positional formatting would be great. Maybe make it zero-based? Would
 it conflict with the '0' flag then? Or $ is enough to disambiguate?
 What about making %1 a shortcut for %1$s?

formatting syntax.

Will you relieve the constraints that there must be no multiple % pointing to the same argument and positional and non-positional % must not be mixed?

Those restrictions have been relaxed. Try it! Andrei
Oct 09 2008
parent Max Samukha <samukha voliacable.com.removethis> writes:
On Thu, 09 Oct 2008 11:22:50 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail erdani.org> wrote:

Max Samukha wrote:
 On Thu, 09 Oct 2008 10:55:34 -0500, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:
 
 Max Samukha wrote:
 Positional formatting would be great. Maybe make it zero-based? Would
 it conflict with the '0' flag then? Or $ is enough to disambiguate?
 What about making %1 a shortcut for %1$s?

formatting syntax.

Will you relieve the constraints that there must be no multiple % pointing to the same argument and positional and non-positional % must not be mixed?

Those restrictions have been relaxed. Try it! Andrei

Relax is the right word, thanks. Didn't know it's in the current phobos. Very nice.
Oct 09 2008
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:
 2. Formatting arrays
 This has been an ongoing problem with formatting functions: there's no 
 proper formatting for arrays beyound writing %s and formatting the 
 entire array with [e0 e1 ... en]. I was thinking of improving that like 
 this:
 int[] a = [ 42, 1, 2 ];
 writefln("%(s, )", a); // prints "42, 1, 2"
 
 "%(" opens a spec that will be applied to each element of the array. For 
 the last element, only the format part of the spec applies, not the 
 trailing string (in the example above ", "). One nice thing is that the 
 specs can be nested, so:
 
 int[][] a = [ [ 42, 1, 2 ], [ 3, 4 ] ];
 writefln("%((s, )\n)", a); // prints "42, 1, 2"
 
 will print:
 
 42, 1, 2
 3, 4

The need to format single items of an array isn't so much common, but it's common enough to be an interesting case. I may be better to reduce the complexity of your idea: you can specify just the type of the bottom level of the given _collection_, and you can't specify the separator. It's less flexible, but I think it covers most of the common situations. So the syntax becomes the following in both cases: %(s) A syntax like %(s:s) may be used to specify how to format the bottom levels of associative arrays :-) Bye, bearophile
Oct 09 2008
prev sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 I don't want to divert anyone's attention from more important issues, 
 but I'm running into a few little problems here with writef and friends.
 
 1. Printing only some arguments
 
 Currently writef insist on formatting all arguments, even those that 
 don't have a format spec allocated. This creates problem in an app of 
 mine that takes a format string as a command-line argument and 
 selectively prints stuff. For example:
 
 ./kernelize --format='%1$s %2$s'
 
 The call is:
 
 uint id1, id2;
 float value;
 ...
 writefln(format, id1, id2, value);
 
 I need:
 
 12 23
 
 But instead I get:
 
 12 230.34
 
 I wonder how this could be addressed. Should presence of positional 
 parameters suppress the "print'em all" approach?
 

Just use/add the C# (Tango) formatting scheme?
 2. Formatting arrays
 
 This has been an ongoing problem with formatting functions: there's no 
 proper formatting for arrays beyound writing %s and formatting the 
 entire array with [e0 e1 ... en]. I was thinking of improving that like 
 this:
 
 int[] a = [ 42, 1, 2 ];
 writefln("%(s, )", a); // prints "42, 1, 2"
 
 "%(" opens a spec that will be applied to each element of the array. For 
 the last element, only the format part of the spec applies, not the 
 trailing string (in the example above ", "). One nice thing is that the 
 specs can be nested, so:
 
 int[][] a = [ [ 42, 1, 2 ], [ 3, 4 ] ];
 writefln("%((s, )\n)", a); // prints "42, 1, 2"
 
 will print:
 
 42, 1, 2
 3, 4
 
 that is, one subarray per line with elements separated with commas and 
 spaces.
 
 Is this something you'd use?
 
 
 Andrei

Oct 09 2008
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 I wonder how this could be addressed. Should presence of positional 
 parameters suppress the "print'em all" approach?

Just use/add the C# (Tango) formatting scheme?

How does that work? Andrei
Oct 09 2008
next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
"Andrei Alexandrescu" wrote
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 I wonder how this could be addressed. Should presence of positional 
 parameters suppress the "print'em all" approach?

Just use/add the C# (Tango) formatting scheme?

How does that work?

eh.. I'm not sure people who like Phobos/writef would like it ;) Technically this is not an enabler for allowing preventing the 'print 'em all' approach: Stdout.formatln("{1}, {0}", "arg1", "arg2", "arg3"); prints "arg2, arg1" It's just the approach that arguments must be specified in the format string to be printed. The format of the token identifiers really isn't important here, you can use the same philosophy with %s tokens, as you said. -Steve
Oct 09 2008
prev sibling next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
Andrei Alexandrescu wrote:
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 I wonder how this could be addressed. Should presence of positional 
 parameters suppress the "print'em all" approach?

Just use/add the C# (Tango) formatting scheme?

How does that work? Andrei

May I say "RTFM"? LOL Anyway, the Tango description is in: http://www.dsource.org/projects/tango/wiki/ChapterConversions#Layoutsformatstring You can check the implementation in the source file but I don't know if you guys have resolved those, ahem, silly licensing issues yet. and C#: (in fact .NET in general) http://msdn.microsoft.com/en-us/library/26etazsy.aspx
Oct 09 2008
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 I wonder how this could be addressed. Should presence of positional 
 parameters suppress the "print'em all" approach?

Just use/add the C# (Tango) formatting scheme?

How does that work? Andrei

May I say "RTFM"? LOL

I was sure someone would mention that, but then hey, I could say the same in lieu of 90% of my posts, so I thought I can indulge this once.
 Anyway, the Tango description is in:
 
 http://www.dsource.org/projects/tango/wiki/ChapterConversions
Layoutsformatstring 
 
 
 You can check the implementation in the source file but I don't know if 
 you guys have resolved those, ahem, silly licensing issues yet.
 
 and C#: (in fact .NET in general)
 
 http://msdn.microsoft.com/en-us/library/26etazsy.aspx

Thanks! Andrei
Oct 09 2008
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
Andrei Alexandrescu wrote:
 KennyTM~ wrote:
 Andrei Alexandrescu wrote:
 I wonder how this could be addressed. Should presence of positional 
 parameters suppress the "print'em all" approach?

Just use/add the C# (Tango) formatting scheme?

How does that work?

Tango has adopted the C# formatting scheme. Googling for it will turn up a lot of links, but here's one: http://blog.stevex.net/index.php/string-formatting-in-csharp/ I don't think Tango currently supports the full formatting spec, but I believe it should. Sean
Oct 09 2008