string fun(string x, string y, string z = "Z", string w = "W")
{
	return x ~ y ~ z ~ w;
}
static assert(fun(   "x",    "y") == "xyZW");
static assert(fun(   "x",    "y", "z", "w") == "xyzw");
static assert(fun(x: "x", y: "y", z: "z", w: "w") == "xyzw");
static assert(fun(w: "w", z: "z", y: "y", x: "x") == "xyzw");
static assert(fun(y: "y",    "z", x: "x") == "xyzW");
static assert(fun(   "x",    "y", w: "w") == "xyZw");
static assert(fun(x: "x",    "y", z: "z") == "xyzW");
// Default arguments need not all be at the end anymore
string fun2(string x = "x", string y, string z = "z")
{
	return x ~ y ~ z;
}
static assert(fun2(y: "y") == "xyz");
// The assumption that first parameter having a default implies all parameters have a default is no longer valid,
// so this struct constructor shouldn't be mistaken for a default constructor.
struct SD { this(int x = 1, int y) { } }
// UFCS
static assert("x".fun("y", w: "w") == "xyZw");
// tuples
alias AliasSeq(T...) = T;
static assert("x".fun(x: AliasSeq!(), "y", w: "w") == "xyZw");
static assert(AliasSeq!("x", "y").fun(w: "w", z: AliasSeq!()) == "xyZw");
static assert(fun(y: AliasSeq!("y", "z", "w"), x: "x") == "xyzw");
// `new` expressions
class C
{
	int x, y;
	this(int x, int y)
	{
		this.x = x;
		this.y = y;
	}
	static C opCall(int x, int y) { return new C(x, y); }
}
struct S
{
	int x, y;
}
static assert(new C(y: 3, x: 2).x == 2);
static assert(    C(y: 3, x: 2).x == 2);
static assert(new S(y: 3, x: 2).x == 2);
static assert(    S(y: 3, x: 2).x == 2);
// opCall
struct Div
{
    static int opCall(int numer, int denom) { return numer / denom; }
}
static assert(Div(denom: 3, numer: 6) == 2);
struct Concat
{
	string s = "s";
    string opCall(string st0, string st1) { return s ~ st0 ~ st1; }
}
static assert(Concat.init("t0", "t1") == "st0t1");