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