May 05, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | printf takes a variable argument list as parameter. Make those variable argument lists first-class, with standardized means of manipulation, construction, and iteration. Would it be possible to make a printf that doesn't take a string as the first parameter? That is what I desire: A free-form mass of output capabilities that can apply however I wish without having to be known specifically at runtime or at compile time. One that doesn't centralize the processing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's, though it'd be nice to import printf handlers from elsewhere kinda like a module. you could call it print. It's like printf, but without the f. In place of the f, you have completely configurable output. throw in some parameterized field justification and precision control which grab hold of a value and modify how it ends up appearing, by building an internal string of it and modifying that then transmitting it on. You could have a "shuffler" structure and reshuffle order of its parameters based on some compile time switches or constants. List processing seems like the very act of iteration. Is this the glimmer of an answer to your iterator problems? Sean "Walter" <walter@digitalmars.com> wrote in message news:b944i9$1o55$1@digitaldaemon.com... > > "Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:b6jf3b$1m3r$1@digitaldaemon.com... > > I'm not so sure about that. > > > > A) printf has to parse all those format specifiers. That slows printing > > down. > > B) printf pulls in all the formatting and conversion functions even if you > > just want to do this: > > > > printf("Hello world"); > > > > Maybe in certain cases it results in smaller code, but not in every case. > > printf is the smallest code to call, although the function itself is substantial. Hence, if you have a lot of calls to printf, the savings are substantial. Me, I always thought printf should just be built in to the operating system, so every program shares one copy. |
May 05, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | const string endl = "\n"; long value = result(); print(just(right, 12)(hex(value)), " is the answer", endl); insert howevermany modifiers (such as just or hex above) here. These could be anything; they could be templates, whatever. Very extensible. Sean "Walter" <walter@digitalmars.com> wrote in message news:b944ia$1o55$2@digitaldaemon.com... > The trouble comes from if you want a %2d format, or %x format, etc., i.e. something other than the default. |
May 05, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | That would be pretty cool. Any further ideas on it? "Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:b94ebo$20n2$1@digitaldaemon.com... > printf takes a variable argument list as parameter. > > Make those variable argument lists first-class, with standardized means of manipulation, construction, and iteration. > > Would it be possible to make a printf that doesn't take a string as the first parameter? That is what I desire: A free-form mass of output capabilities that can apply however I wish without having to be known specifically at runtime or at compile time. One that doesn't centralize the > processing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's, though > it'd be nice to import printf handlers from elsewhere kinda like a module. > > you could call it print. It's like printf, but without the f. In place of > the f, you have completely configurable output. > > throw in some parameterized field justification and precision control which > grab hold of a value and modify how it ends up appearing, by building an internal string of it and modifying that then transmitting it on. > > You could have a "shuffler" structure and reshuffle order of its parameters > based on some compile time switches or constants. > > List processing seems like the very act of iteration. > > Is this the glimmer of an answer to your iterator problems? > > Sean > > > "Walter" <walter@digitalmars.com> wrote in message news:b944i9$1o55$1@digitaldaemon.com... > > > > "Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:b6jf3b$1m3r$1@digitaldaemon.com... > > > I'm not so sure about that. > > > > > > A) printf has to parse all those format specifiers. That slows printing > > > down. > > > B) printf pulls in all the formatting and conversion functions even if > you > > > just want to do this: > > > > > > printf("Hello world"); > > > > > > Maybe in certain cases it results in smaller code, but not in every > case. > > > > printf is the smallest code to call, although the function itself is substantial. Hence, if you have a lot of calls to printf, the savings are > > substantial. Me, I always thought printf should just be built in to the operating system, so every program shares one copy. > > |
May 05, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" wrote: > > printf takes a variable argument list as parameter. > > Make those variable argument lists first-class, with standardized means of manipulation, construction, and iteration. > > Would it be possible to make a printf that doesn't take a string as the first parameter? That is what I desire: A free-form mass of output capabilities that can apply however I wish without having to be known specifically at runtime or at compile time. One that doesn't centralize the processing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's, though it'd be nice to import printf handlers from elsewhere kinda like a module. > > you could call it print. It's like printf, but without the f. In place of the f, you have completely configurable output. I don't quite understand but I think that Venus does a lot of it. It contains (in the type module) a type pointer infomation structure that is used to decorate a primitive data type parameter struct TypeMethods { uint (*hash)(void *p); int (*size)(); int (*equ )(void *p1,void *p2); int (*cmp )(void *p1,void *p2); void (*swap)(void *p1,void *p2); int (*gets)(void *p1,char *buf); int (*getf)(void *p1,char *buf,int w,int d,int opt); } struct Tpi { void *pv; TypeMethods *ptm; } This is given for existing types, but you can extend this system for new types as well. This is the method how the parameter is wrappet Tpi TypeRetTpi(inout cdouble t) { Tpi ret; ret.pv=&t; ret.ptm= &cdouble_Methods; return ret; } This is the generic formated PrintLineFmt void PrintLineFmt(Tpi tpi,int w,int d,int opt) { char buf[80]; int n=(*tpi.ptm.getf)(tpi.pv,buf,w,d,opt); printf("%.*s\n",n,(char *)buf); } This is how it is made available for a single type (always a one-line wrapper that hopefully will be optimized away): void PrintLineFmt(cdouble t,int w,int d,int opt) { PrintLineFmt(TypeRetTpi(t),w,d,opt); } This is the current cdouble getf Function int cdouble_getf(cdouble *p,char *buf,int w,int d,int opt) { return sprintf(buf,"%*.*f + %*.*fi",w,d,(*p).re,w,d,(*p).im); } that does the work. The opt parameter is for extensions. If you want to change how cdouble prints, just do a int my_cdouble_getf(cdouble *p,char *buf,int w,int d,int opt) { return sprintf(buf,"(%*.*f %*.*f)",w,d,(*p).re,w,d,(*p).im); } cdouble_Methods.getf=my_cdouble_getf; If you want to add a new type: - provide or select the methods into mytype_Methods - copy/change to TypeRetTpi(inout mytype t) - add the interface functions one-liners (Print, StrCat) I've tried to make this efficient. There is no object construction needed and the wrapping function should be optimized away. -- Helmut Leitner leitner@hls.via.at Graz, Austria www.hls-software.com |
May 05, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:b94ejo$20rf$1@digitaldaemon.com... > const string endl = "\n"; > long value = result(); > print(just(right, 12)(hex(value)), " is the answer", endl); > > insert howevermany modifiers (such as just or hex above) here. These could > be anything; they could be templates, whatever. Very extensible. True, but I think you'll find that a lot of bloat is generated in the calls. |
May 05, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | Walter wrote:
> ... Me, I always thought printf should just be built in to the
> operating system, so every program shares one copy.
Microsoft compilers, as well as LCC-Win32 and MingW32 make use of this one:
MSVCRT.DLL
:>
-i.
|
May 06, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | So you'd get: mov ebx, [value] lea eax, [esp+4] mov [eax], right mov [eax+4], 12 mov [eax+8], ebx push eax call print_just_int push offset string call print_str push offset endl call print_endl instead of: push offset formatstring // "%+12x%s%c" push 3 // #parms mov ebx, value push ebx push offset string push 10 call printf It's not so bad. I can come up with examples that bend the results in favor of streams, too, if you'd like. It's pretty much the equivalent of using puts/putc instead of printf, except we have to write our own conversion from int/float to string in that case. If you write one humongous printf, it's going to replace quite a few calls to individual print functions. What you're missing is that all those calls are made up for by the gargantuan implementation of printf itself, hidden away in the library. If you have a huge program consisting of mostly printf's, and are optimizing for size, printf is likely a win. If your program deals with very little I/O, or if that I/O needs lots of speed, streams would probably be the better choice. Sean "Walter" <walter@digitalmars.com> wrote in message news:b967p2$mml$1@digitaldaemon.com... > > "Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:b94ejo$20rf$1@digitaldaemon.com... > > const string endl = "\n"; > > long value = result(); > > print(just(right, 12)(hex(value)), " is the answer", endl); > > > > insert howevermany modifiers (such as just or hex above) here. These > could > > be anything; they could be templates, whatever. Very extensible. > > True, but I think you'll find that a lot of bloat is generated in the calls. > > |
May 06, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Helmut Leitner | So I have to provide all those functions (including gets?) just to get something to print out? It seems a bit cumbersome. This might get a bit better once D's builtin typeinfo's improve. The fact that you have to override both Print and StrCat indicates that something is amiss in the design. What about fprintf? What if I want to print into a stream or i/o device of my own design? What if I want to print into a socket or mailslot or named pipe? How do I do all that without having a proliferation of functions? Your wrappers may be efficient, but they're still wrapping sprintf, which is a very weighty function. C++ iostreams got it right. They totally separate the stream buffer/device from the stream formatting/insertion/extraction. That way is so much more flexible. Sean "Helmut Leitner" <helmut.leitner@chello.at> wrote in message news:3EB5FF0C.A10643E2@chello.at... > > > "Sean L. Palmer" wrote: > > > > printf takes a variable argument list as parameter. > > > > Make those variable argument lists first-class, with standardized means of > > manipulation, construction, and iteration. > > > > Would it be possible to make a printf that doesn't take a string as the first parameter? That is what I desire: A free-form mass of output capabilities that can apply however I wish without having to be known specifically at runtime or at compile time. One that doesn't centralize the > > processing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's, though > > it'd be nice to import printf handlers from elsewhere kinda like a module. > > > > you could call it print. It's like printf, but without the f. In place of > > the f, you have completely configurable output. > > I don't quite understand but I think that Venus does a lot of it. > > It contains (in the type module) a type pointer infomation structure that is used to decorate a primitive data type parameter > > struct TypeMethods { > uint (*hash)(void *p); > int (*size)(); > int (*equ )(void *p1,void *p2); > int (*cmp )(void *p1,void *p2); > void (*swap)(void *p1,void *p2); > int (*gets)(void *p1,char *buf); > int (*getf)(void *p1,char *buf,int w,int d,int opt); > } > > struct Tpi { > void *pv; > TypeMethods *ptm; > } > > This is given for existing types, but you can extend this system for new types as well. > > This is the method how the parameter is wrappet > > Tpi TypeRetTpi(inout cdouble t) { > Tpi ret; > ret.pv=&t; > ret.ptm= &cdouble_Methods; > return ret; > } > > This is the generic formated PrintLineFmt > > void PrintLineFmt(Tpi tpi,int w,int d,int opt) { > char buf[80]; > int n=(*tpi.ptm.getf)(tpi.pv,buf,w,d,opt); > printf("%.*s\n",n,(char *)buf); > } > > This is how it is made available for a single type (always a one-line wrapper that > hopefully will be optimized away): > > void PrintLineFmt(cdouble t,int w,int d,int opt) { PrintLineFmt(TypeRetTpi(t),w,d,opt); } > > This is the current cdouble getf Function > > int cdouble_getf(cdouble *p,char *buf,int w,int d,int opt) > { > return sprintf(buf,"%*.*f + %*.*fi",w,d,(*p).re,w,d,(*p).im); > } > > that does the work. The opt parameter is for extensions. > > If you want to change how cdouble prints, just do a > > int my_cdouble_getf(cdouble *p,char *buf,int w,int d,int opt) > { > return sprintf(buf,"(%*.*f %*.*f)",w,d,(*p).re,w,d,(*p).im); > } > > cdouble_Methods.getf=my_cdouble_getf; > > If you want to add a new type: > - provide or select the methods into mytype_Methods > - copy/change to TypeRetTpi(inout mytype t) > - add the interface functions one-liners (Print, StrCat) > > I've tried to make this efficient. There is no object construction needed and the wrapping function should be optimized away. > > -- > Helmut Leitner leitner@hls.via.at > Graz, Austria www.hls-software.com |
May 06, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | For starters how about building variable parameter lists support into the language instead of living in <stdarg.h> They would need methods or properties to: Get the # of parameters Extract each parameter in a typesafe manner (applying automatic conversions if necessary, perhaps) Iteration seems to be the key here. The mechanism behind iteration doesn't seem important; whatever the rest of the language uses would be good. Nobody has come to a consensus about that yet? Then stop and think: Why should varargs be limited only to args? Why not make them a basic type, so they can be stored, created, manipulated kinda like an array? The difference between a variable argument list and a struct initializer is that a struct has curly braces around it, and has a name, and its fields have names. Variable parameter lists are the same thing but with parenthesis, and inferred type. It's like constructing a struct from scratch, with no predetermined layout. Blank slate. Put anything you want in there. And the fields don't have names, they only have order. In fact it's more like a block scope that can only contain data declarations, but without names. If you can declare those anywhere, and name, analyze and manipulate them anywhere, well, you have: A) Variably-typed parameters (single-argument varargs) B) Pairs/Tuples C) Lists D) Easy one-off structs, when you need a struct only once and don't want to give it a name, or give its members names. E) A lot of power If you could put other things in them besides data, such as, say, types, well then you are approaching C++ in power. Making varargs typesafe would make printf tolerable. I still wouldn't like it, but I could tolerate it. But I am not quite clear what all would be involved. I know it would require direct compiler support. Sean ----- Original Message ----- From: "Walter" <walter@digitalmars.com> Newsgroups: D Sent: Sunday, May 04, 2003 9:17 PM Subject: Re: String formatting stuff > That would be pretty cool. Any further ideas on it? > > "Sean L. Palmer" <palmer.sean@verizon.net> wrote in message news:b94ebo$20n2$1@digitaldaemon.com... > > printf takes a variable argument list as parameter. > > > > Make those variable argument lists first-class, with standardized means of > > manipulation, construction, and iteration. > > > > Would it be possible to make a printf that doesn't take a string as the first parameter? That is what I desire: A free-form mass of output capabilities that can apply however I wish without having to be known specifically at runtime or at compile time. One that doesn't centralize > the > > processing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's, > though > > it'd be nice to import printf handlers from elsewhere kinda like a module. > > > > you could call it print. It's like printf, but without the f. In place > of > > the f, you have completely configurable output. > > > > throw in some parameterized field justification and precision control > which > > grab hold of a value and modify how it ends up appearing, by building an internal string of it and modifying that then transmitting it on. > > > > You could have a "shuffler" structure and reshuffle order of its > parameters > > based on some compile time switches or constants. > > > > List processing seems like the very act of iteration. > > > > Is this the glimmer of an answer to your iterator problems? > > > > Sean |
May 06, 2003 Re: String formatting stuff | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" wrote: > > So I have to provide all those functions (including gets?) just to get something to print out? It seems a bit cumbersome. It is cumbersome. > This might get a bit > better once D's builtin typeinfo's improve. I did it because it shows why type abstraction is needed and what it has to replace. > The fact that you have to override both Print and StrCat indicates that something is amiss in the design. What about fprintf? What if I want to print into a stream or i/o device of my own design? I'm not a lover of this Java stuff. Once you start it, It's hard to get it perfectly right. Currently there is a heavy Stream class in Phobos. But to have the kind of extensibility you are looking for, a Stream should maybe be a lightweight interface. One could then have the Console as a redirectable default stream and one could implement it on any object without inheriting from the Stream class. > What if I want to print > into a socket or mailslot or named pipe? How do I do all that without > having a proliferation of functions? No, these are only meant for primitive types and they will surely be replaced by some internal mechanism sooner or later. On the other hand I can't see a difference between an ugly proliferation of functions and the typical ugly proliferation of classes and methods. > Your wrappers may be efficient, but they're still wrapping sprintf, which is a very weighty function. One could replace it by basic functions. I didn't because I would have had to write a lot of code for this. My main goal was to have a simple way to write interfaces that work with any primitive type. BTW sprintf is weighty but also efficient. If you don't ban it completely from your application you will carry its weight around. But if it's there, why not use it? > C++ iostreams got it right. They totally separate the stream buffer/device from the stream formatting/insertion/extraction. That way is so much more flexible. But this IO is very costly and adds a lot to the C++ bloat. It will be interesting to see how D can handle this. -- Helmut Leitner leitner@hls.via.at Graz, Austria www.hls-software.com |
Copyright © 1999-2021 by the D Language Foundation