January 30, 2013
On Tuesday, 29 January 2013 at 18:54:09 UTC, H. S. Teoh wrote:
> 	class Rectangle {
> 		float width, height;
>
> 		// Struct implementation of @property
> 		struct AreaProp {
> 			float value() {
> 				// Error: can't access Rectangle.width
> 				// and Rectangle.height
> 				return width*height;
> 			}
> 			alias value this;
> 			...
> 		}
> 		AreaProp area;
> 	}

Also, I has assumed that opCall or opGet would make more sense than how you did it:

struct AreaProp {
  float opGet() { ... }
  ...
}

Why "alias this" in your version instead of opCall or opGet?
January 30, 2013
On Wednesday, 30 January 2013 at 05:44:36 UTC, Zach the Mystic wrote:
>
> Why "alias this" in your version instead of opCall or opGet?

opCall requires parens, probably to disambiguate from alias this.

string A
{
  int i;
  int opCall() { return _i; }

}

A a,

int i = a; // error
int i = a(); // works

You can however do this

alias opCall this;

int i = a; // works
int i = a(); // works too

--rt
January 30, 2013
On Wed, Jan 30, 2013 at 06:24:56AM +0100, Zach the Mystic wrote:
> On Wednesday, 30 January 2013 at 05:20:51 UTC, Zach the Mystic wrote:
> >You know, I was too dumb to even understand what you wrote when I read it the first time. I was just naively assuming that nested structs were like nested functions. Some rules definitely need to be figured out here. I don't see why the basic functionality which is provided for nested functions couldn't work also for nested structs. Does "static struct" mean anything here? Couldn't it be used exactly like static nested functions? Would it break code if we now forced people to say "static struct" instead of just struct?
> >
> >I'm sorry for missing your point. I'm trying to suggest advanced language features without even knowing some of the basics. I ask you to bear with me.
> 
> Wait, hold on there! This says otherwise: http://dlang.org/struct.html
> 
> So what's up? Who's wrong!?

That page only states the structs nested inside *functions* have a context pointer to the function's local variables. It says nothing about structs nested inside *structs*. (And yes, I looked. I was actually in the middle of writing something about using structs to simulate properties, and decided to look it up to be sure, and found that the spec actually doesn't say what I thought it said.)


T

-- 
Help a man when he is in trouble and he will remember you when he is in trouble again.
January 30, 2013
On Sunday, 27 January 2013 at 18:12:48 UTC, Artur Skawina wrote:
> struct Plain
> {
>     int a;
> }
> 
> struct Tricky
> {
>     int a;
>     Plain opCall() { return Plain.init }
> }
> 
> void func(int) { }
> 
> // What happens?
> Tricky t;
> t.a.func();

I suppose func is called with Tricky.a, because t is a variable not a function.

But, by the way, what are the exact rules of this thing we call "optional parentheses"? Perhaps this:

"Empty parentheses may be omitted when calling functions with a user-defined name."

That leaves operators, delegates, function pointers, and function objects outside of that rule, because they aren't functions with a name. But, parens could be omitted with functions whose all arguments have default values.
January 30, 2013
On Wednesday, 30 January 2013 at 16:39:55 UTC, TommiT wrote:
> "Empty parentheses may be omitted when calling functions with a user-defined name."

Sorry, bad wording. Better one:

"Empty parentheses may be omitted when calling a function that has a user-defined name."
January 30, 2013
On Wednesday, 30 January 2013 at 16:45:04 UTC, TommiT wrote:
> "Empty parentheses may be omitted when calling a function that has a user-defined name."

"... except when the address of the returned value is requested directly after the function call, then parentheses are required."
January 30, 2013
On Wednesday, 30 January 2013 at 06:46:01 UTC, H. S. Teoh wrote:
> That page only states the structs nested inside *functions* have a
> context pointer to the function's local variables. It says nothing about
> structs nested inside *structs*. (And yes, I looked. I was actually in
> the middle of writing something about using structs to simulate
> properties, and decided to look it up to be sure, and found that the
> spec actually doesn't say what I thought it said.)
>
>
> T

Okay, cool. Two questions remain: 1) How hard to implement structs nested in structs to mimic ones nested in functions? 2) How much code breakage?
January 30, 2013
On Wednesday, 30 January 2013 at 06:38:32 UTC, Rob T wrote:
> opCall requires parens, probably to disambiguate from alias this.
>
> string A
> {
>   int i;
>   int opCall() { return _i; }
> }
>
> A a,
>
> int i = a; // error
> int i = a(); // works
>
> You can however do this
>
> alias opCall this;
>
> int i = a; // works
> int i = a(); // works too
>
> --rt

I guess that's how to do it. So now we have all three. Mandate parens with opCall. Allow both with alias opCall this, and disallow parens with opGet.

So let's go back to my previous argument. Aside from a few language changes, such as making current nested structs into nested static structs, and introducing opGet, a @property is nothing but a poor man's struct. Destroy.
January 30, 2013
30-Jan-2013 21:02, Zach the Mystic пишет:
> On Wednesday, 30 January 2013 at 06:46:01 UTC, H. S. Teoh wrote:
>> That page only states the structs nested inside *functions* have a
>> context pointer to the function's local variables. It says nothing about
>> structs nested inside *structs*. (And yes, I looked. I was actually in
>> the middle of writing something about using structs to simulate
>> properties, and decided to look it up to be sure, and found that the
>> spec actually doesn't say what I thought it said.)
>>
>>
>> T
>
> Okay, cool. Two questions remain: 1) How hard to implement structs
> nested in structs to mimic ones nested in functions?


IMO if property is to be implemented in the library it has to include the field itself. (And I suspect properties should enjoy compiler support).

Then something like:

struct A{
	Property!(int, filter, getter) prop;
private:
	void func()
	{
		...
		prop.raw = xxx; //direct write
		prop = yyy; //goes through setter
	}
}

where .raw is the field itself and there must be a way to let only struct itself have access to it. I have one method to get this but I don't like it - put this in each module:

mixin PropertyForModule!(my_module);

introducing a Property template in this module, with private .raw accessible thusly only in this module.

Getter is then just any function that maps T => T, with x => x  by default so can be omitted.

Filter is something new but in essence it works like the following setter:

void setter(T)(ref T val, T newVal)
{
	val =  filter(newVal); //filter may through
}

It's a bit more restrictive though so feel free to destroy.

> 2) How much code
> breakage?

A lot + subtly wasting memory.

-- 
Dmitry Olshansky
January 30, 2013
On Wednesday, 30 January 2013 at 17:02:44 UTC, Zach the Mystic wrote:
> [..] 1) How hard to implement structs nested in structs to mimic ones nested in functions?

Given:

struct Outer {
    struct Inner {
        int n1;
    }
    int n2;
}

Outer.sizeof should be equal to 2 * int.sizeof, because there's no point in introducing any overhead here. Whereas structs inside functions do their magic by having an implicit pointer, which increases their size. I don't think we want to introduce any memory overhead with something as insignificant as properties.