www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Compile-time variadic functions

reply AJG <AJG nospam.com> writes:
Hi there,

It seems to me that the entire variadic function process could run at 
compile-time. That is to say, the compiler has all the information 
required to make this happen.

In other words, correct me if I'm wrong, but there is no way to call a 
function with a dynamically built variadic part. Right?

If my assumption is correct, then why is the variadic mechanism a 
run-time one? In my opinion, as it stands, we are not getting the cake 
nor eating it.

Were the process entirely compile-time, then we could make our variadic 
functions much more robust, and have the compiler trigger the errors, 
instead of the runtime. Wouldn't that be much better?

For example, why couldn't I do something like the following:

void Foo(...) in {
     static assert(_arguments.length > 1);
     static if (_arguments[0] == typeid(float)) {
         pragma(msg, "Warning, float will be truncated to int.");
     }
}

Thoughts?
Cheers,
--AJG.
Sep 12 2005
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"AJG" <AJG nospam.com> wrote in message 
news:dg5ikk$e6s$1 digitaldaemon.com...
 Hi there,

 It seems to me that the entire variadic function process could run at 
 compile-time. That is to say, the compiler has all the information 
 required to make this happen.

 In other words, correct me if I'm wrong, but there is no way to call a 
 function with a dynamically built variadic part. Right?

 If my assumption is correct, then why is the variadic mechanism a run-time 
 one? In my opinion, as it stands, we are not getting the cake nor eating 
 it.

 Were the process entirely compile-time, then we could make our variadic 
 functions much more robust, and have the compiler trigger the errors, 
 instead of the runtime. Wouldn't that be much better?

 For example, why couldn't I do something like the following:

 void Foo(...) in {
     static assert(_arguments.length > 1);
     static if (_arguments[0] == typeid(float)) {
         pragma(msg, "Warning, float will be truncated to int.");
     }
 }

 Thoughts?
 Cheers,
 --AJG.

I'm not sure if this is what you're looking for, but you can overload variadic functions, and the compiler will select the correct one, kind of like template specialization. For example: import std.stdio; void fork(...) { writefln("variadic fork."); } void fork(int x, int y) { writefln("specialized fork."); } void main() { fork(5); fork(5,6); fork(5,6,7); } Prints: variadic fork. specialized fork. variadic fork. Maybe it's useful to you?
Sep 13 2005
parent reply AJG <AJG nospam.com> writes:
Hi,

 I'm not sure if this is what you're looking for, but you can overload 
 variadic functions, and the compiler will select the correct one, kind of 
 like template specialization.  For example:
 
 import std.stdio;
 
 void fork(...)
 {
  writefln("variadic fork.");
 }
 
 void fork(int x, int y)
 {
  writefln("specialized fork.");
 }
 
 void main()
 {
  fork(5);
  fork(5,6);
  fork(5,6,7);
 }
 
 Prints:
 
 variadic fork.
 specialized fork.
 variadic fork.

Hey, that's pretty nice. I didn't know the compiler chose the specialized one in such cases.
 Maybe it's useful to you?

I bet it will. However, it doesn't quite address my original point: Namely, that the variadic function mechanism should occur completely at compile time. As it stands, it's done through a run-time process, which IMO is unnecessary. Thanks, --AJG.
Sep 14 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"AJG" <AJG nospam.com> wrote in message 
news:dgattf$2q0r$1 digitaldaemon.com...
 I bet it will. However, it doesn't quite address my original point: 
 Namely, that the variadic function mechanism should occur completely at 
 compile time. As it stands, it's done through a run-time process, which 
 IMO is unnecessary.

I see what you mean now. It sure is inefficient to have to check the types of the parameters every time the function is called at run-time, when it could be all pre-checked at compile time.
Sep 15 2005
next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Jarrett Billingsley wrote:
 "AJG" <AJG nospam.com> wrote in message 
 news:dgattf$2q0r$1 digitaldaemon.com...
 
I bet it will. However, it doesn't quite address my original point: 
Namely, that the variadic function mechanism should occur completely at 
compile time. As it stands, it's done through a run-time process, which 
IMO is unnecessary.

I see what you mean now. It sure is inefficient to have to check the types of the parameters every time the function is called at run-time, when it could be all pre-checked at compile time.

Maybe they should be treated just like templates!?
Sep 15 2005
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message 
news:dgchlh$1tsh$1 digitaldaemon.com...
 Maybe they should be treated just like templates!?

You're probably right. Variadic functions can be treated as another form of generic programming. And since they're compile-time functions, they'd fit right in.
Sep 15 2005
parent reply Sean Kelly <sean f4.ca> writes:
In article <dgcjfg$20ce$1 digitaldaemon.com>, Jarrett Billingsley says...
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message 
news:dgchlh$1tsh$1 digitaldaemon.com...
 Maybe they should be treated just like templates!?

You're probably right. Variadic functions can be treated as another form of generic programming. And since they're compile-time functions, they'd fit right in.

The only catch here is that this would require implicit template instantiation, which I gather isn't a trivial addition. But I agree that this should be a template feature if it's implemented. Sean
Sep 15 2005
parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Sean Kelly wrote:
 In article <dgcjfg$20ce$1 digitaldaemon.com>, Jarrett Billingsley says...
 
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message 
news:dgchlh$1tsh$1 digitaldaemon.com...

Maybe they should be treated just like templates!?

You're probably right. Variadic functions can be treated as another form of generic programming. And since they're compile-time functions, they'd fit right in.

The only catch here is that this would require implicit template instantiation, which I gather isn't a trivial addition. But I agree that this should be a template feature if it's implemented. Sean

Well, to be honest, I don't know much about templates, and I don't use them much either... but I was just reading the thread "writef / doFormat without formatting", and man, if you look at Dark Parnell's stringer code in that thread, you will that see he's doing a whole bunch of #if( typeid is X ) # somefunction( va_arg!(X) , ..... ) calling the same function for every single basic type. Then I thought, if variadic functions were compile-time, he could've just written #somefunction( va_arg!(typeof(T) ) or something like that. That's probably not only easier to code for the programmer, but also faster at runtime, because the runtime overhead is moved to compile-time.
Sep 15 2005
parent AJG <AJG nospam.com> writes:
Hasan Aljudy wrote:
 Sean Kelly wrote:
 
 In article <dgcjfg$20ce$1 digitaldaemon.com>, Jarrett Billingsley says...

 "Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message 
 news:dgchlh$1tsh$1 digitaldaemon.com...

 Maybe they should be treated just like templates!?

You're probably right. Variadic functions can be treated as another form of generic programming. And since they're compile-time functions, they'd fit right in.

The only catch here is that this would require implicit template instantiation, which I gather isn't a trivial addition. But I agree that this should be a template feature if it's implemented. Sean

Well, to be honest, I don't know much about templates, and I don't use them much either... but I was just reading the thread "writef / doFormat without formatting", and man, if you look at Dark Parnell's stringer code in that thread, you will that see he's doing a whole bunch of #if( typeid is X ) # somefunction( va_arg!(X) , ..... ) calling the same function for every single basic type. Then I thought, if variadic functions were compile-time, he could've just written #somefunction( va_arg!(typeof(T) ) or something like that.

Yep. The possibilities are endless.
 That's probably not only easier to code for the programmer, but also 
 faster at runtime, because the runtime overhead is moved to compile-time.

That's more or less exactly right. ;) --AJG.
Sep 16 2005
prev sibling parent AJG <AJG nospam.com> writes:
Jarrett Billingsley wrote:
 "AJG" <AJG nospam.com> wrote in message 
 news:dgattf$2q0r$1 digitaldaemon.com...
 
I bet it will. However, it doesn't quite address my original point: 
Namely, that the variadic function mechanism should occur completely at 
compile time. As it stands, it's done through a run-time process, which 
IMO is unnecessary.

I see what you mean now. It sure is inefficient to have to check the types of the parameters every time the function is called at run-time, when it could be all pre-checked at compile time.

Yes, exactly. And not just inefficient, but limiting too; variadic functions could be much more robust if checked at compile-time. Cheers, --AJG.
Sep 16 2005
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
AJG wrote:
<snip>
 For example, why couldn't I do something like the following:
 
 void Foo(...) in {
     static assert(_arguments.length > 1);
     static if (_arguments[0] == typeid(float)) {
         pragma(msg, "Warning, float will be truncated to int.");
     }
 }

Why would you want to truncate floats but pass all other types through unchanged? If OTOH you want the first argument to be an int, then you would do void Foo(int bar, ...) { } Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 19 2005
parent AJG <AJG nospam.com> writes:
Hi,

Stewart Gordon wrote:
 AJG wrote:
 <snip>
 
 For example, why couldn't I do something like the following:

 void Foo(...) in {
     static assert(_arguments.length > 1);
     static if (_arguments[0] == typeid(float)) {
         pragma(msg, "Warning, float will be truncated to int.");
     }
 }

Why would you want to truncate floats but pass all other types through unchanged? If OTOH you want the first argument to be an int, then you would do void Foo(int bar, ...) { } Stewart.

No, the example was trivial and not intended to do anything sensible. The point was to show that variadic functions should be resolved at compile time so that static checks can be done. Right now, those checks must: a) Occur at runtime. b) Occur every time a function is called. This is completely unnecessary. Everything (AFAIK) needed to convert the process to compile-time is there. Functions cannot be called with a dynamically-built parameter list. Therefore, why treat it as if it were one? I think the solution lies with what the others suggested, i.e., some form of implicit templating. Cheers, --AJG.
Sep 19 2005