digitalmars.D - Uniform Function Call syntax for properties
- Steven Schveighoffer (19/19) Oct 08 2010 Someone was asking about UFC syntax for properties on d.learn, and I
- Stanislav Blinov (12/31) Oct 08 2010 What if we make @properties have first parameter as ref/ref const if
-
Denis Koroskin
(23/67)
Oct 08 2010
On Fri, 08 Oct 2010 17:26:41 +0400, Stanislav Blinov
... - Steven Schveighoffer (12/24) Oct 08 2010 Using this is a good idea, but I don't think we should automatically ref...
- Stanislav Blinov (3/31) Oct 08 2010 Looks tasty, and besides that's exactly how class/struct methods
- Andrei Alexandrescu (3/8) Oct 08 2010 Good question.
- Sean Kelly (2/13) Oct 09 2010 Setter. Consider "a = b = c".
- Denis Koroskin (8/21) Oct 09 2010 I think you missed the point. Which of the two is it:
- Robert Jacques (5/27) Oct 09 2010 I agree that there is ambiguity here, but does it why does foo have to b...
- Denis Koroskin (4/37) Oct 09 2010 Because you may want to have both, but you can't because their syntax
- Robert Jacques (9/48) Oct 09 2010 Okay I'm confused. How do their syntax overlap? And which syntaxes do yo...
- Denis Koroskin (23/74) Oct 09 2010 I wasn't talking about ambiguity. I told that you can't assign different...
- Robert Jacques (8/85) Oct 10 2010 Actually, that's completely expected, in my humble opinion. Yes, it will...
- Steven Schveighoffer (4/37) Oct 13 2010 Because then we are back to writeln = 42;
- Robert Jacques (13/52) Oct 13 2010 :) I see that despite not valid code for what, over a year now?, writeln...
- Steven Schveighoffer (15/31) Oct 14 2010 IMO, that's because the head squeaky wheel is not really fond of
- Robert Jacques (50/82) Oct 14 2010 First, to avoid confusion, I'd like to separate inappropriate usage at t...
- Steven Schveighoffer (16/61) Oct 14 2010 as well you can rename anything you want. Hell, for most D projects you...
- Robert Jacques (24/89) Oct 17 2010 I think you have misunderstood something. It is partly my fault, as I us...
- Nick Sabalausky (23/41) Oct 08 2010 Ugh, it seems D still doesn't quite understand the concept of a property...
- Jonathan M Davis (5/69) Oct 08 2010 If literals are considered const or immutable, then this takes care of i...
- Nick Sabalausky (11/27) Oct 08 2010 Maybe hunger is blinding me ATM, but don't see how. Unless it would also...
- Steven Schveighoffer (10/25) Oct 09 2010 Property setters can have two parameters, one is the item used to set it...
- Andrei Alexandrescu (7/37) Oct 09 2010 One possibility is to simply say that
- Andrei Alexandrescu (7/37) Oct 09 2010 One possibility is to simply say that
- Denis Koroskin (5/52) Oct 09 2010 I respectfully disagree. I strongly believe writing getters and setters ...
Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int? i.e. int y = foo = 3; or int y = (3).foo; ??? I know arrays have an issue with property setters, see a bug report I filed a while back: http://d.puremagic.com/issues/show_bug.cgi?id=3857 But that seems like a totally unambiguous case (a global property function with two parameters is obviously a setter on the first parameter in UFC). The getter seems much more problematic. Does anyone have a solution besides adding more syntax? Should we disallow global properties to avoid ambiguity? -Steve
Oct 08 2010
08.10.2010 16:55, Steven Schveighoffer пишет:Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int? i.e. int y = foo = 3; or int y = (3).foo; ??? I know arrays have an issue with property setters, see a bug report I filed a while back: http://d.puremagic.com/issues/show_bug.cgi?id=3857 But that seems like a totally unambiguous case (a global property function with two parameters is obviously a setter on the first parameter in UFC). The getter seems much more problematic. Does anyone have a solution besides adding more syntax? Should we disallow global properties to avoid ambiguity?What if we make properties have first parameter as ref/ref const if it's meant to be part of UFC? This way we can keep module-scope properties and easily make UFC properties for existing types: property int foo(int x) { /*...*/ } // module-scope setter property int foo() { /*...*/ } // module-scope getter property int foo(ref int x, int v) { /*...*/ } // UFC 'setter' for int property int foo(ref int x) { /*...*/ } // or int foo(ref const int x) - UFS 'getter' for int There's a caveat, though, as having ref/ref const would disallow doing thigs like 3.foo() (which makes perfect sense for 'setters', but not for getters.
Oct 08 2010
On Fri, 08 Oct 2010 17:26:41 +0400, Stanislav Blinov <blinov loniir.ru> = = wrote:08.10.2010 16:55, Steven Schveighoffer =D0=C9=DB=C5=D4:=Someone was asking about UFC syntax for properties on d.learn, and I ==realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int? i.e. int y =3D foo =3D 3; or int y =3D (3).foo; ??? I know arrays have an issue with property setters, see a bug report I=filed a while back: http://d.puremagic.com/issues/show_bug.cgi?id=3D3857 But that seems like a totally unambiguous case (a global property =function with two parameters is obviously a setter on the first ==parameter in UFC). The getter seems much more problematic. Does anyone have a solution ==besides adding more syntax? Should we disallow global properties to =avoid ambiguity?What if we make properties have first parameter as ref/ref const if =it's meant to be part of UFC? This way we can keep module-scope =properties and easily make UFC properties for existing types: property int foo(int x) { /*...*/ } // module-scope setter property int foo() { /*...*/ } // module-scope getter property int foo(ref int x, int v) { /*...*/ } // UFC 'setter' for in=tproperty int foo(ref int x) { /*...*/ } // or int foo(ref const int x=) =- UFS 'getter' for int There's a caveat, though, as having ref/ref const would disallow doing==thigs like 3.foo() (which makes perfect sense for 'setters', but not f=or =getters.property int set(this int x, int y) { x =3D y; } property int get(this const(int) x) { return x; } int a =3D 1; a.set(42); // a is 42 now 3.set(42); // fails to compile, 3 is of type const(int)
Oct 08 2010
On Fri, 08 Oct 2010 09:30:59 -0400, Denis Koroskin <2korden gmail.com> wrote:property int set(this int x, int y) { x = y; } property int get(this const(int) x) { return x; } int a = 1; a.set(42); // a is 42 now 3.set(42); // fails to compile, 3 is of type const(int)Using this is a good idea, but I don't think we should automatically ref the value. Also this is already a symbol name, can't we just use it? What I think might be a good idea is to *name* the target this, and then just allow the normal adornments to describe the type. i.e.: property int set(ref int this, int y) {} will work only for lvalues, whereas property int set(int this, int y) {} works for rvalues also. The What do you think? -Steve
Oct 08 2010
08.10.2010 17:46, Steven Schveighoffer пишет:On Fri, 08 Oct 2010 09:30:59 -0400, Denis Koroskin <2korden gmail.com> wrote:Looks tasty, and besides that's exactly how class/struct methods actually look.property int set(this int x, int y) { x = y; } property int get(this const(int) x) { return x; } int a = 1; a.set(42); // a is 42 now 3.set(42); // fails to compile, 3 is of type const(int)Using this is a good idea, but I don't think we should automatically ref the value. Also this is already a symbol name, can't we just use it? What I think might be a good idea is to *name* the target this, and then just allow the normal adornments to describe the type. i.e.: property int set(ref int this, int y) {} will work only for lvalues, whereas property int set(int this, int y) {} works for rvalues also. The What do you think?
Oct 08 2010
On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question. Andrei
Oct 08 2010
Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 09 2010
On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 09 2010
On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden gmail.com> wrote:On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use?Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 09 2010
On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford jhu.edu> wrote:On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden gmail.com> wrote:Because you may want to have both, but you can't because their syntax overlap.On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use?Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 09 2010
On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2korden gmail.com> wrote:On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford jhu.edu> wrote:Okay I'm confused. How do their syntax overlap? And which syntaxes do you think are overlapping? All the following 'lowerings' look fine/unambiguous to me: foo = 42; => foo(42); y = x.foo; => y = x.foo(); => y = foo(x); foo = foo = x.foo; => foo = foo = x.foo(); => foo = foo = foo(x); => foo = foo(foo(x)); => foo(foo(foo(x)));On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden gmail.com> wrote:Because you may want to have both, but you can't because their syntax overlap.On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use?Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 09 2010
On Sun, 10 Oct 2010 08:44:59 +0400, Robert Jacques <sandford jhu.edu> wrote:On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2korden gmail.com> wrote:I wasn't talking about ambiguity. I told that you can't assign different behavior to foo = 42; and y = x.foo; Both are resolving to the same symbol. E.g. I'd like to write a setter, "foo = 42;": private int _foo; int foo(int x) { debug writeln("foo = ", x); _foo = x; return x; } But the following code also triggers the setter above: y = 42.foo(); // prints "foo = 42;", sets private variable _foo to 42, and returns that value That's completely unexpected. Imagine yourself writing class Foo with method bar, and a user who highjacks a hole in the language, creates class bar, and invokes method Foo on it. That's what it looks like at this moment.On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford jhu.edu> wrote:Okay I'm confused. How do their syntax overlap? And which syntaxes do you think are overlapping? All the following 'lowerings' look fine/unambiguous to me: foo = 42; => foo(42); y = x.foo; => y = x.foo(); => y = foo(x); foo = foo = x.foo; => foo = foo = x.foo(); => foo = foo = foo(x); => foo = foo(foo(x)); => foo(foo(foo(x)));On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden gmail.com> wrote:Because you may want to have both, but you can't because their syntax overlap.On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use?Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 09 2010
On Sun, 10 Oct 2010 00:58:39 -0400, Denis Koroskin <2korden gmail.com> wrote:On Sun, 10 Oct 2010 08:44:59 +0400, Robert Jacques <sandford jhu.edu> wrote:Actually, that's completely expected, in my humble opinion. Yes, it will be a bit confusing to people new to D, perhaps even to those familiar with UFC, that behavior is perfectly natural.On Sat, 09 Oct 2010 22:03:56 -0400, Denis Koroskin <2korden gmail.com> wrote:I wasn't talking about ambiguity. I told that you can't assign different behavior to foo = 42; and y = x.foo; Both are resolving to the same symbol. E.g. I'd like to write a setter, "foo = 42;": private int _foo; int foo(int x) { debug writeln("foo = ", x); _foo = x; return x; } But the following code also triggers the setter above: y = 42.foo(); // prints "foo = 42;", sets private variable _foo to 42, and returns that value That's completely unexpected.On Sun, 10 Oct 2010 05:58:00 +0400, Robert Jacques <sandford jhu.edu> wrote:Okay I'm confused. How do their syntax overlap? And which syntaxes do you think are overlapping? All the following 'lowerings' look fine/unambiguous to me: foo = 42; => foo(42); y = x.foo; => y = x.foo(); => y = foo(x); foo = foo = x.foo; => foo = foo = x.foo(); => foo = foo = foo(x); => foo = foo(foo(x)); => foo(foo(foo(x)));On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden gmail.com> wrote:Because you may want to have both, but you can't because their syntax overlap.On Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use?Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.Imagine yourself writing class Foo with method bar, and a user who highjacks a hole in the language, creates class bar, and invokes method Foo on it. That's what it looks like at this moment.Well, hijacking won't be possible since D's got really good function hijacking detection. Also, how can Foo be both a method and a class?
Oct 10 2010
On Sat, 09 Oct 2010 21:58:00 -0400, Robert Jacques <sandford jhu.edu> wrote:On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden gmail.com> wrote:Because then we are back to writeln = 42; -SteveOn Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use?Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 13 2010
On Wed, 13 Oct 2010 14:34:14 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Sat, 09 Oct 2010 21:58:00 -0400, Robert Jacques <sandford jhu.edu> wrote::) I see that despite not valid code for what, over a year now?, writeln = 42 still persists. That said, how exactly are we back to the verb = value "problem"? The rearrangement ambiguity was never the expressed reason for introducing property. In fact, despite all the passionate posts about how wrong "verb = value" looks, it took a very specific syntax ambiguity with delegates/opCall to warrant language inclusion. And given the practical problems property has been running into, it kinda makes me wish I had run across the uniform access principle (http://www.eiffel.com/general/column/2005/Sept_October.html) back during the debates.On Sat, 09 Oct 2010 16:28:32 -0400, Denis Koroskin <2korden gmail.com> wrote:Because then we are back to writeln = 42; -SteveOn Sun, 10 Oct 2010 00:09:23 +0400, Sean Kelly <sean invisibleduck.org> wrote:I agree that there is ambiguity here, but does it why does foo have to be only a getter or only a setter? Why can't it behave like either, depending on its implementation and use?Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:I think you missed the point. Which of the two is it: int x = 42; auto y = x.foo(); // transformed into "auto y = foo(x);", getter or foo = 42; // transformed into "foo(42);", setter Both match.On 10/8/10 7:55 CDT, Steven Schveighoffer wrote:Setter. Consider "a = b = c".Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int?Good question.
Oct 13 2010
On Wed, 13 Oct 2010 20:57:54 -0400, Robert Jacques <sandford jhu.edu> wrote:On Wed, 13 Oct 2010 14:34:14 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:IMO, that's because the head squeaky wheel is not really fond of properties :) It will eventually be fixed.Because then we are back to writeln = 42; -Steve:) I see that despite not valid code for what, over a year now?, writeln = 42 still persists.That said, how exactly are we back to the verb = value "problem"?Because you can use properties in ways they weren't meant to be used. Specifically, you can use a getter as a setter or vice versa. I admit it's not exactly the same problem, but it's a very similar issue.The rearrangement ambiguity was never the expressed reason for introducing property. In fact, despite all the passionate posts about how wrong "verb = value" looks, it took a very specific syntax ambiguity with delegates/opCall to warrant language inclusion. And given the practical problems property has been running into, it kinda makes me wish I had run across the uniform access principle (http://www.eiffel.com/general/column/2005/Sept_October.html) back during the debates.I must have said this a hundred thousand times. It has to do with the power of the author to define usage. When you let the user define usage, confusion ensues. To me, the delegate issue is a nice bonus, and if that's what pushed property acceptance over the edge, so be it. Without the restrictions, the author loses the power to define usage, and he resorts to creating more verbose language like getFoo instead of just foo. Welcome to Java. -Steve
Oct 14 2010
On Thu, 14 Oct 2010 09:42:34 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Wed, 13 Oct 2010 20:57:54 -0400, Robert Jacques <sandford jhu.edu> wrote:First, to avoid confusion, I'd like to separate inappropriate usage at the binary level from textual/syntax level. For example, casting, compile-time reflection and .tupleof are all ways to circumvent the fundamental restrictions of a library in order to achieve inappropriate binary access, while alias and 'with()' allow (harmless?) syntactical changes, changing a library's effective API. The decision between what is and isn't inappropriate syntax is generally made by either the language designer or by your project's style guide. Indeed, libraries that define extensive changes in a language's appropriate syntax are often referred to as being domain specific languages instead of a simple libraries, modules or packages. And part of the reason for this nomenclature change is that DSLs, unlike libraries, tend to compose poorly and require varying levels of programmer buy-in. This is one reason why none of the DSL/macro features implemented and/or proposed for D are pervasive; they all have a very specific and defined radius of comprehension and scope. Which brings us to the concept of methods behaving syntactically as fields. The three solutions put forth so far are: methods-as-properties, which allow methods to behave like methods or fields; property, which force specific methods to behave only as fields; and the uniform access principle, which allows methods _and_ fields to behave like either methods or fields. Both MAP and UAP are language level syntax changes, while property gives libraries pervasive DSL-lite abilities. The main advantages of MAP and UAP is that they allow the project team to better select a coding style that suites them. On the downside, neither MAP nor UAP are mainstream concepts, so it can take people time to adapt, and more coding style choice inevitably breeds more coding style wars (i.e. names_with_underscores vs CamelCase, csHangarian vbNotation, sVNs vs longVariableNames, etc.). property, on the other hand, moves the coding style choice to the library author, which, on the plus side, is similar to coding style, which may not be appropriate for all users for all time. (read: poor user buy-in) Worse, an author's style choice will enviably conflict with either the project's style guidelines or a second author's library, leading to user code which has to constantly change styles. (read: poor composition) And the composition problem only worsens for generic code. I fully agree that the ability to define the acceptable syntactic usage is critical to avoiding confusion, I simply believe that putting that responsibility in that hands of a project's style guide provides the best consistency and is the most inclusive. Furthermore, I would point out that ultimately the author serves the user; they are his/her customer and good libraries don't unnecessarily restrict their users. Indeed, one of D's best feature is the collection of things, both great and small, that lets it get out of the way of the coding process. BTW: That article on the uniform access principal has an interesting sidebar on how Eiffel satisfied two very different sets of programmers who desired mutually exclusive syntaxes. (http://www.eiffel.com/general/column/2005/Sept_October.html)On Wed, 13 Oct 2010 14:34:14 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:IMO, that's because the head squeaky wheel is not really fond of properties :) It will eventually be fixed.Because then we are back to writeln = 42; -Steve:) I see that despite not valid code for what, over a year now?, writeln = 42 still persists.That said, how exactly are we back to the verb = value "problem"?Because you can use properties in ways they weren't meant to be used. Specifically, you can use a getter as a setter or vice versa. I admit it's not exactly the same problem, but it's a very similar issue.The rearrangement ambiguity was never the expressed reason for introducing property. In fact, despite all the passionate posts about how wrong "verb = value" looks, it took a very specific syntax ambiguity with delegates/opCall to warrant language inclusion. And given the practical problems property has been running into, it kinda makes me wish I had run across the uniform access principle (http://www.eiffel.com/general/column/2005/Sept_October.html) back during the debates.I must have said this a hundred thousand times. It has to do with the power of the author to define usage. When you let the user define usage, confusion ensues. To me, the delegate issue is a nice bonus, and if that's what pushed property acceptance over the edge, so be it. Without the restrictions, the author loses the power to define usage, and he resorts to creating more verbose language like getFoo instead of just foo. Welcome to Java. -Steve
Oct 14 2010
On Thu, 14 Oct 2010 20:28:45 -0400, Robert Jacques <sandford jhu.edu> wrote:First, to avoid confusion, I'd like to separate inappropriate usage at the binary level from textual/syntax level. For example, casting, compile-time reflection and .tupleof are all ways to circumvent the fundamental restrictions of a library in order to achieve inappropriate binary access, while alias and 'with()' allow (harmless?) syntactical changes, changing a library's effective API. The decision between what is and isn't inappropriate syntax is generally made by either the language designer or by your project's style guide. Indeed, libraries that define extensive changes in a language's appropriate syntax are often referred to as being domain specific languages instead of a simple libraries, modules or packages. And part of the reason for this nomenclature change is that DSLs, unlike libraries, tend to compose poorly and require varying levels of programmer buy-in. This is one reason why none of the DSL/macro features implemented and/or proposed for D are pervasive; they all have a very specific and defined radius of comprehension and scope.as well you can rename anything you want. Hell, for most D projects you have the source, just rename it! But if you want your code to be readable, you should follow the convention that the author intended, because that's how everyone else will read it and understand it.Which brings us to the concept of methods behaving syntactically as fields. The three solutions put forth so far are: methods-as-properties, which allow methods to behave like methods or fields; property, which force specific methods to behave only as fields; and the uniform access principle, which allows methods _and_ fields to behave like either methods or fields. Both MAP and UAP are language level syntax changes, while property gives libraries pervasive DSL-lite abilities. The main advantages of MAP and UAP is that they allow the project team to better select a coding style that suites them. On the downside, neither MAP nor UAP are mainstream concepts, so it can take people time to adapt, and more coding style choice inevitably breeds more coding style wars (i.e. names_with_underscores vs CamelCase, csHangarian vbNotation, sVNs vs longVariableNames, etc.). property, on the other hand, moves the coding style choice to the library author, which, on the plus side, is similar single coding style, which may not be appropriate for all users for all time. (read: poor user buy-in) Worse, an author's style choice will enviably conflict with either the project's style guidelines or a second author's library, leading to user code which has to constantly change styles. (read: poor composition) And the composition problem only worsens for generic code.Couldn't disagree more. An API without appropriate function names == fail. And the call style is part of the function name, like it or not. People see x = y, they think field. People see x(y) they think function. No matter the camel casing, or spacing between parentheses, or prefixes to the function name, or whether the curly brace is on the next line or not. It amazes me how many times we have to go over this.I fully agree that the ability to define the acceptable syntactic usage is critical to avoiding confusion, I simply believe that putting that responsibility in that hands of a project's style guide provides the best consistency and is the most inclusive. Furthermore, I would point out that ultimately the author serves the user; they are his/her customer and good libraries don't unnecessarily restrict their users. Indeed, one of D's best feature is the collection of things, both great and small, that lets it get out of the way of the coding process.I want the *compiler* to tell me when I incorrectly used a property, not a style guide (which requires a person for interpretation). -Steve
Oct 14 2010
On Thu, 14 Oct 2010 22:22:19 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Thu, 14 Oct 2010 20:28:45 -0400, Robert Jacques <sandford jhu.edu> wrote:I think you have misunderstood something. It is partly my fault, as I used naming styles as an example. More pertinent examples would be function calls vs operator overloading, or prefix (= x y) vs infix (x = y) vs postfix (x y =) notation. These are issues which are normally the purview of the language designer. When the language designer opens up field / method syntax to programmer control, the assumption that x = y means fields ceases to be axiomatic and becomes a programming convention/style. Similarly, that x(y) indicates a function call can also become a programming convention/style. Other programming languages, for example Eiffel, have proven the usefulness of field/method styles other than those of the C-family. In fact Eiffel does not syntactically differentiate stored values (aka fields) from computed values (aka methods), giving it a slightly functional feel. Given a method of control, be it by the Universal-Access-Principal, Method-as-Properties or property, users/authors will all write code in their own preferred style. And although each of these styles is internally logical and self-consistent, unlike names_with_underscores and CamelCaseNames, they may violate each others internal assumptions. So, yes, property allows the authors to define a compiler enforceable way to use a property. And that's great when your preferred style and the author's match. But it also means you're forced to write the equivalent of 'writeln = 42' when your preferred style and the author's don't match.First, to avoid confusion, I'd like to separate inappropriate usage at the binary level from textual/syntax level. For example, casting, compile-time reflection and .tupleof are all ways to circumvent the fundamental restrictions of a library in order to achieve inappropriate binary access, while alias and 'with()' allow (harmless?) syntactical changes, changing a library's effective API. The decision between what is and isn't inappropriate syntax is generally made by either the language designer or by your project's style guide. Indeed, libraries that define extensive changes in a language's appropriate syntax are often referred to as being domain specific languages instead of a simple libraries, modules or packages. And part of the reason for this nomenclature change is that DSLs, unlike libraries, tend to compose poorly and require varying levels of programmer buy-in. This is one reason why none of the DSL/macro features implemented and/or proposed for D are pervasive; they all have a very specific and defined radius of comprehension and scope.as well you can rename anything you want. Hell, for most D projects you have the source, just rename it! But if you want your code to be readable, you should follow the convention that the author intended, because that's how everyone else will read it and understand it.Which brings us to the concept of methods behaving syntactically as fields. The three solutions put forth so far are: methods-as-properties, which allow methods to behave like methods or fields; property, which force specific methods to behave only as fields; and the uniform access principle, which allows methods _and_ fields to behave like either methods or fields. Both MAP and UAP are language level syntax changes, while property gives libraries pervasive DSL-lite abilities. The main advantages of MAP and UAP is that they allow the project team to better select a coding style that suites them. On the downside, neither MAP nor UAP are mainstream concepts, so it can take people time to adapt, and more coding style choice inevitably breeds more coding style wars (i.e. names_with_underscores vs CamelCase, csHangarian vbNotation, sVNs vs longVariableNames, etc.). property, on the other hand, moves the coding style choice to the library author, which, on the plus side, is choose a single coding style, which may not be appropriate for all users for all time. (read: poor user buy-in) Worse, an author's style choice will enviably conflict with either the project's style guidelines or a second author's library, leading to user code which has to constantly change styles. (read: poor composition) And the composition problem only worsens for generic code.Couldn't disagree more. An API without appropriate function names == fail. And the call style is part of the function name, like it or not. People see x = y, they think field. People see x(y) they think function. No matter the camel casing, or spacing between parentheses, or prefixes to the function name, or whether the curly brace is on the next line or not. It amazes me how many times we have to go over this.I fully agree that the ability to define the acceptable syntactic usage is critical to avoiding confusion, I simply believe that putting that responsibility in that hands of a project's style guide provides the best consistency and is the most inclusive. Furthermore, I would point out that ultimately the author serves the user; they are his/her customer and good libraries don't unnecessarily restrict their users. Indeed, one of D's best feature is the collection of things, both great and small, that lets it get out of the way of the coding process.I want the *compiler* to tell me when I incorrectly used a property, not a style guide (which requires a person for interpretation). -Steve
Oct 17 2010
"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:op.vj9cunrweav7ka localhost.localdomain...Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int? i.e. int y = foo = 3; or int y = (3).foo; ??? I know arrays have an issue with property setters, see a bug report I filed a while back: http://d.puremagic.com/issues/show_bug.cgi?id=3857 But that seems like a totally unambiguous case (a global property function with two parameters is obviously a setter on the first parameter in UFC). The getter seems much more problematic. Does anyone have a solution besides adding more syntax? Should we disallow global properties to avoid ambiguity?Ugh, it seems D still doesn't quite understand the concept of a property. Here: property int foo() // Obviously getter property void foo(int x) // Obviously setter No other form makes any sence as a property. Frankly, I'm very surprised, and dissapointed, that anything else is even allowed. The only *possible* exception being: property int foo(int x) // Combined getter/setter, if we decide that's needed It doesn't make any sense for a property getter to have a parameter (unless it's one parameter and it's used to set a new value). And it doesn't make any sence for a setter to have anthing other than exactly one parameter. Just disallow it. What could possibly be the point anyway? If it's got parameters it's a function call, not a variable. Additionally, with that understanding in place, this: property void foo(int x) {...} (3).foo(); Is probably the one place where UFC syntax should never be allowed, because it's obviously a setter, and since when does this ever make any sence: int x; (3).x; // Set x to 3?? WTF??
Oct 08 2010
On Friday, October 08, 2010 13:56:14 Nick Sabalausky wrote:"Steven Schveighoffer" <schveiguy yahoo.com> wrote in message news:op.vj9cunrweav7ka localhost.localdomain...I agree 100%.Someone was asking about UFC syntax for properties on d.learn, and I realized, we have a huge ambiguity here. Given a function: property int foo(int x) Is this a global setter or a getter on an int? i.e. int y = foo = 3; or int y = (3).foo; ??? I know arrays have an issue with property setters, see a bug report I filed a while back: http://d.puremagic.com/issues/show_bug.cgi?id=3857 But that seems like a totally unambiguous case (a global property function with two parameters is obviously a setter on the first parameter in UFC). The getter seems much more problematic. Does anyone have a solution besides adding more syntax? Should we disallow global properties to avoid ambiguity?Ugh, it seems D still doesn't quite understand the concept of a property. Here: property int foo() // Obviously getter property void foo(int x) // Obviously setter No other form makes any sence as a property. Frankly, I'm very surprised, and dissapointed, that anything else is even allowed. The only *possible* exception being: property int foo(int x) // Combined getter/setter, if we decide that's needed It doesn't make any sense for a property getter to have a parameter (unless it's one parameter and it's used to set a new value). And it doesn't make any sence for a setter to have anthing other than exactly one parameter. Just disallow it. What could possibly be the point anyway? If it's got parameters it's a function call, not a variable.Additionally, with that understanding in place, this: property void foo(int x) {...} (3).foo(); Is probably the one place where UFC syntax should never be allowed, because it's obviously a setter, and since when does this ever make any sence: int x; (3).x; // Set x to 3?? WTF??If literals are considered const or immutable, then this takes care of itself, since then the type system would then disallow it. - Jonathan M Davis
Oct 08 2010
"Jonathan M Davis" <jmdavisProg gmx.com> wrote in message news:mailman.483.1286572389.858.digitalmars-d puremagic.com...On Friday, October 08, 2010 13:56:14 Nick Sabalausky wrote:Maybe hunger is blinding me ATM, but don't see how. Unless it would also prevent this: void bar(int a) {...} bar(3); // Cannot implicitly cast away immutable But that would obviously be a bad thing. And even at that, there's still this that would need to be prevented: property void foo(int x) {...} int x = cast(int)3; x.foo; // Set foo to 3 with stupid syntaxAdditionally, with that understanding in place, this: property void foo(int x) {...} (3).foo(); Is probably the one place where UFC syntax should never be allowed, because it's obviously a setter, and since when does this ever make any sence: int x; (3).x; // Set x to 3?? WTF??If literals are considered const or immutable, then this takes care of itself, since then the type system would then disallow it.
Oct 08 2010
On Fri, 08 Oct 2010 16:56:14 -0400, Nick Sabalausky <a a.a> wrote:Ugh, it seems D still doesn't quite understand the concept of a property. Here: property int foo() // Obviously getter property void foo(int x) // Obviously setter No other form makes any sence as a property. Frankly, I'm very surprised, and dissapointed, that anything else is even allowed. The only *possible* exception being: property int foo(int x) // Combined getter/setter, if we decide that's needed It doesn't make any sense for a property getter to have a parameter (unless it's one parameter and it's used to set a new value). And it doesn't make any sence for a setter to have anthing other than exactly one parameter. Just disallow it. What could possibly be the point anyway? If it's got parameters it's a function call, not a variable.Property setters can have two parameters, one is the item used to set it, and one is the rvalue to use when setting. In objects, the first parameter is the hidden this parameter. With UFC, the parameter is explicit. Unless you feel builtin arrays should never have properties? The only exception are global properties which are not set on anything. And this is the problem. I think the syntax discussed in the other part of this thread is probably a good way to disambiguate the issues. -Steve
Oct 09 2010
On 10/9/10 13:33 CDT, Steven Schveighoffer wrote:On Fri, 08 Oct 2010 16:56:14 -0400, Nick Sabalausky <a a.a> wrote:One possibility is to simply say that property int foo(T x); always means a getter for T. This is because if you want to define a global with getter and setter you can always write a type with assignment and alias this. AndreiUgh, it seems D still doesn't quite understand the concept of a property. Here: property int foo() // Obviously getter property void foo(int x) // Obviously setter No other form makes any sence as a property. Frankly, I'm very surprised, and dissapointed, that anything else is even allowed. The only *possible* exception being: property int foo(int x) // Combined getter/setter, if we decide that's needed It doesn't make any sense for a property getter to have a parameter (unless it's one parameter and it's used to set a new value). And it doesn't make any sence for a setter to have anthing other than exactly one parameter. Just disallow it. What could possibly be the point anyway? If it's got parameters it's a function call, not a variable.Property setters can have two parameters, one is the item used to set it, and one is the rvalue to use when setting. In objects, the first parameter is the hidden this parameter. With UFC, the parameter is explicit. Unless you feel builtin arrays should never have properties? The only exception are global properties which are not set on anything. And this is the problem. I think the syntax discussed in the other part of this thread is probably a good way to disambiguate the issues. -Steve
Oct 09 2010
On 10/9/10 13:33 CDT, Steven Schveighoffer wrote:On Fri, 08 Oct 2010 16:56:14 -0400, Nick Sabalausky <a a.a> wrote:One possibility is to simply say that property int foo(T x); always means a getter for T. This is because if you want to define a global with getter and setter you can always write a type with assignment and alias this. AndreiUgh, it seems D still doesn't quite understand the concept of a property. Here: property int foo() // Obviously getter property void foo(int x) // Obviously setter No other form makes any sence as a property. Frankly, I'm very surprised, and dissapointed, that anything else is even allowed. The only *possible* exception being: property int foo(int x) // Combined getter/setter, if we decide that's needed It doesn't make any sense for a property getter to have a parameter (unless it's one parameter and it's used to set a new value). And it doesn't make any sence for a setter to have anthing other than exactly one parameter. Just disallow it. What could possibly be the point anyway? If it's got parameters it's a function call, not a variable.Property setters can have two parameters, one is the item used to set it, and one is the rvalue to use when setting. In objects, the first parameter is the hidden this parameter. With UFC, the parameter is explicit. Unless you feel builtin arrays should never have properties? The only exception are global properties which are not set on anything. And this is the problem. I think the syntax discussed in the other part of this thread is probably a good way to disambiguate the issues. -Steve
Oct 09 2010
On Sat, 09 Oct 2010 23:37:51 +0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 10/9/10 13:33 CDT, Steven Schveighoffer wrote:I respectfully disagree. I strongly believe writing getters and setters should be a) consistent with each other and b) consistent with class/struct properties.On Fri, 08 Oct 2010 16:56:14 -0400, Nick Sabalausky <a a.a> wrote:One possibility is to simply say that property int foo(T x); always means a getter for T. This is because if you want to define a global with getter and setter you can always write a type with assignment and alias this. AndreiUgh, it seems D still doesn't quite understand the concept of a property. Here: property int foo() // Obviously getter property void foo(int x) // Obviously setter No other form makes any sence as a property. Frankly, I'm very surprised, and dissapointed, that anything else is even allowed. The only *possible* exception being: property int foo(int x) // Combined getter/setter, if we decide that's needed It doesn't make any sense for a property getter to have a parameter (unless it's one parameter and it's used to set a new value). And it doesn't make any sence for a setter to have anthing other than exactly one parameter. Just disallow it. What could possibly be the point anyway? If it's got parameters it's a function call, not a variable.Property setters can have two parameters, one is the item used to set it, and one is the rvalue to use when setting. In objects, the first parameter is the hidden this parameter. With UFC, the parameter is explicit. Unless you feel builtin arrays should never have properties? The only exception are global properties which are not set on anything. And this is the problem. I think the syntax discussed in the other part of this thread is probably a good way to disambiguate the issues. -Steve
Oct 09 2010