On Saturday, 15 December 2012 at 20:20:10 UTC, H. S. Teoh wrote:
On Sat, Dec 15, 2012 at 12:02:16PM -0800, Jonathan M Davis
wrote:
On Saturday, December 15, 2012 11:45:10 H. S. Teoh wrote:
> Ironically enough, Andrei in the subsequent paragraph
> discourages
> the use of such nested structs, whereas Walter's article
> promotes
> the use of such Voldemort types as a "happy discovery". :)
No, the real irony is that it's Andrei who promoted them in
the first
place. :)
Heh. :)
We _are_ finding some serious issues with them though (e.g.
they don't
work with init and apparently can't work with init), and there
has
been some discussion of ditching them due to such issues, but
no
consensus has been reached on that.
[...]
Hmm, that's true. They can't possibly work with init: if you do
something like:
auto func(int x) {
struct V {
@property int value() { return x; }
}
return V();
}
auto v = func(123);
auto u = v.init; // <-- what happens here?
writeln(u.value); // <-- and here?
It seems that we'd have to make .init illegal on these Voldemort
structs. But that breaks consistency with the rest of the
language that
every type must have an .init value.
Alternatively, .init can implicitly create a context where the
value of
x is set to int.init. But this is unnecessary (it's supposed to
be a
*Voldemort* type!) and very ugly (why are we creating a
function's local
context when it isn't even being called?), not to mention
useless
(u.value will return a nonsensical value).
Or, perhaps a less intrusive workaround, is to have .init set
the hidden
context pointer to null, and you'll get a null deference when
accessing
u.value. Which is not pretty either, since no pointers or
references are
apparent in V.value; it's implicit.
It seems that the only clean way to do this is to use a class
instead of
a struct, since the .init value will conveniently just be null,
thereby
sidestepping the problem.
T
auto func(int x) {
struct V {
int value() { return x; }
@property V init() { return this; }
}
return V();
}
auto v = func(123);
auto u = v.init; // <-- what happens here?
auto x = u.value;
writeln(x);
If you add an init property then it is not null. I'm not sure if
this is the correct behavior as I just jumped into this
discussion and I'm not sure if I understand exactly what the
problem with these types of structs are. (as far as I can tell
they simply let you pass "sets" of data from a function rather
easily while also keeping the details hidden(impossible to
directly instantiate the struct since it is hidden inside the
func)
In any case, when stepping through the code above, I noticed that
init being called but resulting in u.value throwing a null
exception. so I added an init property to V and then got the
expected behavior. Probably too easy to be the correct solution
but who knows ;)