On Monday, 26 February 2018 at 21:07:52 UTC, Meta wrote:
This is possible in the language today using the implicit class
construction feature of runtime variadic arrays:
class VArray
{
Variant[] va;
this(T...)(T ts) { foreach(t; ts) { va ~= Variant(t); } }
}
void test(VArray ta...)
...
test(1, "asdf", false);
Problems:
* The author of `test` has to specifically design support for
this to work. `test` might be in a library outside the control of
the programmer.
* `test` might be part of a template such as a type constructor
taking a type as a template parameter - you can't pass e.g.
VArray as the type because `test` wouldn't have the ... ellipsis
- if it did then `test` would be variadic when the type was an
array (which would be inconsistent).
* If there's an overload `test(int,string,bool)` then implicit
construction will no longer work - this is a general problem with
the (Aggregate arg...) feature.
That said, there is exactly 1 case where I really, really want
some kind of implicit conversion:
struct Success {}
struct Error { string msg; }
alias Result = Algebraic!(Success, Error);
Result connectToHost(IPAddress host)
{
//do some stuff
if (operationSucceeded)
{
return Success();
}
else
{
return Error(statusMessage);
}
}
This currently doesn't work, and you instead have to return
Result(Success()) and
Result(Error(statusMessage)).
This is a great example. If we had `@implicit this(T v)` it could
be restricted to accepting literals, struct constructor call
expressions and new expressions for `v`. That would allow support
for your example, plus allow:
void f(Result);
f(Success());
f(Error(statusMessage));
This should only work for an exactly matching implicit
constructor. Suppose we have a type Q that has an implicit
constructor for type P, and P has an implicit constructor for int:
void g(Q);
g(P()); // OK
g(5); // error, int is not implicitly convertible to Q
For g(5), the compiler doesn't consider P's `@implicit
this(int)`, it only matches an implicit constructor of Q when the
argument type is P exactly.