Proposal: real struct literals
Jarrett Billingsley
kb3ctd2 at yahoo.com
Tue Jun 24 13:30:28 PDT 2008
The status of struct literals and construction in D1 has always really
grated on me. So I've come up with a possible alternative syntax which
would supplant the current syntax. (I've reproduced this in an enhancement
request in bugzilla.)
The current struct literals use a function-call-looking style to construct
structs. This has some minor issues:
- If you define a static opCall for the struct, even if it isn't supposed to
be used as a "constructor", you can no longer use struct literals on that
struct. I'm not sure if this was an intended aspect of the design, but it
becomes annoying to implement that static opCall without using struct
literals!
- Once structs get real constructors, the opCall "blessing" becomes
superfluous, and I hope plans are in the works to remove it.
- Using a struct literal does not call a function, so it seems weird to use
syntax that looks like a function call to construct it.
The much more serious issue is that in terms of features and syntax, static
struct initialization and struct literals are *completely* different.
struct S
{
int x, y;
char[] s;
}
void foo()
{
static S s = { 5, y: 10, s: "hi!" };
auto s2 = S(5, 10, "hi!");
}
They have completely different syntax and features. Static struct
initializers are far more powerful: you can name members, initialize them
out of order, and skip arbitrary members. The struct literal syntax is far
more limited: you must initialize the members in order (which quickly gets
out of hand for more than 2 or 3 members), you can't name them, and you can
only skip members at the end of the struct.
So I propose that struct "literals" be replaced with actual struct literals,
which look like static struct initializers. There is a very obvious,
simple, unambiguous syntax for this: an identifier, followed by a static
struct initializer. Crazy, I know!
static s = S{ 5, y: 10, s: "hi!" };
auto s2 = S{ 5, y: 10, s: "hi!" };
Now struct literals have all the nice capabilities of static struct
initializers. Static struct initializers actually no longer have to be
special-cased. The declaration of s above expects the initializer to be
evaluatable at compile-time, just like any other static declaration, and so
the struct literal on the RHS now just has to contain all
compile-time-evaluatable values. No problem.
------
Dreaming, this also opens up the possibility for named function parameters.
Consider a function:
struct Args
{
void* dest;
void* src;
size_t num;
}
void memcopy(Args args)
{
// Copy args.num bytes from args.src to args.dest
}
...
memcopy(Args{ dst, src, 8 }); // Use ordered params
memcopy(Args{ src: a, dest: b, num: a.length }); // Use named params
The issue with this is that you have to have a different named struct for
every function that takes this style of parameters. But -- here's the cool
trick -- extend typesafe variadic parameters to take structures like they
already do for classes...
void memcopy(Args args...) // hee hee!
memcopy(dst, src, 8); // woah, looks like a normal function..
memcopy(src: a, dest: b, num: a.length); // bam, named params for free!
Having colons in the parameter list for a function call is also unambiguous.
More information about the Digitalmars-d
mailing list