Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
January 03, 2004 Variable arguments! | ||||
---|---|---|---|---|
| ||||
We need a D way to have variable arguments soon! Here's another idea of mine. This might not be the best syntax but I think the ideas behind it are good. Explanation below. enum Base { Decimal, Octal, Hex, } void dprint(Stream stm, typeof T args ...) { foreach(T arg; args) { switch(typeof(arg)) { case char[]: stm.writeString(arg); break; case int: // I'm sure this could be better optimized stm.writeString(std.string.toString(num)); break; case bool: stm.writeString(arg ? "true" : "false"); break; case Base: // Change some flag for use with printing int break; case Object: stm.writeString(arg.toString()); break; default: throw new DPrintException("Unknown print type."); } } } void stdprint(typeof T args ...) { dprint(std.stream.stdout, args); } void doit() { stdprint(2, "hello ", "world ", 123, 456); } What this can internally do is pass a dynamic array of type IDs as the parameter before a typeof... in the function call. This array won't even need to be constructed on the fly, right? it could be in the data segment. Any class made will work since it will call toString() on it, but I don't know about structs and others. |
January 03, 2004 Re: Variable arguments! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vathix | Realized it won't work so great for classes, might be better to do this: case class: stm.writeString(arg.toString()); break; To find out an object's derived type, cast and check for null as usual. All structs, unions, and enums would have a unique case, since they're not for polymorphism; and all classes just gets one. Would be difficult to determine unhandled type sizes so I thought they could be assumed to be 4 unless there were 0 entries in the type array to indicate each 4 more bytes of the current type. If I passed a long (id 1), char (id 2), and int (id 3), the type array would be [1, 0, 2, 3]. |
January 03, 2004 Re: Variable arguments! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vathix | i don't see much use in it. i prefer to overload opCall instead, and write it as ()()()() wich a variable in everyone. In article <bt6aic$2km$1@digitaldaemon.com>, Vathix says... > >Realized it won't work so great for classes, might be better to do this: case class: > stm.writeString(arg.toString()); > break; >To find out an object's derived type, cast and check for null as usual. > >All structs, unions, and enums would have a unique case, since they're not for polymorphism; and all classes just gets one. > >Would be difficult to determine unhandled type sizes so I thought they could >be assumed to be 4 unless there were 0 entries in the type array to indicate >each 4 more bytes of the current type. If I passed a long (id 1), char (id >2), >and int (id 3), the type array would be [1, 0, 2, 3]. > > |
January 03, 2004 Re: Variable arguments! | ||||
---|---|---|---|---|
| ||||
Posted in reply to davepermen | "davepermen" <davepermen_member@pathlink.com> wrote in message news:bt791v$1fhi$1@digitaldaemon.com... > i don't see much use in it. i prefer to overload opCall instead, and write it as > ()()()() wich a variable in everyone. But doesn't that have the same performance problems as C++ iostream? Having to call a function repeatedly with the "this" pointer. I thought we were still looking for something better.. |
January 03, 2004 Re: Variable arguments! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vathix | the compiler can optimize the thispointer (as its constant all the time) to be "passed" just one time (and it depends on calling convention to really hurt, or not at all) your require to pass types around, and switch on them. my one does not need ANY runtime performance except direct calls to the correct functions. the same feature c++ streams do have.. printf("%i",i) is slower than cout<<i; by default. why? because printf has to parse the first string, analize, and then print out the int cout<<i is the same as this: printInteger(cout,i); all at compile time determined. it is actually max performance you can get. the calling overhead is a small one then (can be inlined even, if that gives performance). i'm still interested in getting some syntax sugar to make stream coding more general. and i still miss the ability to have operators AS FUNCTIONS and not member functions (because they DON'T BELONG TO MEMBERS). the c++ streams are some of the best idea ever, for streams. the implementation is another issue (and is very clumpsy). but the multiparameter calling design of the streams is great. In article <bt7e8g$1n1t$1@digitaldaemon.com>, Vathix says... > >"davepermen" <davepermen_member@pathlink.com> wrote in message news:bt791v$1fhi$1@digitaldaemon.com... >> i don't see much use in it. i prefer to overload opCall instead, and write >it as >> ()()()() wich a variable in everyone. > >But doesn't that have the same performance problems as C++ iostream? Having to call a function repeatedly with the "this" pointer. I thought we were still looking for something better.. > > > |
January 04, 2004 Re: Variable arguments! | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vathix | Vathix wrote: > We need a D way to have variable arguments soon! Here's another idea of > mine. > This might not be the best syntax but I think the ideas behind it are good. > Explanation below. XL <http://mozart-dev.sourceforge.net/xl.html> does something kind of neat, though it's a drastically different language. The ubiquitious 'Min' function is implemented as: generic type ordered if with ordered A, B with boolean C := A < B function Min(ordered A) return ordered is return A function Min(ordered A; other) return ordered is result := Min(other) if A < result then result := A 'other' is just all the successive arguments passed. It essentially compiles to Min(x, Min(y, Min(z, Min(...) ) ) ) Of course, this more or less stipulates that the function be written in a functional way, instead of imperative. (I don't know whether that's important at all or not) This approach could also cause problems with vararg functions that are too large to inline, should anybody be insane enough to pass 800 arguments to one at a time. Typical overloading rules would be able to decide what types are allowed. printf could look something like: void printf() { // Trivial base case. } void printf(int i, other) { std.c.printf("%i", i); printf(other); } void printf(char[] s, other) { std.c.printf("%.s", s); printf(other); } and so forth. --andy |
Copyright © 1999-2021 by the D Language Foundation