Ouput-UFCS proposal: void fun(A a,ref B b) <=> B fun(A a);
timotheecour
thelastmammoth at gmail.com
Fri Feb 1 01:25:56 PST 2013
I'd like to suggest the following feature that extends UFCS to
output arguments, hence the name Output-UFCS.
in short:
1) given a function "void fun(A a, ref B b);" (0 or more
arguments before b)
2) The proposal is to always allow the following expression:
"auto b=fun(a);" which the compiler interprets as:
2.1) "OutputType b=fun(a);" if there's a currently compatible
function call (eg OutputType fun(A a);) (ie the current behavior
takes precedence).
2.1) or if no such function call is compatible, it'll rewrite it
under the hood as:
"B b; fun(a,b);"
----------------
Notes:
N0) The obvious advantage is remove BOILERPLATE code. Here's a
common case:
N0.1) void fun(int n , ref double[]b){b.length=n; b[]=0;}
N0.2) double[] fun(int n){double[]b; fun(n,b); return b;}
N0.2 is needed for convenience for client code, but N0.1 is
needed for optimization in certain cases where an existing b can
be reused, thus avoiding allocations, etc. That's very common.
N1) More generally, fun() could be a free function or a
struct/class method, be templated or not, have any number of
arguments before b (including 0).
N2) this plays nicely with existing UFCS conversions: eg: the
following are equivalent for a free function "void fun(A a,ref B
b)": (unless some of those are already defined in the code, in
which case they take precedence):
the expression "auto b=fun(a)" is rewritten as "B b; fun(a,b)"
//OUFCS
the expression "auto b=a.fun()" is rewritten as "B b; a.fun(b)"
//OUFCS
the expression "a.fun(b)" might be rewritten as "fun(a,b)" under
UFCS (unless fun is already a member function, in accordance to
UFCS rules).
with no arg before b: "void fun(ref B b)" :
the expression "auto b=fun()" is rewritten as "B b; fun(b)"
//OUFCS
N3) There are other cases in which we can allow the conversion to
happen:
N3.1) "auto b=fun(a);" (disccussed above)
N3.2) "B b=fun(a);" (same as above; we could also decide to have
a warning or CT error in there's an incompatible existing
function OutputType fun(A a); where OutputType doesn't implicitly
convert to B, but that's optional.)
N3.3) "C b=fun(a);" : same as above, but the attempted rewriting
could look like:
"C b; fun(a,b);" first, or "B b_temp; fun(a,b_temp); b=b_temp;"
second
N3.4) expression involving fun(a), eg: "expr(fun(a),...)":
rewritten as "expr(fun_temp(a),...)"
with the following function generated:
B fun_temp(A a){ B b; fun(a,b); return b; }
N3.4) finally if anyone's unhappy with introducing too much
magic, we can always introduce a UDA annotation on the function
to indicate the conversion can happen.
N3.5) can this be done in library code as opposed to compiler?
that might work for non templated functions but what about
templates? That seems more complicated isn't it?
Please let me know what you think.
More information about the Digitalmars-d
mailing list