digitalmars.D - Variadic functions again
- Andrew Edwards (69/69) Jun 08 2004 This is an attempt to generate conversation on variadic functions, the
- J C Calvarese (10/100) Jun 08 2004 I think a built-in variant type would be Fantastic!
- Derek Parnell (12/102) Jun 08 2004 Love it!
- Ben Hinkle (16/104) Jun 09 2004 three thoughts come to mind:
- Andrew Edwards (25/131) Jun 09 2004 The idea is for it to be a self-dereferencing pointer (similar to the &v...
This is an attempt to generate conversation on variadic functions, the implementation of which would ultimately lesson our search for an adequate solution to the D I/O issue. Note: I'm often uncomfortable referring to arguments and parameters in speech and writing so I'll be referring to all such items as arguments. ------print.d------ int main() { double d; char c; print(d,c); } void print(char[] start, ...) { } ------------------- compiler errors messages: print.d(5): function print (char[]start,...) does not match argument types (double,char) print.d(5): cannot implicitly convert double to char[] Given the function print(), as defined above, it is clear to see (from the generated error messages) that the compiler is capable of not only discerning the total numbers of arguments used to call that function, but also the type of each of those arguments. IMHO it wouldn't be too unreasonable to assume that in order for it to gather this information, the compiler must know beforehand where each of those arguments are stored (i.e. the address of each argument) in memory. Now suppose for a moment that we had a built-in type-pointer, called "variant", that points to and assumes the characteristics of any, and all, other built-in types. Making the following legal: variant variable; // value automatically dereferenced to the value of // whatever it points to. (Does NOT return an // address and is NOT a copy!) void space; char[] string; int i; double j; char c; etc... variable = space; // typeof(variable) -> void variable = string; // typeof(variable) -> char[] variable = i; // typeof(variable) -> int variable = j; // typeof(variable) -> double variable = c; // typeof(variable) -> char etc... Wouldn't this allow us to deal with variables at compile time without knowing it's actual type? Hold that thought for a moment! Review of the stdarg functions reveal that variable arguments are arranged sequentially in memory. Simply knowing the size of each argument allows us to move from one memory location to another within the argument list. So what if we stored those arguments in an array (call it "sequence" if you will) internally to the compiler whenever a variadic function is encountered? [e.g. echo(char[] v, int i, char c, ...) or scan(...), but not foo(char ch) or bar()] Wouldn't we be able to access each argument individually through array indexing (akin to accessing arguments passed in to the main() function)? Now suppose the array was an associative array: variant[int] sequence; // syntactic sugar for this would be ... Wouldn't we be able to foreach through each of those arguments and manipulate them without regard to type? This functionality could drastically reduce our search for a proper I/O facility for The D Language and completely eliminate the problem of traversing arguments of a variadic function (thereby eliminating the need for std.c.stdarg). Your thoughts and opinions are greatly appreciated. If I'm somewhere off in coocoo land, please don't be afraid to say so!!! Thanks, Andrew
Jun 08 2004
Andrew Edwards wrote:This is an attempt to generate conversation on variadic functions, the implementation of which would ultimately lesson our search for an adequate solution to the D I/O issue. Note: I'm often uncomfortable referring to arguments and parameters in speech and writing so I'll be referring to all such items as arguments. ------print.d------ int main() { double d; char c; print(d,c); } void print(char[] start, ...) { } ------------------- compiler errors messages: print.d(5): function print (char[]start,...) does not match argument types (double,char) print.d(5): cannot implicitly convert double to char[] Given the function print(), as defined above, it is clear to see (from the generated error messages) that the compiler is capable of not only discerning the total numbers of arguments used to call that function, but also the type of each of those arguments. IMHO it wouldn't be too unreasonable to assume that in order for it to gather this information, the compiler must know beforehand where each of those arguments are stored (i.e. the address of each argument) in memory. Now suppose for a moment that we had a built-in type-pointer, called "variant", that points to and assumes the characteristics of any, and all, other built-in types. Making the following legal: variant variable; // value automatically dereferenced to the value of // whatever it points to. (Does NOT return an // address and is NOT a copy!) void space; char[] string; int i; double j; char c; etc... variable = space; // typeof(variable) -> void variable = string; // typeof(variable) -> char[] variable = i; // typeof(variable) -> int variable = j; // typeof(variable) -> double variable = c; // typeof(variable) -> char etc... Wouldn't this allow us to deal with variables at compile time without knowing it's actual type? Hold that thought for a moment! Review of the stdarg functions reveal that variable arguments are arranged sequentially in memory. Simply knowing the size of each argument allows us to move from one memory location to another within the argument list. So what if we stored those arguments in an array (call it "sequence" if you will) internally to the compiler whenever a variadic function is encountered? [e.g. echo(char[] v, int i, char c, ...) or scan(...), but not foo(char ch) or bar()] Wouldn't we be able to access each argument individually through array indexing (akin to accessing arguments passed in to the main() function)? Now suppose the array was an associative array: variant[int] sequence; // syntactic sugar for this would be ... Wouldn't we be able to foreach through each of those arguments and manipulate them without regard to type? This functionality could drastically reduce our search for a proper I/O facility for The D Language and completely eliminate the problem of traversing arguments of a variadic function (thereby eliminating the need for std.c.stdarg). Your thoughts and opinions are greatly appreciated. If I'm somewhere off in coocoo land, please don't be afraid to say so!!! Thanks, AndrewI think a built-in variant type would be Fantastic! It would also help us seduce programmers from all kinds of languages that have easy variant support, such as Visual Basic, VBScript, JavaScript, JScript, etc. (Of course some might also consider this a disadvantage. ;) ) Now we just need to twist Walter's arm... -- Justin (a/k/a jcc7) http://jcc_7.tripod.com/d/
Jun 08 2004
On Tue, 08 Jun 2004 21:54:15 -0400, Andrew Edwards wrote:This is an attempt to generate conversation on variadic functions, the implementation of which would ultimately lesson our search for an adequate solution to the D I/O issue. Note: I'm often uncomfortable referring to arguments and parameters in speech and writing so I'll be referring to all such items as arguments. ------print.d------ int main() { double d; char c; print(d,c); } void print(char[] start, ...) { } ------------------- compiler errors messages: print.d(5): function print (char[]start,...) does not match argument types (double,char) print.d(5): cannot implicitly convert double to char[] Given the function print(), as defined above, it is clear to see (from the generated error messages) that the compiler is capable of not only discerning the total numbers of arguments used to call that function, but also the type of each of those arguments. IMHO it wouldn't be too unreasonable to assume that in order for it to gather this information, the compiler must know beforehand where each of those arguments are stored (i.e. the address of each argument) in memory. Now suppose for a moment that we had a built-in type-pointer, called "variant", that points to and assumes the characteristics of any, and all, other built-in types. Making the following legal: variant variable; // value automatically dereferenced to the value of // whatever it points to. (Does NOT return an // address and is NOT a copy!) void space; char[] string; int i; double j; char c; etc... variable = space; // typeof(variable) -> void variable = string; // typeof(variable) -> char[] variable = i; // typeof(variable) -> int variable = j; // typeof(variable) -> double variable = c; // typeof(variable) -> char etc... Wouldn't this allow us to deal with variables at compile time without knowing it's actual type? Hold that thought for a moment! Review of the stdarg functions reveal that variable arguments are arranged sequentially in memory. Simply knowing the size of each argument allows us to move from one memory location to another within the argument list. So what if we stored those arguments in an array (call it "sequence" if you will) internally to the compiler whenever a variadic function is encountered? [e.g. echo(char[] v, int i, char c, ...) or scan(...), but not foo(char ch) or bar()] Wouldn't we be able to access each argument individually through array indexing (akin to accessing arguments passed in to the main() function)? Now suppose the array was an associative array: variant[int] sequence; // syntactic sugar for this would be ... Wouldn't we be able to foreach through each of those arguments and manipulate them without regard to type? This functionality could drastically reduce our search for a proper I/O facility for The D Language and completely eliminate the problem of traversing arguments of a variadic function (thereby eliminating the need for std.c.stdarg). Your thoughts and opinions are greatly appreciated. If I'm somewhere off in coocoo land, please don't be afraid to say so!!! Thanks, AndrewLove it! I'm *so* used to working with polymorphic variables that I know I'll be missing them in D. And your idea will not cause compiled programs that DO NOT use the variant type to slow down any either. So, if a coder chooses to use a variant datatye then they accept the (slight) performance hit in order to use a *much* easier programming paradigm. I assume that we could work with classes and structures in this scheme too. -- Derek Melbourne, Australia 9/Jun/04 2:36:25 PM
Jun 08 2004
Andrew Edwards wrote:This is an attempt to generate conversation on variadic functions, the implementation of which would ultimately lesson our search for an adequate solution to the D I/O issue. Note: I'm often uncomfortable referring to arguments and parameters in speech and writing so I'll be referring to all such items as arguments. ------print.d------ int main() { double d; char c; print(d,c); } void print(char[] start, ...) { } ------------------- compiler errors messages: print.d(5): function print (char[]start,...) does not match argument types (double,char) print.d(5): cannot implicitly convert double to char[] Given the function print(), as defined above, it is clear to see (from the generated error messages) that the compiler is capable of not only discerning the total numbers of arguments used to call that function, but also the type of each of those arguments. IMHO it wouldn't be too unreasonable to assume that in order for it to gather this information, the compiler must know beforehand where each of those arguments are stored (i.e. the address of each argument) in memory. Now suppose for a moment that we had a built-in type-pointer, called "variant", that points to and assumes the characteristics of any, and all, other built-in types. Making the following legal: variant variable; // value automatically dereferenced to the value of // whatever it points to. (Does NOT return an // address and is NOT a copy!) void space; char[] string; int i; double j; char c; etc... variable = space; // typeof(variable) -> void variable = string; // typeof(variable) -> char[] variable = i; // typeof(variable) -> int variable = j; // typeof(variable) -> double variable = c; // typeof(variable) -> char etc... Wouldn't this allow us to deal with variables at compile time without knowing it's actual type? Hold that thought for a moment! Review of the stdarg functions reveal that variable arguments are arranged sequentially in memory. Simply knowing the size of each argument allows us to move from one memory location to another within the argument list. So what if we stored those arguments in an array (call it "sequence" if you will) internally to the compiler whenever a variadic function is encountered? [e.g. echo(char[] v, int i, char c, ...) or scan(...), but not foo(char ch) or bar()] Wouldn't we be able to access each argument individually through array indexing (akin to accessing arguments passed in to the main() function)? Now suppose the array was an associative array: variant[int] sequence; // syntactic sugar for this would be ... Wouldn't we be able to foreach through each of those arguments and manipulate them without regard to type? This functionality could drastically reduce our search for a proper I/O facility for The D Language and completely eliminate the problem of traversing arguments of a variadic function (thereby eliminating the need for std.c.stdarg). Your thoughts and opinions are greatly appreciated. If I'm somewhere off in coocoo land, please don't be afraid to say so!!! Thanks, Andrewthree thoughts come to mind: 1) variant feels very close to Object except variant also works for primitive types (reminds me of post long ago about boxing/unboxing or wrapping primitive types) 2) have you looked into using a struct like struct variant { TypeInfo* ti; void* data; } 3) variant is somewhat like a plain old void* since it isn't clear what "manipulate them without regard to type" would mean in a compiled language. What operations should be supported by a variant? addition? toString? printf? I think this is an interesting topic but is hard to work into a compiled language where there isn't any RTTI for primitive types.
Jun 09 2004
In article <ca70oe$2adn$1 digitaldaemon.com>, Ben Hinkle says...Andrew Edwards wrote:The idea is for it to be a self-dereferencing pointer (similar to the &var of C++ or the inout parameter of D). Modifying the variant directly affects the variable to which it points, but it should facilitate pointing to a different variable later on.This is an attempt to generate conversation on variadic functions, the implementation of which would ultimately lesson our search for an adequate solution to the D I/O issue. Note: I'm often uncomfortable referring to arguments and parameters in speech and writing so I'll be referring to all such items as arguments. ------print.d------ int main() { double d; char c; print(d,c); } void print(char[] start, ...) { } ------------------- compiler errors messages: print.d(5): function print (char[]start,...) does not match argument types (double,char) print.d(5): cannot implicitly convert double to char[] Given the function print(), as defined above, it is clear to see (from the generated error messages) that the compiler is capable of not only discerning the total numbers of arguments used to call that function, but also the type of each of those arguments. IMHO it wouldn't be too unreasonable to assume that in order for it to gather this information, the compiler must know beforehand where each of those arguments are stored (i.e. the address of each argument) in memory. Now suppose for a moment that we had a built-in type-pointer, called "variant", that points to and assumes the characteristics of any, and all, other built-in types. Making the following legal: variant variable; // value automatically dereferenced to the value of // whatever it points to. (Does NOT return an // address and is NOT a copy!) void space; char[] string; int i; double j; char c; etc... variable = space; // typeof(variable) -> void variable = string; // typeof(variable) -> char[] variable = i; // typeof(variable) -> int variable = j; // typeof(variable) -> double variable = c; // typeof(variable) -> char etc... Wouldn't this allow us to deal with variables at compile time without knowing it's actual type? Hold that thought for a moment! Review of the stdarg functions reveal that variable arguments are arranged sequentially in memory. Simply knowing the size of each argument allows us to move from one memory location to another within the argument list. So what if we stored those arguments in an array (call it "sequence" if you will) internally to the compiler whenever a variadic function is encountered? [e.g. echo(char[] v, int i, char c, ...) or scan(...), but not foo(char ch) or bar()] Wouldn't we be able to access each argument individually through array indexing (akin to accessing arguments passed in to the main() function)? Now suppose the array was an associative array: variant[int] sequence; // syntactic sugar for this would be ... Wouldn't we be able to foreach through each of those arguments and manipulate them without regard to type? This functionality could drastically reduce our search for a proper I/O facility for The D Language and completely eliminate the problem of traversing arguments of a variadic function (thereby eliminating the need for std.c.stdarg). Your thoughts and opinions are greatly appreciated. If I'm somewhere off in coocoo land, please don't be afraid to say so!!! Thanks, Andrewthree thoughts come to mind: 1) variant feels very close to Object except variant also works for primitive types (reminds me of post long ago about boxing/unboxing or wrapping primitive types)2) have you looked into using a struct like struct variant { TypeInfo* ti; void* data; }As a matter of fact I have. This, however, does not fit the bill. The variant should assume the characteristics of the variable to which it points. double trouble; // initial value nan variant var; // initial value null var = trouble; // var takes the address of trouble (var == nan) // maybe we could recall the adressof operator (&)? var = 6.66; // trouble = 6.66 typeof(var) foo; // foo is of type double printf(toString(var)); // calls toString(double)3) variant is somewhat like a plain old void* since it isn't clear what "manipulate them without regard to type" would mean in a compiled language. What operations should be supported by a variant? addition? toString? printf?Not quite! "variant" is like a void* in the sense that it can point to anything. However, unlike void*, once it points to a variable it assumes all characteristics of that variable. If it points to an int, you can treat the variant as if it were an int. All changes made to the variant would <strong>*directly*</strong> affect the variable to which it points. Absolutely no need for casting as with void*s.I think this is an interesting topic but is hard to work into a compiled language where there isn't any RTTI for primitive types.This is where I get confused. It is also the purpose of the little example provided earlier. If the compiler is capable of identifying that the incorrect number and type of arguments (and vice-versa) are used to call a function, isn't that enought information to determine the type of variable to which a variant points?
Jun 09 2004