D - variable argument lists
- Achilleas Margaritis (14/14) Sep 01 2003 A cool way to do 'variable argument lists' would be to allow for methods
- Walter (3/17) Sep 01 2003 That is an intriguing solution!
- Matthew Wilson (6/28) Sep 01 2003 But wouldn't it mislead the coder as to the serialisation stipulations i...
- Walter (4/35) Sep 02 2003 You lost me there!
- Helmut Leitner (27/61) Sep 02 2003 I think his idea is this: Assume that could command to break up a parame...
- Walter (18/76) Sep 02 2003 in
- Helmut Leitner (25/28) Sep 02 2003 And there would be a number of nice uses e. g.
- Philippe Mori (22/35) Sep 02 2003 Then the solution would be to uses a class instead of free function
- Russ Lewis (35/157) Sep 02 2003 It makes it difficult to implement thread-safe varargs, since you have
- Walter (8/45) Sep 02 2003 there's a
- Sean L. Palmer (19/47) Sep 02 2003 ints
- Walter (9/23) Sep 02 2003 Function overhead isn't as big a problem as double buffering each argume...
- Sean L. Palmer (49/56) Sep 02 2003 larger
- Vathix (20/34) Sep 02 2003 Can somebody please tell me how this idea is better than mine that I pos...
- Helmut Leitner (20/62) Sep 02 2003 I think that your idea is "perfect", but you just offer a syntax.
- Sean L. Palmer (38/43) Sep 02 2003 It still smells strongly of 'hack' to me.
- Walter (17/22) Sep 02 2003 without
- Riccardo De Agostini (52/57) Sep 03 2003 IMO printf-like embedded formatting, while being easy, flexible, standar...
- Achilleas Margaritis (25/64) Sep 02 2003 I don't know if my idea is better or worse, and frankly, I don't care. I
A cool way to do 'variable argument lists' would be to allow for methods with a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because of multiple calls), but it would improve those tedious 'print' blocks of code, as well as being easier on the eye.
Sep 01 2003
That is an intriguing solution! "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...A cool way to do 'variable argument lists' would be to allow for methods with a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because of multiple calls), but it would improve those tedious 'print' blocks of code, as well as being easier on the eye.
Sep 01 2003
But wouldn't it mislead the coder as to the serialisation stipulations in multi-threaded systems? "Walter" <walter digitalmars.com> wrote in message news:bj0sfg$9r0$1 digitaldaemon.com...That is an intriguing solution! "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...multipleA cool way to do 'variable argument lists' would be to allow for methods with a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because ofwellcalls), but it would improve those tedious 'print' blocks of code, asas being easier on the eye.
Sep 01 2003
You lost me there! "Matthew Wilson" <matthew stlsoft.org> wrote in message news:bj16vn$om3$1 digitaldaemon.com...But wouldn't it mislead the coder as to the serialisation stipulations in multi-threaded systems? "Walter" <walter digitalmars.com> wrote in message news:bj0sfg$9r0$1 digitaldaemon.com...methodsThat is an intriguing solution! "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...A cool way to do 'variable argument lists' would be to allow formultiplewith a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because ofwellcalls), but it would improve those tedious 'print' blocks of code, asas being easier on the eye.
Sep 02 2003
Walter wrote:You lost me there! "Matthew Wilson" <matthew stlsoft.org> wrote in message news:bj16vn$om3$1 digitaldaemon.com...I think his idea is this: Assume that could command to break up a parameter list into more than one call to the same function name. Let's use a the keyword 'serialize' for this. Then serialize print(int i) { .... } ; serialize print(char [] s) { .... }; could command the compiler to break up an arbitrary parameter list of ints and strings into separate calls: print("i=",i," j=",j,"\n"); would just be compiled as if the programmer had written: print("i="); print(i); print(" j="); print(j); print("\n"); I think it's an interesting "low level" idea, that appeals to me (as a basically C, Perl and "low level thinking" man). Although I'm not sure what the consequences are. I would still prefer a solution for a clean variable length parameter lists (like in Visual Basic!). But Achilleas idea might be the next best thing and it should be very easy to implement. Just look after each parameter whether a matching 'serialize' function exists. On the other hand, it is also unclear, whether the necessary wrapping of a variable parameter list into a clean object array will have a performance advantage. If it doesn't, then this suggestion might have a value of its own. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.comBut wouldn't it mislead the coder as to the serialisation stipulations in multi-threaded systems? "Walter" <walter digitalmars.com> wrote in message news:bj0sfg$9r0$1 digitaldaemon.com...methodsThat is an intriguing solution! "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...A cool way to do 'variable argument lists' would be to allow formultiplewith a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because ofwellcalls), but it would improve those tedious 'print' blocks of code, asas being easier on the eye.
Sep 02 2003
"Helmut Leitner" <leitner hls.via.at> wrote in message news:3F54530C.B0855051 hls.via.at...Walter wrote:inYou lost me there! "Matthew Wilson" <matthew stlsoft.org> wrote in message news:bj16vn$om3$1 digitaldaemon.com...But wouldn't it mislead the coder as to the serialisation stipulationsbemulti-threaded systems? "Walter" <walter digitalmars.com> wrote in message news:bj0sfg$9r0$1 digitaldaemon.com...methodsThat is an intriguing solution! "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...A cool way to do 'variable argument lists' would be to allow forwith a single parameter that are overloaded for various types toForexpressed with one call, using commas to separate the arguments.beexample: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That wouldasmultipletype-safe, although a little slower than the C method (because ofcalls), but it would improve those tedious 'print' blocks of code,parameterI think his idea is this: Assume that could command to break up awellas being easier on the eye.list into more than one call to the same function name. Let's use a the keyword 'serialize' for this. Then serialize print(int i) { .... } ; serialize print(char [] s) { .... }; could command the compiler to break up an arbitrary parameter list of ints and strings into separate calls: print("i=",i," j=",j,"\n"); would just be compiled as if the programmer had written: print("i="); print(i); print(" j="); print(j); print("\n"); I think it's an interesting "low level" idea, that appeals to me (as abasically C,Perl and "low level thinking" man). Although I'm not sure what theconsequences are.I would still prefer a solution for a clean variable length parameterlists(like in Visual Basic!). But Achilleas idea might be the next best thing and it should be very easyto implement.Just look after each parameter whether a matching 'serialize' functionexists.On the other hand, it is also unclear, whether the necessary wrapping of avariableparameter list into a clean object array will have a performanceadvantage.If it doesn't, then this suggestion might have a value of its own.It seems at first blush like a pretty good idea. I'm worrying that there's a gotcha I'm not seeing. It does seem to rather neatly solve the typesafe problem.
Sep 02 2003
Walter wrote:It seems at first blush like a pretty good idea. I'm worrying that there's a gotcha I'm not seeing. It does seem to rather neatly solve the typesafe problem.And there would be a number of nice uses e. g. serialize drawto(int x,int y); moveto(0,0); drawto(10,0,10,10,0,10,0,0); or (in connection with the last example): serialize print(Format f,int i); print("i=",i,Format("j= %06x\n"),j); ==== Problems might come from needing a 'sticky' parameter type that would have to be repeated on all subsequent calls: serialize fprintf(sticky FILE f,char [] s); serialize fprintf(sticky FILE f,int i); because fprintf(f,"i=",i); should transform to fprintf(f,"i="); fprintf(f,i); although even this might also be easy to implement: after a serialize call resolution just keep the 'sticky' parameters. But I share your feelings. It almost looks too good and simple. There must be some hidden traps. -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
Sep 02 2003
Problems might come from needing a 'sticky' parameter type that would have to be repeated on all subsequent calls: serialize fprintf(sticky FILE f,char [] s); serialize fprintf(sticky FILE f,int i); because fprintf(f,"i=",i); should transform to fprintf(f,"i="); fprintf(f,i); although even this might also be easy to implement: after a serialize call resolution just keep the 'sticky' parameters. But I share your feelings. It almost looks too good and simple. There must be some hidden traps.Then the solution would be to uses a class instead of free function (or support both). We could have something like: auto serialize class fprintf { public: this(some_args); void do_serialize(int i); void do_serialize(char [] s); } The function name could also be an operator like () or << or have a better name. Also exact modifier for classes and or functions might be changed. We could maybe support a return value but IMO exceptions would typically be used if we must terminate before reading all parameters.... Neverthless, in some case it might be interesting to support a return value to control what to do (continue with next arg, break silently, break with an error, skip next arg,...) The constructor will get first arguments (sticky parameters) and could store then as member for later uses. We could have more than one constructor provide there are no ambiguities. We could also have a destructor (that might flush the stream for example).
Sep 02 2003
Walter wrote:"Helmut Leitner" <leitner hls.via.at> wrote in message news:3F54530C.B0855051 hls.via.at...It makes it difficult to implement thread-safe varargs, since you have to save (thread specific) data from previous calls. In some architectures, getting/setting thread-specific data may require a syscall (to get the process or thread ID), which will impose a serious performance penalty. I earlier suggested a similar proposal, but one that passes a state variable from call to call. Although I am playing with more flexible versions, my original idea was to require that the varargs function return the same value as its first parameter. So printf would be declared with a prototype like this: varargs char[] printf(char[], ...); You would then declare various implementation functions, including the one (if desired for the case where there were no additional functions: char[] printf(char[]) { ... } char[] printf(char[], int) { ... } char[] printf(char[], char[]) { ... } and so on. When a varargs call was made, it would be turned into a recursive call of the various implementations. So the call printf("%s %d %d %d\n", str,a,b,c); would be translated into this: printf(printf(printf(printf("%s %d %d %d\n",str),a),b),c); This variation requires no thread-specific data, because the return code from each implementation is passed in as the first argument of the next impelementation. So, in the previous example, the innermost printf() will return "%d %d %d\n", the second returns "%d %d\n", and so on. The last printf() returns "".Walter wrote:inYou lost me there! "Matthew Wilson" <matthew stlsoft.org> wrote in message news:bj16vn$om3$1 digitaldaemon.com...But wouldn't it mislead the coder as to the serialisation stipulationsbemulti-threaded systems? "Walter" <walter digitalmars.com> wrote in message news:bj0sfg$9r0$1 digitaldaemon.com...methodsThat is an intriguing solution! "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...A cool way to do 'variable argument lists' would be to allow forwith a single parameter that are overloaded for various types toForexpressed with one call, using commas to separate the arguments.beexample: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That wouldasmultipletype-safe, although a little slower than the C method (because ofcalls), but it would improve those tedious 'print' blocks of code,parameterI think his idea is this: Assume that could command to break up awellas being easier on the eye.list into more than one call to the same function name. Let's use a the keyword 'serialize' for this. Then serialize print(int i) { .... } ; serialize print(char [] s) { .... }; could command the compiler to break up an arbitrary parameter list of ints and strings into separate calls: print("i=",i," j=",j,"\n"); would just be compiled as if the programmer had written: print("i="); print(i); print(" j="); print(j); print("\n"); I think it's an interesting "low level" idea, that appeals to me (as abasically C,Perl and "low level thinking" man). Although I'm not sure what theconsequences are.I would still prefer a solution for a clean variable length parameterlists(like in Visual Basic!). But Achilleas idea might be the next best thing and it should be very easyto implement.Just look after each parameter whether a matching 'serialize' functionexists.On the other hand, it is also unclear, whether the necessary wrapping of avariableparameter list into a clean object array will have a performanceadvantage.If it doesn't, then this suggestion might have a value of its own.It seems at first blush like a pretty good idea. I'm worrying that there's a gotcha I'm not seeing. It does seem to rather neatly solve the typesafe problem.
Sep 02 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> wrote in message news:bj26ti$27gt$1 digitaldaemon.com...there's aIt seems at first blush like a pretty good idea. I'm worrying thatWhile your idea works, what I view as the difficulty is the overhead in translating each argument into a char[]. This is the double buffering performance problem. The keeping state problem can be dealt by, as suggested by Philippe, making print() a class member and have the class object keep the state.gotcha I'm not seeing. It does seem to rather neatly solve the typesafe problem.It makes it difficult to implement thread-safe varargs, since you have to save (thread specific) data from previous calls. In some architectures, getting/setting thread-specific data may require a syscall (to get the process or thread ID), which will impose a serious performance penalty. I earlier suggested a similar proposal, but one that passes a state variable from call to call. Although I am playing with more flexible versions, my original idea was to require that the varargs function return the same value as its first parameter. So printf would be declared with a prototype like this: varargs char[] printf(char[], ...); You would then declare various implementation functions, including the one (if desired for the case where there were no additional functions: char[] printf(char[]) { ... } char[] printf(char[], int) { ... } char[] printf(char[], char[]) { ... } and so on. When a varargs call was made, it would be turned into a recursive call of the various implementations. So the call printf("%s %d %d %d\n", str,a,b,c); would be translated into this: printf(printf(printf(printf("%s %d %d %d\n",str),a),b),c); This variation requires no thread-specific data, because the return code from each implementation is passed in as the first argument of the next impelementation. So, in the previous example, the innermost printf() will return "%d %d %d\n", the second returns "%d %d\n", and so on. The last printf() returns "".
Sep 02 2003
"Walter" <walter digitalmars.com> wrote in message news:bj1nal$1i1k$1 digitaldaemon.com...intsI think his idea is this: Assume that could command to break up aparameterlist into more than one call to the same function name. Let's use a the keyword 'serialize' for this. Then serialize print(int i) { .... } ; serialize print(char [] s) { .... }; could command the compiler to break up an arbitrary parameter list ofand strings into separate calls: print("i=",i," j=",j,"\n"); would just be compiled as if the programmer had written: print("i="); print(i); print(" j="); print(j); print("\n");aOn the other hand, it is also unclear, whether the necessary wrapping ofvariableparameter list into a clean object array will have a performanceadvantage.If it doesn't, then this suggestion might have a value of its own.It seems at first blush like a pretty good idea. I'm worrying that there'sagotcha I'm not seeing. It does seem to rather neatly solve the typesafe problem.It would. It would end up with more calls than printf, but then again doesn't printf do some calls internally? The resulting overall executable would get a bit bigger, the library code for formatting would get a bit smaller. It's alot more direct and the type safety is probably worth it. Need some overloaded print functions that take formatting structures, and this still doesn't seem to help with other streams besides the console. All stream i/o functions should be unified methinks. There shouldn't be a different function name for printing to a file or string than for printing to the console. There should be a way to get a stream interface to a string, and maybe a way to set the "current" stream so each call doesn't have to specify it. Or these print functions could be methods of a 'Stream' class. Sean Sean
Sep 02 2003
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:bj2h51$2lt1$1 digitaldaemon.com...It would. It would end up with more calls than printf, but then again doesn't printf do some calls internally?Function overhead isn't as big a problem as double buffering each argument into separate char[]s, but the extra function calls would probably be larger than having a separate Typeinfo[] for the varargs.The resulting overall executable would get a bit bigger, the library code for formatting would get a bit smaller. It's alot more direct and the type safety is probably worth it. Need some overloaded print functions that take formatting structures, and this still doesn't seem to help with other streams besides the console.I think this problem can be dealt with by making print() a member function, as you suggest further on.All stream i/o functions should be unified methinks. There shouldn't be a different function name for printing to a file or string than for printing to the console. There should be a way to get a stream interface to a string, and maybe a way to set the "current" stream so each call doesn't have to specify it. Or these print functions could be methods of a'Stream'class.Yes, your last statement!
Sep 02 2003
"Walter" <walter digitalmars.com> wrote in message news:bj2n49$2ud9$2 digitaldaemon.com..."Sean L. Palmer" <palmer.sean verizon.net> wrote in message news:bj2h51$2lt1$1 digitaldaemon.com...largerIt would. It would end up with more calls than printf, but then again doesn't printf do some calls internally?Function overhead isn't as big a problem as double buffering each argument into separate char[]s, but the extra function calls would probably bethan having a separate Typeinfo[] for the varargs.Listen. All I/O is buffered. Even asynchronous network transmissions. Almost all external (and some internal) devices work via DMA to/from buffers. Converting the object to a Unicode representation is work that has to be done no matter what. The problem you have is with everything being converted to string, separately, and those strings being concatenated, separately. That is wasteful. Also there is code bloat problem if all Unicode conversion has to be done separately for string stream vs. file stream. To solve that problem make everything buffered, and conversion happens to the buffer. The structure of the buffer, how the buffer gets flushed and to where is the responsibility of the other half. The stream I/O library is then how these two parts hook onto each other and how they both interface to client code. Then you get one copy of conversion for char, one for wchar, and that's that. So the argument on the language syntax end is that having an actual function call (with parameter passing overhead) for each part generates bigger code than calling one function with a TypeInfo[] argument that says how to interpret the rest of it. Very data-driven, and that's not such a bad approach. It would indeed save space. But you will want to have user-accessible versions of those conversion functions available to client code anyway right? And the implementation will walk the list and call those functions in turn based on the typeinfo's. Maybe call each object's StreamToBuffer method which invokes the low-level stream's "give me some memory to write bytes to" method. Most of the time the conversion function can give a good estimate of how much space it will need ahead of time. The "give me memory" function may not be able to provide the entire amount, at least not all at once, in one block. Maybe in several smaller blocks. Conversion functions should tolerate this. This is probably a good use for coroutines/fibers/yielding. Should there be a way to stream objects to either a textfile (and ANSI vs. Unicode?) or straight binary, or maybe by some miraculous chance to some "compatibility binary" format? Would objects derived from Streamable have to provide both? What would the sensible defaults be like? Maybe if there are sensible defaults for the basic types, larger structures would "just work". We already went through how to cut down the size of the indices to the typeinfo's. Streams should have a watchdog thread to cause them to auto-flush after a short (1/8 second?) timeout. ;) Otherwise we always have to remember to flush. Mostly this stuff are solved problems already, just find the implementation that is the best and copy its structure. What language has the best streaming facility? Oh, wait, blatant plagiarism is bad. ;) Sean
Sep 02 2003
Can somebody please tell me how this idea is better than mine that I posted a couple hours before this one, besides that it's a simpler rule? You guys are making up all these rules to do things and my idea put it all together nicely. With mine you could buffer output, return values, have startup and exit code, decide which variables are "sticky" just by adding a parameter, it would be multithread safe as far as I can tell... Here: void printall(this ...) { this(char* sz) print(sz); } this(int i) { print(i); } } or void fprintd(FILE *f, this ...) { this(char[] s) { c.stdio.fwrite(s, 1, s.length, f); } this(int i) { c.stdio.fwrite(&i, i.size, 1, f); } } "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...A cool way to do 'variable argument lists' would be to allow for methods with a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because of multiple calls), but it would improve those tedious 'print' blocks of code, as well as being easier on the eye.
Sep 02 2003
Vathix wrote:Can somebody please tell me how this idea is better than mine that I posted a couple hours before this one, besides that it's a simpler rule? You guys are making up all these rules to do things and my idea put it all together nicely. With mine you could buffer output, return values, have startup and exit code, decide which variables are "sticky" just by adding a parameter, it would be multithread safe as far as I can tell... Here: void printall(this ...) { this(char* sz) print(sz); } this(int i) { print(i); } } or void fprintd(FILE *f, this ...) { this(char[] s) { c.stdio.fwrite(s, 1, s.length, f); } this(int i) { c.stdio.fwrite(&i, i.size, 1, f); } }I think that your idea is "perfect", but you just offer a syntax. What about the implementation? To be typesafe, the parameters passed must be organized by the compiler in some data structure, perhaps an array of objects, or an array describing the types and pointing to the various parameters. There are many ways to do it, and it needs a lot of critical and nonobvious decisions. it is able to wrap/unwrap single primitives automatically. Visual Basic does, but only for a limited set of primitive types, so you can't pass a user defined structure or object. AMs idea is perhaps "worse", but it points to a simple implementation without serious flaws in performance or complexity. There may be other problems that are not jet visible. It has a certain "preprocessor touch". Does it fit into the language? Or has it the quality of a clever hack, solving a problem at hand but hindering more innovative solutions?"Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...-- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.comA cool way to do 'variable argument lists' would be to allow for methods with a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because of multiple calls), but it would improve those tedious 'print' blocks of code, as well as being easier on the eye.
Sep 02 2003
It still smells strongly of 'hack' to me. A variable parameter list is just that, a list, but of heterogenous types, which D's dynamic arrays does not support. Seems like a tuple or 'in-place' struct would be an appropriate low-level language feature, but of course printf would then need enough introspection that it could walk the structure and print out the fields in order. Turning the parameters into serial calls to overloaded functions is what that machinery would ultimately do anyway, but it does seem like rather a special case. So far, I dislike the proposals for binding a stream 'this' pointer to each parameter as it's peeled off. I'm assuming D's streaming solution will take the form of a stream class from which derives console, file, and string/memory streams. What if we start with the idea of a flushable buffered memory stream... you can control the number of buffers and the size of each buffer. For file I/O you just set the buffer size to a disk block size, hook up the buffer flush to a file block write, and off you go. For reads it'd read in a whole disk block into the memory buffer (when a buffer is requested). For memory streams it'd also maintain a "list" of which memory blocks form the "file" in memory, and buffer overflows just allocate a new block for the buffer and hook the newly-filled block into the list. So you could hook any functionality you want onto the buffer flush events, and control the size of the buffering, and that way all the formatting code lives in one place and the output goes straight to the buffer. Yeah, the OS can do buffering for the app, but if the runtime does the buffering, it can use unbuffered file I/O for extra performance. The problem is, that the printing/formatting functions must be extensible too (hopefully without the overhead of calling an object's toString() method, but it could do that as a last resort if there's no other print function that matches). In C++ they ended up with a two-level design that nobody ended up being very happy with. Sean "Helmut Leitner" <leitner hls.via.at> wrote in message news:3F54B504.BE07037E hls.via.at...AMs idea is perhaps "worse", but it points to a simple implementationwithoutserious flaws in performance or complexity. There may be other problemsthatare not jet visible. It has a certain "preprocessor touch". Does it fitintothe language? Or has it the quality of a clever hack, solving a problem at hand but hindering more innovative solutions?
Sep 02 2003
"Helmut Leitner" <leitner hls.via.at> wrote in message news:3F54B504.BE07037E hls.via.at...AMs idea is perhaps "worse", but it points to a simple implementationwithoutserious flaws in performance or complexity. There may be other problemsthatare not jet visible. It has a certain "preprocessor touch". Does it fitintothe language? Or has it the quality of a clever hack, solving a problem at hand but hindering more innovative solutions?One issue I have with it is I still would like to have the option of embedded formatting, such as: char[] s; uint u; print("the value of ", s, " is %02x\n", u); ... serialize print(char[]); serialize print(uint); serialize print(char[] format, uint); So could 'serialized' lists of functions include functions with multiple parameters? If so, I think that some rather nasty ambiguity problems would arise.
Sep 02 2003
"Walter" <walter digitalmars.com> ha scritto nel messaggio news:bj2nn5$2v55$1 digitaldaemon.com...One issue I have with it is I still would like to have the option of embedded formatting, such as: char[] s; uint u; print("the value of ", s, " is %02x\n", u);IMO printf-like embedded formatting, while being easy, flexible, standard, still makes it too easy to make mistakes. Once you have a separate serializable call for (char[] format, uint), another for (char[] format, ulong) etc.you may print("%08lu", x) where x is, for instance, a char... (Warning: loud thinking follows. I KNOW I'm writing horribly from the POV of anyone who knows better than me about parsers, compiler theory and the like. I'm just trying to express an idea as clearly as I can manage to). A possible solution, at least for base types, could be defining a formatting operator similar to the pseudo-op Pascal and Delphi use for formatting numbers. In Pascal you can WriteLn('The value is: ', x:8:2) which means 8 max digits, 2 decimals. Now, this is something which does not fit well in D's parser probably, because it is a special case and only works in calls to Write and WriteLn. But what if there was, say, an operator always yielding a char [] (and as such valid everywhere a char[] expression is valid) of some form like the following: width> [ : <size_t decimals> ] I'm giving a type to parameters so the don't have to be just constants, which allows for run-time formatting like using asterisks in printf. <char alignment> may be 'L' (default?), 'R' or 'C', with the obvious meanings of left aligned, right aligned and centered. <short base> might cause an exception or a compile-time error if <n> is a char[] or anyway not a number. Valid bases for numbers range from 2 to 36 (maybe also from -36 to -2, so there's a way to specify if one wants uppercase or lowercase letters for bases over 10). As for app-defined types, the behavior will be defined by the overloaded operator. Default (passed to the overloaded op-function if no base is specified) is 0, which for numbers should behave the same as 10. <size_t width> poses no limits if 0 (i.e. yield just as many characters as are necessary) <size_t decimals> raises an exception if it is greater than <width - 1> It comes without saying that streams _are_ necessary nonetheless, but an operator comes in handy in a lot of situations, and it could be overloaded for app-defined types, by defining an overloaded fmt() function. char [] fmt (MyType n, char alignment = 'L', short base = 0, size_t width = 0, size_t decimals = 0) Why yet another operator? Aw, come on, we format things all the time; why not make it something built into the language? What about non-significant zeros, both to the left and to the right of the decimal point? Anyone got some clue? Some examples of use: my_stream.put( n $ 'R' : 8 ); // Right aligned, 8 digits my_stream.put( customer_name $ 'L' : 50 ); // Left aligned, 50 chars max my_stream.put( price $ 10 : 2 ); // For floating point my_stream.put( price $ 10 : (use_cents ? 2 : 0) ); // Not just constants! In case it all looks crazy, maybe it is :-) but I shared the idea just in case it's any good. Ric
Sep 03 2003
I don't know if my idea is better or worse, and frankly, I don't care. I just want the best possible programming language available(and D looks like it!!!), and if your idea is smarter, that's ok by me. Personally, I think that there can be two type-safe ways of doing variable argument lists. The 1st one I have already proposed: the programmer would combine multiple calls of the same overloaded function into one, and the compiler would call each method successively. It looks like a 'preprocessor hack', but so does the use of 'add' for operator +, 'sub' for operator - etc. The 2nd solution is to provide complete run-time information on the variables pushed on the stack; then, a switch statement in the method would process each argument according to its type. The 1st solution seems more elegant to me, and the internal switch statement of the 2nd solution would be avoided. Serialization issues are to be resolved by a 'synchronized' keyword, ala Java (does D support multitasking ? it should, if it does not; I will search for it later), as it has already been proposed. Printf style formatters would either passed as objects that affect the state of the next element or as overloaded 2-argument methods. Hack or no hack, it makes life easier, doesn't it ? I don't see why BASIC has a 'print 10, 20, i, 5' statement and D could not have it. "Vathix" <vathix dprogramming.com> wrote in message news:bj29ns$2bk2$1 digitaldaemon.com...Can somebody please tell me how this idea is better than mine that Iposteda couple hours before this one, besides that it's a simpler rule? You guys are making up all these rules to do things and my idea put it all together nicely. With mine you could buffer output, return values, have startup and exit code, decide which variables are "sticky" just by adding a parameter, it would be multithread safe as far as I can tell... Here: void printall(this ...) { this(char* sz) print(sz); } this(int i) { print(i); } } or void fprintd(FILE *f, this ...) { this(char[] s) { c.stdio.fwrite(s, 1, s.length, f); } this(int i) { c.stdio.fwrite(&i, i.size, 1, f); } } "Achilleas Margaritis" <axilmar in.gr> wrote in message news:bivp1f$1qvj$1 digitaldaemon.com...multipleA cool way to do 'variable argument lists' would be to allow for methods with a single parameter that are overloaded for various types to be expressed with one call, using commas to separate the arguments. For example: instead of print("The quick brown fox"); print(10); print(20.5); one could write print("The quick brown fox", 10, 20.5); and then the compiler would translate it to the above. That would be type-safe, although a little slower than the C method (because ofwellcalls), but it would improve those tedious 'print' blocks of code, asas being easier on the eye.
Sep 02 2003