Thread overview
Can we deprecate "D-style Variadic Functions"
Mar 25, 2015
Freddy
Mar 25, 2015
Idan Arye
Mar 26, 2015
Dicebot
Mar 26, 2015
Freddy
Mar 27, 2015
Shammah Chancellor
Mar 27, 2015
deadalnix
Mar 27, 2015
Freddy
Mar 27, 2015
Freddy
Mar 27, 2015
Dicebot
March 25, 2015
"D-style Variadic Functions" found here:http://dlang.org/function.html seem entirely out classed by Variadic Function Templates. Can we deprecate them?
March 25, 2015
On Wednesday, 25 March 2015 at 22:12:04 UTC, Freddy wrote:
> "D-style Variadic Functions" found here:http://dlang.org/function.html seem entirely out classed by Variadic Function Templates. Can we deprecate them?

Surely you mean they are classed out by Typesafe Variadic Functions? Variadic Function Templates is a different thing used for a slightly different purpose...
March 26, 2015
On Wednesday, 25 March 2015 at 22:12:04 UTC, Freddy wrote:
> "D-style Variadic Functions" found here:http://dlang.org/function.html seem entirely out classed by Variadic Function Templates. Can we deprecate them?

Those are two different concepts with different trade-offs. Using variadic templates adds template bloat. Using D-style variadics requires RTTI (and small overhead for it). It is up to library/application writer to decide what is best in his case.
March 26, 2015
On Thursday, 26 March 2015 at 00:11:05 UTC, Dicebot wrote:
> On Wednesday, 25 March 2015 at 22:12:04 UTC, Freddy wrote:
>> "D-style Variadic Functions" found here:http://dlang.org/function.html seem entirely out classed by Variadic Function Templates. Can we deprecate them?
>
> Those are two different concepts with different trade-offs. Using variadic templates adds template bloat. Using D-style variadics requires RTTI (and small overhead for it). It is up to library/application writer to decide what is best in his case.

My ploblem is that Variadic Function shouldn't be builtin the language. They are rarely need and can be abstracted into a library. Something like this:
```
import core.stdc.stdlib: alloca;
import std.stdio;
template VariadicFunction(alias Imp){
	auto VariadicFunction(T...)(T args){
		enum size=T.length * TypeInfo.sizeof;
		auto rtti=cast(TypeInfo[])(alloca(size)[0..size]);
		foreach(i,type;T){
			rtti[i]=typeid(type);
		}
		//auto data=&args; bug? doesn't work
		void* data;
		{
			size_t datasize;//T.sizeof doesn't work
			foreach(type;T){
				datasize+=type.sizeof;
			}
			data=alloca(datasize);
			size_t inc;
			foreach(v;args){
				*cast(typeof(v)*)(data+inc)=v;
				inc+=v.sizeof;
			}
		}
		Imp(data,rtti);
	}
}

private void rtVariadicImp(void* vars,scope const TypeInfo[] rtinfo){
	writeln(*cast(int*)vars);
	writeln(rtinfo);
}

alias rtVariadic=VariadicFunction!(rtVariadicImp);

void main(){
	rtVariadic(1,'a');
}
```
March 27, 2015
On 2015-03-26 01:04:03 +0000, Freddy said:

> On Thursday, 26 March 2015 at 00:11:05 UTC, Dicebot wrote:
>> On Wednesday, 25 March 2015 at 22:12:04 UTC, Freddy wrote:
>>> "D-style Variadic Functions" found here:http://dlang.org/function.html seem entirely out classed by Variadic Function Templates. Can we deprecate them?
>> 
>> Those are two different concepts with different trade-offs. Using variadic templates adds template bloat. Using D-style variadics requires RTTI (and small overhead for it). It is up to library/application writer to decide what is best in his case.
> 
> My ploblem is that Variadic Function shouldn't be builtin the language. They are rarely need and can be abstracted into a library. Something like this:
> ```
> import core.stdc.stdlib: alloca;
> import std.stdio;
> template VariadicFunction(alias Imp){
> 	auto VariadicFunction(T...)(T args){
> 		enum size=T.length * TypeInfo.sizeof;
> 		auto rtti=cast(TypeInfo[])(alloca(size)[0..size]);
> 		foreach(i,type;T){
> 			rtti[i]=typeid(type);
> 		}
> 		//auto data=&args; bug? doesn't work
> 		void* data;
> 		{
> 			size_t datasize;//T.sizeof doesn't work
> 			foreach(type;T){
> 				datasize+=type.sizeof;
> 			}
> 			data=alloca(datasize);
> 			size_t inc;
> 			foreach(v;args){
> 				*cast(typeof(v)*)(data+inc)=v;
> 				inc+=v.sizeof;
> 			}
> 		}
> 		Imp(data,rtti);
> 	}
> }
> 
> private void rtVariadicImp(void* vars,scope const TypeInfo[] rtinfo){
> 	writeln(*cast(int*)vars);
> 	writeln(rtinfo);
> }
> 
> alias rtVariadic=VariadicFunction!(rtVariadicImp);
> 
> void main(){
> 	rtVariadic(1,'a');
> }
> ```

I disagree, and your example does not get rid of the template bloat.  That does in fact instantiate a template for every set of argument types.

-Shammah

March 27, 2015
What Shammah has said. Your proposal is not a proper replacement, it has very different effect on a binary. It could be possible to reimplement D-style varargs on top of C-style varargs + manual RTTI usage but not with template variadics.
March 27, 2015
On Friday, 27 March 2015 at 14:24:47 UTC, Shammah Chancellor wrote:
> On 2015-03-26 01:04:03 +0000, Freddy said:
>
>> On Thursday, 26 March 2015 at 00:11:05 UTC, Dicebot wrote:
>>> On Wednesday, 25 March 2015 at 22:12:04 UTC, Freddy wrote:
>>>> "D-style Variadic Functions" found here:http://dlang.org/function.html seem entirely out classed by Variadic Function Templates. Can we deprecate them?
>>> 
>>> Those are two different concepts with different trade-offs. Using variadic templates adds template bloat. Using D-style variadics requires RTTI (and small overhead for it). It is up to library/application writer to decide what is best in his case.
>> 
>> My ploblem is that Variadic Function shouldn't be builtin the language. They are rarely need and can be abstracted into a library. Something like this:
>> ```
>> import core.stdc.stdlib: alloca;
>> import std.stdio;
>> template VariadicFunction(alias Imp){
>> 	auto VariadicFunction(T...)(T args){
>> 		enum size=T.length * TypeInfo.sizeof;
>> 		auto rtti=cast(TypeInfo[])(alloca(size)[0..size]);
>> 		foreach(i,type;T){
>> 			rtti[i]=typeid(type);
>> 		}
>> 		//auto data=&args; bug? doesn't work
>> 		void* data;
>> 		{
>> 			size_t datasize;//T.sizeof doesn't work
>> 			foreach(type;T){
>> 				datasize+=type.sizeof;
>> 			}
>> 			data=alloca(datasize);
>> 			size_t inc;
>> 			foreach(v;args){
>> 				*cast(typeof(v)*)(data+inc)=v;
>> 				inc+=v.sizeof;
>> 			}
>> 		}
>> 		Imp(data,rtti);
>> 	}
>> }
>> 
>> private void rtVariadicImp(void* vars,scope const TypeInfo[] rtinfo){
>> 	writeln(*cast(int*)vars);
>> 	writeln(rtinfo);
>> }
>> 
>> alias rtVariadic=VariadicFunction!(rtVariadicImp);
>> 
>> void main(){
>> 	rtVariadic(1,'a');
>> }
>> ```
>
> I disagree, and your example does not get rid of the template bloat.  That does in fact instantiate a template for every set of argument types.
>
> -Shammah

To be fair, this is most likely going to be inlined an ditched away with any decent optimizer.
March 27, 2015
On Friday, 27 March 2015 at 19:59:13 UTC, deadalnix wrote:
> To be fair, this is most likely going to be inlined an ditched away with any decent optimizer.

It wouldn't even need alloca if sizeof and address of worked with tuples.
```
template VariadicFunction(alias Imp){
	auto VariadicFunction(T...)(T args){
		void* data=&args;
		TypeInfo[T.length] rtti;
		foreach(i,type;T){
			rtti[i]=typeid(type);
		}
		Imp(data,rtti);
	}
}
```
March 27, 2015
On Friday, 27 March 2015 at 20:57:51 UTC, Freddy wrote:
> template VariadicFunction(alias Imp){
> 	auto VariadicFunction(T...)(T args){
> 		void* data=&args;
> 		TypeInfo[T.length] rtti;
> 		foreach(i,type;T){
> 			rtti[i]=typeid(type);
> 		}
> 		Imp(data,rtti);
> 	}
> }
> ```
I haven't looked in dmd's source yet but doesn't the compiler have to do (an inlined version of) this anyway for runtime variadic functions.