Possible @property compromise
Zach the Mystic
reachBUTMINUSTHISzach at gOOGLYmail.com
Thu Jan 31 16:59:46 PST 2013
On Thursday, 31 January 2013 at 22:54:21 UTC, Steven
Schveighoffer wrote:
> C# has properties like this:
>
> property int foo {
> get {return _foo;}
> set {_foo = value;}
> }
>
> Your proposal looks like this:
>
> foo struct {
> int opGet() {return _foo;}
> void opSet(int value) {_foo = value;}
> }
>
> What I see is that the getter and setter are assigned specific
> contextual keywords (opGet vs. get, and opSet vs. set). It
> seems like a very similar (albeit more verbose) solution.
>
> What I had originally suggested for properties is this:
>
> property int foo {
> int get() {return _foo;} // only one getter allowed
> void set(int v) {_foo = v;}
> void set(float v) {_foo = (int)v;} // more than one setter
> allowed
> }
>
> I think these are all along the same line of solutions. I
> don't think they are bad, but clearly they weren't used 4 years
> ago, so it may be difficult to convince Walter to use them now.
>
>> My opGet is just another opXXX definable for all structs, not
>> just properties.
>
> I didn't see that, but I also don't really see the point of
> that. What value does opGet have unless it's a getter for a
> property?
>
>> I had said it was necessary to achieve structs as properties,
>> but I think I was wrong. It's just the equivalent of:
>>
>> int __someRandomFunction() { return _propValue; }
>> alias __someRandomFunction this;
>>
>> But it would be syntactically nicer, much like Highlander
>> structs are syntactically nicer. Therefore, the only language
>> change absolutely required would be making non-static structs
>> nested in structs behave like non-static structs nested in
>> functions, which they arguably should do anyway. Also under
>> the hood, some important optimizations getting rid of pointers
>> for data-less structs.
>
> This is a VERY bad idea. A struct is POD. For example,
> consider a range type for a container. You may not NEED to
> have a pointer to the container, so that is wasted bytes.
>
> Also note that structs are not meant to have internal pointers.
> So a "property" struct with an internal pointer
>
> The strange case for a struct type inside a function kind of
> makes sense, because of the ability to access the function's
> variables, and because you can't really move the stack frame.
>
> -Steve
I think my suggestion goes far beyond what you suspect. It goes
way beyond mere getting and setting of variables. Here is
basically how you implement a basic int as a property, assuming
my new syntax and language adjustments. You need: 1) a struct to
have the property in, which is just a normal struct. 2) An actual
integer which will be indirectly accessed by using the
properties. Let's call it "_n" and the property "n". 3) a struct
to hold all of the property functions which access _n. THIS
STRUCT CONTAINS NO DATA OF ITS OWN. 4) A bunch of methods
implementing all the operators you want. For int, that's quite a
lot, so I'll shorten it to a getter, a setter, and an adder. I'll
even leave out opGet and use an alias to what might as well be
opGet. I'll give the adder a little personality because what's
the point of properties if they don't do something different from
a basic type?
struct myStruct
{
int _n;
n struct
{
int __mightAsWellBeOpGet() { return _n; }
alias __mightAsWellBeOpGet this;
int opAssign(int newN) { _n = newN; return _n; }
int opBinary(string op) (int rhs)
{
static if (op == "+")
{
writeln("You sure are adding a funky int, my friend...");
return _n + rhs;
}
else static assert(0, "Operator "~op~" not implemented");
}
}
}
This is not some kind of special property implementation. n is a
struct. It has no data and therefore is a very peculiar kind of
struct. A struct with no data needs only one instance, ever.
Copying it is pointless. Taking its address is pointless.
Creating a new instance is pointless. Passing it by ref is
pointless. All operations which require more than one instance
are pointless, which is why it doesn't need a separately defined
type. The type and the instance can therefore use the same name,
n in this case.
Note that n uses the new rule which allows it access to its
parent's scope, the same way it would in a nested function. The
only pointer it needs is the same pointer used for myStruct,
since myStruct actually stores some data.
Using the int is as simple as:
myStruct foo;
foo.n = 4; // Calls opAssign
writeln(foo.n); // uses alias this to call __mightAsWellBeOpGet
writeln(foo.n + 4); // Calls opBinary. Prints:
You sure are adding a funky int, my friend...
8
There's literally nothing these properties can't do that a
full-fledged struct type couldn't do.
More information about the Digitalmars-d
mailing list