On Thu, 23 Apr 2009 19:34:38 +0400, Don <[email protected]> wrote: > Georg Wrede wrote: >> Don wrote: >>> Georg Wrede wrote: >>>> Don wrote: >>>>> Georg Wrede wrote: >>>>>> Don wrote: >>>>>>> bearophile wrote: >>>>>>>> This post is mostly for Andrei. >>>>>>>> I have played with D2 a bit; probably I'll need months to digest >>>>>>>> it and its new Phobos2. While I explore Phobos I'll probably post >>>>>>>> some comments/bugs around here. >>>>>>>> >>>>>>>> After reading this: >>>>>>>> http://blogs.msdn.com/vcblog/archive/2009/04/22/decltype-c-0x-features-in-vc10-part-3.aspx >>>>>>>> >>>>>>>> I have tried to write a toy implementation of it in D2 (not using >>>>>>>> Phobos2 yet): >>>>>>>> >>>>>>>> import std.stdio: writeln; >>>>>>>> import std.string: format; >>>>>>>> >>>>>>>> struct Watts { >>>>>> ... >>>>>> >>>>>>>> Two things to improve: >>>>>>>> 1) All structs must have a default built-in opString, a good >>>>>>>> representation can be: >>>>>>>> StructName(field_value1, field_value2, field_value1, ...). >>>>>>>> It's not a perfect textual representation, but it's WAY better >>>>>>>> than the current one (currently it shows just the struct name). >>>>>>>> (Printing the module name before the struct name is bad, most >>>>>>>> times is just noise) >>>>>>> >>>>>>> No! >>>>>>> <rant> >>>>>>> toString() is one of the most dreadful features in D. Trying to >>>>>>> slightly improve it is a waste of time -- the whole concept needs >>>>>>> to be redone. >>>>>>> It's horribly inflexible, tedious, and hugely inefficient. What >>>>>>> more could there be to hate? >>>>>>> >>>>>>> - the object being called has no context. It doesn't know what >>>>>>> format is desired, for example. >>>>>>> - you can't emulate formatting of built-in types, NOT EVEN int! >>>>>>> You can't do left-align, pad with zeros, include + sign, display >>>>>>> in hex. >>>>>>> >>>>>>> - it's got no stream concept. Every object has to create and >>>>>>> manage its own buffer, and nobody knows if anyone actually needs >>>>>>> it. >>>>>>> >>>>>>> It ought to be at least as simple as: >>>>>>> >>>>>>> struct Foo(A, B, C){ >>>>>>> A[10] a; >>>>>>> B b; >>>>>>> C c; >>>>>>> void toString(Sink sink){ >>>>>>> foreach(x; a) sink(x); >>>>>>> sink(b); >>>>>>> sink(c); >>>>>>> } >>>>>>> } >>>>>>> ... but it's not, you have to create a silly buffer to put all >>>>>>> your strings in, even if there are 200 million of them and your >>>>>>> giant string is just going to be written to a file anyway. >>>>>>> >>>>>>> I'd like to see version(debug) {} put around Object.toString(). >>>>>>> It's a deathtrap feature that's got no business being used other >>>>>>> than for debugging. >>>>>>> </rant> >>>>>> >>>>>> First of all, printing stuff "struct.toString()" style is for two >>>>>> things: >>>>>> >>>>>> o Debugging >>>>>> o Small throwaway code snippets >>>>>> >>>>>> The latter mainly being for two purposes: >>>>>> >>>>>> o Testing quick concepts, trying out library functions, etc. >>>>>> o For the newbie, when he's learning D, but not output formatting. >>>>>> >>>>>> No "Real Program" uses this, because there you typically do proper >>>>>> formatting of the output anyway, and almost never print entire >>>>>> structs or objects as such. Instead, rather the information that >>>>>> they represent. >>>>> >>>>> How about something like BigInt? Why can't you just print it out? >>>> >>>> ?? Why couldn't you? >>>> >>>> They're not stored as strings (not Janice's anyway), but I don't >>>> understand the question. >>> >>> You can write: >>> >>> int a, b; >>> a=10; b=20; >>> writefln("%d %x", a, b); >>> >>> I'd like to be able to write: >>> >>> BigInt a, b; >>> a=10; b=20; >>> writefln("%d %x", a, b); >>> >>> and have it behave exactly the same. >> Hmm. My idea was to only have writeln (and not writefln) be >> automated. (For the small/debugging purpose.) >> Andrei seems to be at this, but right now I don't know enough details >> to say anything. It seems to be an even bigger thing than what I >> suggested, and knowing he does things in a universal way, one would >> assume that if a class "wants" to be printed in some way, then maybe >> there'll be some provisions for it. >> But, things like BigInt, that really are classes or structs that have >> to be printed in a specific way, I have a hard time figuring out how to >> printe them using write_f_ln. >> One way would be to have the format specification (as in "%x") be >> somehow passed to the toString of the struct/class. Then the class >> could decide for itself how to be printed in this case. >> But even this is stretching it a bit, since some more complicated >> class/struct might need a more elaborate hint than just one letter. And >> by that time the whole thing starts to crumble, in usability issues, at >> least. >> One thing we sholuld be wary of is overdesign. BigInt is ok, but by >> the time we try to include a class called >> CompleteSimulationOfAnF1RaceCar, we're screwed. :-) I see no way to >> incorporate them into writefln or even plain writeln. Or at least, no >> *use*. > > I think it'd be reasonable to limit things to the options available for > built-in types. Outside of that, custom formatting functions make a lot > of sense. The problem is that toString() _looks_ like it emulates > built-in formatting, but it only does '%s'. So it's really beguiling. > > BTW, when passing the output to a sink, it should be possible to (say) > format your members with '%x' format, but you can't do that by > permanently altering sink: it should revert to its previous value once > you've sunk your last member. (I think this C++ iostreams got this > wrong).
I'm not sure Sink should know anything about formatting. It's up to class designer to decide what custom formatters mean - they may be *very* complex. See my other post about formatting.
