Bug in D!!!

EntangledQuanta via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Aug 30 17:49:22 PDT 2017


On Wednesday, 30 August 2017 at 22:52:41 UTC, Adam D. Ruppe wrote:
> On Wednesday, 30 August 2017 at 20:47:12 UTC, EntangledQuanta 
> wrote:
>> This is quite surprising!
>
> In the new version pending release (scheduled for later this 
> week), we get a new feature `static foreach` that will let you 
> loop through the types you want and declare all the functions 
> that way.
>
> When it is released, we'll have to take a second look at this 
> problem.

I've already implemented a half ass library solution. It works, 
but is not robust. The compiler can and should do this!




string OverLoadTemplateDefinition(string name, alias func, T...)()
{
	import std.string;
	string str;
	foreach(t; T) str ~= ((func!t).stringof).replace("function(", 
name~"(")~";\n";
	return str;
}

string OverLoadTemplateMethod(string name, alias func, T...)()
{
	import std.traits, std.algorithm, std.meta, std.string;

	alias RT(S) = ReturnType!(func!S);
	alias PN(S) = ParameterIdentifierTuple!(func!S);
	alias P(S) = Parameters!(func!S);
	alias PD(S) = ParameterDefaults!(func!S);

	string str;
	foreach(t; T)
	{
		str ~= (RT!t).stringof~" "~name~"(";
		foreach(k,p; P!t)
		{
			auto d = "";
			static if (PD!t[k].stringof != "void")
				d = " = "~(PD!t)[k].stringof;
			str ~= p.stringof~" "~(PN!t)[k]~d;
			if (k < (P!t).length - 1)
				str ~= ", ";
		}
		
		str ~= ") { _"~name~"(";
		foreach(k, n; PN!t)
		{
			str ~= n;
			if (k < (P!t).length - 1)
				str ~= ", ";
		}
		str ~= "); }\n";
	}
	return str;
}


They are basically the generic version of what Jonathan 
implemented by hand.

In the interface:

private alias _Go(T) = void function();

mixin(OverLoadTemplateDefinition!("Go", _Go, int, short, float, 
double)());

In class:

mixin(OverLoadTemplateMethod!("Go", _Go, int, short, float, 
double)());

protected final void _Go(T)()
	{
....
	}


The alias simply defines the function that we are creating. The 
mixin OverLoadTemplateDefinition creates the N templates.

in the class, we have to do something similar but dispatch them 
to the protected _Go... very similar to what Jonathan did by 
hand. But the code to do so is not robust and will break in many 
cases because I left a lot of details out(linkage, attributes, 
etc).

It is a proof of concept, and as you can see, it is not 
difficult. The compiler, and anyone that has a decent 
understanding of the internals of it, should be able to implement 
something quite easily.

Maybe it is also possible to use OpCall to do something similar?

I'd like to reiterate that this is not an insolvable problem or 
an NP problem. It is quite easy. If we require restricting the 
types to a computable set, it is just simple overloading and 
templatizing to reduce the complexity.

Having the compiler to this can reduce the noise and increase the 
robustness and also provide a nice feature that it currently does 
not have, but should.

Using templates with inheritance is a good thing, It should be 
allowed instead of blinding preventing all cases when only one 
case is uncomputable. The logic that some are using is akin to 
"We can't divide by 0 so lets not divide at all", but of course, 
division is very useful and one pathological case doesn't prevent 
all other cases from being useful.



More information about the Digitalmars-d-learn mailing list