www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DIP9 -- Redo toString API

reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
I just created a new D Improvement Proposal to fix the toString problem I  
brought up several posts ago.

See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9

-Steve
Nov 18 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 I just created a new D Improvement Proposal to fix the toString problem I  
 brought up several posts ago.
Thank you for writing the DIP. It looks interesting. I suggest to add an example, the implementation of toString() and writeTo() for a simple struct like this (or a class), so it's easy to compare them (code untested): struct Pair(T1, T2) { T1 first; T2 second; string toString() { return format("Pair(%s, %s)", first, second); } void writeTo(scope void delegate(in char[] data) sink, string format="") const { // code here... } } Bye, bearophile
Nov 18 2010
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 18 Nov 2010 17:43:51 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 I just created a new D Improvement Proposal to fix the toString problem  
 I
 brought up several posts ago.
Thank you for writing the DIP. It looks interesting. I suggest to add an example, the implementation of toString() and writeTo() for a simple struct like this (or a class), so it's easy to compare them (code untested): struct Pair(T1, T2) { T1 first; T2 second; string toString() { return format("Pair(%s, %s)", first, second); } void writeTo(scope void delegate(in char[] data) sink, string format="") const { // code here... } }
Will do. -Steve
Nov 19 2010
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, November 18, 2010 14:21:20 Steven Schveighoffer wrote:
 I just created a new D Improvement Proposal to fix the toString problem I
 brought up several posts ago.
 
 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
Looks good overall, but I would point out that the text claims that sink is const scope - i.e. in - but the signature that's given is only scope. I assume that you intended to make the signature use in (or an explicit const scope) instead? - Jonathan M Davis
Nov 18 2010
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 18 Nov 2010 20:18:19 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Thursday, November 18, 2010 14:21:20 Steven Schveighoffer wrote:
 I just created a new D Improvement Proposal to fix the toString problem  
 I
 brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
Looks good overall, but I would point out that the text claims that sink is const scope - i.e. in - but the signature that's given is only scope. I assume that you intended to make the signature use in (or an explicit const scope) instead?
I looked at it again, I see 'in' there, is there something I'm missing? Reiterating here: void writeTo(scope void delegate(>>> in <<< char[] data) sink, string format = null) const -Steve
Nov 19 2010
prev sibling next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Thu, 18 Nov 2010 17:21:20 -0500, Steven Schveighoffer wrote:

 I just created a new D Improvement Proposal to fix the toString problem
 I brought up several posts ago.
 
 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
I think it's best to leave out the '%' from the format string, like Don has done with BigInt. This will facilitate the use of positional parameters, in which the percent is followed by a position specifier which necessarily has to be handled at a higher level than writeTo/ toString. Example: writefln("%2$s, %1$s!", "World", "Hello"); It's not clear from the DIP whether this is what you intended, so I think it should be specified. Other than that, I think this proposal looks solid. What's cool about this, apart from the performance benefits, is that it allows custom format specifiers to be used in a seamless manner. It would be even more powerful with Tango-like format specifiers, i.e. "{...}", but I guess that ship sailed a long time ago. ("%{...}s" could be an alternative, though.) -Lars
Nov 18 2010
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Nov 2010 02:27:07 -0500, Lars T. Kyllingstad  
<public kyllingen.nospamnet> wrote:

 On Thu, 18 Nov 2010 17:21:20 -0500, Steven Schveighoffer wrote:

 I just created a new D Improvement Proposal to fix the toString problem
 I brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
I think it's best to leave out the '%' from the format string, like Don has done with BigInt. This will facilitate the use of positional parameters, in which the percent is followed by a position specifier which necessarily has to be handled at a higher level than writeTo/ toString. Example: writefln("%2$s, %1$s!", "World", "Hello"); It's not clear from the DIP whether this is what you intended, so I think it should be specified.
Yes, I was not clear on what is passed in via format specifier. It should be more clear, will fix.
 Other than that, I think this proposal looks solid.  What's cool about
 this, apart from the performance benefits, is that it allows custom
 format specifiers to be used in a seamless manner.  It would be even more
 powerful with Tango-like format specifiers, i.e. "{...}", but I guess
 that ship sailed a long time ago.  ("%{...}s" could be an alternative,
 though.)
I think it leaves room for improvement, all that is necessary is to change the grammar for format specifiers to allow some kind of bracketing, and then we can have as much custom specifier as necessary. I didn't want to pretend I was good at tweaking format grammar specs, so I left it out :) All I said was that the format specifiers should follow the rules for standard format specifiers. -Steve
Nov 19 2010
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2010-11-18 23:21, Steven Schveighoffer wrote:
 I just created a new D Improvement Proposal to fix the toString problem
 I brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9

 -Steve
Why do we have to remove toString, can't toString call writeTo and behave as it does now? -- /Jacob Carlborg
Nov 19 2010
next sibling parent reply "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
On Fri, 19 Nov 2010 10:22:29 +0100, Jacob Carlborg wrote:

 On 2010-11-18 23:21, Steven Schveighoffer wrote:
 I just created a new D Improvement Proposal to fix the toString problem
 I brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9

 -Steve
Why do we have to remove toString, can't toString call writeTo and behave as it does now?
Nobody's forcing anyone to remove toString(), the point is that Phobos just won't be using it anymore. Furthermore, std.conv.to!string() should be defined to call writeTo(), so you won't have to define both toString() and writeTo() for your types. -Lars
Nov 19 2010
parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 19-nov-10, at 11:13, Lars T. Kyllingstad wrote:

 On Fri, 19 Nov 2010 10:22:29 +0100, Jacob Carlborg wrote:

 On 2010-11-18 23:21, Steven Schveighoffer wrote:
 I just created a new D Improvement Proposal to fix the toString  
 problem
 I brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9

 -Steve
Why do we have to remove toString, can't toString call writeTo and behave as it does now?
Nobody's forcing anyone to remove toString(), the point is that Phobos just won't be using it anymore. Furthermore, std.conv.to!string() should be defined to call writeTo(), so you won't have to define both toString() and writeTo() for your types. -Lars
I think that it is a good, a breaking change, but good. having something like what I did with writeOut would minimize the hassles, because then you have a uniform way to print out a type: writeOut(sink,type,possiblyExtraArgs) that works for everything, basic types, old style objects with toString,... it is useful for generic code.
Nov 19 2010
prev sibling parent Fawzi Mohamed <fawzi gmx.ch> writes:
On 19-nov-10, at 10:22, Jacob Carlborg wrote:

 On 2010-11-18 23:21, Steven Schveighoffer wrote:
 I just created a new D Improvement Proposal to fix the toString  
 problem
 I brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9

 -Steve
Why do we have to remove toString, can't toString call writeTo and behave as it does now?
that is what I do in blip. toString by default is char[] toString(){ return collectAppender(&desc); } I called the method desc because I saw it as description of the object. and if the object implements serialization then the description if just a serialization to json format (both of those are added by mixin printOut!();
Nov 19 2010
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 18 Nov 2010 17:21:20 -0500, Steven Schveighoffer  
<schveiguy yahoo.com> wrote:

 I just created a new D Improvement Proposal to fix the toString problem  
 I brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
I've made suggested changes, please review again. Thanks -Steve
Nov 19 2010
next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 I've made suggested changes, please review again.
Good, thank you. Just a note: a DIP is a public document so it's better to encourage good idioms inside it. "null" to represent empty arrays/strings is a bad practice, so instead of this: void writeTo(scope delegate(in char[] data) sink, string format = null) const { formattedWrite(sink, "(%s, %s)", first, second); } I suggest you to write something like: void writeTo(scope delegate(in char[] data) sink, string format="") const { formattedWrite(sink, "(%s, %s)", first, second); } More info about it: http://d.puremagic.com/issues/show_bug.cgi?id=3889 Bye, bearophile
Nov 19 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Nov 2010 09:14:07 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 I've made suggested changes, please review again.
Good, thank you. Just a note: a DIP is a public document so it's better to encourage good idioms inside it. "null" to represent empty arrays/strings is a bad practice, so instead of this: void writeTo(scope delegate(in char[] data) sink, string format = null) const { formattedWrite(sink, "(%s, %s)", first, second); } I suggest you to write something like: void writeTo(scope delegate(in char[] data) sink, string format="") const { formattedWrite(sink, "(%s, %s)", first, second); }
Who said setting an array to null is bad practice? I disagree. null is a better way to represent it, because it sets both the ptr and the length to 0, while "" only sets the length to 0. char[] arr = ""; assert(arr == null); // passes assert(arr is null); // fails I'd rather use a value that also allows code like: if(format is null) { // default to decimal format = "d"; } -Steve
Nov 19 2010
parent reply bearophile <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 Who said setting an array to null is bad practice?  I disagree.  null is a  
 better way to represent it, because it sets both the ptr and the length to  
 0, while "" only sets the length to 0.
 
 char[] arr = "";
 
 assert(arr == null); // passes
 assert(arr is null); // fails
I see, I didn't know this. Bye, bearophile
Nov 19 2010
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Nov 2010 09:30:11 -0500, bearophile <bearophileHUGS lycos.com>  
wrote:

 Steven Schveighoffer:

 Who said setting an array to null is bad practice?  I disagree.  null  
 is a
 better way to represent it, because it sets both the ptr and the length  
 to
 0, while "" only sets the length to 0.

 char[] arr = "";

 assert(arr == null); // passes
 assert(arr is null); // fails
I see, I didn't know this.
BTW, the default value is not part of the function signature, if you want to in your code use = "", as long as you do the comparison correct, it should be valid. -Steve
Nov 19 2010
prev sibling next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, November 19, 2010 05:54:15 Steven Schveighoffer wrote:
 On Thu, 18 Nov 2010 17:21:20 -0500, Steven Schveighoffer
 
 <schveiguy yahoo.com> wrote:
 I just created a new D Improvement Proposal to fix the toString problem
 I brought up several posts ago.
 
 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
I've made suggested changes, please review again. Thanks
The difference between the text and the function signature still exists (the text says that sink is const scope whereas the signature just says scope), though now the example (which I don't think was there before) is another place where just scope is used, so if the text is right and the actual function signature is wrong (as opposed to the other way around), then there are two places that need to be fixed. - Jonathan M Davis
Nov 19 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 19 Nov 2010 12:51:29 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 On Friday, November 19, 2010 05:54:15 Steven Schveighoffer wrote:
 On Thu, 18 Nov 2010 17:21:20 -0500, Steven Schveighoffer

 <schveiguy yahoo.com> wrote:
 I just created a new D Improvement Proposal to fix the toString  
problem
 I brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
I've made suggested changes, please review again. Thanks
The difference between the text and the function signature still exists (the text says that sink is const scope whereas the signature just says scope),
Maybe you are confusing sink with sink's parameter, which is marked 'in'? I reworded the text to make it clearer. -Steve
Nov 19 2010
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, November 19, 2010 10:26:40 Steven Schveighoffer wrote:
 On Fri, 19 Nov 2010 12:51:29 -0500, Jonathan M Davis <jmdavisProg gmx.com>
 
 wrote:
 On Friday, November 19, 2010 05:54:15 Steven Schveighoffer wrote:
 On Thu, 18 Nov 2010 17:21:20 -0500, Steven Schveighoffer
 
 <schveiguy yahoo.com> wrote:
 I just created a new D Improvement Proposal to fix the toString
problem
 I brought up several posts ago.
 
 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
I've made suggested changes, please review again. Thanks
The difference between the text and the function signature still exists (the text says that sink is const scope whereas the signature just says scope),
Maybe you are confusing sink with sink's parameter, which is marked 'in'? I reworded the text to make it clearer.
The way I read it was that the delegate was supposed to be scope const, so if that's not the case, the original text wasn't clear enough, bu it's definitely clearer now. - Jonathan M Davis
Nov 19 2010
prev sibling parent Pillsy <pillsbury gmail.com> writes:
Steven Schveighoffer Wrote:

 On Thu, 18 Nov 2010 17:21:20 -0500, Steven Schveighoffer  
 <schveiguy yahoo.com> wrote:
 I just created a new D Improvement Proposal to fix the toString 
 problem I brought up several posts ago.
 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
 I've made suggested changes, please review again.
I like this design. Thanks for proposing it. Cheers, Pillsy
Nov 19 2010
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On Thu, 18 Nov 2010 17:21:20 -0500
"Steven Schveighoffer" <schveiguy yahoo.com> wrote:

=20
 I just created a new D Improvement Proposal to fix the toString problem I=
=20
 brought up several posts ago.
=20
 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
Hello, [Sorry for a partly personal message, but I cannot help it. At first sight,= my gut reaction in front of this proposal has been: no, nooo, NOOO!!! I wa= ited a few days because, _surely_, I was missing or misinterpreting some ba= sic point. But after several days and reads of the DIP, I still feel the sa= me and nobody seems to address the issue; so here I go. Excuse the noise if= I'm simply wrong. I feel ashamed to send that -- but let's be bold :-).] What I do not want is tostring be deprecated in any case. The proposal woul= d be OK if it introduced an _alternative_ for the cases (?) where string ou= tput efficiency is relevant. The language could/should default to writeTo i= s toString is not defined, *and* conversely default to toString if writeTo = is not defined. But in no way let down toString. Below quote of the DIP's r= elevant part. It is also, certainly, a very good idea to allow passing formatting data de= fault textual expression routines; but I fail to see why deprecating tostri= ng is necessary for that. Instead, it would certainly be a highly useful to= String parameter in numerous cases. I consider time & space efficiency for string output to be irrelevant, not = even a theoretic question. Maybe I simply have never reached points where i= t would? Have you ever stepped on a app not running correctly because toStr= ing allocates on the heap? Or is it random thoughts? First, as the proposal states, "Debug output is a common need when testing = code or logging data." Most uses of such tools are for programmer own feedb= ack -- user interface requires far more sophisticated, and in most case cus= tom, tools. Who cares how much memory or time is required? Memory is eventu= ally freed ayway, and output speed is not limited on the program side, but = well by rendering computations and/or physical limits (try to write to buff= er vs file vs terminal). Moreover, string output tasks often come last in a process chain -- that's = what a programmer waits for to get useful information on program behaviour = and be able to control, diagnose, compare... But the key point is that language features like D's toString are far to be= used only for _direct_ string output. They are extremely useful for numero= us tasks of string manipulation and processing, most of which again for pro= grammer's own use. Sometimes, at the end of process chain comes string otup= ut -- but indirectly. I have used languages in which there is no builtin support for an equivalen= t of toString, or not both for builtin and custom types. instead, one could= only writeTo, precisely. This is just pain (for me) at every corner of dev= elopper experience, from discovering the language to app maintenance, via e= xplorative development. Note there is no way to implement it by custom rout= ines in a typical static language, because it requires a high level of refl= exion; all builtin types must have it _and_ one must be able to explore the= complete description of custom types. My language of choice would be Oberon if only it included the strict minima= l programmer comfort toolkit, namely toString and a true builtin textual ty= pe. I let it down a few month ago *only* because of that -- it is a wonder= fully designed language in all other aspects, integrating the core needs fo= r modern programming in a few pages of spec -- it was simply no fun, consta= ntly. I want XXIth century programmming! ;-) [These news make me sad because I soon started to like D the language, even= its present chaotic pass, and its community as well.] Denis << The compiler will change its requirement for toString on structs. Curren= tly, if a struct defines toString, a function pointer to that function is p= laced in the {TypeInfo Struct}? member xtoString for that struct type. Sinc= e toString is no longer used, it should instead populate a new {TypeInfo St= ruct}? member xwriteTo function pointer with appropriate signature. As a path for deprecation, the compiler should populate both xtoString and = xwriteTo as defined in the struct. The runtime should use xwriteTo if defin= ed, and xtoString if not. After an appropriate time period (6 months?) the = compiler should print a message when toString is defined and writeTo is not= . Then after another appropriate time period, the compiler/runtime should s= top using toString and member xtoString altogether. Along the same lines, the default Object.writeTo should simply call toStrin= g and output the result to the sink. After an initial wait period, toString= should be deprecated, and after a transition period, toString should be re= moved, and the default writeTo should perform a similar action that the def= ault toString does now (print the object type name). Note that a cast will = be required in order for the const writeTo function to call the non-const t= oString. >> -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 21 2010
next sibling parent reply =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= <pelle.mansson gmail.com> writes:
On 11/21/2010 11:10 AM, spir wrote:
 What I do not want is tostring be deprecated in any case. The proposal would
be OK if it introduced an _alternative_ for the cases (?) where string output
efficiency is relevant. The language could/should default to writeTo is
toString is not defined, *and* conversely default to toString if writeTo is not
defined. But in no way let down toString. Below quote of the DIP's relevant
part.
 It is also, certainly, a very good idea to allow passing formatting data
default textual expression routines; but I fail to see why deprecating tostring
is necessary for that. Instead, it would certainly be a highly useful toString
parameter in numerous cases.
Instead of return "something"; write sink("something"); You lose nothing. You do, however, gain the ability to output an object without concatenating a string over and over.
 I consider time&  space efficiency for string output to be irrelevant, not
even a theoretic question. Maybe I simply have never reached points where it
would? Have you ever stepped on a app not running correctly because toString
allocates on the heap? Or is it random thoughts?
 First, as the proposal states, "Debug output is a common need when testing
code or logging data." Most uses of such tools are for programmer own feedback
-- user interface requires far more sophisticated, and in most case custom,
tools. Who cares how much memory or time is required? Memory is eventually
freed ayway, and output speed is not limited on the program side, but well by
rendering computations and/or physical limits (try to write to buffer vs file
vs terminal).
 Moreover, string output tasks often come last in a process chain -- that's
what a programmer waits for to get useful information on program behaviour and
be able to control, diagnose, compare...

 But the key point is that language features like D's toString are far to be
used only for _direct_ string output. They are extremely useful for numerous
tasks of string manipulation and processing, most of which again for
programmer's own use. Sometimes, at the end of process chain comes string
otuput -- but indirectly.
With this, it doesn't need to be. Instead of writing another function for non-debuglike string output, just use writeTo.
Nov 21 2010
parent reply spir <denis.spir gmail.com> writes:
On Sun, 21 Nov 2010 15:55:10 +0100
Pelle M=C3=A5nsson <pelle.mansson gmail.com> wrote:

 But the key point is that language features like D's toString are far t=
o be used only for _direct_ string output. They are extremely useful for nu= merous tasks of string manipulation and processing, most of which again for= programmer's own use. Sometimes, at the end of process chain comes string = otuput -- but indirectly. =20
=20
 With this, it doesn't need to be. Instead of writing another function=20
 for non-debuglike string output, just use writeTo.
No, just use toString. As said above, I don't want to writeTo, I want the s= tring; and be free to do whatever I want to with it. Being only able to wri= te is... (rather censure). Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 21 2010
next sibling parent "Nick Sabalausky" <a a.a> writes:
"spir" <denis.spir gmail.com> wrote in message 
news:mailman.532.1290349037.21107.digitalmars-d puremagic.com...
On Sun, 21 Nov 2010 15:55:10 +0100
Pelle Månsson <pelle.mansson gmail.com> wrote:

 But the key point is that language features like D's toString are far 
 to be used only for _direct_ string output. They are extremely useful 
 for numerous tasks of string manipulation and processing, most of which 
 again for programmer's own use. Sometimes, at the end of process chain 
 comes string otuput -- but indirectly.
With this, it doesn't need to be. Instead of writing another function for non-debuglike string output, just use writeTo.
No, just use toString. As said above, I don't want to writeTo, I want the string; and be free to do whatever I want to with it. Being only able to write is... (rather censure).
If you just want the string, then just use to!string(x), or format("%s", x), or anything else that implicity converts types to strings. I don't understand what the problem is.
Nov 21 2010
prev sibling parent reply =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= <pelle.mansson gmail.com> writes:
On 11/21/2010 03:17 PM, spir wrote:
 No, just use toString. As said above, I don't want to writeTo, I want the
string; and be free to do whatever I want to with it. Being only able to write
is... (rather censure).
I... don't think you understand what writeTo is supposed to do. Inside to!string, it would be something like this: string s; arg.writeTo((const(char)[] data) { s ~= data; }); return s; There, you got the string. It will even be in a function for you, so you'll never have to write that piece of code. If you ever need the string of an object, you just write to!string(obj). No functionality lost, ever, at all. However, writeln can do this: foreach (arg; args) { arg.writeTo((const(char)[] data) { outputbuffer.put(data); }) } thereby removing the need to store the string, and the extra allocations. This design is much cleaner than the current strategy, and also more flexible.
Nov 21 2010
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2010-11-21 17:28, Pelle MÃ¥nsson wrote:
 On 11/21/2010 03:17 PM, spir wrote:
 No, just use toString. As said above, I don't want to writeTo, I want
 the string; and be free to do whatever I want to with it. Being only
 able to write is... (rather censure).
I... don't think you understand what writeTo is supposed to do. Inside to!string, it would be something like this: string s; arg.writeTo((const(char)[] data) { s ~= data; }); return s;
Why can't toString do the same ?
 There, you got the string. It will even be in a function for you, so
 you'll never have to write that piece of code. If you ever need the
 string of an object, you just write to!string(obj). No functionality
 lost, ever, at all.

 However, writeln can do this:

 foreach (arg; args) {
 arg.writeTo((const(char)[] data) { outputbuffer.put(data); })
 }

 thereby removing the need to store the string, and the extra allocations.

 This design is much cleaner than the current strategy, and also more
 flexible.
-- /Jacob Carlborg
Nov 21 2010
parent =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= <pelle.mansson gmail.com> writes:
On 11/21/2010 09:37 PM, Jacob Carlborg wrote:
 Inside to!string, it would be something like this:

 string s;
 arg.writeTo((const(char)[] data) { s ~= data; });
 return s;
Why can't toString do the same ?
Because then you'd have to write it? I'm afraid I don't understand.
Nov 21 2010
prev sibling parent reply spir <denis.spir gmail.com> writes:
On Sun, 21 Nov 2010 17:28:09 +0100
Pelle M=C3=A5nsson <pelle.mansson gmail.com> wrote:

 However, writeln can do this:
=20
      foreach (arg; args) {
          arg.writeTo((const(char)[] data) { outputbuffer.put(data); })
      }
=20
 thereby removing the need to store the string, and the extra allocations.
=20
 This design is much cleaner than the current strategy, and also more=20
 flexible.
(Sorry for the irony.) "Make simple things easy." Have to write a delegate = to get feedback... to print a bit of text. (What is "hello, world!" in D?) Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 21 2010
next sibling parent =?UTF-8?B?UGVsbGUgTcOlbnNzb24=?= <pelle.mansson gmail.com> writes:
On 11/21/2010 09:49 PM, spir wrote:
 (Sorry for the irony.) "Make simple things easy." Have to write a delegate to
get feedback... to print a bit of text.
 (What is "hello, world!" in D?)
Missing the point, are we? Hello world is unchanged.
Nov 21 2010
prev sibling next sibling parent KennyTM~ <kennytm gmail.com> writes:
On Nov 22, 10 04:49, spir wrote:
 On Sun, 21 Nov 2010 17:28:09 +0100
 Pelle MÃ¥nsson<pelle.mansson gmail.com>  wrote:

 However, writeln can do this:

       foreach (arg; args) {
           arg.writeTo((const(char)[] data) { outputbuffer.put(data); })
       }

 thereby removing the need to store the string, and the extra allocations.

 This design is much cleaner than the current strategy, and also more
 flexible.
(Sorry for the irony.) "Make simple things easy." Have to write a delegate to get feedback... to print a bit of text. (What is "hello, world!" in D?) Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Can't detect irony, captain. *You* don't need to write a delegate to get the string. That lower-level facility should have been packed up in the standard library function to!string which you don't need to care. All you need is to call the simple and easy function to!string(x) 1000 times if you want to waste 1000 memory allocations to get 1000 copy of strings.
Nov 21 2010
prev sibling parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
spir wrote:
 On Sun, 21 Nov 2010 17:28:09 +0100
 Pelle M=C3=A5nsson <pelle.mansson gmail.com> wrote:
=20
 However, writeln can do this:

      foreach (arg; args) {
          arg.writeTo((const(char)[] data) { outputbuffer.put(data); })=
      }

 thereby removing the need to store the string, and the extra allocatio=
ns.
 This design is much cleaner than the current strategy, and also more=20
 flexible.
=20 (Sorry for the irony.) "Make simple things easy." Have to write a deleg=
ate to get feedback... to print a bit of text.
 (What is "hello, world!" in D?)
=20
Like others have said, the only change to user code is that you will write "to!string (x)" instead of "x.toString()" How is that less easy? Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Nov 21 2010
prev sibling next sibling parent Michel Fortin <michel.fortin michelf.com> writes:
On 2010-11-21 05:10:13 -0500, spir <denis.spir gmail.com> said:

 I consider time & space efficiency for string output to be irrelevant, not
 even a theoretic question. Maybe I simply have never reached points where i
 t would? Have you ever stepped on a app not running correctly because toStr
 ing allocates on the heap? Or is it random thoughts?
 
 First, as the proposal states, "Debug output is a common need when testing
 code or logging data." Most uses of such tools are for programmer own feedb
 ack -- user interface requires far more sophisticated, and in most case cus
 tom, tools. Who cares how much memory or time is required? Memory is eventu
 ally freed ayway, and output speed is not limited on the program side, but
 well by rendering computations and/or physical limits (try to write to buff
 er vs file vs terminal).
I felt like that at first too. I like the simplicity of toString and though that perhaps both writeTo and toString should be allowed to coexist peacefully. But then I came to this realization: toString is almost like a language feature. And as a very visible idiom, it should set the example. If you show people toString functions with a signature that force needless allocations, they're going to reproduce the pattern for other things where they shouldn't. I think toString, or rather writeTo, should be a showcase of good practice, and thus I'm in favor of deprecating toString to increase exposure to the better idiom. Is this going to startle some people? Probably. But then perhaps they'll take a closer look and understand the design has its advantages and reuse it elsewhere. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Nov 21 2010
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 21 Nov 2010 05:10:13 -0500, spir <denis.spir gmail.com> wrote:

 On Thu, 18 Nov 2010 17:21:20 -0500
 "Steven Schveighoffer" <schveiguy yahoo.com> wrote:

 I just created a new D Improvement Proposal to fix the toString problem  
 I
 brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
Hello, [Sorry for a partly personal message, but I cannot help it. At first sight, my gut reaction in front of this proposal has been: no, nooo, NOOO!!! I waited a few days because, _surely_, I was missing or misinterpreting some basic point. But after several days and reads of the DIP, I still feel the same and nobody seems to address the issue; so here I go. Excuse the noise if I'm simply wrong. I feel ashamed to send that -- but let's be bold :-).]
Thanks for the input, but you are missing several very important points: 1. toString will not be made 'illegal', you can still write toString methods and use them as you wish (writing a toString method without also writing a writeTo method will be deprecated for a time, but after that the compiler will not complain). But writeln, format, to!string, etc. will not use them. 2. toString can unequivocally be replaced anywhere you see it with to!string. There is zero loss of functionality, and the change is not unpleasant. Not only that, but almost *no* code uses toString, it is more correct to use to!string, and let to!string make the right decision. The reason is because to!string handles builtin types (which have no toString member), and custom structs without a toString member. You should never have to write a delegate to pass to writeTo directly unless you have some funky way of outputting the data, but in that case, writeTo is better for you anyways. 3. Yes, toString could support an optional formatting argument, but that is not my main concern (it is Don's and others, I'm assuming you too). My main concern is that in order to hook into writeln, format, to!string, etc, your type *must* define a function that necessarily allocates memory. writeTo not only solves that problem, but in most cases does not change the difficulty of converting objects/structs to text format (and in many cases, it simplifies the code which creates the string). -Steve
Nov 22 2010
parent spir <denis.spir gmail.com> writes:
On Mon, 22 Nov 2010 11:02:48 -0500
"Steven Schveighoffer" <schveiguy yahoo.com> wrote:

 On Sun, 21 Nov 2010 05:10:13 -0500, spir <denis.spir gmail.com> wrote:
=20
 On Thu, 18 Nov 2010 17:21:20 -0500
 "Steven Schveighoffer" <schveiguy yahoo.com> wrote:

 I just created a new D Improvement Proposal to fix the toString proble=
m =20
 I
 brought up several posts ago.

 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
Hello, [Sorry for a partly personal message, but I cannot help it. At first =20 sight, my gut reaction in front of this proposal has been: no, nooo, =20 NOOO!!! I waited a few days because, _surely_, I was missing or =20 misinterpreting some basic point. But after several days and reads of =
=20
 the DIP, I still feel the same and nobody seems to address the issue; s=
o =20
 here I go. Excuse the noise if I'm simply wrong. I feel ashamed to send=
=20
 that -- but let's be bold :-).]
=20 Thanks for the input, but you are missing several very important points: =20 1. toString will not be made 'illegal', you can still write toString =20 methods and use them as you wish (writing a toString method without also =
=20
 writing a writeTo method will be deprecated for a time, but after that th=
e =20
 compiler will not complain).  But writeln, format, to!string, etc. will =
=20
 not use them.
 2. toString can unequivocally be replaced anywhere you see it with =20
 to!string.  There is zero loss of functionality, and the change is not =20
 unpleasant.  Not only that, but almost *no* code uses toString, it is mor=
e =20
 correct to use to!string, and let to!string make the right decision.  The=
=20
 reason is because to!string handles builtin types (which have no toString=
=20
 member), and custom structs without a toString member.  You should never =
=20
 have to write a delegate to pass to writeTo directly unless you have some=
=20
 funky way of outputting the data, but in that case, writeTo is better for=
=20
 you anyways.
 3. Yes, toString could support an optional formatting argument, but that =
=20
 is not my main concern (it is Don's and others, I'm assuming you too).  M=
y =20
 main concern is that in order to hook into writeln, format, to!string, =20
 etc, your type *must* define a function that necessarily allocates =20
 memory.  writeTo not only solves that problem, but in most cases does not=
=20
 change the difficulty of converting objects/structs to text format (and i=
n =20
 many cases, it simplifies the code which creates the string).
=20
 -Steve
Right, thank you for the answer. Let us stop this discusson (I will) and wa= it for real trial when an implementation is available. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 22 2010
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday 21 November 2010 02:10:13 spir wrote:
 On Thu, 18 Nov 2010 17:21:20 -0500
 
 "Steven Schveighoffer" <schveiguy yahoo.com> wrote:
 I just created a new D Improvement Proposal to fix the toString problem I
 brought up several posts ago.
 
 See: http://prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP9
Hello, [Sorry for a partly personal message, but I cannot help it. At first sight, my gut reaction in front of this proposal has been: no, nooo, NOOO!!! I waited a few days because, _surely_, I was missing or misinterpreting some basic point. But after several days and reads of the DIP, I still feel the same and nobody seems to address the issue; so here I go. Excuse the noise if I'm simply wrong. I feel ashamed to send that -- but let's be bold :-).]
You're not really losing toString(). to!string() would use writeTo() to convert objects to strings. writeln() and writefln() would use writeTo() to convert objects to strings (with the added benefit of potentially being able to use format specifiers other than %s - such as %d and %x for BigInt). format() would do the same. You're not losing _anything_ out of the deal except that you wouldn't do obj.toString(). Instead you'd do to!string(obj). The _only_ downside to it that I see is that it's going to be offputting to people to see writeTo()'s signature in comparison to toString(), and people will initially not understand how to just get a string like you currently would with toString() (similarly to your reaction). Once you understand how to using writeTo() to get a string, it should be quite easy and straightforward and not a problem at all. The end result will be more flexible and efficient, just potentially offputting until you understand how to use it. - Jonathan M Davis
Nov 21 2010
prev sibling parent reply spir <denis.spir gmail.com> writes:
On Sun, 21 Nov 2010 03:17:57 -0800
Jonathan M Davis <jmdavisProg gmx.com> wrote:

 You're not losing _anything_ out of the deal except that you wouldn't do=
=20
 obj.toString(). Instead you'd do to!string(obj).
I'm usually not using toString(), it's supported by the language. What abou= t format("%s:%s", a,b)? Will it still call toString implicitely, or writeTo= a buffer, or what else? Anyway, I cannot see any advantage in deprecating toString() for every prog= rammer in every use case, just for hypothetical efficiency issues -- that h= ave not yet been shown in concrete cases: an app that cannot work fine beca= use of toString allocating on the heap. Let us free to use our favorite too= ls, please! Do not pretend & telling us what is best for us. The solution is simple: toString() defaults to writeTo, writeTo defaults to= toString. This also solves 2 "human" issue you evoke: that people are used= to toString and know it very well, and that writeTo looks more intimidatin= g. As said in previous post, enhancing toString with a format specifier would = be cool. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 21 2010
next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 21.11.2010 17:08, spir wrote:
 On Sun, 21 Nov 2010 03:17:57 -0800
 Jonathan M Davis<jmdavisProg gmx.com>  wrote:

 You're not losing _anything_ out of the deal except that you wouldn't do
 obj.toString(). Instead you'd do to!string(obj).
I'm usually not using toString(), it's supported by the language. What about format("%s:%s", a,b)? Will it still call toString implicitely, or writeTo a buffer, or what else?
toString is supported by the library, not the language. In fact, format may use whatever it wishes inside, as long as the net result is the same.
 Anyway, I cannot see any advantage in deprecating toString() for every
programmer in every use case, just for hypothetical efficiency issues -- that
have not yet been shown in concrete cases: an app that cannot work fine because
of toString allocating on the heap. Let us free to use our favorite tools,
please! Do not pretend&  telling us what is best for us.
As you said, you never use toString directly, why would you care if your apps just got a slight overall speed up in text I/O ? The only thing is to change the overridden method in your classes/structs, and besides your favorite toString is going to be supported for sometime. And allocating string on heap *is* an impact on performance when you want to print custom collections (and mind you, they can be quite long) in human-readable form.
 The solution is simple: toString() defaults to writeTo, writeTo defaults to
toString. This also solves 2 "human" issue you evoke: that people are used to
toString and know it very well, and that writeTo looks more intimidating.
Meaningless.
 As said in previous post, enhancing toString with a format specifier would be
cool.

 Denis
 -- -- -- -- -- -- --
 vit esse estrany ☣

 spir.wikidot.com
-- Dmitry Olshansky
Nov 21 2010
prev sibling parent reply Don <nospam nospam.com> writes:
spir wrote:
 On Sun, 21 Nov 2010 03:17:57 -0800
 Jonathan M Davis <jmdavisProg gmx.com> wrote:
 
 You're not losing _anything_ out of the deal except that you wouldn't do 
 obj.toString(). Instead you'd do to!string(obj).
I'm usually not using toString(), it's supported by the language. What about format("%s:%s", a,b)? Will it still call toString implicitely, or writeTo a buffer, or what else? Anyway, I cannot see any advantage in deprecating toString() for every programmer in every use case, just for hypothetical efficiency issues
The efficiency issues are important, but are not the primary motivation. toString() is just wrong. The idea that there is ONE AND ONLY ONE textual representation of an object, is, frankly, idiotic.
Nov 21 2010
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Don:

 The efficiency issues are important, but are not the primary motivation.
 toString() is just wrong. The idea that there is ONE AND ONLY ONE 
 textual representation of an object, is, frankly, idiotic.
To solve that the toString() may take an argument, like a formatting string or an enum, given to it by the to!() and writef(). (But I understand the idea with the sink is more efficient). Bye, bearophile
Nov 21 2010
prev sibling next sibling parent reply spir <denis.spir gmail.com> writes:
On Sun, 21 Nov 2010 18:21:48 +0100
Don <nospam nospam.com> wrote:

 spir wrote:
 On Sun, 21 Nov 2010 03:17:57 -0800
 Jonathan M Davis <jmdavisProg gmx.com> wrote:
=20
 You're not losing _anything_ out of the deal except that you wouldn't =
do=20
 obj.toString(). Instead you'd do to!string(obj).
=20 I'm usually not using toString(), it's supported by the language. What =
about format("%s:%s", a,b)? Will it still call toString implicitely, or wri= teTo a buffer, or what else?
=20
 Anyway, I cannot see any advantage in deprecating toString() for every =
programmer in every use case, just for hypothetical efficiency issues
=20
 The efficiency issues are important,
1. Please bring concrete cases of apps that do not work well because of toS= tring and would work fine just by replacing it with writeTo.=20 2. That a given %age of apps suffer of it is not enough reason for privatin= g other of their favorite tool, esp one that is anchored in everyday practi= ce. 3. Is anyone forced to use toString? Why don't people who refuse toString u= se any other tool they like better? Some argue that we don't lose anything.= .. the same applies for you. 4. If you want another default and builtin tool, why not have both? 5. 99% of "hand-made" string construction & output happen at the end of a p= rocess, before waiting for user input, or other situations where efficiency= is no more that blank word. Man, this is simply not fair.
 but are not the primary motivation.
 toString() is just wrong. The idea that there is ONE AND ONLY ONE=20
 textual representation of an object, is, frankly, idiotic.
Who argues for "ONE AND ONLY ONE textual representation"? And how does writ= eTo allow better textual diversity, anyway (aside passing format specs, whi= ch could as well fit toString)? Where is the argument? toString is so wrong that it's often the first method most users of most OO= language implement -- to ensure vivious bugs won't pass unseen -- to be ab= le to combine representations into more complete representations-- to const= ruct useful feedback about their app in general. When a type has only 2 met= hods thet're the constructor and toString. But, yes, you are right and we a= ll have been wrong for 20 years: toString is junk. Thank you for this sudde= n enlightenment. (Aside this point, I guess we all are used to build various textual represe= ntations of all kinds of objects, for various uses. The one provided by toS= tring beeing special in that it is implicitely invoked by some very handy t= ools like %s. So handy that I ) denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 21 2010
next sibling parent =?UTF-8?B?IkrDqXLDtG1lIE0uIEJlcmdlciI=?= <jeberger free.fr> writes:
spir wrote:
 On Sun, 21 Nov 2010 18:21:48 +0100
 Don <nospam nospam.com> wrote:
=20
 spir wrote:
 On Sun, 21 Nov 2010 03:17:57 -0800
 Jonathan M Davis <jmdavisProg gmx.com> wrote:

 You're not losing _anything_ out of the deal except that you wouldn'=
t do=20
 obj.toString(). Instead you'd do to!string(obj).
I'm usually not using toString(), it's supported by the language. Wha=
t about format("%s:%s", a,b)? Will it still call toString implicitely, or= writeTo a buffer, or what else?
 Anyway, I cannot see any advantage in deprecating toString() for ever=
y programmer in every use case, just for hypothetical efficiency issues
 The efficiency issues are important,
=20 1. Please bring concrete cases of apps that do not work well because of=
toString and would work fine just by replacing it with writeTo.=20 Please bring a concrete example of code that would suffer from the proposal. Jerome --=20 mailto:jeberger free.fr http://jeberger.free.fr Jabber: jeberger jabber.fr
Nov 21 2010
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
spir:

 1. Please bring concrete cases of apps that do not work well because of
toString and would work fine just by replacing it with writeTo.
writeln is already slow. To print quickly numerical genomic data in D I have had to use printf in some situations.
 4. If you want another default and builtin tool, why not have both?
Because having two ways to do something makes the language more complex.
 But, yes, you are right and we all have been wrong for 20 years: toString is
junk. Thank you for this sudden enlightenment.
Progress happens :-) Bye, bearophile
Nov 21 2010
prev sibling next sibling parent Don <nospam nospam.com> writes:
spir wrote:
 On Sun, 21 Nov 2010 18:21:48 +0100
 Don <nospam nospam.com> wrote:
 
 spir wrote:
 On Sun, 21 Nov 2010 03:17:57 -0800
 Jonathan M Davis <jmdavisProg gmx.com> wrote:

 You're not losing _anything_ out of the deal except that you wouldn't do 
 obj.toString(). Instead you'd do to!string(obj).
I'm usually not using toString(), it's supported by the language. What about format("%s:%s", a,b)? Will it still call toString implicitely, or writeTo a buffer, or what else? Anyway, I cannot see any advantage in deprecating toString() for every programmer in every use case, just for hypothetical efficiency issues
The efficiency issues are important,
1. Please bring concrete cases of apps that do not work well because of toString and would work fine just by replacing it with writeTo.
std.complex. A 3D vector. In fact, anything that involves floating point. Performance-wise, anything with a large array. Anything that calculates lazily. Etc.
 2. That a given %age of apps suffer of it is not enough reason for privating
other of their favorite tool, esp one that is anchored in everyday practice
 3. Is anyone forced to use toString? 
Yes. It's built into the type info of every struct.
 Man, this is simply not fair.
What do you think you will lose?
Nov 21 2010
prev sibling parent Daniel Gibson <metalcaedes gmail.com> writes:
spir schrieb:
 toString is so wrong that it's often the first method most users of most
 OO language implement -- to ensure vivious bugs won't pass unseen -- to
 be able to combine representations into more complete representations--
 to construct useful feedback about their app in general.
 When a type has only 2 methods thet're the constructor and toString.
So? In the future the first implemented method will be writeTo(). Sure, "void writeTo(scope void delegate(in char[] data) sink, string format) const" looks more intimidating than "string toString()", but once you've seen an example how this is to be implemented (like struct Pair from the DIP) that's not a problem anymore. "formattedWrite(sink, "blahfoo %s", foo);" is as easy as "return format("blahfoo %s", foo);" Isn't it? Cheers, - Daniel
Nov 22 2010
prev sibling next sibling parent reply =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= <just ask.me> writes:
Don <nospam nospam.com> napisa=B3(a):

 The efficiency issues are important, but are not the primary motivatio=
n.
 toString() is just wrong. The idea that there is ONE AND ONLY ONE  =
 textual representation of an object, is, frankly, idiotic.
I always thought of toString() as an aid in debugging, where having one = = and only way to print out an object makes sense. But strong words sugges= t = you see something I don't. What problems does offering choice solve? How= = and to whom would I pass my choice? -- = Tomek
Nov 21 2010
parent reply Don <nospam nospam.com> writes:
Tomek Sowiñski wrote:
 Don <nospam nospam.com> napisa³(a):
 
 The efficiency issues are important, but are not the primary motivation.
 toString() is just wrong. The idea that there is ONE AND ONLY ONE 
 textual representation of an object, is, frankly, idiotic.
I always thought of toString() as an aid in debugging, where having one and only way to print out an object makes sense.
It isn't just used in debugging. It's used for writefln. But even for debugging, it doesn't work. If I have a struct: struct Foo { Complex!(double) val; } and, for debugging purposes, I want to write 'val' to 10 decimal places. How do I do that?
 But strong words 
 suggest you see something I don't. What problems does offering choice 
 solve? How and to whom would I pass my choice?
Creating a wrapper for the simple case is trivial, once you have the more general case. The simple case doesn't need to integrated into the compiler and runtime at all. (Nor does the general case, actually, a fact which is not recognized in the DIP). I think it's actually a hack from the days before the language had templates.
Nov 22 2010
parent reply spir <denis.spir gmail.com> writes:
On Mon, 22 Nov 2010 10:14:03 +0100
Don <nospam nospam.com> wrote:

 Tomek Sowi=C5=84ski wrote:
 Don <nospam nospam.com> napisa=C5=82(a):
=20
 The efficiency issues are important, but are not the primary motivatio=
n.
 toString() is just wrong. The idea that there is ONE AND ONLY ONE=20
 textual representation of an object, is, frankly, idiotic.
=20 I always thought of toString() as an aid in debugging, where having one=
=20
 and only way to print out an object makes sense.=20
=20 It isn't just used in debugging. It's used for writefln. But even for debugging, it doesn't work. =20 If I have a struct: =20 struct Foo { Complex!(double) val; } =20 and, for debugging purposes, I want to write 'val' to 10 decimal places. How do I do that?
I agree with you. toString lacks flexibility in some (not very common but r= elevant) cases, that would be brought by an optional format specifier. I wo= uld enjoy beeing able to write this with toString, instead of a custom text= () method: struct Complex { float r,i; string text(string numberFormat=3D"%.3f") { string outFormat =3D format("%s+%sj", numberFormat,numberFormat); return format(outFormat, this.r,this.i); } } void main () { auto c =3D Complex(1.11111,3.333333333); writeln(c.text()); writeln(c.text("%.7f")); } =3D=3D> 1.111+3.333j 1.1111100+3.3333333j But, to be fair, does this have anything to do with the current <writeTo vs= toString> debate? The only actual point of said debate is efficiency. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 22 2010
next sibling parent Don <nospam nospam.com> writes:
spir wrote:
 On Mon, 22 Nov 2010 10:14:03 +0100
 Don <nospam nospam.com> wrote:
 
 Tomek Sowiński wrote:
 Don <nospam nospam.com> napisał(a):

 The efficiency issues are important, but are not the primary motivation.
 toString() is just wrong. The idea that there is ONE AND ONLY ONE 
 textual representation of an object, is, frankly, idiotic.
I always thought of toString() as an aid in debugging, where having one and only way to print out an object makes sense.
It isn't just used in debugging. It's used for writefln. But even for debugging, it doesn't work. If I have a struct: struct Foo { Complex!(double) val; } and, for debugging purposes, I want to write 'val' to 10 decimal places. How do I do that?
I agree with you. toString lacks flexibility in some (not very common but relevant) cases, that would be brought by an optional format specifier. I would enjoy beeing able to write this with toString, instead of a custom text() method: struct Complex { float r,i; string text(string numberFormat="%.3f") { string outFormat = format("%s+%sj", numberFormat,numberFormat); return format(outFormat, this.r,this.i); } } void main () { auto c = Complex(1.11111,3.333333333); writeln(c.text()); writeln(c.text("%.7f")); } ==> 1.111+3.333j 1.1111100+3.3333333j But, to be fair, does this have anything to do with the current <writeTo vs toString> debate? The only actual point of said debate is efficiency.
The debate was triggered by me saying (in Bugzilla) that BigInt would not provide a parameterless toString(), because I can't implement it. Instead, in BigInt, I provided a function: void toString( void delegate(const(char)[]) sink, string format); which solves the formatting issue, as well as the performance issue. I'm certainly open to other ways of solving the problem. But string toString(); doesn't seem adequate for the task.
Nov 22 2010
prev sibling parent so <so so.do> writes:
 toString lacks flexibility in some (not very common but relevant) cases.
That pretty much says that you don't do much of math coding/debugging. It is very common on the other side of the world. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Nov 22 2010
prev sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 21/11/2010 17:21, Don wrote:
 spir wrote:
 On Sun, 21 Nov 2010 03:17:57 -0800
 Jonathan M Davis <jmdavisProg gmx.com> wrote:

 You're not losing _anything_ out of the deal except that you wouldn't
 do obj.toString(). Instead you'd do to!string(obj).
I'm usually not using toString(), it's supported by the language. What about format("%s:%s", a,b)? Will it still call toString implicitely, or writeTo a buffer, or what else? Anyway, I cannot see any advantage in deprecating toString() for every programmer in every use case, just for hypothetical efficiency issues
The efficiency issues are important, but are not the primary motivation. toString() is just wrong. The idea that there is ONE AND ONLY ONE textual representation of an object, is, frankly, idiotic.
That idea is quite idiotic indeed, no question about it. However, that is not toString() 's idea! The point of toString (at least across languages, not D specifically) is to provide a *default* representation of a type. It doesn't preclude other representations, and if format&friends (writef, etc.), don't provide an integrated way to create/write a string using custom formats for a given object/struct, that is format's problem, it is not toString's fault. One might ask, well, is toString any use then? Yes, very much, the idea to provide a *default* representation of an object/struct is quite useful. There are many situations where one would want to print a string of an object without specifying any particular format. In fact, there are some situations where specifying a particular format would not even be possible or make sense, for example, when the code doesn't know the exact type of the underlying object/struct (and thus not know what formats are supported). Like a container printing its elements. Another example I take from Java, it doesn't apply that much to D (at least not at the moment), but still I want to point it out: toString() is used extensively by the integrated debugger in JDT to print representations of objects in views, popups, etc.. In fact, I think that coding only a default toString for a type may be more common than otherwise (coding a toString that actually uses the format specifiers). The string based format specifier is just not that common outside of numerical types. The question remains, if toString should support a format specifier or not. I think it shouldn't, if there is an alternative satisfactorily solution for numerical types and format&friends. -- Bruno Medeiros - Software Engineer
Dec 02 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 02 Dec 2010 11:31:49 -0500, Bruno Medeiros  
<brunodomedeiros+spam com.gmail> wrote:

 On 21/11/2010 17:21, Don wrote:
 spir wrote:
 On Sun, 21 Nov 2010 03:17:57 -0800
 Jonathan M Davis <jmdavisProg gmx.com> wrote:

 You're not losing _anything_ out of the deal except that you wouldn't
 do obj.toString(). Instead you'd do to!string(obj).
I'm usually not using toString(), it's supported by the language. What about format("%s:%s", a,b)? Will it still call toString implicitely, or writeTo a buffer, or what else? Anyway, I cannot see any advantage in deprecating toString() for every programmer in every use case, just for hypothetical efficiency issues
The efficiency issues are important, but are not the primary motivation. toString() is just wrong. The idea that there is ONE AND ONLY ONE textual representation of an object, is, frankly, idiotic.
That idea is quite idiotic indeed, no question about it. However, that is not toString() 's idea! The point of toString (at least across languages, not D specifically) is to provide a *default* representation of a type. It doesn't preclude other representations, and if format&friends (writef, etc.), don't provide an integrated way to create/write a string using custom formats for a given object/struct, that is format's problem, it is not toString's fault.
to!string(x) will handle what toString does now.
 In fact, I think that coding only a default toString for a type may be  
 more common than otherwise (coding a toString that actually uses the  
 format specifiers). The string based format specifier is just not that  
 common outside of numerical types.
You can ignore the format specifier if you want to. -Steve
Dec 02 2010
parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 02/12/2010 21:08, Steven Schveighoffer wrote:
 On Thu, 02 Dec 2010 11:31:49 -0500, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 On 21/11/2010 17:21, Don wrote:

 That idea is quite idiotic indeed, no question about it. However, that
 is not toString() 's idea! The point of toString (at least across
 languages, not D specifically) is to provide a *default*
 representation of a type.

 It doesn't preclude other representations, and if format&friends
 (writef, etc.), don't provide an integrated way to create/write a
 string using custom formats for a given object/struct, that is
 format's problem, it is not toString's fault.
to!string(x) will handle what toString does now.
So? What was the point here, I didn't get it.
 In fact, I think that coding only a default toString for a type may be
 more common than otherwise (coding a toString that actually uses the
 format specifiers). The string based format specifier is just not that
 common outside of numerical types.
You can ignore the format specifier if you want to. -Steve
For calling toString, yes, you can ignore it. But as for defining the toString method, not entirely, you still have to write the format parameter (", string format = null"). After that it won't hinder you in any way, it will just be unnecessary visual baggage. So the downside of having to write that extra parameter is incredibly low, it is merely aesthetic (plus the initial one-off impact of people learning what the format parameter is for). However, toString is a core part of the language, and a very common to define, and if D were to gain more mainstream usage, I worry that something like 98% (or something like that) of all toStrings would not use format, so it seems like a bit of a waste. It is not an issue I care that much about, only a little bit. -- Bruno Medeiros - Software Engineer
Dec 07 2010
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Tue, 07 Dec 2010 11:44:56 -0500, Bruno Medeiros  
<brunodomedeiros+spam com.gmail> wrote:

 On 02/12/2010 21:08, Steven Schveighoffer wrote:
 On Thu, 02 Dec 2010 11:31:49 -0500, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 On 21/11/2010 17:21, Don wrote:

 That idea is quite idiotic indeed, no question about it. However, that
 is not toString() 's idea! The point of toString (at least across
 languages, not D specifically) is to provide a *default*
 representation of a type.

 It doesn't preclude other representations, and if format&friends
 (writef, etc.), don't provide an integrated way to create/write a
 string using custom formats for a given object/struct, that is
 format's problem, it is not toString's fault.
to!string(x) will handle what toString does now.
So? What was the point here, I didn't get it.
The point is, we don't need a toString method *and* a formatted output method. The toString method is replaced by the formatted output method in the proposal (writeTo), which already contains a format specifier.
 In fact, I think that coding only a default toString for a type may be
 more common than otherwise (coding a toString that actually uses the
 format specifiers). The string based format specifier is just not that
 common outside of numerical types.
You can ignore the format specifier if you want to. -Steve
For calling toString, yes, you can ignore it. But as for defining the toString method, not entirely, you still have to write the format parameter (", string format = null"). After that it won't hinder you in any way, it will just be unnecessary visual baggage.
Yes, that is my point.
 So the downside of having to write that extra parameter is incredibly  
 low, it is merely aesthetic (plus the initial one-off impact of people  
 learning what the format parameter is for).
 However, toString is a core part of the language, and a very common to  
 define, and if D were to gain more mainstream usage, I worry that  
 something like 98% (or something like that) of all toStrings would not  
 use format, so it seems like a bit of a waste.

 It is not an issue I care that much about, only a little bit.
In the proposal, toString is removed, only writeTo would exist (which has formatting support). I guess I don't really understand what you are asking for. I interpreted your posts as requests that we don't change/deprecate toString, is that not the case? -Steve
Dec 07 2010
parent Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
On 07/12/2010 17:31, Steven Schveighoffer wrote:
 On Tue, 07 Dec 2010 11:44:56 -0500, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 On 02/12/2010 21:08, Steven Schveighoffer wrote:
 On Thu, 02 Dec 2010 11:31:49 -0500, Bruno Medeiros
 <brunodomedeiros+spam com.gmail> wrote:

 On 21/11/2010 17:21, Don wrote:

 That idea is quite idiotic indeed, no question about it. However, that
 is not toString() 's idea! The point of toString (at least across
 languages, not D specifically) is to provide a *default*
 representation of a type.

 It doesn't preclude other representations, and if format&friends
 (writef, etc.), don't provide an integrated way to create/write a
 string using custom formats for a given object/struct, that is
 format's problem, it is not toString's fault.
to!string(x) will handle what toString does now.
So? What was the point here, I didn't get it.
The point is, we don't need a toString method *and* a formatted output method. The toString method is replaced by the formatted output method in the proposal (writeTo), which already contains a format specifier.
 In fact, I think that coding only a default toString for a type may be
 more common than otherwise (coding a toString that actually uses the
 format specifiers). The string based format specifier is just not that
 common outside of numerical types.
You can ignore the format specifier if you want to. -Steve
For calling toString, yes, you can ignore it. But as for defining the toString method, not entirely, you still have to write the format parameter (", string format = null"). After that it won't hinder you in any way, it will just be unnecessary visual baggage.
Yes, that is my point.
 So the downside of having to write that extra parameter is incredibly
 low, it is merely aesthetic (plus the initial one-off impact of people
 learning what the format parameter is for).
 However, toString is a core part of the language, and a very common to
 define, and if D were to gain more mainstream usage, I worry that
 something like 98% (or something like that) of all toStrings would not
 use format, so it seems like a bit of a waste.

 It is not an issue I care that much about, only a little bit.
In the proposal, toString is removed, only writeTo would exist (which has formatting support). I guess I don't really understand what you are asking for. I interpreted your posts as requests that we don't change/deprecate toString, is that not the case? -Steve
No, that wasn't the case at all. Looking back, it's partially my fault I wasn't clear on that. I was disagreeing with Don's "The idea that there is ONE AND ONLY ONE textual representation of an object, is, frankly, idiotic" , but it wasn't to support spir's argument "I cannot see any advantage in deprecating toString()". I'm fine with D's current toString to be removed/deprecated, or made into a final method that calls writeTo (slightly prefer last alternative). Also, I kept mentioning "toString" and not "writeTo" in my posts because I started by talking generically of the string-representation mechanism across languages, not about D specifically. Actually, this brings me to another beef I have with the proposal (kinda bikeshed, but still a bit significant): the new "writeTo" method should have string somewhere in the name. So, like "writeString", or "writeStringTo", or something like that. If it's about strings, it should have string in the signature. Even more so because "writeTo" is a very generic name, it might cause a bit of confusion with socket or serialization kinds of classes. -- Bruno Medeiros - Software Engineer
Dec 14 2010