Proposal: real struct literals

Robert Fraser fraserofthenight at gmail.com
Tue Jun 24 14:10:23 PDT 2008


Jarrett Billingsley Wrote:

> 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. 

Usually I like to find one thing to argue with in these proposals, but that
sounds about perfect. Mad props for typing this all up, though I'm not sure
it'll get anywhere. Try Bugzilla, too.




More information about the Digitalmars-d mailing list