D - String formatting stuff
- Andy Friesen (4/4) Mar 18 2003 I got this idea from boost. Seems to work pretty nicely. Comments/etc
-
Carlos Santander B.
(24/24)
Mar 19 2003
"Andy Friesen"
escribió en el mensaje - Andy Friesen (7/37) Mar 19 2003 Nope. My mistake. Change the writeBlock method to read:
- Carlos Santander B. (16/16) Mar 20 2003 | Nope. My mistake. Change the writeBlock method to read:
- Carlos Santander B. (52/52) Mar 20 2003 This might be to Walter, but is related to your console utility. I've ad...
- Andy Friesen (4/70) Mar 20 2003 It's probably buffering things. Replace the fwrite call in
-
Carlos Santander B.
(13/13)
Mar 20 2003
"Andy Friesen"
escribió en el mensaje - eluusive NOMAPSsbcglobal.net (30/74) Mar 20 2003 Does the console module have a buffer that it only prints out on deconst...
- Juarez Rudsatz (12/12) Mar 21 2003 Incredible Idea !
- Sean L. Palmer (14/26) Mar 21 2003 This is why putting the printed values after the format string isn't a g...
- eluusive NOMAPSsbclgobal.net (4/14) Mar 21 2003 Except for the fact that va_lists are not type aware.Thus the whole form...
- Walter (5/8) Apr 03 2003 anything
- Ilya Minkov (18/32) Mar 22 2003 Format string are not that bad. Consider: we are living in an
- Andy Friesen (14/34) Mar 22 2003 I was thinking about allowing some type information in the insertion
- Walter (5/14) Apr 03 2003 good
- Sean L. Palmer (10/13) Apr 04 2003 I'm not so sure about that.
- Walter (6/13) May 04 2003 printf is the smallest code to call, although the function itself is
- Sean L. Palmer (24/40) May 04 2003 printf takes a variable argument list as parameter.
- Walter (10/52) May 04 2003 That would be pretty cool. Any further ideas on it?
- Sean L. Palmer (43/79) May 05 2003 For starters how about building variable parameter lists support into th...
- Ilya Minkov (61/75) May 06 2003 I'm not sure i know what varargs are for.
- Walter (10/45) May 06 2003 Putting in types would require essentially an array of TypeInfo pointers
- Richard Krehbiel (38/152) May 07 2003 In news://news.digitalmars.com/a7d9d2$qtv$1@digitaldaemon.com I wrote up...
- Walter (3/40) May 09 2003 Some good ideas there.
- Helmut Leitner (56/72) May 04 2003 I don't quite understand but I think that Venus does a lot of it.
- Sean L. Palmer (23/95) May 05 2003 So I have to provide all those functions (including gets?) just to get
- Helmut Leitner (28/44) May 05 2003 I did it because it shows why type abstraction is needed and what
- Sean L. Palmer (57/98) May 06 2003 How about this:
-
Carlos Santander B.
(42/42)
May 06 2003
"Sean L. Palmer"
escribió en el mensaje - Sean L. Palmer (12/54) May 06 2003 x would be a special case because it's an iterator used on a varargs lis...
- Helmut Leitner (12/81) May 06 2003 I think you are absolutely right.
- Sean L. Palmer (34/112) May 06 2003 Of course, before anyone freaks out about making D more like VB, we woul...
- Ilya Minkov (30/36) May 07 2003 This rather seems a problem of partial OO in D.
- Martin M. Pedersen (16/27) May 07 2003 This is much like 'instanceof' in Nice:
- Walter (5/9) May 09 2003 buffer/device
- Ilya Minkov (5/7) May 05 2003 Microsoft compilers, as well as LCC-Win32 and MingW32 make use of this o...
- Walter (6/11) May 09 2003 one:
- Ilya Minkov (16/19) May 09 2003 And what would you call "building into an operating system"? The Windows
- Walter (15/33) May 09 2003 Good point, but there is a distinction. Operating system APIs are well
- Andy Friesen (6/11) Apr 01 2003 Updated. http://www.ikagames.com/andy/d/formatter.zip
- Achilleas Margaritis (8/19) Apr 15 2003 I had a ZX Spectrum back in 1985 and I could do a (in its embedded Basic...
- Walter (6/29) May 04 2003 Comments/etc
- Sean L. Palmer (8/10) May 04 2003 const string endl = "\n";
- Walter (4/9) May 05 2003 could
- Sean L. Palmer (36/46) May 05 2003 So you'd get:
- Walter (4/8) May 09 2003 calls
- Sean L. Palmer (13/21) May 09 2003 But then you also have sprintf and fprintf!! ;)
- Walter (10/18) May 09 2003 Those are only a few bytes each. All the printf variants call the same c...
- Sean L. Palmer (37/56) May 09 2003 core
- Andy Friesen (14/42) May 10 2003 One could always simply add a %o command, which would assume an object
-
Carlos Santander B.
(40/40)
May 10 2003
"Andy Friesen"
escribió en el mensaje - Helmut Leitner (6/16) May 10 2003 You violated one of the basic C rules: *never* use fscanf
- Sean L. Palmer (4/7) May 10 2003 What use is a function you can't use?
- Helmut Leitner (7/16) May 10 2003 Not much use. A lot of C functions are like that.
- Walter (3/4) May 14 2003 Support legacy code.
- Sean L. Palmer (4/8) May 14 2003 Good answer!
-
Carlos Santander B.
(23/23)
May 10 2003
"Helmut Leitner"
escribió en el mensaje - Walter (4/6) May 14 2003 LOL. I never use either. I always read the file in one read operation, t...
- Sean L. Palmer (7/13) May 14 2003 You get into trouble with portability if you read directly into structs....
- Walter (6/21) May 15 2003 I didn't mean that, I meant I read it into one array of bytes. Then I pa...
- Helmut Leitner (15/23) May 14 2003 That's that best way, but it's sometimes not general enough.
- Walter (15/33) May 15 2003 then
- Sean L. Palmer (15/30) May 10 2003 it
- Walter (21/62) May 14 2003 Up to a point, you're right. That point is if you write wrappers for you...
- Sean L. Palmer (43/100) May 14 2003 it
- Richard Krehbiel (14/29) May 07 2003 I've got an odd little philosophy regarding printf.
I got this idea from boost. Seems to work pretty nicely. Comments/etc welcome. Console.io.write(format("String: '{%}' {%} + {%} = {%}") % "A string!" % 5 % 3 % (5+3));
Mar 18 2003
"Andy Friesen" <andy ikagames.com> escribió en el mensaje news:b58o2e$1rbj$1 digitaldaemon.com... | I got this idea from boost. Seems to work pretty nicely. Comments/etc | welcome. | | Console.io.write(format("String: '{%}' {%} + {%} = {%}") % "A string!" % | 5 % 3 % (5+3)); | I liked it a lot. I created console.lib merging your file with some routines I created a while ago for handling a text console (color, clrscr, etc... incomplete, though). I also added a write (char[] str) function for ConsoleStream. Anyway, I think there's some sort of mistake with the writeString(char[]) function, because if I do this: Console.io.write("Hello, "); Console.io.write("world"); I get two lines instead of just one. Since writeString is from stream (I assume), I think it's not your mistake. Well, I just thought I should let you all guys know this. ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.463 / Virus Database: 262 - Release Date: 2003-03-17
Mar 19 2003
Carlos Santander B. wrote:"Andy Friesen" <andy ikagames.com> escribió en el mensaje news:b58o2e$1rbj$1 digitaldaemon.com... | I got this idea from boost. Seems to work pretty nicely. Comments/etc | welcome. | | Console.io.write(format("String: '{%}' {%} + {%} = {%}") % "A string!" % | 5 % 3 % (5+3)); | I liked it a lot. I created console.lib merging your file with some routines I created a while ago for handling a text console (color, clrscr, etc... incomplete, though). I also added a write (char[] str) function for ConsoleStream. Anyway, I think there's some sort of mistake with the writeString(char[]) function, because if I do this: Console.io.write("Hello, "); Console.io.write("world"); I get two lines instead of just one. Since writeString is from stream (I assume), I think it's not your mistake. Well, I just thought I should let you all guys know this. ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.463 / Virus Database: 262 - Release Date: 2003-03-17Nope. My mistake. Change the writeBlock method to read: override uint writeBlock(void* buffer, uint size) { return c.stdio.fwrite(buffer, 1, size, c.stdio.stdout); } All will be well.
Mar 19 2003
| Nope. My mistake. Change the writeBlock method to read: | | override uint writeBlock(void* buffer, uint size) | { | return c.stdio.fwrite(buffer, 1, size, c.stdio.stdout); | } | | All will be well. | Thanks ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.463 / Virus Database: 262 - Release Date: 2003-03-17
Mar 20 2003
This might be to Walter, but is related to your console utility. I've added this to Console: import console2; static void clear() { clrscr(); } static void gotoxy(int x,int y) { console2.gotoxy(x,y); } static void where (out int x,out int y) { x=wherex(); y=wherey(); } In console2 I have: void clrscr() { COORD coord; DWORD written; CONSOLE_SCREEN_BUFFER_INFO info; coord.X = 0; coord.Y = 0; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); FillConsoleOutputCharacterW (GetStdHandle(STD_OUTPUT_HANDLE), ' ', info.dwSize.X * info.dwSize.Y, coord, &written); gotoxy (1, 1); } void gotoxy(int x, int y) { COORD c; c.X = x - 1; c.Y = y - 1; SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c); } int wherex() { CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); return info.dwCursorPosition.X; } int wherey() { CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); return info.dwCursorPosition.Y - 2; } That's the intro. Now the problem. I have this: import console; void main() { Console.io.write('hello'); Console.gotoxy(2,2); Console.io.write('world'\n); } But for some odd reason, DMD first processes the gotoxy function and then both write's. I mean, it first goes to (2,2) and then prints helloworld. What's wrong? I know that sometimes C stdout/in/err behaves weird (at least it has happened to me on Linux), so that might be the reason. If that's so, is it a good enough reason to get D own's stdout/in/err? ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.463 / Virus Database: 262 - Release Date: 2003-03-17
Mar 20 2003
Carlos Santander B. wrote:This might be to Walter, but is related to your console utility. I've added this to Console: import console2; static void clear() { clrscr(); } static void gotoxy(int x,int y) { console2.gotoxy(x,y); } static void where (out int x,out int y) { x=wherex(); y=wherey(); } In console2 I have: void clrscr() { COORD coord; DWORD written; CONSOLE_SCREEN_BUFFER_INFO info; coord.X = 0; coord.Y = 0; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); FillConsoleOutputCharacterW (GetStdHandle(STD_OUTPUT_HANDLE), ' ', info.dwSize.X * info.dwSize.Y, coord, &written); gotoxy (1, 1); } void gotoxy(int x, int y) { COORD c; c.X = x - 1; c.Y = y - 1; SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c); } int wherex() { CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); return info.dwCursorPosition.X; } int wherey() { CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info); return info.dwCursorPosition.Y - 2; } That's the intro. Now the problem. I have this: import console; void main() { Console.io.write('hello'); Console.gotoxy(2,2); Console.io.write('world'\n); } But for some odd reason, DMD first processes the gotoxy function and then both write's. I mean, it first goes to (2,2) and then prints helloworld. What's wrong? I know that sometimes C stdout/in/err behaves weird (at least it has happened to me on Linux), so that might be the reason. If that's so, is it a good enough reason to get D own's stdout/in/err? ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.463 / Virus Database: 262 - Release Date: 2003-03-17It's probably buffering things. Replace the fwrite call in ConsoleStream.write with a WriteConsole call. Either that or just fflush(c.stdio.stdout) after the fwrite. Both should work.
Mar 20 2003
"Andy Friesen" <andy ikagames.com> escribió en el mensaje news:b5dmaf$2c5d$1 digitaldaemon.com... | It's probably buffering things. Replace the fwrite call in | ConsoleStream.write with a WriteConsole call. Either that or just | fflush(c.stdio.stdout) after the fwrite. Both should work. | Thanks! fflush worked. ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.463 / Virus Database: 262 - Release Date: 2003-03-17
Mar 20 2003
Does the console module have a buffer that it only prints out on deconstruction or when it gets to be a certain size? You should probably have gotoxy flush that buffer, if that's the case. In article <b5dl9s$2bgt$1 digitaldaemon.com>, Carlos Santander B. says...This might be to Walter, but is related to yourconsole utility. I've addedthis to Console: import console2; static voidclear() { clrscr(); }static void gotoxy(int x,int y) { console2.gotoxy(x,y);}static void where (out int x,out int y) { x=wherex(); y=wherey(); } Inconsole2 I have:void clrscr() { COORD coord; DWORD written;CONSOLE_SCREEN_BUFFER_INFO info;coord.X = 0; coord.Y = 0;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);FillConsoleOutputCharacterW (GetStdHandle(STD_OUTPUT_HANDLE), ' ',info.dwSize.X * info.dwSize.Y, coord, &written);gotoxy (1, 1); } voidgotoxy(int x, int y) {COORD c; c.X = x - 1; c.Y = y - 1;SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);} intwherex() {CONSOLE_SCREEN_BUFFER_INFO info;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);returninfo.dwCursorPosition.X;} int wherey() { CONSOLE_SCREEN_BUFFER_INFOinfo;GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);return info.dwCursorPosition.Y - 2;} That's the intro. Now the problem. Ihave this:import console; void main() { Console.io.write('hello');Console.gotoxy(2,2);Console.io.write('world'\n); } But for some oddreason, DMD first processes the gotoxy function and thenboth write's. I mean,it first goes to (2,2) and then prints helloworld.What's wrong? I know thatsometimes C stdout/in/err behaves weird (at leastit has happened to me onLinux), so that might be the reason. If that's so,is it a good enough reasonto get D own's stdout/in/err?------------------------- CarlosSantander--- Outgoing mail is certified Virus Free. Checked by AVGanti-virus system (http://www.grisoft.com).Version: 6.0.463 / Virus Database:262 - Release Date: 2003-03-17
Mar 20 2003
Incredible Idea ! But there are two not solved problems: 1) %5.0f -> How can I format the same type in diferent ways? - This could be easy added. 2) char[] s = 'This is not a number.'; format("I am printing a number here {%}") % s; Here appear not to be a error. But if you have many parameters, you could easily change the order, use a wrong var and another problems. The final problem is the formatting is not type safe at compile time. E.g: printf("This is a number %s", s); Some solution for this ?
Mar 21 2003
This is why putting the printed values after the format string isn't a good idea. It should be: int n=5; char[] s = "wow"; char c = '.'; char[] fmt = format("I am printing a number here ", n, " and then a string ", s, " and finally a period", c); But apparently printf rules, so why try anything else? Sean "Juarez Rudsatz" <Juarez_member pathlink.com> wrote in message news:b5fdv1$nh2$1 digitaldaemon.com...Incredible Idea ! But there are two not solved problems: 1) %5.0f -> How can I format the same type in diferent ways? - This could be easy added. 2) char[] s = 'This is not a number.'; format("I am printing a number here {%}") % s; Here appear not to be a error. But if you have many parameters, you couldeasilychange the order, use a wrong var and another problems. The final problemis theformatting is not type safe at compile time. E.g: printf("This is a number %s", s); Some solution for this ?
Mar 21 2003
Except for the fact that va_lists are not type aware.Thus the whole format string telling print what the arguements types are. I don't know of anything else in D that changes this. Or am i confused? In article <b5fm9d$u9e$1 digitaldaemon.com>, Sean L. Palmer says...This is why putting the printed values after the format string isn't a good idea. It should be: int n=5; char[] s = "wow"; char c = '.'; char[] fmt = format("I am printing a number here ", n, " and then a string ", s, " and finally a period", c); But apparently printf rules, so why try anything else? Sean
Mar 21 2003
<eluusive NOMAPSsbclgobal.net> wrote in message news:b5ftto$14es$1 digitaldaemon.com...Except for the fact that va_lists are not type aware.Thus the whole format string telling print what the arguements types are. I don't know ofanythingelse in D that changes this. Or am i confused?No, you're not confused. Variable argument lists in D work just like they do in C/C++.
Apr 03 2003
Format string are not that bad. Consider: we are living in an international world. Your format string needs not be stored in the program, it may be in the database. Different languages may have different order of words. The solution would be a formatting operator which would take a format string on the left side, and an associative array of strings at the right side. The format string would then contain parameter names, which would be then have to be contained as indizes in an assoziative array. I'm not exactly sure whether there's a convinient way to define an associative array literal in D in-line, IMO there should. If there isn't, a multiarg function can be created to take pairs of string literals and make an assoziative aray out of them. Obviously, this is even more time-consuming than simple format-string procesing. But where "time matters", Sean's format function serves much better than printf. Compile-time typechecking can not be expessed in terms of the D language and would thus requiere to be "special"... -i. Sean L. Palmer wrote:This is why putting the printed values after the format string isn't a good idea. It should be: int n=5; char[] s = "wow"; char c = '.'; char[] fmt = format("I am printing a number here ", n, " and then a string ", s, " and finally a period", c); But apparently printf rules, so why try anything else? Sean
Mar 22 2003
Ilya Minkov wrote:Format string are not that bad. Consider: we are living in an international world. Your format string needs not be stored in the program, it may be in the database. Different languages may have different order of words. The solution would be a formatting operator which would take a format string on the left side, and an associative array of strings at the right side. The format string would then contain parameter names, which would be then have to be contained as indizes in an assoziative array. I'm not exactly sure whether there's a convinient way to define an associative array literal in D in-line, IMO there should. If there isn't, a multiarg function can be created to take pairs of string literals and make an assoziative aray out of them. Obviously, this is even more time-consuming than simple format-string procesing. But where "time matters", Sean's format function serves much better than printf. Compile-time typechecking can not be expessed in terms of the D language and would thus requiere to be "special"... -i.I was thinking about allowing some type information in the insertion string, and then having the formatter throw an exception if the expected type is not given. Something like: format("Name: {%s}\tAge: {%i}\tpi: {%f3.8}") % name % age % pi; Where the %f bit is for precision. The alternative is to just copy printf's syntax, which, come to think of it, is probably better because of the familiarity factor. Compile-time checking could be done, but I doubt it's worth it. You'd have to chain methods. format("blah {%} {%}").insertString("blah").insertFloat(3.14); // ew By the way, I coded that, not Sean. :) (he added the console methods for repositioning the cursor, and colouring things) --andy
Mar 22 2003
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message news:b5fm9d$u9e$1 digitaldaemon.com...This is why putting the printed values after the format string isn't agoodidea. It should be: int n=5; char[] s = "wow"; char c = '.'; char[] fmt = format("I am printing a number here ", n, " and then a string ", s, " and finally a period", c); But apparently printf rules, so why try anything else?Why, indeed <g>. Note that printf also results in the smallest code generated.
Apr 03 2003
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. Sean "Walter" <walter digitalmars.com> wrote in message news:b6ieen$udg$3 digitaldaemon.com...But apparently printf rules, so why try anything else?Why, indeed <g>. Note that printf also results in the smallest code generated.
Apr 04 2003
"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 04 2003
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...youI'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 ifcase.just want to do this: printf("Hello world"); Maybe in certain cases it results in smaller code, but not in everyprintf 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 04 2003
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 centralizetheprocessing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's,thoughit'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 placeofthe f, you have completely configurable output. throw in some parameterized field justification and precision controlwhichgrab 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 itsparametersbased 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...printing"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 slowsareyoudown. B) printf pulls in all the formatting and conversion functions even ifcase.just want to do this: printf("Hello world"); Maybe in certain cases it results in smaller code, but not in everyprintf is the smallest code to call, although the function itself is substantial. Hence, if you have a lot of calls to printf, the savingssubstantial. Me, I always thought printf should just be built in to the operating system, so every program shares one copy.
May 04 2003
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: 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 stuffThat 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...ofprintf takes a variable argument list as parameter. Make those variable argument lists first-class, with standardized meansmodule.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 centralizetheprocessing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's,thoughit'd be nice to import printf handlers from elsewhere kinda like ayou could call it print. It's like printf, but without the f. In placeofthe f, you have completely configurable output. throw in some parameterized field justification and precision controlwhichgrab 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 itsparametersbased 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 05 2003
I'm not sure i know what varargs are for. * They requiere you to explicitly - or implicitly secify a number of parameters beforehand * They spoil the calling convention. * They are by definition error-prone. In C, you couldn't define an array right in your code, so the varargs jumped in. What you are used to looks like this: printf ("format %s %d", s, b); is it really worse than: printf ("format %s %d", [s,b]); And even if you think it is, if a function expects an array, why can't you make the compiler turn the first into the second one? It would also solve the problem of "how do i write a varargs function in an easy and elegant manner". Either it is a relative of a printf or some other array or varargs function - so it gets an array and passes it further. Or it is a completely new beast - then it simply iterates through an array with standard means. And with all that: the PASCAL-like calling convention can be maintained, with called function doing the cleanup. You might take a look at OpenGL. Yes, it *can* use varargs - but then you need to specify number of arguments explicitly. In D, where dynamic arrays are a part of the language, this is not requered any longer. DUMP VARARGS! They have *really* nothing to do in D. Instead, you can provide an alternative calling syntax for functions accepting arrays - maybe other agregates as well. I believe some new agregates could be useful, like tuples named here -- maybe even lists... Further comments are embedded... Sean L. Palmer wrote: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?Why not use an array? Varargs have never actually been for accepting different types. They are a hack, based on rudimentary C's way of handling functions without prototypes. Later, as prototypes became a requierement, a way had to be found to formalise this nonsense. Mind that you actually have to give printf *manually* all argument types in the format string?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.--- 8< -/- >8 --- That would be a tuple. :) A useful type all by itself. I can summarise the way Sather handles tuples and console io stuff later. I know it's not state-of-the-art, but i find it appropriate for the OO environment - which is what we have here. BTW, there is a problem with a function expecting a tuple - it has to know its exact type, else we're back to dealing with an array of generics.A) Variably-typed parameters (single-argument varargs)--- 8< -/- >8 --- There is a slight problem with that. It is possible in a true OO language like Sather - *everything* is a descendant of the root object, even INT and such. Note that it doesn't mean that Sather attaches a vtable to all types - it does only to those handled by reference. It also allows types handled by value, stack-allocated, which don't get a vtable ptr. They only get it when passed where an abstract object is expected - this is called boxing. :) And just like in D, abstract object defines conversion into a string. Sorry to say that, but D's OO seems like fairly half-hearted as compared to Sather.If you could put other things in them besides data, such as, say, types, well then you are approaching C++ in power.If you get an abstract object, you don't have any problem since you can inspect its type. But in D, "lightweight" data types don't get boxed. This, BTW, is also a problem with unions - that they are typeless - would also get solved by boxing.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.There *is* a typesafe varargs printf out there. Take DLI and look in its library source. It is not included in the DMD's Version of Phobos. And take a look at "generic" type. D shows its glory sides in it. But one glory side more - and it were *much* simpler. -i.
May 06 2003
Putting in types would require essentially an array of TypeInfo pointers paralleling it. "Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b97f7e$1suu$1 digitaldaemon.com...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: Extract each parameter in a typesafe manner (applying automaticconversionsif necessary, perhaps) Iteration seems to be the key here. The mechanism behind iterationdoesn'tseem 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 initializeristhat 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 predeterminedlayout.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 wanttogive 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'tlikeit, but I could tolerate it. But I am not quite clear what all would be involved. I know it would require direct compiler support.
May 06 2003
In news://news.digitalmars.com/a7d9d2$qtv$1 digitaldaemon.com I wrote up a type-safe varargs proposal: Start with the function declaration: void printf(char[], PrintfParam args...) { // Function body "type args..." is like "type args[]" but signals that the compiler should collect up the arguments into the array. "type... args" should be a synonym of "type args..." just as "type[] array" is the same as "type array[]". The body of this function treats args as if it were a regular dynamic array, because it is. When a user codes: char[] name = "Cecil"; printf("My name is %s\n", name); ..the compiler does the equivalent of this: PrintfParms[] _t; _t[0] = new PrintfParms(name); printf("My name is %s\n", _t); Rules: Each function argument must be implicitly compatible with the argument type; else, Each argument must be convertible to the argument type via the type's constructor; else, The argument's not valid and the compiler prints an error. Only the final parameter to a function can be varargs, just like C. I like this better than the universal VARIANT type that VB uses, since that way allows programmers to pass types that the function doesn't expect, and/or requires the called function to expect every type. The argument type only needs constructors for types it can deal with. You can't make a varargs function in C which is allowed to take zero arguments. But with this method, you can: void NoArgs(Type args...) could be called with no arguments, and would receive a zero-length array. "<type> args..." is implicitly compatible with "<type> args[]" and, as such, can be passed around between functions, like C's va_list can. But it's even better: you can write code to construct the a "<type> args[]", but you *can't* construct a va_list in C except by calling a varargs function. Sean L. Palmer wrote: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: 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 stuffThat 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...ofprintf takes a variable argument list as parameter. Make those variable argument lists first-class, with standardized meansmodule.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 centralizetheprocessing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's,thoughit'd be nice to import printf handlers from elsewhere kinda like ayou could call it print. It's like printf, but without the f. In placeofthe f, you have completely configurable output. throw in some parameterized field justification and precision controlwhichgrab 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 itsparametersbased 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 07 2003
Some good ideas there. "Richard Krehbiel" <rich kastle.com> wrote in message news:b9bilf$2uu6$1 digitaldaemon.com...In news://news.digitalmars.com/a7d9d2$qtv$1 digitaldaemon.com I wrote up a type-safe varargs proposal: Start with the function declaration: void printf(char[], PrintfParam args...) { // Function body "type args..." is like "type args[]" but signals that the compiler should collect up the arguments into the array. "type... args" should be a synonym of "type args..." just as "type[] array" is the same as "type array[]". The body of this function treats args as if it were a regular dynamic array, because it is. When a user codes: char[] name = "Cecil"; printf("My name is %s\n", name); ..the compiler does the equivalent of this: PrintfParms[] _t; _t[0] = new PrintfParms(name); printf("My name is %s\n", _t); Rules: Each function argument must be implicitly compatible with the argument type; else, Each argument must be convertible to the argument type via the type's constructor; else, The argument's not valid and the compiler prints an error. Only the final parameter to a function can be varargs, just like C. I like this better than the universal VARIANT type that VB uses, since that way allows programmers to pass types that the function doesn't expect, and/or requires the called function to expect every type. The argument type only needs constructors for types it can deal with. You can't make a varargs function in C which is allowed to take zero arguments. But with this method, you can: void NoArgs(Type args...) could be called with no arguments, and would receive a zero-length array. "<type> args..." is implicitly compatible with "<type> args[]" and, as such, can be passed around between functions, like C's va_list can. But it's even better: you can write code to construct the a "<type> args[]", but you *can't* construct a va_list in C except by calling a varargs function.
May 09 2003
"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 04 2003
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:ofprintf takes a variable argument list as parameter. Make those variable argument lists first-class, with standardized meansthemanipulation, 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 centralizethoughprocessing of tokens like printf does. One that is truly extensible by everybody. You wouldn't want to clutter up other peoples' printf's,module.it'd be nice to import printf handlers from elsewhere kinda like aofyou could call it print. It's like printf, but without the f. In placewrapper thatthe 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-linehopefully 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
"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
May 05 2003
How about this: If you declare a list, the compiler knows exactly what's in it because it parsed it and used type inference. But if you pass that list to a variable argument function, the compiler must supply enough type info that the function knows what's in the list. The compiler could auto-generate this parallel list of type info's. Once the function has this list, and the corresponding type info's, (which should be wrapped transparently into one structure, the variable argument list) it can iterate thru the list and dispatch based on the type info to whatever registered functions it has for the type. You could register any type (think: formatter functions) If you want real generic support you want a way to auto-register types. This is where an extension to the overloading mechanism would come in. Overload the parameters with *runtime dispatch*. That means if you call a function on a type that is unknown at compile time, it figures out what type it is at runtime and calls the appropriate functions (think: switch/call or some kind of map of function pointers). Then just by providing a global overload for "write into stream" you could get any class to be able to be written into any stream. void write(stream s, int t) { s.write(t.tostring()); } void write(stream s, string t) { s.write(t); } void write(stream s, mytype t) { s.write(t.tostring()); } void print(... args) { for(x in args) { write(consoleoutstream, x); // runtime dispatch on type of x } } int main() { print(1, "+", 2, "=", 1+2); mytype a; print("a is", a); return 1; } This is totally analogous to the way printf works, but modernized and *type safe*. And if varargs wasn't just for args, but was yet another basic type, compatible with user-defined lists, it could prove extremely useful in other situations as well. Think what you could do if you add this to the above: void write<type T> (stream s, T t) { s.write(t.tostring()); } // that's newfangled template syntax, not D. D's template scope would cause namespace lookup and overloading issues One problem might be how is the print function above (in some module A) supposed to know about write functions declared in some other module B? Overloading wouldn't work right. Oh well. Sean "Helmut Leitner" <helmut.leitner chello.at> wrote in message news:3EB74DD5.53F278D6 chello.at..."Sean L. Palmer" wrote:toSo 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 wantwhich isprint 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,froma 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 completelyyour application you will carry its weight around. But if it's there, whynotuse it?buffer/deviceC++ iostreams got it right. They totally separate the streammorefrom the stream formatting/insertion/extraction. That way is so muchflexible.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
May 06 2003
"Sean L. Palmer" <palmer.sean verizon.net> escribió en el mensaje news:b97q8f$27if$1 digitaldaemon.com... | ... | | void write(stream s, int t) { s.write(t.tostring()); } | void write(stream s, string t) { s.write(t); } | void write(stream s, mytype t) { s.write(t.tostring()); } | | void print(... args) | { | for(x in args) | { | write(consoleoutstream, x); // runtime dispatch on type of x | } | } | | ... The more I think about it, the more I like it. However (correct me if I'm wrong) x needs to be declared somewhere. And that's a problem because args could contain (following your example) int, string, or mytype. Now, how do you declare x? You can't declare it as object, because it will complain when there's an int, float, or whatever. That wouldn't be a problem if D did some boxing/unboxing a la .NET (is that so or did I mix up some terms?). I mean, if D allowed us to do: void foo(object o) { ... } ... int i; foo(i); ... Or the opposite, for instance. That would be awesome. I think there've been arguments against it before, but now we can see where it can be useful. Even more: I remember someone asking toString() for all the basic types. Well, with this, and when toString() gets implemented, you could do this: void write(stream s, object o) { s.write(o.tostring()); } And you wouldn't need to provide any other function. I don't know if all this is desirable or not, but at least I think it would be useful. Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.476 / Virus Database: 273 - Release Date: 2003-04-24
May 06 2003
x would be a special case because it's an iterator used on a varargs list; it'll have various types throughout the iteration. Pretty much any type that can show up there (that a valid overload exists for write, maybe) will get its own version of the loop body, customized for that type. Sean "Carlos Santander B." <carlos8294 msn.com> wrote in message news:b98dvl$2p4g$1 digitaldaemon.com..."Sean L. Palmer" <palmer.sean verizon.net> escribió en el mensaje news:b97q8f$27if$1 digitaldaemon.com... | ... | | void write(stream s, int t) { s.write(t.tostring()); } | void write(stream s, string t) { s.write(t); } | void write(stream s, mytype t) { s.write(t.tostring()); } | | void print(... args) | { | for(x in args) | { | write(consoleoutstream, x); // runtime dispatch on type of x | } | } | | ... The more I think about it, the more I like it. However (correct me if I'm wrong) x needs to be declared somewhere. And that's a problem because args could contain (following your example) int, string, or mytype. Now, how do you declare x? You can't declare it as object, because it will complainwhenthere's an int, float, or whatever. That wouldn't be a problem if D didsomeboxing/unboxing a la .NET (is that so or did I mix up some terms?). Imean,if D allowed us to do: void foo(object o) { ... } ... int i; foo(i); ... Or the opposite, for instance. That would be awesome. I think there'vebeenarguments against it before, but now we can see where it can be useful.Evenmore: I remember someone asking toString() for all the basic types. Well, with this, and when toString() gets implemented, you could do this: void write(stream s, object o) { s.write(o.tostring()); } And you wouldn't need to provide any other function. I don't know if all this is desirable or not, but at least I think it would be useful. ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.476 / Virus Database: 273 - Release Date: 2003-04-24
May 06 2003
I think you are absolutely right. The best of this kind is in VB (really!!!). You define a function IIRC like foo(int x,int y,ParamArray pa) and you can call it this way foo(x,y,1,"xy",-13.5) Within foo you can query the array size, you have the "Variant" type that may hold any other simple type, you can query the type of each array element and do any conversion you need... "Sean L. Palmer" wrote:How about this: If you declare a list, the compiler knows exactly what's in it because it parsed it and used type inference. But if you pass that list to a variable argument function, the compiler must supply enough type info that the function knows what's in the list. The compiler could auto-generate this parallel list of type info's. Once the function has this list, and the corresponding type info's, (which should be wrapped transparently into one structure, the variable argument list) it can iterate thru the list and dispatch based on the type info to whatever registered functions it has for the type. You could register any type (think: formatter functions) If you want real generic support you want a way to auto-register types. This is where an extension to the overloading mechanism would come in. Overload the parameters with *runtime dispatch*. That means if you call a function on a type that is unknown at compile time, it figures out what type it is at runtime and calls the appropriate functions (think: switch/call or some kind of map of function pointers). Then just by providing a global overload for "write into stream" you could get any class to be able to be written into any stream. void write(stream s, int t) { s.write(t.tostring()); } void write(stream s, string t) { s.write(t); } void write(stream s, mytype t) { s.write(t.tostring()); } void print(... args) { for(x in args) { write(consoleoutstream, x); // runtime dispatch on type of x } } int main() { print(1, "+", 2, "=", 1+2); mytype a; print("a is", a); return 1; } This is totally analogous to the way printf works, but modernized and *type safe*. And if varargs wasn't just for args, but was yet another basic type, compatible with user-defined lists, it could prove extremely useful in other situations as well. Think what you could do if you add this to the above: void write<type T> (stream s, T t) { s.write(t.tostring()); } // that's newfangled template syntax, not D. D's template scope would cause namespace lookup and overloading issues One problem might be how is the print function above (in some module A) supposed to know about write functions declared in some other module B? Overloading wouldn't work right. Oh well. Sean-- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
May 06 2003
Of course, before anyone freaks out about making D more like VB, we would not use this all the time, but only for special situations like printf or when it's useful. Not everything would be done as varargs. There'd still be actual variables and exact parameter types if you wanted. There'd still be arrays of uniform type. Just adding ordered bags of datums of mixed types, and a bit of reflection to help figure out what's in them later. I'm not sure I'd not rather have to specify: foo(x, y, (1, "xy", -13.5) ) instead. Or, foo(x, y, [1, "xy", -13.5] ) Also Variant is kind of a nice way to write "void*" but it's kinda lame because it's so final. I'd rather be able to constrain the types admitted somehow so they all have to derive off some base class or interface. list of printables, list of streamables, maybe. They don't have to be all the same type or size, and they wouldn't even really have to be references, they could be values such as structs or ints. for instance, list of numerics. Sean "Helmut Leitner" <helmut.leitner chello.at> wrote in message news:3EB7FD0A.8350CC5A chello.at...I think you are absolutely right. The best of this kind is in VB (really!!!). You define a function IIRClikefoo(int x,int y,ParamArray pa) and you can call it this way foo(x,y,1,"xy",-13.5) Within foo you can query the array size, you have the "Variant" type that may hold any other simple type, you can query the type of each arrayelementand do any conversion you need... "Sean L. Palmer" wrote:itHow about this: If you declare a list, the compiler knows exactly what's in it becausemustparsed it and used type inference. But if you pass that list to a variable argument function, the compiler(whichsupply enough type info that the function knows what's in the list. The compiler could auto-generate this parallel list of type info's. Once the function has this list, and the corresponding type info's,argumentshould be wrapped transparently into one structure, the variabletolist) it can iterate thru the list and dispatch based on the type infotime,whatever registered functions it has for the type. You could register any type (think: formatter functions) If you want real generic support you want a way to auto-register types. This is where an extension to the overloading mechanism would come in. Overload the parameters with *runtime dispatch*. That means if you call a function on a type that is unknown at compilepointers).it figures out what type it is at runtime and calls the appropriate functions (think: switch/call or some kind of map of functioncouldThen just by providing a global overload for "write into stream" you*typeget any class to be able to be written into any stream. void write(stream s, int t) { s.write(t.tostring()); } void write(stream s, string t) { s.write(t); } void write(stream s, mytype t) { s.write(t.tostring()); } void print(... args) { for(x in args) { write(consoleoutstream, x); // runtime dispatch on type of x } } int main() { print(1, "+", 2, "=", 1+2); mytype a; print("a is", a); return 1; } This is totally analogous to the way printf works, but modernized andtype,safe*. And if varargs wasn't just for args, but was yet another basicothercompatible with user-defined lists, it could prove extremely useful innamespacesituations as well. Think what you could do if you add this to the above: void write<type T> (stream s, T t) { s.write(t.tostring()); } // that's newfangled template syntax, not D. D's template scope would causelookup and overloading issues One problem might be how is the print function above (in some module A) supposed to know about write functions declared in some other module B? Overloading wouldn't work right. Oh well. Sean
May 06 2003
Sean L. Palmer wrote:I'd rather be able to constrain the types admitted somehow so they all have to derive off some base class or interface. list of printables, list of streamables, maybe. They don't have to be all the same type or size, and they wouldn't even really have to be references, they could be values such as structs or ints. for instance, list of numerics.This rather seems a problem of partial OO in D. In Sather, you could simply accept $OB and then do something like: typecase some_arg when INT then #OUT + "Got Integer: " + some_arg; when FLT then #OUT + "Got Float: " + some_arg; when $STR then #OUT + "Got String: " + some_arg; end; The typecase statement tries to cast the object to diffrent types and allows to do type-dependant actions. It may also contain an else-branch. If there is no else-branch and no match is found, an exception is rased analogous to the one the D cast would cause. Please note, that INT, FLT, and such are value types - they have value semantics and are layed on the stack, as opposed to $STR and $OB - these are abstract types and are handled by reference. Only $-types have a VTable pointer. But nontheless, value types are descendants of $OB, and thus get *boxed* whenever you pass them and a reference to a abstract type is needed. BTW, you can see that you actually don't need to know a type for printing - because $OB defines a method for string conversion, like in D for reference objects. Maybe *boxing* would be a solution. But wait, hasn't the basic printf problem been solved in the DLI version of Phobos? -i. P.S. It may also be that Sather system could use a bit more abstraction - but this would be the issue of a library and not the language. I have to check this in-depth someday.
May 07 2003
"Ilya Minkov" <midiclub 8ung.at> wrote in message news:b9brks$7sd$1 digitaldaemon.com...In Sather, you could simply accept $OB and then do something like: typecase some_arg when INT then #OUT + "Got Integer: " + some_arg; when FLT then #OUT + "Got Float: " + some_arg; when $STR then #OUT + "Got String: " + some_arg; end; The typecase statement tries to cast the object to diffrent types and allows to do type-dependant actions. It may also contain an else-branch.This is much like 'instanceof' in Nice: http://nice.sourceforge.net/safety.html In D, that could be make work like this: class A { ... } class B : A { ... } void foo(A a) { if (cast(B)a) { // in this scope, 'a' is casted to B. } } The mechanism does not seem to be fully functional in Nice yet. I don't know if it causes any problems. Regards, Martin M. Pedersen
May 07 2003
"Helmut Leitner" <helmut.leitner chello.at> wrote in message news:3EB74DD5.53F278D6 chello.at...buffer/deviceC++ iostreams got it right. They totally separate the streammorefrom the stream formatting/insertion/extraction. That way is so muchI agree. iostreams is both bloated and slow.flexible.But this IO is very costly and adds a lot to the C++ bloat.
May 09 2003
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 05 2003
"Ilya Minkov" <midiclub 8ung.at> wrote in message news:b96mc5$15eh$1 digitaldaemon.com...Walter wrote:one:... 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 thisMSVCRT.DLLThat's not really building it into the operating system, it's just making a dll out of their C runtime library. The downside of that is the usual dll-hell versioning problem.
May 09 2003
Walter wrote:That's not really building it into the operating system, it's just making a dll out of their C runtime library.And what would you call "building into an operating system"? The Windows kernel is a DLL. The whole OS is all based off DLLs.The downside of that is the usual dll-hell versioning problem.I'm not intending to start a flame on DLL hell... BUT there is definately a basic functionality which you should be able to rely upon - and it is documented somewhere. And what do you care what version of DLL it is, if it does the right stuff??? Maybe some new OS would need a new version - or could run better with it than with a program-embedded runtime? It also appears to me that the DLL versioning problems are more or less in the past - since executables now have a version signature, and installer programs are not allowed to overwrite systemwide installed libraries with older ones. I see a possibility - and it is yet a compiler writer's decision whether he makes use of it or embeds his own. That's another reason why GCC version of D would be good. -i.
May 09 2003
"Ilya Minkov" <midiclub 8ung.at> wrote in message news:b9gptd$pfu$1 digitaldaemon.com...Walter wrote:Good point, but there is a distinction. Operating system APIs are well documented and relatively language agnostic. The MSVC runtime dll is intimately connected with MSVC. Calling the printf in it may bet (and is) heavilly dependent on undocumented MSVC startup code and other characteristics in it. To successfully call printf in it essentially means you must be calling it from code compiled with VC. This is not true for operating system APIs.That's not really building it into the operating system, it's just making a dll out of their C runtime library.And what would you call "building into an operating system"? The Windows kernel is a DLL. The whole OS is all based off DLLs.runtime? The problem is the dependency of printf on the rest of the runtime system for the C compiler, which does change.The downside of that is the usual dll-hell versioning problem.I'm not intending to start a flame on DLL hell... BUT there is definately a basic functionality which you should be able to rely upon - and it is documented somewhere. And what do you care what version of DLL it is, if it does the right stuff??? Maybe some new OS would need a new version - or could run better with it than with a program-embeddedIt also appears to me that the DLL versioning problems are more or less in the past - since executables now have a version signature, and installer programs are not allowed to overwrite systemwide installed libraries with older ones.That doesn't really solve the problem, as a program may depend on the distinct behavior of an older DLL. Every time I upgrade, I pray that my apps don't break <g>.I see a possibility - and it is yet a compiler writer's decision whether he makes use of it or embeds his own. That's another reason why GCC version of D would be good.
May 09 2003
Andy Friesen wrote:I got this idea from boost. Seems to work pretty nicely. Comments/etc welcome. Console.io.write(format("String: '{%}' {%} + {%} = {%}") % "A string!" % 5 % 3 % (5+3));Updated. http://www.ikagames.com/andy/d/formatter.zip char[] isFalse = "IS FALSE WHEN PRECEDED BY ITS QUOTATION"; char[] str = new Formatter("\"{0}\" {0}. {1} + {2} = {3}") % isFalse % 5 % 3 % (5+3) % Formatter.end; As always, comments welcome.
Apr 01 2003
"Andy Friesen" <andy ikagames.com> wrote in message news:b6d82j$2qg$1 digitaldaemon.com...Andy Friesen wrote:I had a ZX Spectrum back in 1985 and I could do a (in its embedded Basic): print 1, "aaaa", 2, " The quick brown fox is ", var1 which will print: 1aaaa2 The quick brown fox is 3.5 assuming of course var1 is of type real. Why can't it be so simple ?I got this idea from boost. Seems to work pretty nicely. Comments/etc welcome. Console.io.write(format("String: '{%}' {%} + {%} = {%}") % "A string!" % 5 % 3 % (5+3));Updated. http://www.ikagames.com/andy/d/formatter.zip char[] isFalse = "IS FALSE WHEN PRECEDED BY ITS QUOTATION"; char[] str = new Formatter("\"{0}\" {0}. {1} + {2} = {3}") % isFalse % 5 % 3 % (5+3) % Formatter.end; As always, comments welcome.
Apr 15 2003
"Achilleas Margaritis" <axilmar in.gr> wrote in message news:b7h964$ub5$1 digitaldaemon.com..."Andy Friesen" <andy ikagames.com> wrote in message news:b6d82j$2qg$1 digitaldaemon.com...Comments/etcAndy Friesen wrote:I got this idea from boost. Seems to work pretty nicely.%welcome. Console.io.write(format("String: '{%}' {%} + {%} = {%}") % "A string!"The trouble comes from if you want a %2d format, or %x format, etc., i.e. something other than the default.I had a ZX Spectrum back in 1985 and I could do a (in its embedded Basic): print 1, "aaaa", 2, " The quick brown fox is ", var1 which will print: 1aaaa2 The quick brown fox is 3.5 assuming of course var1 is of type real. Why can't it be so simple ?5 % 3 % (5+3));Updated. http://www.ikagames.com/andy/d/formatter.zip char[] isFalse = "IS FALSE WHEN PRECEDED BY ITS QUOTATION"; char[] str = new Formatter("\"{0}\" {0}. {1} + {2} = {3}") % isFalse % 5 % 3 % (5+3) % Formatter.end; As always, comments welcome.
May 04 2003
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 04 2003
"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. Thesecouldbe 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
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...calls.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. Thesecouldbe anything; they could be templates, whatever. Very extensible.True, but I think you'll find that a lot of bloat is generated in the
May 05 2003
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b97dmp$1rj1$1 digitaldaemon.com...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 thosecallsare made up for by the gargantuan implementation of printf itself, hidden away in the library.printf actually isn't that large.
May 09 2003
But then you also have sprintf and fprintf!! ;) The main problems with printf are: It's not extensible It's not typesafe It's not retargetable I could care less if it generates slightly smaller code than the library which does all of the above. Code size, so long as it's reasonable, is not that big of a deal. Sean "Walter" <walter digitalmars.com> wrote in message news:b9gk4i$gsq$2 digitaldaemon.com..."Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b97dmp$1rj1$1 digitaldaemon.com...callsIf you write one humongous printf, it's going to replace quite a fewhiddento individual print functions. What you're missing is that all thosecallsare made up for by the gargantuan implementation of printf itself,away in the library.printf actually isn't that large.
May 09 2003
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b9gn26$lqj$1 digitaldaemon.com...But then you also have sprintf and fprintf!! ;)Those are only a few bytes each. All the printf variants call the same core routine.The main problems with printf are: It's not extensibleYup.It's not typesafeI've been using printf for 20 years and this just hasn't been an issue.It's not retargetableNot sure what you mean.I could care less if it generates slightly smaller code than the library which does all of the above. Code size, so long as it's reasonable, isnotthat big of a deal.That depends on who you are! If you're doing embedded systems, code size is still a big deal.
May 09 2003
"Walter" <walter digitalmars.com> wrote in message news:b9gpa1$ott$1 digitaldaemon.com..."Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b9gn26$lqj$1 digitaldaemon.com...coreBut then you also have sprintf and fprintf!! ;)Those are only a few bytes each. All the printf variants call the sameroutine.This means you can't add your own formatting commands. You can't make it handle new types.The main problems with printf are: It's not extensibleYup.Lucky you. You will admit however that it is not type safe? Personal issues aside, just a simple yes or no.It's not typesafeI've been using printf for 20 years and this just hasn't been an issue.Meaning you can't printf to anything you want. You also have to know the size of the buffer before you call, for sprintf. This is tedious. It's another aspect of not being extensible, but on the back end. You've heard me bitching about not being able to redirect printf to OutputDebugString for a while now, haven't you? I'd use fprintf if that would work, but it doesn't. And there's no way to call the printf core without going thru sprintf, which destroys any buffering possibilities because you have to preallocate enough storage to guarantee it'll be sufficient. What if sprintf runs out of room? Oh, wait, there's snprintf. If your vendor supports it. There's no such thing as smallocprintf, but I suppose someone could figure out a way to make one. C standard library designers did *not* think of every possible use ahead of time, but there's no way we can extend it properly. That doesn't seem elegant to me. That seems really sad.It's not retargetableNot sure what you mean.isI could care less if it generates slightly smaller code than the library which does all of the above. Code size, so long as it's reasonable, isnotthat big of a deal.That depends on who you are! If you're doing embedded systems, code sizestill a big deal.We've already established that typesafe printf could be had for the same number of bytes as printf would take. It would however require compiler support. My gcc compiler for PS/2 is so sloppy, it outputs 4 32-bit NOP's in a row all over the place, just because it feels like it, evidently. It's supposed to be an optimized build. With that kind of overhead who would notice a few extra parms pushed or a few extra calls? It's not like printf needs to be especially fast; it's either printing to screen (limited by human perception) or disk (limited by mechanical processes), so fprintf probably spends most of its time waiting on the OS to flush the buffers. It would seriously pay to concentrate on making a truly elegant, *usable* I/O foundation for D. Most of the work can be done by someone here, there are people willing to code I/O libraries, but some of the functionality needs to be in the language itself, and its early implementations. Sean
May 09 2003
Sean L. Palmer wrote: *snip*One could always simply add a %o command, which would assume an object reference, and use its toString method to string-ize it. voila.This means you can't add your own formatting commands. You can't make it handle new types.The main problems with printf are: It's not extensibleYup.This has kicked me in the pants a few times, most notably when I wanted to print out an integer to some log file or other, and used %s due to a brain-fart. blechIt's not typesafeI've been using printf for 20 years and this just hasn't been an issue.Lucky you. You will admit however that it is not type safe? Personal issues aside, just a simple yes or no.A sprintf derivant could be coded for D to return a char[] or wchar[]. Either that or use the stream classes; they have printf methods, and can be directed around freely.Meaning you can't printf to anything you want. You also have to know the size of the buffer before you call, for sprintf. This is tedious. It's another aspect of not being extensible, but on the back end.It's not retargetableNot sure what you mean.It would seriously pay to concentrate on making a truly elegant, *usable* I/O foundation for D. Most of the work can be done by someone here, there are people willing to code I/O libraries, but some of the functionality needs to be in the language itself, and its early implementations.I rather like the monad solution, using self-reference-returning methods (or overloaded operators) to specify the data to be formatted. I'm not sure if this is the cause of C++ streams' purported bloat; if it's not, then I'm fresh out of reasons not to do it this way. :)
May 10 2003
"Andy Friesen" <andy ikagames.com> escribió en el mensaje news:b9i862$23u0$1 digitaldaemon.com... | ... | This has kicked me in the pants a few times, most notably when I wanted | to print out an integer to some log file or other, and used %s due to a | brain-fart. blech | ... I had a similar problem too (but with fscanf). Last year I was making a university project in VC++. I had to read some nodes from a text file, but at the beginning of the file I had how many nodes were. I accidently wrote fscanf(file,"%s",&count) and continued like that. I was one day from the dead-line and my program: 1) didn't work properly, and 2) took 10 minutes to load! If I ran it twice, I got a "low virtual memory" message. The program used MapObjects to load an AutoCad drawing, so I thought that could be the reason. However, when I loaded the same drawing in VB, there was nothing wrong. So I checked my code, there was that fatal line. I know it's not exactly the same, but it kinda shows that, just as scanf, printf can be dangerous sometimes. ------------------------- Carlos Santander "Andy Friesen" <andy ikagames.com> escribió en el mensaje news:b9i862$23u0$1 digitaldaemon.com... | ... | This has kicked me in the pants a few times, most notably when I wanted | to print out an integer to some log file or other, and used %s due to a | brain-fart. blech | ... I had a similar problem too (but with fscanf). Last year I was making a university project in VC++. I had to read some nodes from a text file, but at the beginning of the file I had how many nodes were. I accidently wrote fscanf(file,"%s",&count) and continued like that. I was one day from the dead-line and my program: 1) didn't work properly, and 2) took 10 minutes to load! If I ran it twice, I got a "low virtual memory" message. The program used MapObjects to load an AutoCad drawing, so I thought that could be the reason. However, when I loaded the same drawing in VB, there was nothing wrong. So I checked my code, there was that fatal line. I know it's not exactly the same, but it kinda shows that, just as scanf, printf can be dangerous sometimes. ------------------------- Carlos Santander
May 10 2003
"Carlos Santander B." wrote:"Andy Friesen" <andy ikagames.com> escribió en el mensaje news:b9i862$23u0$1 digitaldaemon.com... | ... | This has kicked me in the pants a few times, most notably when I wanted | to print out an integer to some log file or other, and used %s due to a | brain-fart. blech | ... I had a similar problem too (but with fscanf)...You violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields). -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
May 10 2003
What use is a function you can't use? Sean "Helmut Leitner" <leitner hls.via.at> wrote in message news:3EBD1659.C0E8144F hls.via.at...I had a similar problem too (but with fscanf)...You violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields).
May 10 2003
"Sean L. Palmer" wrote:What use is a function you can't use?Not much use. A lot of C functions are like that. There are functions that are tremendously useful while others just don't live up to their potential."Helmut Leitner" <leitner hls.via.at> wrote in message news:3EBD1659.C0E8144F hls.via.at...-- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.comI had a similar problem too (but with fscanf)...You violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields).
May 10 2003
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b9ji54$dil$1 digitaldaemon.com...What use is a function you can't use?Support legacy code.
May 14 2003
Good answer! Sean "Walter" <walter digitalmars.com> wrote in message news:b9v38j$30qd$3 digitaldaemon.com..."Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b9ji54$dil$1 digitaldaemon.com...What use is a function you can't use?Support legacy code.
May 14 2003
"Helmut Leitner" <leitner hls.via.at> escribió en el mensaje news:3EBD1659.C0E8144F hls.via.at... | | | "Carlos Santander B." wrote: | > | > | > I had a similar problem too (but with fscanf)... | | You violated one of the basic C rules: *never* use fscanf | (use fgets, split according to separators, read the fields). | | -- | Helmut Leitner leitner hls.via.at | Graz, Austria www.hls-software.com Now I could do that, then I couldn't. I often go for the easiest way, even if they're not too good. ------------------------- Carlos Santander --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.478 / Virus Database: 275 - Release Date: 2003-05-06
May 10 2003
"Helmut Leitner" <leitner hls.via.at> wrote in message news:3EBD1659.C0E8144F hls.via.at...You violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields).LOL. I never use either. I always read the file in one read operation, then parse it.
May 14 2003
You get into trouble with portability if you read directly into structs. Be careful. And parsing takes time; we find it to be significantly impacting our game's load times. Sean "Walter" <walter digitalmars.com> wrote in message news:b9v38j$30qd$2 digitaldaemon.com..."Helmut Leitner" <leitner hls.via.at> wrote in message news:3EBD1659.C0E8144F hls.via.at...thenYou violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields).LOL. I never use either. I always read the file in one read operation,parse it.
May 14 2003
I didn't mean that, I meant I read it into one array of bytes. Then I parse or cut it up as needed. "Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b9v9kp$5op$1 digitaldaemon.com...You get into trouble with portability if you read directly into structs.Becareful. And parsing takes time; we find it to be significantlyimpactingour game's load times. Sean "Walter" <walter digitalmars.com> wrote in message news:b9v38j$30qd$2 digitaldaemon.com..."Helmut Leitner" <leitner hls.via.at> wrote in message news:3EBD1659.C0E8144F hls.via.at...thenYou violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields).LOL. I never use either. I always read the file in one read operation,parse it.
May 15 2003
Walter wrote:"Helmut Leitner" <leitner hls.via.at> wrote in message news:3EBD1659.C0E8144F hls.via.at...That's that best way, but it's sometimes not general enough. (You can't analyze Apache access logs this way, because you don't want to burden your server with e.g. 5-50 MB of RAM usage) This is a Windows / Unix issue. Unix has so efficient text file handling that you won't win a cent reading whole files. In fact using Perl it turned out to be the slower method although it is widely used as an optimization method. If you "think client" (Windwos) you don't care about memory usage, because you own your machine and any free RAM buys you nothing, but if you "think server" (Unix) any memory or resource used by one process is lost for the other users. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.comYou violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields).LOL. I never use either. I always read the file in one read operation, then parse it.
May 14 2003
"Helmut Leitner" <helmut.leitner chello.at> wrote in message news:3EC32F66.732C71E5 chello.at...Walter wrote:then"Helmut Leitner" <leitner hls.via.at> wrote in message news:3EBD1659.C0E8144F hls.via.at...You violated one of the basic C rules: *never* use fscanf (use fgets, split according to separators, read the fields).LOL. I never use either. I always read the file in one read operation,Not necessary - use memory mapped files!parse it.That's that best way, but it's sometimes not general enough. (You can't analyze Apache access logs this way, because you don't want to burden your server with e.g. 5-50 MB of RAM usage)This is a Windows / Unix issue. Unix has so efficient text file handling that you won't win a cent reading whole files. In fact using Perl it turned out to be the slower method although it is widely used as an optimization method.I can see how that can happen because if you're reading the entire file in one gulp, you cannot do any processing until the entire file is read in. If buffered, you can start working on the file while the OS anticipates you wanting the rest and reads it in. (In such cases, I'd switch to memory mapped files which brings things back to par.) In any case, I find reading the file in one operation to not only be faster, but LESS code to write and fewer errors to check for and recover from.If you "think client" (Windwos) you don't care about memory usage, because you own your machine and any free RAM buys you nothing, but if you "think server" (Unix) any memory or resource used by one process is lost for the other users.Point taken. But I'll counter that many C programs spend a lot of time allocating memory for strings parsed out of files and then copying those strings byte by byte. I just point into the file buffer. If you're clever you can avoid making any dirty pages and get some really screaming code.
May 15 2003
"Andy Friesen" <andy ikagames.com> wrote in message news:b9i862$23u0$1 digitaldaemon.com...Sean L. Palmer wrote:itThis means you can't add your own formatting commands. You can't makeBut if you convert to string first, it's less efficient than putting the characters directly into the stream. What if your object has 4K or more worth of textual representation?handle new types.One could always simply add a %o command, which would assume an object reference, and use its toString method to string-ize it. voila.theMeaning you can't printf to anything you want. You also have to knowThat's nice. I need to look at Phobos streams again.size of the buffer before you call, for sprintf. This is tedious. It's another aspect of not being extensible, but on the back end.A sprintf derivant could be coded for D to return a char[] or wchar[]. Either that or use the stream classes; they have printf methods, and can be directed around freely.I rather like the monad solution, using self-reference-returning methods (or overloaded operators) to specify the data to be formatted.Operators are great for this. They don't look as ugly and they don't require parenthesis. Visually they don't get in the way as much as a method call would.I'm not sure if this is the cause of C++ streams' purported bloat; if it's not, then I'm fresh out of reasons not to do it this way. :)Supposedly it's the individual calls to print individual things, instead of one call to print multiple things. So put your I/O in a function and call those functions multiple times. ;) Sean
May 10 2003
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b9i48s$201b$1 digitaldaemon.com...Up to a point, you're right. That point is if you write wrappers for your new types that convert them to strings, and then printf a string.This means you can't add your own formatting commands. You can't make it handle new types.The main problems with printf are: It's not extensibleYup.You are correct, it is not typesafe.Lucky you. You will admit however that it is not type safe? Personal issues aside, just a simple yes or no.It's not typesafeI've been using printf for 20 years and this just hasn't been an issue.Check out outbuffer.printf. I believe it handilly resolves that issue, which is a nuisance problem.Meaning you can't printf to anything you want. You also have to know the size of the buffer before you call, for sprintf. This is tedious. It's another aspect of not being extensible, but on the back end.It's not retargetableNot sure what you mean.You've heard me bitching about not being able to redirect printf to OutputDebugString for a while now, haven't you? I'd use fprintf if that would work, but it doesn't. And there's no way to call the printf core without going thru sprintf, which destroys any buffering possibilities because you have to preallocate enough storage to guarantee it'll be sufficient. What if sprintf runs out of room? Oh, wait, there'ssnprintf.If your vendor supports it. There's no such thing as smallocprintf, but I suppose someone could figure out a way to make one.Check out outbuffer.printf! I use that (and variants of it) all the time.I thought we established that it would cost an extra vector of types for each printf.That depends on who you are! If you're doing embedded systems, code sizeisstill a big deal.We've already established that typesafe printf could be had for the same number of bytes as printf would take. It would however require compiler support.My gcc compiler for PS/2 is so sloppy, it outputs 4 32-bit NOP's in a row all over the place, just because it feels like it, evidently. It'ssupposedto be an optimized build.I won't make any excuses for that <g>.With that kind of overhead who would notice a few extra parms pushed or a few extra calls?I would. I've been paid many times based on my ability to write small/fast code.It's not like printf needs to be especially fast; it's either printing to screen (limited by human perception) or disk (limited by mechanical processes), so fprintf probably spends most of its time waiting on the OS to flush the buffers.printf does need to be fast. You'd be amazed how many benchmarks are throttled by it and used (rightly or wrongly) for customer buy decisions. I've many times almost sat down and recoded the entire ugly thing in assembler. In fact, a competitor of mine did so for printf and thereby was able to cover for their poor code generation.It would seriously pay to concentrate on making a truly elegant, *usable* I/O foundation for D. Most of the work can be done by someone here, there are people willing to code I/O libraries, but some of the functionality needs to be in the language itself, and its early implementations.I agree. Though I think outbuffer can handle quite a bit.
May 14 2003
"Walter" <walter digitalmars.com> wrote in message news:b9v38i$30qd$1 digitaldaemon.com..."Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b9i48s$201b$1 digitaldaemon.com...itThis means you can't add your own formatting commands. You can't makeThe main problems with printf are: It's not extensibleYup.But that's slower (as has been pointed out) since you first have to convert your type to the string, then print the string. It forces the intermediate data into memory, for one thing. But not in its final resting place, in a temporary buffer. It then has to be moved. Besides then you need a separate object.tostring() property for every type, anyway. Or is it .toString()? I forget. It wouldn't always necessarily be slower to make the string first. The CPU data cache will help alot. I don't have a firm argument here.handle new types.Up to a point, you're right. That point is if you write wrappers for your new types that convert them to strings, and then printf a string.issue.It's not typesafeI've been using printf for 20 years and this just hasn't been anI just wanted to get that on record. ;)Lucky you. You will admit however that it is not type safe? Personal issues aside, just a simple yes or no.You are correct, it is not typesafe.theMeaning you can't printf to anything you want. You also have to knowIt's not retargetableNot sure what you mean.whichsize of the buffer before you call, for sprintf. This is tedious. It's another aspect of not being extensible, but on the back end.Check out outbuffer.printf. I believe it handilly resolves that issue,is a nuisance problem.Hmm. I gotta admit to not being terribly familiar with D's standard library yet.IYou've heard me bitching about not being able to redirect printf to OutputDebugString for a while now, haven't you? I'd use fprintf if that would work, but it doesn't. And there's no way to call the printf core without going thru sprintf, which destroys any buffering possibilities because you have to preallocate enough storage to guarantee it'll be sufficient. What if sprintf runs out of room? Oh, wait, there'ssnprintf.If your vendor supports it. There's no such thing as smallocprintf, butI guess I should.suppose someone could figure out a way to make one.Check out outbuffer.printf! I use that (and variants of it) all the time.sizeThat depends on who you are! If you're doing embedded systems, codeAnd those are two bytes each, indexing into an additional array of real pointers to typeinfo's for each type in the program, each of which is four bytes. That's competitive with printf, surely. Format specifiers are at least 2 bytes, don't forget the trailing NUL.isI thought we established that it would cost an extra vector of types for each printf.still a big deal.We've already established that typesafe printf could be had for the same number of bytes as printf would take. It would however require compiler support.And you know that 90% of the time gets spent in 10% of the code. Well, 50% or so percent of the ram gets spent on 50% of the data structures as well. If you want to save ram you may be able to get the savings elsewhere. If that's what it takes to get good semantics, ease of use, and extensibility, I'm willing to sacrifice a couple of CPU cycles or a couple of bytes. btw 80% of programmer time is dealing with 20% of the crufty codebase consisting of ugly inelegant hacks and riddled with nightmarish bugs and memory leaks. And 98.75% of statistics are bullshit. I do have one more argument: How do you put a color change into a result of a .tostring() operation? ANSI escape codes? Then you have to modify the backend processor to. Done as a mutator it merely requires a flush then a direct color change. If it's auto it could change color back when it goes out of scope.With that kind of overhead who would notice a few extra parms pushed or a few extra calls?I would. I've been paid many times based on my ability to write small/fast code.probablyIt's not like printf needs to be especially fast; it's either printing to screen (limited by human perception) or disk (limited by mechanical processes), so fprintfThen you're surely aware of the above "statistic". ;)spends most of its time waiting on the OS to flush the buffers.printf does need to be fast. You'd be amazed how many benchmarks are throttled by it and used (rightly or wrongly) for customer buy decisions. I've many times almost sat down and recoded the entire ugly thing in assembler. In fact, a competitor of mine did so for printf and thereby was able to cover for their poor code generation.*usable*It would seriously pay to concentrate on making a truly elegant,thereI/O foundation for D. Most of the work can be done by someone here,Then I definitely _must_ research it. Seanare people willing to code I/O libraries, but some of the functionality needs to be in the language itself, and its early implementations.I agree. Though I think outbuffer can handle quite a bit.
May 14 2003
Walter wrote:"Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:b94ejo$20rf$1 digitaldaemon.com...I've got an odd little philosophy regarding printf. The C library printf function is like a little "virtual machine," whose "machine language" consists of the format string and the arguments. Broadly speaking, using a specialized VM gains you a lot of brevity, but has a performance const. In the case of printf, the performance lost by interpreting the format string is massively overshadowed by the cost of the external I/O operations also involved, so it's a win. I've got no problem so far. But that still leaves the fact that C language users must code printf's "machine code" themselves, which is a source of many programming errors. It sure would be nice to have some new compiler, which could create printf's machine language for me, one which would correctly match the number and types or the arguments to the format string. (Hint, hint.)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. Thesecouldbe 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 07 2003