February 01, 2013
On Friday, 1 February 2013 at 03:33:05 UTC, Zach the Mystic wrote:
> On Friday, 1 February 2013 at 03:28:05 UTC, TommiT wrote:
>> On Friday, 1 February 2013 at 03:08:12 UTC, Zach the Mystic wrote:
>>> alias template theFuncIActuallyWant this;
>>>
>>> int theFuncIActuallyWant() { return 1; }
>>>
>>> ...in order to have it pass the right thing to the template parameter? That's just a jury rigged syntax which might help structs make more sense to the compiler when passed through templates.
>>
>> None of the alias this conversions are even looked at when you pass a variable to a templated parameter. The template simply conforms to whatever type the passed variable is. No conversions ever happen. That's just how templates work in D. I can't right off the bat say that it's impossible to design a language where templates perform conversions. But it's safe to say that it's not happening with this language. It would be a huge change.
>
> What I meant to suggest was an actual new feature which would allow one preferred argument to be passed to a template.

Frankly, it was your use of the word "insurmountable" which rubbed me the wrong way, but I reach the limits of my awareness at this point.
February 01, 2013
On 1/31/13 10:14 PM, Jonathan M Davis wrote:
> On Friday, February 01, 2013 01:01:02 Jesse Phillips wrote:
>> I think his suggestions need implemented regardless of what we do
>> with @property. I think Walter just felt this would appease the
>> pro-property.
>
> Well, it doesn't even come close. For the most part, the pro-@property folks
> want explicit proprties, and that's precisely what Walter is proposing that we
> get rid of.
>
>> writeln = "hi" would not compile with Walters suggested changes.
>
> Only because it's variadic. Something like
>
> range.popFrontN = 7;
>
> _would_ compile. And that's just as bad. We need explicit setter properties in
> order to avoid letting assignment work with functions where it makes no sense
> for it to work.

Under some proposals range.popFrontN = 7 would not compile because there's no corresponding range.popFrontN that yields an int.

Andrei

February 01, 2013
On Friday, 1 February 2013 at 03:13:42 UTC, Zach the Mystic wrote:
> On Friday, 1 February 2013 at 02:27:30 UTC, TommiT wrote:
>> And here's another example of why it is as big of a problem as I make it sound to be:
>>
>> import std.concurrency;
>>
>> struct Array
>> {
>>    int _len;
>>
>>    length struct // Using Zach's syntax
>>    {
>>        @property get() { return _len; }
>>        alias this = get;
>>        void opAssign(int rhs) { _len = rhs; }
>>    }
>> }
>>
>> void func(T)(T t)
>> {
>>    auto v = t;
>>    v = 10;
>> }
>>
>> void main()
>> {
>>    Array arr;
>>    spawn(&func!int, arr.length);
>>    arr.length = 20; // And here we have a data-race.
>>                     // Good luck trying to find these
>>                     // kinds of bugs.
>> }
>
> I'm sorry, I know very little about race conditions. If you might explain just a little bit about what is happening here, I'd be in a better position to understand what you're saying. I really can't say anything other than please describe what this does and why it's a problem at this time.

spawn(&func!int, arr.length);

...creates a new thread and runs the following function call in it:
func!(int)(arr.length)

While that function call is evaluating in the new thread, the old thread may simultaneosly execute:
arr.length = 20;

Since both of those threads end up at some point calling arr.length.opAssign and therefore both of them may assign to arr._len simultaneously, that's a data-race. It would be data-race also if only one of them wrote to it and the other one just read it.
February 01, 2013
On Friday, 1 February 2013 at 03:23:09 UTC, Zach the Mystic wrote:
> I think it might mean "it is used" since I don't know why it would use "is" instead of the opCast. If that's true, just override opCast(string), no?

Yes, there's probably a way to pass to writeln by providing opCast(string). But we're not talking only about writeln here, we're talking about all function templates being a potential problem.

February 01, 2013
On Friday, 1 February 2013 at 03:39:19 UTC, TommiT wrote:
> On Friday, 1 February 2013 at 03:13:42 UTC, Zach the Mystic wrote:
>> On Friday, 1 February 2013 at 02:27:30 UTC, TommiT wrote:
>>> And here's another example of why it is as big of a problem as I make it sound to be:
>>>
>>> import std.concurrency;
>>>
>>> struct Array
>>> {
>>>   int _len;
>>>
>>>   length struct // Using Zach's syntax
>>>   {
>>>       @property get() { return _len; }
>>>       alias this = get;
>>>       void opAssign(int rhs) { _len = rhs; }
>>>   }
>>> }
>>>
>>> void func(T)(T t)
>>> {
>>>   auto v = t;
>>>   v = 10;
>>> }
>>>
>>> void main()
>>> {
>>>   Array arr;
>>>   spawn(&func!int, arr.length);
>>>   arr.length = 20; // And here we have a data-race.
>>>                    // Good luck trying to find these
>>>                    // kinds of bugs.
>>> }
>>
>> I'm sorry, I know very little about race conditions. If you might explain just a little bit about what is happening here, I'd be in a better position to understand what you're saying. I really can't say anything other than please describe what this does and why it's a problem at this time.
>
> spawn(&func!int, arr.length);
>
> ...creates a new thread and runs the following function call in it:
> func!(int)(arr.length)
>
> While that function call is evaluating in the new thread, the old thread may simultaneosly execute:
> arr.length = 20;
>
> Since both of those threads end up at some point calling arr.length.opAssign and therefore both of them may assign to arr._len simultaneously, that's a data-race. It would be data-race also if only one of them wrote to it and the other one just read it.

I'm familiar with the fact that programmers face endless woes with regard to data-races. I thought that D has unshared data by default. But since Array arr is defined in main instead of outside main, therefore it is sharable between the two threads? If two threads have access to the same data, what makes length as a property different from length as an int? This problem may be over my head for now...
February 01, 2013
On Friday, 1 February 2013 at 03:44:51 UTC, TommiT wrote:
> On Friday, 1 February 2013 at 03:23:09 UTC, Zach the Mystic wrote:
>> I think it might mean "it is used" since I don't know why it would use "is" instead of the opCast. If that's true, just override opCast(string), no?
>
> Yes, there's probably a way to pass to writeln by providing opCast(string). But we're not talking only about writeln here, we're talking about all function templates being a potential problem.

Not really sure what you mean. I have a bunch of thoughts, but my overall knowledge of these things is too little, I'm afraid. If you're interested, I'd like an example of how the templates will be so much of a problem, illustrating the collision between the two core language features in question.
February 01, 2013
On Thu, 31 Jan 2013 19:59:46 -0500, Zach the Mystic <reachBUTMINUSTHISzach@googlymail.com> wrote:

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

No, the struct must have data.  If it doesn't, how does it get back to the owner type?  In other words, your n struct must have a pointer to the myStruct instance it intends to modify _n on.

Unless, of course, you pass the pointer to myStruct as the 'this' reference.  But then, this isn't a normal struct, and I'm really failing to see why we have to make this a struct at all.

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

FYI, nested structs in functions (the ones you want to use as a model) have an extra hidden reference pointer back to the stack frame data.  That is how they can access the local variables of the function.

This proposal looks way too complicated.  I don't see how it's a win over the current state of affairs, or even the @property implementation we expected to get but didn't.  You need to solve the "owner pointer" problem before it's even viable.

-Steve
February 01, 2013
On Thu, 31 Jan 2013 22:38:04 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 1/31/13 10:14 PM, Jonathan M Davis wrote:
>> On Friday, February 01, 2013 01:01:02 Jesse Phillips wrote:
>>> I think his suggestions need implemented regardless of what we do
>>> with @property. I think Walter just felt this would appease the
>>> pro-property.
>>
>> Well, it doesn't even come close. For the most part, the pro-@property folks
>> want explicit proprties, and that's precisely what Walter is proposing that we
>> get rid of.
>>
>>> writeln = "hi" would not compile with Walters suggested changes.
>>
>> Only because it's variadic. Something like
>>
>> range.popFrontN = 7;
>>
>> _would_ compile. And that's just as bad. We need explicit setter properties in
>> order to avoid letting assignment work with functions where it makes no sense
>> for it to work.
>
> Under some proposals range.popFrontN = 7 would not compile because there's no corresponding range.popFrontN that yields an int.

I don't think this rule is good enough.

You are inviting strange properties to invade your types, especially with the advent of UFCS.

-Steve
February 01, 2013
On 1/31/13 11:41 PM, Steven Schveighoffer wrote:
> On Thu, 31 Jan 2013 22:38:04 -0500, Andrei Alexandrescu
> <SeeWebsiteForEmail@erdani.org> wrote:
>
>> On 1/31/13 10:14 PM, Jonathan M Davis wrote:
>>> On Friday, February 01, 2013 01:01:02 Jesse Phillips wrote:
>>>> I think his suggestions need implemented regardless of what we do
>>>> with @property. I think Walter just felt this would appease the
>>>> pro-property.
>>>
>>> Well, it doesn't even come close. For the most part, the
>>> pro-@property folks
>>> want explicit proprties, and that's precisely what Walter is
>>> proposing that we
>>> get rid of.
>>>
>>>> writeln = "hi" would not compile with Walters suggested changes.
>>>
>>> Only because it's variadic. Something like
>>>
>>> range.popFrontN = 7;
>>>
>>> _would_ compile. And that's just as bad. We need explicit setter
>>> properties in
>>> order to avoid letting assignment work with functions where it makes
>>> no sense
>>> for it to work.
>>
>> Under some proposals range.popFrontN = 7 would not compile because
>> there's no corresponding range.popFrontN that yields an int.
>
> I don't think this rule is good enough.
>
> You are inviting strange properties to invade your types, especially
> with the advent of UFCS.

I agree. Was just sayin'.

Andrei

February 01, 2013
On Thu, 31 Jan 2013 19:01:02 -0500, Jesse Phillips <Jessekphillips+D@gmail.com> wrote:

> On Thursday, 31 January 2013 at 01:26:19 UTC, Steven Schveighoffer wrote:
>> On Tue, 29 Jan 2013 23:57:14 -0500, Jesse Phillips <Jessekphillips+d@gmail.com> wrote:
>>
>>> Sorry I have to oppose this. It is in no way a compromise as it is completely different from everything suggested. I'm going to take this opportunity to highjack your thread.
>>
>> You are welcome to it!  I don't know if there is a thread on this newsgroup about properties that hasn't been hijacked.
>
> Thank you.
>
>> I should explain that my reasoning behind this is:
>>
>> 1. Walter wants to get rid of @property
>
> I can't really speak to what Walter wants, but I think there is more to it than removing a keyword.

I meant the @property design, including the keyword.  Basically whatever @property was supposed to stand for.

>> The compromise is: OK, you want to ditch @property?  I can live with that as long as we have some way to designate properties.  How about this?
>
> I don't think that is a compromise as i don't believe it is @property that is slated for removal, it is designating something a property.

I don't think that's the case.  D1 has a designation of what is a property -- if it has no arguments it is a getter, if it has a single argument it is a setter.

The extra rules Walter is proposing are a half-baked design that covers some cases.  But the rules are controlling the behavior based on superficial observations instead of allowing an author to express specific intents.  It sounds like something Congress would come up with...

>>> Can an pro-@property members claim that the current behavior is what you want? I believe this answer is no.
>>
>> The answer is no, but only because what we asked for was never implemented.  What was ORIGINALLY designed with @property (enforcement of parentheses on functions, enforcement against parentheses on properties) is what we wanted.
>
> Yep, totally thought that was coming. I'd still be ok with it, but I'm still partial to not having it enforced, would rather see field -> property a seamless transition.

First, it's not seamless without a keyword or special syntax (remember the delegate problem).  Second, that's not a mutually exclusive choice.  If you enforce property syntax, then it's still seamless (and even more so since you actually *CAN* implement what is desired).

>>> It seems at least some members for @property feel that currently functions are being annotated with @property that shouldn't be.
>>
>> This is unavoidable.  It's like saying I feel some functions are incorrectly named.  @property has nothing to do with it.  There is no "right" answer to whether something should be a @property or not, just like there is no "right" name for a function.
>
> Yes, but I was thinking more on the degree of wrongness that is currently acceptable. Something to think on for what my proposal would be. But again, I don't care about the appearance, only behavior.

Then why ever have properties at all?  Functions work just fine.

>>> It also seems those for @property aren't fighting optional parens as much? Can we discuss fixing the issues we have with this. I think a good change is to require parens if returning a callable (opposite of Walters suggestion).
>>
>> Yes, if the choice is between having the previous implementation (D1) and optional parentheses with a way to designate properties, I'll choose the latter.
>
> Walter's suggestion isn't (D1) implementation it address some concerns with the existing behavior, but doesn't give you a way to declare properties.

I think you are misunderstanding his proposal.  Under his proposal, two completely unrelated and unconnected functions could combine together to allow a setter that is completely unintended.  Instead of specifying intent, we have to jump through the compiler hoops to avoid accidental intent.  This is not a solution, it's actually worse than D1 style properties.  You'll have code that can call a 'setter' on an object or struct with no 'getter' and you'll have no idea why.

> I think his suggestions need implemented regardless of what we do with @property. I think Walter just felt this would appease the pro-property.

I certainly hope none of his suggestions are implemented, they will only confuse the situation.

>>> If I have my above claims mostly correct, then I'd say @property needs to be put back in the drawing board and re-implemented.
>>
>> If you want to replace @property, we need a replacement.  @property still serves a purpose, even in it's currently crippled form.
>
> What purpose is that? Isn't it a no-op by default, and barely enforce () with -property?

The purpose is to specify intent "I declare this is a property, use it that way".  It's the whole point of having a property syntax.  It's just not enforced by the compiler.

The compiler has numerous bugs on it, that doesn't mean the features should be ditched, it means we have to correctly implement those features.  array.dup allows implicit casting away from immutable (at least it did, not sure if that was fixed).  Does that mean we should get rid of dup?

>>> I'd be for removing it from the language and if we decide on what in needs to enforce and should be part of the language, then its implementation is completed in a feature branch and remains out of the language until it meets the needed enforcement and behavior.
>>
>> Fine, but leave @property in until you have completed the replacement feature.
>
> I'm not sure if we are going to have a complete replacement, but your right, we can leave it in until such a choice is finalized, but let us get rid of -property.

That doesn't hurt anything, that switch is an experimental feature, and once we have the blessed property syntax, we likely will need that experimental feature to obey the new syntax.

>> The real fact of the matter is, if D never had the "hack" properties it did, I actually wouldn't care.  Calling functions instead of setting or getting properties is not that horrible.  But writeln = "hi" is horrible.
>
> Yep, introducing properties would have been easy, because no one would have fallen for the joys of optional parens.

I see only minor issue with optional parens.  It's the setters that are the most disruptive.

> writeln = "hi" would not compile with Walters suggested changes.

No, but other abuses would.

>> In general, the idea is to implement fields without having to create storage for them.  It will never perform as well as a field.
>
> I know, but you can't trust when reading code that is what happens. And having that convention was being argued for, I like Walter's position of having the compiler make guarantees and not conventions (I'm sure I've got some exception I'd want but can't think of one).

The compiler cannot make performance guarantees of any kind really.  That is up to convention.  Properties do provide a *mechanism* to create a convention.  What the convention is remains the will of the author.

>> In other words, go back to D1 properties.  No thanks.
>
> Again, it wouldn't be D1, and we aren't going back because that is what we currently have. We need to fix it.

OK, I stand corrected, if it is a choice between D1 properties and Walter's new rules, I'll choose D1 properties.  At least I know what I get there.  But if we have *any* property syntax at all, I'd prefer that.  Even the current design, while not implemented, has the PROMISE of having a fully functional property syntax.  I prefer the promise of something that is usable to something that is utterly useless, even if it's already implemented.

-Steve