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