digitalmars.D - Property syntax revisited
- John C (65/65) Jan 04 2006 As I see it, the problem with D's property syntax is that they're actual...
- S. Chancellor (18/30) Jan 04 2006 Your example seems a bit odd to me as the setter can have a different in...
- Sean Kelly (6/40) Jan 04 2006 I think a property syntax is a reasonable idea so long as we don't lose
- John C (4/47) Jan 04 2006 Yes, I find it useful too. But there's no reason why a property block
- Fredrik Olsson (26/32) Jan 05 2006 My $0.02 (I like that one :) ).
- Ivan Senji (7/32) Jan 05 2006 I am strongly in favor for adding extendable properties to *all* types
- Fredrik Olsson (7/46) Jan 05 2006 In 99% of the cases indexes are probably int and char[]. But allowing
- Ivan Senji (9/21) Jan 05 2006 I think there might be a missunderstanding here. I will try to explain
- Don Clugston (3/31) Jan 05 2006 I love it. Especially if it meant that properties could be added to any
- Fredrik Olsson (5/37) Jan 05 2006 I can not see why this could not be made to work with any type. But then...
- Ivan Senji (14/20) Jan 05 2006 I find it really useful too, but wouldn't agree on the unchanged part.
- John C (4/11) Jan 04 2006 It was an attempt to avoid context-sensitive keywords, which Walter's no...
- S. Chancellor (11/22) Jan 04 2006 It can as long as I type it twice. If there's a restriction that it has
- James Dunne (2/33) Jan 04 2006 Well said!
- James Dunne (48/123) Jan 04 2006 Properties are meant to have the same semantics as methods, NOT fields.
- Derek Parnell (28/44) Jan 04 2006 And current D syntax:
- S. Chancellor (8/24) Jan 04 2006 I don't know that I like the idea of having properties accept more than
- Derek Parnell (11/15) Jan 04 2006 Why?
- Chris Sauls (24/34) Jan 04 2006 I proposed something similar to this many ages ago. Mine looked like:
-
James Dunne
(14/58)
Jan 04 2006
- Chris Sauls (4/19) Jan 05 2006 No worries, actually what you say makes perfectly good sense. I probabl...
- James Dunne (5/29) Jan 05 2006 Ouch. Yeah this whole week I'm pulling 10-12 hour shifts, 9am to 9pm or...
- Derek Parnell (35/60) Jan 04 2006 However, there is no necessary requirement for a property to be implemen...
- Chris Sauls (8/31) Jan 05 2006 Actually, Derek, I think I like your refined proposal, even the new use ...
- Kris (31/65) Jan 05 2006 Not so much the purpose of properties, but the purpose of behavioral
- Derek Parnell (23/51) Jan 05 2006 Yes, I understood all of that but the difference is in how you refer to ...
- Kris (14/30) Jan 05 2006 Isn't that's just a naming concern? The method approach could just as ea...
- Chris Sauls (5/9) Jan 05 2006 It does, although the last time I tried playing with this syntax, it wou...
- Kris (5/14) Jan 05 2006 OK, Gotcha. I think that's still the case? It seems to be that it always...
- Kris (14/25) Jan 05 2006 This is a refactoring issue, which is surely a much larger problem than ...
- S. Chancellor (8/26) Jan 04 2006 I fully agree with your here. I'm glad to find out I'm not alone in the
- John C (31/155) Jan 05 2006 I just hadn't considered it. Makes sense to allow that.
- Chris Sauls (9/16) Jan 05 2006 Clearer, yes... Better, no, IMHO. :) I don't see the utility in requi...
- John C (4/21) Jan 05 2006 I think I see what you're getting at - like overloads, but contained wit...
- Chris Miller (17/17) Jan 05 2006 How about simply adding a 'property' attribute? The compiler could at
- Kris (7/23) Jan 05 2006 I'm still trying to get a handle on this, Chris, so please forgive the
- Chris Miller (7/41) Jan 05 2006 No, so that you can't use properties as functions and you can't use
- Kris (43/52) Jan 05 2006 I'll admit that I don't see a solid semantic distinction (at the code-us...
- tj0258 gmail.com (22/75) Jan 05 2006 I myself see setters & getters being different from ordinary functions:
- Zeljko (29/36) Jan 06 2006 some
- Zeljko (19/42) Jan 06 2006 Along this lines proposal for D can be (taking in account that
As I see it, the problem with D's property syntax is that they're actually methods, and the compiler has to try to disamiguate between method and property calls/assignments, which it's not 100% successful at - sometimes you have to add a pair of parentheses '()' when using a property to stop the compiler from choking (for example, when used in conjunction with 'auto'). Another issue is that it introduces ambiguity in the way they are called, and users have no way of knowing how they are intended to be used - 'my.name("John")' or 'my.name = "John"'. The other issue is that properties have the semantics of fields, not methods (even if, in the end, the compiler just generates the same code as for a method). They just don't feel like first-class citizens. I'd like to suggest a new syntax that I think addresses these issues. The only downside is the addition of a new keyword, 'property'. But otherwise it's quite elegant and is only slightly more verbose than the current syntax (the keyword itself). It's basically a way of grouping a pair of getters and setters in a 'property block'. Here's a class that utilises it. class Person { private float weight_; // Manually written backing store for 'weight' property protected void onWeightChanged() { // Warn of heart attack risk if above a certain weight } property weight { // 'weight' property block float() { // This defines the signature of the getter return weight_; } void(float value) { // This defines the signature of the setter; // setters must have a void return type weight_ = value; onWeightChanged(); } } // end 'weight' property block // In this property block, we don't provide definitions, // which tells the compiler to generate a backing store // and the definitions on our behalf. // Let's call it a 'simple property'. property height { float(); void(float); } // property block with getter only property bmi { float() { return weight / (height * height); } } } Some notes: 1) Any attempt to define a setter with an argument type that doesn't match that of the getter return type would be an error (and vise versa). 2) Different protection attributes can be applied to the getter and setter, as with methods. 3) For property blocks without manual definitions (as in the 'height' example above), either the getter or setter signature can be omitted, making them either read- or write-only, which distinguishes them from public fields. 4) Within the scope of a property block, use of the property name itself is legal, since the compiler knows to refer to the automatically generated backing store (as opposed to introducing a recursive call). No doubt there will be objections to this notation, so fire away. But I require three contextual keywords: 'get', 'set' and 'value') and the current D syntax.
Jan 04 2006
In article <dphgrp$nbt$1 digitaldaemon.com>, John C says....... property weight { // 'weight' property block float() { // This defines the signature of the getter return weight_; } void(float value) { // This defines the signature of the setter; // setters must have a void return type weight_ = value; onWeightChanged(); } } // end 'weight' property blockYour example seems a bit odd to me as the setter can have a different input type from the getter. If you're going to go the way of implementing a whole property block it seems that they should have their type specified in the property area. IE: float weight_; property float weight { get { return weight_; } set { weight_ = weight; } } If there is a requirement that a property be able to return differen types, the casting features of D should take over. IMHO. -S.
Jan 04 2006
S. Chancellor wrote:In article <dphgrp$nbt$1 digitaldaemon.com>, John C says...I think a property syntax is a reasonable idea so long as we don't lose the ability to use free functions as properties. I'm finding it quite useful that I can even replace global variables with no-argument functions and leave all other code unchanged. Sean.... property weight { // 'weight' property block float() { // This defines the signature of the getter return weight_; } void(float value) { // This defines the signature of the setter; // setters must have a void return type weight_ = value; onWeightChanged(); } } // end 'weight' property blockYour example seems a bit odd to me as the setter can have a different input type from the getter. If you're going to go the way of implementing a whole property block it seems that they should have their type specified in the property area. IE: float weight_; property float weight { get { return weight_; } set { weight_ = weight; } } If there is a requirement that a property be able to return differen types, the casting features of D should take over. IMHO.
Jan 04 2006
"Sean Kelly" <sean f4.ca> wrote in message news:dphn95$s0l$1 digitaldaemon.com...S. Chancellor wrote:Yes, I find it useful too. But there's no reason why a property block couldn't be valid for modules as well.In article <dphgrp$nbt$1 digitaldaemon.com>, John C says...I think a property syntax is a reasonable idea so long as we don't lose the ability to use free functions as properties. I'm finding it quite useful that I can even replace global variables with no-argument functions and leave all other code unchanged..... property weight { // 'weight' property block float() { // This defines the signature of the getter return weight_; } void(float value) { // This defines the signature of the setter; // setters must have a void return type weight_ = value; onWeightChanged(); } } // end 'weight' property blockYour example seems a bit odd to me as the setter can have a different input type from the getter. If you're going to go the way of implementing a whole property block it seems that they should have their type specified in the property area. float weight_; property float weight { get { return weight_; } set { weight_ = weight; } } If there is a requirement that a property be able to return differen types, the casting features of D should take over. IMHO.Sean
Jan 04 2006
Sean Kelly skrev:S. Chancellor wrote:<snip>I think a property syntax is a reasonable idea so long as we don't lose the ability to use free functions as properties. I'm finding it quite useful that I can even replace global variables with no-argument functions and leave all other code unchanged.My $0.02 (I like that one :) ). 1. IMHO it is bad to be able to call both as function and as property, it confuses adopters. 2. Breaking backward compatibility for properties is too late(?). 3. I want more syntactic sugar! Today we have int length(char[] str); That can be called in two ways: 1. int bar = length(foo); 2. int baz = foo.length; Why not add a "property" modifier, like this; property int length(char[] str); And now the 1. syntax is forbidden for the "function". For extra syntactic sugar, if we have more then one parameter the rest of the parameters can be used as indexers. Like this: property bool charIsNumber(char[] str, uint index) { return '0' <= str[index] && str[index] <= '9'; } char[] foo = "Atari 520STe"; bool jupp = foo.charIsNumber[4]; So in 0.150 the property modifier gets adopted and non property marked properties gets depricated, then people start cleaning out their code, and by 1.0 everything is nice and jolly :). // Fredrik Olsson.
Jan 05 2006
Fredrik Olsson wrote:My $0.02 (I like that one :) ).OK, here is my 0.02kn (currency where i come from and < $0.02) :)1. IMHO it is bad to be able to call both as function and as property, it confuses adopters. 2. Breaking backward compatibility for properties is too late(?). 3. I want more syntactic sugar! Today we have int length(char[] str); That can be called in two ways: 1. int bar = length(foo); 2. int baz = foo.length; Why not add a "property" modifier, like this; property int length(char[] str); And now the 1. syntax is forbidden for the "function".I am strongly in favor for adding extendable properties to *all* types and this syntax is as good as any other sugested.For extra syntactic sugar, if we have more then one parameter the rest of the parameters can be used as indexers. Like this:But this isn't....property bool charIsNumber(char[] str, uint index) { return '0' <= str[index] && str[index] <= '9'; } char[] foo = "Atari 520STe"; bool jupp = foo.charIsNumber[4];...beacuse the rest of the parameters are in 99% of the cases not going to semanticaly be indexes.
Jan 05 2006
Ivan Senji skrev:Fredrik Olsson wrote:In 99% of the cases indexes are probably int and char[]. But allowing any type makes it dead easy to emulate any kind of associative arrays. Perhaps even making the opIndex() function obsolete? As this one: property int this(uint index); Could mean the same thing and be consistent as well. // Fredrik OlssonMy $0.02 (I like that one :) ).OK, here is my 0.02kn (currency where i come from and < $0.02) :)1. IMHO it is bad to be able to call both as function and as property, it confuses adopters. 2. Breaking backward compatibility for properties is too late(?). 3. I want more syntactic sugar! Today we have int length(char[] str); That can be called in two ways: 1. int bar = length(foo); 2. int baz = foo.length; Why not add a "property" modifier, like this; property int length(char[] str); And now the 1. syntax is forbidden for the "function".I am strongly in favor for adding extendable properties to *all* types and this syntax is as good as any other sugested.For extra syntactic sugar, if we have more then one parameter the rest of the parameters can be used as indexers. Like this:But this isn't....property bool charIsNumber(char[] str, uint index) { return '0' <= str[index] && str[index] <= '9'; } char[] foo = "Atari 520STe"; bool jupp = foo.charIsNumber[4];...beacuse the rest of the parameters are in 99% of the cases not going to semanticaly be indexes.
Jan 05 2006
Fredrik Olsson wrote:Ivan Senji skrev:I think there might be a missunderstanding here. I will try to explain what i wanted to say with an example: property int[] selectIfGreaterThan(int[] numbers, int condition); int[] numbers; numbers.selectIfGreaterThan(5); 5 in this case is not an index and i think in most cases of extending other types with additional properties the other parameters aren't going to be indexes but something else as in the example above....beacuse the rest of the parameters are in 99% of the cases not going to semanticaly be indexes.In 99% of the cases indexes are probably int and char[]. But allowing any type makes it dead easy to emulate any kind of associative arrays. Perhaps even making the opIndex() function obsolete? As this one: property int this(uint index); Could mean the same thing and be consistent as well.
Jan 05 2006
Fredrik Olsson wrote:Sean Kelly skrev:I love it. Especially if it meant that properties could be added to any type (including built-in types), rather than just arrays.S. Chancellor wrote:<snip>I think a property syntax is a reasonable idea so long as we don't lose the ability to use free functions as properties. I'm finding it quite useful that I can even replace global variables with no-argument functions and leave all other code unchanged.My $0.02 (I like that one :) ). 1. IMHO it is bad to be able to call both as function and as property, it confuses adopters. 2. Breaking backward compatibility for properties is too late(?). 3. I want more syntactic sugar! Today we have int length(char[] str); That can be called in two ways: 1. int bar = length(foo); 2. int baz = foo.length; Why not add a "property" modifier, like this; property int length(char[] str); And now the 1. syntax is forbidden for the "function".
Jan 05 2006
Don Clugston skrev:Fredrik Olsson wrote:I can not see why this could not be made to work with any type. But then again I see no reason why the "void func(T foo)" only creates "fake methods" for arrays. // Fredrik OlssonSean Kelly skrev:I love it. Especially if it meant that properties could be added to any type (including built-in types), rather than just arrays.S. Chancellor wrote:<snip>I think a property syntax is a reasonable idea so long as we don't lose the ability to use free functions as properties. I'm finding it quite useful that I can even replace global variables with no-argument functions and leave all other code unchanged.My $0.02 (I like that one :) ). 1. IMHO it is bad to be able to call both as function and as property, it confuses adopters. 2. Breaking backward compatibility for properties is too late(?). 3. I want more syntactic sugar! Today we have int length(char[] str); That can be called in two ways: 1. int bar = length(foo); 2. int baz = foo.length; Why not add a "property" modifier, like this; property int length(char[] str); And now the 1. syntax is forbidden for the "function".
Jan 05 2006
Sean Kelly wrote:I think a property syntax is a reasonable idea so long as we don't lose the ability to use free functions as properties. I'm finding it quite useful that I can even replace global variables with no-argument functions and leave all other code unchanged.I find it really useful too, but wouldn't agree on the unchanged part. int x; and replace it with: int x(){return ...} int x(int ... this code will break: void bla(inout int v); bla(x); I really wish there was a reasonable way of solving this problem. Not ideal but maybe translating the above code to: int __x = x(); bla(__x); x(__x);
Jan 05 2006
Your example seems a bit odd to me as the setter can have a different input type from the getter.No it can't. I do note in my original post that the types have to match.If you're going to go the way of implementing a whole property block it seems that they should have their type specified in the property area.It was an attempt to avoid context-sensitive keywords, which Walter's not fond of. Hence type signatures in my design take the place of 'get' and 'set'.
Jan 04 2006
n article <dphnia$si9$1 digitaldaemon.com>, John C says...It can as long as I type it twice. If there's a restriction that it has to be what I typed the first time... then I shouldn't have to type it twice.Your example seems a bit odd to me as the setter can have a different input type from the getter.No it can't. I do note in my original post that the types have to match.True, but either way uses context-sensitive something. The current method doesn't require context sensitive anything. If we're going to introduce new semantic regions, and change the syntax for function declarations within, we might as well introduce keywords for it. Your method just reuses keywords, for something they weren't intended, which is arguably more confusing. -S.If you're going to go the way of implementing a whole property block it seems that they should have their type specified in the property area.It was an attempt to avoid context-sensitive keywords, which Walter's not fond of. Hence type signatures in my design take the place of 'get' and 'set'.
Jan 04 2006
S. Chancellor wrote:n article <dphnia$si9$1 digitaldaemon.com>, John C says...Well said!It can as long as I type it twice. If there's a restriction that it has to be what I typed the first time... then I shouldn't have to type it twice.Your example seems a bit odd to me as the setter can have a different input type from the getter.No it can't. I do note in my original post that the types have to match.True, but either way uses context-sensitive something. The current method doesn't require context sensitive anything. If we're going to introduce new semantic regions, and change the syntax for function declarations within, we might as well introduce keywords for it. Your method just reuses keywords, for something they weren't intended, which is arguably more confusing. -S.If you're going to go the way of implementing a whole property block it seems that they should have their type specified in the property area.It was an attempt to avoid context-sensitive keywords, which Walter's not fond of. Hence type signatures in my design take the place of 'get' and 'set'.
Jan 04 2006
John C wrote:As I see it, the problem with D's property syntax is that they're actually methods, and the compiler has to try to disamiguate between method and property calls/assignments, which it's not 100% successful at - sometimes you have to add a pair of parentheses '()' when using a property to stop the compiler from choking (for example, when used in conjunction with 'auto'). Another issue is that it introduces ambiguity in the way they are called, and users have no way of knowing how they are intended to be used - 'my.name("John")' or 'my.name = "John"'. The other issue is that properties have the semantics of fields, not methods (even if, in the end, the compiler just generates the same code as for a method). They just don't feel like first-class citizens.Properties are meant to have the same semantics as methods, NOT fields. They are made to have the same SYNTAX as fields. I agree, they don't feel like first-class citizens in D.I'd like to suggest a new syntax that I think addresses these issues. The only downside is the addition of a new keyword, 'property'. But otherwise it's quite elegant and is only slightly more verbose than the current syntax (the keyword itself). It's basically a way of grouping a pair of getters and setters in a 'property block'.Here's a class that utilises it. class Person { private float weight_; // Manually written backing store for 'weight' property protected void onWeightChanged() { // Warn of heart attack risk if above a certain weight } property weight { // 'weight' property block float() { // This defines the signature of the getter return weight_; } void(float value) { // This defines the signature of the setter; // setters must have a void return type weight_ = value; onWeightChanged(); } } // end 'weight' property blockWhy must the return value of the setter be void? What if I want to chain my property setter calls in an 'a = b = c = d' manner? Then if you change the void-return rule to allow returning any type, you must then define if that return type is required to match the implied type of the property. It follows that it becomes increasingly more difficult to determine the actual type of the property. Another note, it would be much clearer to the D beginner if he/she were required to name the getter method as "get" and the setter method as "set", instead of the quirky-looking identifier-removed function definition syntax proposed above. Best to remain consistent with the rest of the language - it also makes implementation easier.// In this property block, we don't provide definitions, // which tells the compiler to generate a backing store // and the definitions on our behalf. // Let's call it a 'simple property'. property height { float(); void(float); }Does this mean that properties can be inherited and overridden?// property block with getter only property bmi { float() { return weight / (height * height); } } } Some notes: 1) Any attempt to define a setter with an argument type that doesn't match that of the getter return type would be an error (and vise versa).Lol. There is no vice-versa in this case. =P2) Different protection attributes can be applied to the getter and setter, as with methods.So, hypothetically, I can read from a property in public and perhaps write to it only in a child class? What's the point of that?3) For property blocks without manual definitions (as in the 'height' example above), either the getter or setter signature can be omitted, making them either read- or write-only, which distinguishes them from public fields.This would make them read-only, write-only, OR read/write properties, not just either read-only or write-only. Best to be clear about such things. In fact, the notion of a field being read-only doesn't really apply here in the true sense of the return value being read-only.4) Within the scope of a property block, use of the property name itself is legal, since the compiler knows to refer to the automatically generated backing store (as opposed to introducing a recursive call).You mean use of the property name when defining a local variable to one of the setter/getter methods, right? AFAIK, we don't allow such things in regular functions so this would be inconsistent with the rest of D.No doubt there will be objections to this notation, so fire away. But I require three contextual keywords: 'get', 'set' and 'value') and the current D syntax.Nobody says that "get" or "set" must be keywords (or contextual keywords). They can be context-dependent special identifiers. ------------------- Why not propose also a 'reflect' sort-of syntax, such that a public property may reflect the value of a corresponding private member without having to write redundant code. I see a lot of situations like this in It seems completely silly to write such redundant code as property float Height { get { return _height; } set { _height = value; } } Your proposed D syntax: property Height { float() { return _height; } void (float value) { _height = value; } } Why not reduce the potential for bugs in such a case by telling the compiler what you actually want to do? I don't see any clean way to do this in addition to your syntax proposal, unfortunately.
Jan 04 2006
On Wed, 04 Jan 2006 20:00:53 -0600, James Dunne wrote:It seems completely silly to write such redundant code as property float Height { get { return _height; } set { _height = value; } } Your proposed D syntax: property Height { float() { return _height; } void (float value) { _height = value; } }And current D syntax: float Height() { return _height; } void Height(float value) { _height = value; }Why not reduce the potential for bugs in such a case by telling the compiler what you actually want to do? I don't see any clean way to do this in addition to your syntax proposal, unfortunately.Just playing here but something like this seems nice to me ... float _height; property Height { get float { Height = _height; } // Value must be zero or greater. set float { _height = fmax(0.0, Height); } set real { _height = fmax(0.0, cast(float)Height); } set char[]{ _height = fmax(0.0, atof(Height)); } } And assignment chaining would be achieved by calling the getter whenever needed. a.Height = b.Height = "4.0"; would be equivalent to ... b.setHeight("4.0"); a.setHeight( b.getHeight() ); -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 5/01/2006 1:51:53 PM
Jan 04 2006
Derek Parnell <derek psych.ward> wrote:Just playing here but something like this seems nice to me ... float _height; property Height { get float { Height = _height; } // Value must be zero or greater. set float { _height = fmax(0.0, Height); } set real { _height = fmax(0.0, cast(float)Height); } set char[]{ _height = fmax(0.0, atof(Height)); } } And assignment chaining would be achieved by calling the getter whenever needed. a.Height = b.Height = "4.0"; would be equivalent to ... b.setHeight("4.0"); a.setHeight( b.getHeight() );I don't know that I like the idea of having properties accept more than one type input. I think they should use the normal type conversion rules if the property doesn't accept the type of data you want to shove into it. -S. -- Email works.
Jan 04 2006
On Thu, 5 Jan 2006 03:39:24 +0000 (UTC), S. Chancellor wrote:I don't know that I like the idea of having properties accept more than one type input. I think they should use the normal type conversion rules if the property doesn't accept the type of data you want to shove into it.Why? And as a side point, I would really like to be able to specify abnormal type conversions that are called by the compiler on assignment. -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 5/01/2006 3:22:11 PM
Jan 04 2006
Derek Parnell wrote:Just playing here but something like this seems nice to me ... float _height; property Height { get float { Height = _height; } // Value must be zero or greater. set float { _height = fmax(0.0, Height); } set real { _height = fmax(0.0, cast(float)Height); } set char[]{ _height = fmax(0.0, atof(Height)); } }I proposed something similar to this many ages ago. Mine looked like: If I remember right. I'm not sure how I feel about the reflective style, where property 'height' has an auto-generated storage of '_height' as mentioned in another post, but it does solve a problem. Maybe the syntax should be more like what you suggest, but with the gettor not concernings itself with type (in other words, the property is considered strongly typed for get purposes). So, something like: No redundant type information, yet we get keywords... that's one notable downside, especially the keywords 'get' and 'set' which can make perfectly good sense as collection object methods. -- Chris Sauls
Jan 04 2006
Chris Sauls wrote:Derek Parnell wrote:<rant> What is it with you people and the dependence on keywords? =P You only need a special context-dependent identifier - this is NOT A KEYWORD. Keywords are language tokens and can only be used for the one thing that they mean. OTOH, a special context-dependent identifier (as I call it, I guess) means that the compiler tests the name of the identifier given for a special word only within certain contexts. In this case, when getter/setter methods are defined within a property block, the identifiers "get" and "set" have special meaning and are not just regular identifiers anymore. HOWEVER, EVERYWHERE ELSE THEY HAVE NO SPECIAL MEANING. </rant> Not blowing up on you particularly, Chris. =)Just playing here but something like this seems nice to me ... float _height; property Height { get float { Height = _height; } // Value must be zero or greater. set float { _height = fmax(0.0, Height); } set real { _height = fmax(0.0, cast(float)Height); } set char[]{ _height = fmax(0.0, atof(Height)); } }I proposed something similar to this many ages ago. Mine looked like: If I remember right. I'm not sure how I feel about the reflective style, where property 'height' has an auto-generated storage of '_height' as mentioned in another post, but it does solve a problem. Maybe the syntax should be more like what you suggest, but with the gettor not concernings itself with type (in other words, the property is considered strongly typed for get purposes). So, something like: conversion No redundant type information, yet we get keywords... that's one notable downside, especially the keywords 'get' and 'set' which can make perfectly good sense as collection object methods. -- Chris Sauls
Jan 04 2006
James Dunne wrote:<rant> What is it with you people and the dependence on keywords? =P You only need a special context-dependent identifier - this is NOT A KEYWORD. Keywords are language tokens and can only be used for the one thing that they mean. OTOH, a special context-dependent identifier (as I call it, I guess) means that the compiler tests the name of the identifier given for a special word only within certain contexts. In this case, when getter/setter methods are defined within a property block, the identifiers "get" and "set" have special meaning and are not just regular identifiers anymore. HOWEVER, EVERYWHERE ELSE THEY HAVE NO SPECIAL MEANING. </rant> Not blowing up on you particularly, Chris. =)No worries, actually what you say makes perfectly good sense. I probably shouldn't post to the NG right after ten hour shifts, else I might've realised that on my own. :) -- Chris Sauls
Jan 05 2006
Chris Sauls wrote:James Dunne wrote:Ouch. Yeah this whole week I'm pulling 10-12 hour shifts, 9am to 9pm or so. Deadlines are so stupid and pointless... especially when no one outside your organization is depending on them, and even when they have no effect on anything.<rant> What is it with you people and the dependence on keywords? =P You only need a special context-dependent identifier - this is NOT A KEYWORD. Keywords are language tokens and can only be used for the one thing that they mean. OTOH, a special context-dependent identifier (as I call it, I guess) means that the compiler tests the name of the identifier given for a special word only within certain contexts. In this case, when getter/setter methods are defined within a property block, the identifiers "get" and "set" have special meaning and are not just regular identifiers anymore. HOWEVER, EVERYWHERE ELSE THEY HAVE NO SPECIAL MEANING. </rant> Not blowing up on you particularly, Chris. =)No worries, actually what you say makes perfectly good sense. I probably shouldn't post to the NG right after ten hour shifts, else I might've realised that on my own. :) -- Chris Sauls
Jan 05 2006
On Thu, 05 Jan 2006 00:46:02 -0600, Chris Sauls wrote:I proposed something similar to this many ages ago. Mine looked like: If I remember right. I'm not sure how I feel about the reflective style, where property 'height' has an auto-generated storage of '_height' as mentioned in another post, but it does solve a problem. Maybe the syntax should be more like what you suggest, but with the gettor not concernings itself with type (in other words, the property is considered strongly typed for get purposes). So, something like:However, there is no necessary requirement for a property to be implemented by just a single internal (private?) variable. Also, other members in the class might deal with the internal property variables in a more efficient manner than using the get/set paradigm. Ok, so here's another refinement ... private { float A; long B; } property goofy { out (float) { goofy = cast(float)B + A; } in (float) { B = cast(long) toInt(goofy); A = goofy - cast(float)B;} } void someFunc(long x) { if (B > 0) B *= x; } Sure this is contrived, but you get my point. I imagine the purpose of properties is to totally divorce the implementation from the usage. Such that the 'public' face of the property is a float, for example, but the implementation can change over time without haven't to change any referencing source code. The implementation can start off being a simple, single float variable but later can change to some complex function and all the source code that references the property doesn't have to be modified.No redundant type information, yet we get keywords... that's one notable downside, especially the keywords 'get' and 'set' which can make perfectly good sense as collection object methods.So maybe 'gettor' and 'settor' as special and unusual words? -- Derek (skype: derek.j.parnell) Melbourne, Australia "A learning experience is one of those things that says, 'You know that thing you just did? Don't do that.'" - D.N. Adams 5/01/2006 6:01:22 PM
Jan 04 2006
Derek Parnell wrote:However, there is no necessary requirement for a property to be implemented by just a single internal (private?) variable. Also, other members in the class might deal with the internal property variables in a more efficient manner than using the get/set paradigm. Ok, so here's another refinement ... private { float A; long B; } property goofy { out (float) { goofy = cast(float)B + A; } in (float) { B = cast(long) toInt(goofy); A = goofy - cast(float)B;} } void someFunc(long x) { if (B > 0) B *= x; } Sure this is contrived, but you get my point.Actually, Derek, I think I like your refined proposal, even the new use of the in/out keywords (despite my recent education on that matter, see other posts). It might've been arguable that internally a class might be able to do something like 'this.height._height' but... ew. My only quirk, is I really would prefer the gettor type of a property be strong. I just don't trust the compiler enough, I guess? There would have to be fairly explicit rules about how it determines which 'out' clause to use. -- Chris Sauls
Jan 05 2006
"Derek Parnell" <derek psych.ward> wrote...On Thu, 05 Jan 2006 00:46:02 -0600, Chris Sauls wrote:[snip]I proposed something similar to this many ages ago. Mine looked like:Ok, so here's another refinement ... private { float A; long B; } property goofy { out (float) { goofy = cast(float)B + A; } in (float) { B = cast(long) toInt(goofy); A = goofy - cast(float)B;} } void someFunc(long x) { if (B > 0) B *= x; } Sure this is contrived, but you get my point. I imagine the purpose of properties is to totally divorce the implementation from the usage. Such that the 'public' face of the property is a float, for example, but the implementation can change over time without haven't to change any referencing source code. The implementation can start off being a simple, single float variable but later can change to some complex function and all the source code that references the property doesn't have to be modified.Not so much the purpose of properties, but the purpose of behavioral abstraction. 'Normal' methods are no different in this regard, and classes are just larger-grained instances. Programs themselves are larger-grained again. I know you know this, but it's worth regurgitating anyway. While I think the idea of special 'property' sugar is seductive, one has to wonder whether it really has value? For instance, the 'normal' implementation of the above example is approximately as follows: private float A; private long B; void setGoofy (float goofy) { B = cast(long) toInt(goofy); A = goofy - cast(float) B; } float getGoofy () { return cast(float) B + A; } void someFunc (long x) { if (B > 0) B *= x; } I think it's arguable that the above is actually clearer (partly because you don't have to understand alternate syntax), plus you also have the options to inherit, override, implement call-chaining etc. Sure, it might be nice to have some means of reducing the amount of typing involved for trivial properties; but isn't there always a tradeoff? And, isn't the 'typing aspect' a job for an IDE? 2 Cents;
Jan 05 2006
On Fri, 06 Jan 2006 05:52:44 +1100, Kris <fu bar.com> wrote: [snip]While I think the idea of special 'property' sugar is seductive, one has to wonder whether it really has value? For instance, the 'normal' implementation of the above example is approximately as follows: private float A; private long B; void setGoofy (float goofy) { B = cast(long) toInt(goofy); A = goofy - cast(float) B; } float getGoofy () { return cast(float) B + A; } void someFunc (long x) { if (B > 0) B *= x; } I think it's arguable that the above is actually clearer (partly because you don't have to understand alternate syntax), plus you also have the options to inherit, override, implement call-chaining etc. Sure, it might be nice to have some means of reducing the amount of typing involved for trivial properties; but isn't there always a tradeoff? And, isn't the 'typing aspect' a job for an IDE?Yes, I understood all of that but the difference is in how you refer to the 'property'. With a true property it would X = A.goofy; and in your version it would be X = A.getGoofy(); The difference is not just how much you type in. For example the original version of the class might have defined 'goofy' as just ... float goofy; So code referring to it would have been ... X = A.goofy; And then later when it was turned into a property, that type of reference would not also have to be changed but if the function-type property was implemented (ala your example) all references to 'goofy' would also have to be changed. Why can't one inherit, override, and implement call-chaining with properties? There is nothing built into the concept which precluses those functionalities. You can even get compilers to cope with properties beibg used as 'inout' parameters if one wanted to. -- Derek Parnell Melbourne, Australia
Jan 05 2006
"Derek Parnell" <derek psych.ward> wrote ...On Fri, 06 Jan 2006 05:52:44 +1100, Kris <fu bar.com> wrote: [snip] Yes, I understood all of that but the difference is in how you refer to the 'property'. With a true property it would X = A.goofy; and in your version it would be X = A.getGoofy();Isn't that's just a naming concern? The method approach could just as easily be: float goofy() { return XYZ; } Thus producing X = A.goofy(); which the compiler will currently map to X = A.goofy;The difference is not just how much you type in. For example the original version of the class might have defined 'goofy' as just ... float goofy; So code referring to it would have been ... X = A.goofy; And then later when it was turned into a property, that type of reference would not also have to be changed but if the function-type property was implemented (ala your example) all references to 'goofy' would also have to be changed.I thought the compiler currently supports method references in an identical manner e.g. X = A.goofy; Does it not?
Jan 05 2006
Kris wrote:I thought the compiler currently supports method references in an identical manner e.g. X = A.goofy; Does it not?It does, although the last time I tried playing with this syntax, it would break in random places, requiring the addition of the parenthesis to resolve correctly. That might have been mostly resolved, though; I don't know. -- Chris Sauls
Jan 05 2006
"Chris Sauls" <ibisbasenji gmail.com> wrote ...Kris wrote:OK, Gotcha. I think that's still the case? It seems to be that it always works from within an expression e.g. if (x.goofy) ... but sometimes fails when used as the rValue of an assignment? Should that be reported as a bug?I thought the compiler currently supports method references in an identical manner e.g. X = A.goofy; Does it not?It does, although the last time I tried playing with this syntax, it would break in random places, requiring the addition of the parenthesis to resolve correctly. That might have been mostly resolved, though; I don't know.
Jan 05 2006
Doh! Forgot to add something: "Derek Parnell" <derek psych.ward> wrote ..On Fri, 06 Jan 2006 05:52:44 +1100, Kris <fu bar.com> wrote: [snip] The difference is not just how much you type in. For example the original version of the class might have defined 'goofy' as just ... float goofy; So code referring to it would have been ... X = A.goofy; And then later when it was turned into a property, that type of reference would not also have to be changed but if the function-type property was implemented (ala your example) all references to 'goofy' would also have to be changed.This is a refactoring issue, which is surely a much larger problem than the specific handling of 'properties'? For example, what happens when I want to change the name of a method? Or the order of method-arguments? Or the types or number of arguments? Or the name of a class? etc.etc. As a recent post noted, this is the domain of 3rd party tools, such as Eclipse or IntelliJ, which handle just this kind of thing with aplomb. It is certainly a delight to heavily refactor a large body of code in just a few minutes rather than possibly days of tedious grunt-work. And to do it all in a manner that does not introduce errors <g> A refactoring module for one of the developing D IDE would be a very useful thing to have. - Kris
Jan 05 2006
James Dunne <james.jdunne gmail.com> wrote:Why not propose also a 'reflect' sort-of syntax, such that a public property may reflect the value of a corresponding private member without having to write redundant code. I see a lot of situations like this in It seems completely silly to write such redundant code as property float Height { get { return _height; } set { _height = value; } } Your proposed D syntax: property Height { float() { return _height; } void (float value) { _height = value; } } Why not reduce the potential for bugs in such a case by telling the compiler what you actually want to do? I don't see any clean way to do this in addition to your syntax proposal, unfortunately.I fully agree with your here. I'm glad to find out I'm not alone in the war against blank properties! In fact .NET requires you to write blank properties in some cases. (IE: passing a collection of classes to a DataGrid, you can only specify property names for output.) -S. -- Email works.
Jan 04 2006
"James Dunne" <james.jdunne gmail.com> wrote in message news:dphugm$11vq$1 digitaldaemon.com...John C wrote:I just hadn't considered it. Makes sense to allow that.As I see it, the problem with D's property syntax is that they're actually methods, and the compiler has to try to disamiguate between method and property calls/assignments, which it's not 100% successful at - sometimes you have to add a pair of parentheses '()' when using a property to stop the compiler from choking (for example, when used in conjunction with 'auto'). Another issue is that it introduces ambiguity in the way they are called, and users have no way of knowing how they are intended to be used - 'my.name("John")' or 'my.name = "John"'. The other issue is that properties have the semantics of fields, not methods (even if, in the end, the compiler just generates the same code as for a method). They just don't feel like first-class citizens.Properties are meant to have the same semantics as methods, NOT fields. They are made to have the same SYNTAX as fields. I agree, they don't feel like first-class citizens in D.I'd like to suggest a new syntax that I think addresses these issues. The only downside is the addition of a new keyword, 'property'. But otherwise it's quite elegant and is only slightly more verbose than the current syntax (the keyword itself). It's basically a way of grouping a pair of getters and setters in a 'property block'.Here's a class that utilises it. class Person { private float weight_; // Manually written backing store for 'weight' property protected void onWeightChanged() { // Warn of heart attack risk if above a certain weight } property weight { // 'weight' property block float() { // This defines the signature of the getter return weight_; } void(float value) { // This defines the signature of the setter; // setters must have a void return type weight_ = value; onWeightChanged(); } } // end 'weight' property blockWhy must the return value of the setter be void? What if I want to chain my property setter calls in an 'a = b = c = d' manner?Then if you change the void-return rule to allow returning any type, you must then define if that return type is required to match the implied type of the property. It follows that it becomes increasingly more difficult to determine the actual type of the property. Another note, it would be much clearer to the D beginner if he/she were required to name the getter method as "get" and the setter method as "set", instead of the quirky-looking identifier-removed function definition syntax proposed above. Best to remain consistent with the rest of the language - it also makes implementation easier.I won't contradict you - it is quirky, but I was trying to placate those who might gasp at the propsect of introducing yet more keywords. Once you realise that in fact 'get' and 'set' would only have special meaning within the property block, and that they remain valid identifiers elsewhere, it's ok. The other thing is what name to use for the compiler-generated setter parameter? 'value' is the obvious choice. That the compiler has to generate a magic variable at all shouldn't be an issue, since there's a precedent for this with variadic functions ('_arguments' and '_argptr').Like methods, yes.// In this property block, we don't provide definitions, // which tells the compiler to generate a backing store // and the definitions on our behalf. // Let's call it a 'simple property'. property height { float(); void(float); }Does this mean that properties can be inherited and overridden?Any attempt to define a) a setter with an argument type that doesn't match that of the getter return type, or b) a getter with a return type that doesn't match that of the setter argument type, would be an error. Better?// property block with getter only property bmi { float() { return weight / (height * height); } } } Some notes: 1) Any attempt to define a setter with an argument type that doesn't match that of the getter return type would be an error (and vise versa).Lol. There is no vice-versa in this case. =PThe same rules that apply to methods should apply to properties.2) Different protection attributes can be applied to the getter and setter, as with methods.So, hypothetically, I can read from a property in public and perhaps write to it only in a child class? What's the point of that?Yes, that's clearer.3) For property blocks without manual definitions (as in the 'height' example above), either the getter or setter signature can be omitted, making them either read- or write-only, which distinguishes them from public fields.This would make them read-only, write-only, OR read/write properties, not just either read-only or write-only. Best to be clear about such things.In fact, the notion of a field being read-only doesn't really apply here in the true sense of the return value being read-only.I should have said with a "simple property" block, since there's no backing store variable to refer to until compilation.4) Within the scope of a property block, use of the property name itself is legal, since the compiler knows to refer to the automatically generated backing store (as opposed to introducing a recursive call).You mean use of the property name when defining a local variable to one of the setter/getter methods, right? AFAIK, we don't allow such things in regular functions so this would be inconsistent with the rest of D.Point taken, although if you've read some of the other replies, you'll see people are inferring that this would require them to be keywords.No doubt there will be objections to this notation, so fire away. But I require three contextual keywords: 'get', 'set' and 'value') and the current D syntax.Nobody says that "get" or "set" must be keywords (or contextual keywords). They can be context-dependent special identifiers.------------------- Why not propose also a 'reflect' sort-of syntax, such that a public property may reflect the value of a corresponding private member without having to write redundant code. I see a lot of situations like this in seems completely silly to write such redundant code as property float Height { get { return _height; } set { _height = value; } }It's redundant until the class writer decides to perform more complex operations within the accessor functions (such as resizing a window or repainting a shape). But yes, if it's just going to update a private field, and it's read/write, then you may as well use a public field. Unless there's extra value in tagging something as a property (perhaps for the benefit of an IDE or Ddoc documentation).Your proposed D syntax: property Height { float() { return _height; } void (float value) { _height = value; } } Why not reduce the potential for bugs in such a case by telling the compiler what you actually want to do? I don't see any clean way to do this in addition to your syntax proposal, unfortunately.Maybe something analogous to an alias: property Height _height;
Jan 05 2006
John C wrote:Any attempt to define a) a setter with an argument type that doesn't match that of the getter return type, or b) a getter with a return type that doesn't match that of the setter argument type, would be an error. Better?Clearer, yes... Better, no, IMHO. :) I don't see the utility in requiring that a property only allow one data type for its settor. I'm all for locking down the gettor, but being able to send different kinds of data into a property can make perfectly good sense in some designs. Stupid example: a property for setting an HTTP response code, which accepts either a ushort (401, 202, etc) or a string (char[], wchar[], dchar[]) containing the code number.I do like this. -- Chris Sauls2) Different protection attributes can be applied to the getter and setter, as with methods.
Jan 05 2006
"Chris Sauls" <ibisbasenji gmail.com> wrote in message news:dpjn4t$2i2k$1 digitaldaemon.com...John C wrote:I think I see what you're getting at - like overloads, but contained within the property block? That sounds useful, I hadn't considered it.Any attempt to define a) a setter with an argument type that doesn't match that of the getter return type, or b) a getter with a return type that doesn't match that of the setter argument type, would be an error. Better?Clearer, yes... Better, no, IMHO. :) I don't see the utility in requiring that a property only allow one data type for its settor. I'm all for locking down the gettor, but being able to send different kinds of data into a property can make perfectly good sense in some designs. Stupid example: a property for setting an HTTP response code, which accepts either a ushort (401, 202, etc) or a string (char[], wchar[], dchar[]) containing the code number.I do like this. -- Chris Sauls2) Different protection attributes can be applied to the getter and setter, as with methods.
Jan 05 2006
How about simply adding a 'property' attribute? The compiler could at least enforce more rules with it, like making sure the get/set types match, allow them to be used more like fields, not allow them to be used like functions (which the magic, built-in ones already enforce (inconsistent)), and not allow regular functions to be used as properties. Example: private int _foo = 1; property int foo() { return 3; } Or use a property block to group them, since it's an attribute: property { int foo() { return 3; } void foo(int value) { _foo = value; } } Yes, there's duplicated information, but it's much simpler on the compiler and will require minimal changes to existing code. - Chris
Jan 05 2006
"Chris Miller" <chris dprogramming.com> wroteHow about simply adding a 'property' attribute? The compiler could at least enforce more rules with it, like making sure the get/set types match, allow them to be used more like fields, not allow them to be used like functions (which the magic, built-in ones already enforce (inconsistent)), and not allow regular functions to be used as properties. Example: private int _foo = 1; property int foo() { return 3; } Or use a property block to group them, since it's an attribute: property { int foo() { return 3; } void foo(int value) { _foo = value; } } Yes, there's duplicated information, but it's much simpler on the compiler and will require minimal changes to existing code.I'm still trying to get a handle on this, Chris, so please forgive the naiive questions: a) Is this based on a desire to use 'property' methods as lValues? b) what exactly are the characteristics that distinguish a 'property' method from a 'normal' one? - Kris
Jan 05 2006
On Thu, 05 Jan 2006 17:24:16 -0500, Kris <fu bar.com> wrote:"Chris Miller" <chris dprogramming.com> wroteNo, so that you can't use properties as functions and you can't use functions as properties, so they're used as intended; and the other reasons I explained above; also so that documentation generation like Ddoc can output function or property as appropriate.How about simply adding a 'property' attribute? The compiler could at least enforce more rules with it, like making sure the get/set types match, allow them to be used more like fields, not allow them to be used like functions (which the magic, built-in ones already enforce (inconsistent)), and not allow regular functions to be used as properties. Example: private int _foo = 1; property int foo() { return 3; } Or use a property block to group them, since it's an attribute: property { int foo() { return 3; } void foo(int value) { _foo = value; } } Yes, there's duplicated information, but it's much simpler on the compiler and will require minimal changes to existing code.I'm still trying to get a handle on this, Chris, so please forgive the naiive questions: a) Is this based on a desire to use 'property' methods as lValues?b) what exactly are the characteristics that distinguish a 'property' method from a 'normal' one?property attribute; personal preference to have property or method.. not sure what you want me to say here beyond what I already said.
Jan 05 2006
"Chris Miller" <chris dprogramming.com> wrote ... [snip]I'll admit that I don't see a solid semantic distinction (at the code-usage level) between 'property' methods and 'normal' methods (or did you mean some other kind of function?). They are both an exposure of capability via some level of abstraction. They can both set or expose internal state. They can both be arbitrarily complex or completely trivial. They are both intended to encapsulate behaviour specific to their containing entity. Why is one somehow special? I don't get it :-(I'm still trying to get a handle on this, Chris, so please forgive the naiive questions: a) Is this based on a desire to use 'property' methods as lValues?No, so that you can't use properties as functions and you can't use functions as properties, so they're used as intended;and the other reasons I explained above;While it does seem reasonable for set/get to be consistent in type usage, it's not necessarily a hard rule. If it were, some people might use 'functions' instead of 'properties' to get around it, leading to other problems? And, could this kind of thing (auto-generation of appropriate methods, with consistent types) perhaps be handled by an IDE, similar to the refactoring angle? Do Eclipse and IntelliJ (etc) do it this way?also so that documentation generation like Ddoc can output function or property as appropriate.That makes sense only if you view them as sematically distinct from a code usage-aspect? OTOH, I do see a usage distinction regarding IDE handling of properties, such as property sheets and so on? But that seems quite different from a code-usage perpective ~ instead, IDE property sheets expose an alternative to explicit, configuration of components? If so, could the notion of a 'property' be just some kind of convenient tagging that an IDE looks for? For example: class X { property double velocity; property char[] description; ... } Perhaps the notion could be used by an IDE to expand into other composite aggregates? e.g. class Y { property int something; property X x; ... } There would presumeably be no need to do the same via inheritance? Perhaps, with introspection, such a tag might be useful for other things? These examples use 'property' purely for attribute-decoration only ~ they don't change the behaviour of the compiler per se, except perhaps to imply "private"? - Kris
Jan 05 2006
I myself see setters & getters being different from ordinary functions: 1) Set always is passed a single parameter and returns void. 2) Get always returns a single type. 3) Set will always change the state of an object (unless rvalue is current value). Functions don't necessarily change the state of the value. 4) Get and Set provide a standardization to access the properties of an object. Otherwise we could have code like car.setwheelcount(4), assert (car.passengerscount(4)!=0) and if(car.wiperblades()=3) { writefln("mgb!\n") } Tom J From http://c2.com/cgi/wiki?AccessorsAreEvil ..Setters and Getters are different breeds of dog. A setter involves this-here-object modifying the state of that-there-object. This almost always creates maintenence problems and is smelly in the extreme. If fu needs data from bar because (and only because) bar is the authoritative source or an agent of the authoritative source (users, databases and other outside things need agents), then bar needs to provide a getter interface for fu to use. There are a half-dozen design patterns to choose from that let bar tell any and all interested fus that new or changed data is available and to "come and get it". Since fu is in control, and the coupling is kept to the minimum required for bar to provide its service, it doesn't smell at all. This is the essence of MVC. In article <dpkeff$462$1 digitaldaemon.com>, Kris says..."Chris Miller" <chris dprogramming.com> wrote ... [snip]I'll admit that I don't see a solid semantic distinction (at the code-usage level) between 'property' methods and 'normal' methods (or did you mean some other kind of function?). They are both an exposure of capability via some level of abstraction. They can both set or expose internal state. They can both be arbitrarily complex or completely trivial. They are both intended to encapsulate behaviour specific to their containing entity. Why is one somehow special? I don't get it :-(I'm still trying to get a handle on this, Chris, so please forgive the naiive questions: a) Is this based on a desire to use 'property' methods as lValues?No, so that you can't use properties as functions and you can't use functions as properties, so they're used as intended;and the other reasons I explained above;While it does seem reasonable for set/get to be consistent in type usage, it's not necessarily a hard rule. If it were, some people might use 'functions' instead of 'properties' to get around it, leading to other problems? And, could this kind of thing (auto-generation of appropriate methods, with consistent types) perhaps be handled by an IDE, similar to the refactoring angle? Do Eclipse and IntelliJ (etc) do it this way?also so that documentation generation like Ddoc can output function or property as appropriate.That makes sense only if you view them as sematically distinct from a code usage-aspect? OTOH, I do see a usage distinction regarding IDE handling of properties, such as property sheets and so on? But that seems quite different from a code-usage perpective ~ instead, IDE property sheets expose an alternative to explicit, configuration of components? If so, could the notion of a 'property' be just some kind of convenient tagging that an IDE looks for? For example: class X { property double velocity; property char[] description; ... } Perhaps the notion could be used by an IDE to expand into other composite aggregates? e.g. class Y { property int something; property X x; ... } There would presumeably be no need to do the same via inheritance? Perhaps, with introspection, such a tag might be useful for other things? These examples use 'property' purely for attribute-decoration only ~ they don't change the behaviour of the compiler per se, except perhaps to imply "private"? - Kris
Jan 05 2006
"Kris" <fu bar.com> wrote in message news:dpkeff$462>I'll admit that I don't see a solid semantic distinction (at thecode-usagelevel) between 'property' methods and 'normal' methods (or did you meansomeother kind of function?). They are both an exposure of capability via some level of abstraction. They can both set or expose internal state. They can both be arbitrarily complex or completely trivial. They are both intendedtoencapsulate behaviour specific to their containing entity. Why is one somehow special? I don't get it :-(Let me cite Dylan Reference Manual: " Order of execution aside, the following pairs of function calls are equivalent: america.capital capital(america) window.position position(window) " and: " name(arg1,...argn ) := new-value behaves exactly the same as begin let temp = new-value; name-setter(temp, arg1,...argn ); temp end " (note: ':=' is Dylan assigment operator as it is '=' in D) No semantics here! Programmers add semantics. What is importan here to have SIMPLE and CONSISTENT GENERAL rule! No special cases. It's beter for programmer and compiler :) At first look D here remembers me Dylan, but it was only half way. Zeljko
Jan 06 2006
Let me cite Dylan Reference Manual: " Order of execution aside, the following pairs of function calls are equivalent: america.capital capital(america) window.position position(window) " and: " name(arg1,...argn ) := new-value behaves exactly the same as begin let temp = new-value; name-setter(temp, arg1,...argn ); temp end " (note: ':=' is Dylan assigment operator as it is '=' in D) No semantics here! Programmers add semantics. What is importan here to have SIMPLE and CONSISTENT GENERAL rule! No special cases. It's beter for programmer and compiler :)Along this lines proposal for D can be (taking in account that D has 'natural methods' what Dylan has not): 1. a.f is equivalent a.f() and a.f() is equivalent to f(a) so: resolve a.f as rvalue: try a.f, then a.f() resolve a.f(): try a.f() then f(a) resolve f(a): unambiguous 2. Only for methods (as it is now, well done IMHO): a.f = x is equivalent a.f(x) Dot! 1a. Sugestion for programmers: use a.f for constant methods only (in C++ sense) (note: some_array.sort or some_aaray.rehash is really wrong, but it is not a big problem if one can use some_array.sort() and everything follows one simple rule. It is always possible to add sam declarative modifier to enforce this pattern of usage.) Not sure, but probably no current code break. Zeljko What is a property? There is no satch thing in D! :) What is a extended method? There is no satch thing in D! :)
Jan 06 2006