-
-
Notifications
You must be signed in to change notification settings - Fork 740
Add std.typecons.HeadConst #2881
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
this(Args...)(auto ref Args args) | ||
if(__traits(compiles, T(args))) | ||
{ | ||
this.data = data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.data = T(args); ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would do exactly the same thing.
edit:
Added a test for construction with multiple arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I see, your code is the same as
this.data = this.data;
which is practically a no-op. Your unittest does not check if any field actually gets assigned. Of course it compiles, but it does not do anything meaningful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I intended to do this.data = args;
. Thanks!
fe0821e
to
d309a1e
Compare
How about calling it |
D1 programmers, but also Java programmers. |
If someone knows what a final class is, then they've probably used Java, and so they probably know what it means to mark a variable as final. |
I also find |
+1 for naming it |
Renamed it to |
LGTM! @andralex can we get an approval for this? |
{ | ||
int i; | ||
|
||
pure nothrow @safe: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tabs2spaces please.
No |
|
||
public: | ||
/// $(D HeadConst) subtypes $(D T) as an rvalue. | ||
inout(T) HeadConst_get() inout pure nothrow @nogc @safe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually a public function we want users to be able to use? I realize it probably needs to be public for the bellow alias to work, but let's not document it that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not pure nothrow (etc...), as it depends on the attributes applied to T's postblit.
Speaking of which, it might be worth having a const-by-ref overload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually a public function we want users to be able to use? I realize it probably needs to be public for the bellow alias to work, but let's not document it that way.
Yeah, it's public for AliasThis to work. I chose to document it because it's currently not possible to document an AliasThis declaration with DDoc, but it could simply be mentioned in the type description instead.
This is not pure nothrow (etc...), as it depends on the attributes applied to T's postblit.
You're right, I was hoping the postblit operator would be called in the environment of the callsite :( Removing the explicit attributes and relying on inference seems to work well.
Speaking of which, it might be worth having a const-by-ref overload.
I tried this, but the const-by-ref overload is never chosen when the this-reference is const
, and when I make it inout
like the other overload, I get "matches both" errors.
I like the idea, but I am less than thrilled about the following behavior: import std.stdio;
struct S
{
int i;
void doit() {
++i;
}
}
void main()
{
HeadConst!S s;
s.i = 5; //No-op
writeln(s.i);
s.doit(); //No-op
writeln(s.i);
} I realize S is a value type, but still. At the very least, I argue that for non-explicit reference types (classes, pointers, interfaces), than alias this should simply resolve to a const variable. Accessing a mutable copy should be done via an explicit "get()" or "copy()" or something. Having alias this do anything more than return a ref to a field has always led to problems at one point or another... |
Ouch, didn't notice that one. Maybe some
I think this type is much less appealing if it's not a drop-in replacement for
Although it would make the implementation much more involved, we could always go the |
I'm going to close this for now and prioritise other things. If someone wants to spearhead this they are more than welcome to pick up where I left it. I think a correct implementation needs to use operator overloading (notably |
A simple type constructor that replicates the functionality of the now-defunct
final
variable storage class, allowing for easy creation of "read-only" variables and fields without going the full mile with transitive immutability. UsingFinal
is quite a bit shorter than using a private variable with a public getter, and it's easier to get right since using a property correctly requires understanding ofinout
and the various function attributes. I guess it's also a nice thing to point to when queried about by Java programmers, and maybe even useful for porting Java code to D.Please destroy.