www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why are opCall's not implicitely assignable?

reply Karen Lanrap <karen digitaldaemon.com> writes:
class C{
    int opCall(int i){
      return 2*i;
    }
}

int main(){
    auto c= new C;
    int x=c.opCall=3; // compiles
    int x=c=3; // does not compile
}
Sep 17 2006
next sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Karen Lanrap" <karen digitaldaemon.com> wrote in message 
news:Xns98428255B9E6digitaldaemoncom 63.105.9.61...
 class C{
    int opCall(int i){
      return 2*i;
    }
 }

 int main(){
    auto c= new C;
    int x=c.opCall=3; // compiles
    int x=c=3; // does not compile
 }

Long story short, the compiler sees "c = 3" first as an assignment, and since assignment can't be overloaded, it complains.
Sep 17 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Jarrett Billingsley wrote:

 since assignment can't be overloaded, it complains. 

Assignments are overloadable. import std.stdio; int f(int p) { return 2*p; } real f(real p) { return 3.0*p; } void main() { auto i=f=2; auto r=f=2.0; writefln( i, r); }
Sep 21 2006
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Karen Lanrap" <karen digitaldaemon.com> wrote in message 
news:Xns9846572EEDA8digitaldaemoncom 63.105.9.61...
 Jarrett Billingsley wrote:

 since assignment can't be overloaded, it complains.

Assignments are overloadable.

Sorry, I meant overloading as in operator overloading. You can't overload opAssign in a class.
 import std.stdio;
 int f(int p)
 {
  return 2*p;
 }
 real f(real p)
 {
  return 3.0*p;
 }

 void main()
 {
  auto i=f=2;
  auto r=f=2.0;
  writefln( i, r);
 }

This is just function overloading - keep in mind that you're not _really_ assigning anything to f, it's just sugar.
Sep 21 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Jarrett Billingsley wrote:
 keep in mind that you're not_really_ assigning anything to f,
 it's just sugar. 

Yes, and that is the problem with this sugar. It dilutes what an assignment _really_ is---if there is a definition for a _real_ assignment at all. Assume there is a definition for what an assignment in D _really_ is. If you then claim that "f=2" is not a _real_ assignment, you have to define what it is other than a _real_ assignment. If you then say it is not an overloading of the assignment operator you have to give a reason, why it differs from overloading the assignment operator. I do not see any difference. So please explain. I am posting in the learn group with the aim to understand the language. If I would have a clear opinion on this matter I would post in the main D group.
Sep 22 2006
parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Karen Lanrap" <karen digitaldaemon.com> wrote in message 
news:Xns984698A00AE21digitaldaemoncom 63.105.9.61...

 If you then say it is not an overloading of the assignment operator
 you have to give a reason, why it differs from overloading the
 assignment operator.

 I do not see any difference. So please explain. I am posting in the
 learn group with the aim to understand the language. If I would have
 a clear opinion on this matter I would post in the main D group.

When I talk about operator overloading, I mean in the sense of classes. Have a look at the Operator Overloading section of the spec. opAdd, opSub, etc. that kind of operator overloading. I think you're taking the idea of "overloading" a bit literally. When we say that "f = 4" is just syntactic sugar for "f(4)", I suppose that yes, in a very literal sense of the word, the assignment operator is overloaded to mean "function call" in this case. However, it's not user defined, it's part of the language. So I wouldn't really call it "overloaded." It's the same thing as anything with multiple meanings in the language -- would you call the tilde (~) operator "overloaded" because it means both bitwise complement and array concatenation? Since the user cannot control what the assignment operator means, it is not overloadable, and by that, I mean you cannot create an opAssign to change its semantics.
Sep 22 2006
prev sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Karen Lanrap wrote:
 class C{
     int opCall(int i){
       return 2*i;
     }
 }
 
 int main(){
     auto c= new C;
     int x=c.opCall=3; // compiles
     int x=c=3; // does not compile
 }

Because the expression form has nothing to do with opCall whatsoever. The purpose of opCall is specifically to overload the (...) form to make the class act like a function. There's no reason that the property syntactic sugar should apply to an object of the class being used as a function. If it did, then how would you assign object references of classes that have opCall at all? Similarly, void function(int) qwert; ... qwert(yuiop); // calling the pointed-to function qwert = asfdg; // changing which function is pointed to Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 20 2006
next sibling parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Stewart Gordon wrote:
 Karen Lanrap wrote:
 class C{
     int opCall(int i){
       return 2*i;
     }
 }

 int main(){
     auto c= new C;
     int x=c.opCall=3; // compiles
     int x=c=3; // does not compile
 }

Because the expression form has nothing to do with opCall whatsoever. The purpose of opCall is specifically to overload the (...) form to make the class act like a function. There's no reason that the property syntactic sugar should apply to an object of the class being used as a function. If it did, then how would you assign object references of classes that have opCall at all? Similarly, void function(int) qwert; ... qwert(yuiop); // calling the pointed-to function qwert = asfdg; // changing which function is pointed to Stewart.

Something bugs me here .. there's some level of inconsistency with all the stuff related to property syntax sugar.
Sep 20 2006
prev sibling parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Stewart Gordon wrote:

 If it did, then how would you
 assign object references of classes that have opCall at all?

The answer is easy: the opCall for a reference of its own class should be disallowed. By the way: the ._= seems to be a useful shorthand for overloading an assignment :-)
 Similarly,
 
      void function(int) qwert;
      ...
      qwert(yuiop);   // calling the pointed-to function
      qwert = asfdg;  // changing which function is pointed to

That is also easy: no qwert can have its own type as a single parameter. Otherwise show me an example. Therefore its distinguishable whether a "=" is a call or an assignment.
Sep 21 2006
next sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Karen Lanrap wrote:
 Stewart Gordon wrote:
 
 If it did, then how would you
 assign object references of classes that have opCall at all?

The answer is easy: the opCall for a reference of its own class should be disallowed. By the way: the ._= seems to be a useful shorthand for overloading an assignment :-)
 Similarly,

      void function(int) qwert;
      ...
      qwert(yuiop);   // calling the pointed-to function
      qwert = asfdg;  // changing which function is pointed to

That is also easy: no qwert can have its own type as a single parameter. Otherwise show me an example. Therefore its distinguishable whether a "=" is a call or an assignment.

Maybe to the compiler .. but to the user?
Sep 21 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Hasan Aljudy wrote:
 Therefore its distinguishable whether a "=" is a call or an 
 assignment.

Maybe to the compiler .. but to the user?

Tools are made to support our thinking---and tools influence the way we think: When all you own is a hammer, every problem starts looking like a nail. (Abraham Maslow)
Sep 22 2006
parent nobody <nobody mailinator.com> writes:
Karen Lanrap wrote:
 Tools are made to support our thinking---and tools influence the way 
 we think:
 
 When all you own is a hammer, every problem starts looking like a 
 nail. (Abraham Maslow)

It is my impression that the Sapir-Whorf hypothesis is still hotly contended. Your argument seems to invoke it which seems like bad form. However you still get points for being able to attribute the hammer-nail quote to Maslow.
Sep 22 2006
prev sibling next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Karen Lanrap wrote:
 Stewart Gordon wrote:
 
 If it did, then how would you
 assign object references of classes that have opCall at all?

The answer is easy: the opCall for a reference of its own class should be disallowed.

And thereby lose the ability to use it for lambda-calculus/combinator stuff?
 By the way: the ._= seems to be a useful shorthand for overloading an 
 assignment :-)

Use it if you like. But the basic question is: Why do you want to overload the assignment operator? http://www.digitalmars.com/d/faq.html#assignmentoverloading
 Similarly,

      void function(int) qwert;
      ...
      qwert(yuiop);   // calling the pointed-to function
      qwert = asfdg;  // changing which function is pointed to

That is also easy: no qwert can have its own type as a single parameter. Otherwise show me an example. Therefore its distinguishable whether a "=" is a call or an assignment.

It's distinguishable at the moment by whether the lvalue is a variable or a function. Trying to add a further dependence on the type of the rvalue would make the language more complicated and possibly harder to understand. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 21 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Stewart Gordon wrote:
 It's distinguishable at the moment by whether the lvalue is a
 variable or a function.
 
 Trying to add a further dependence on the type of the rvalue
 would make the language more complicated and possibly harder to
 understand. 

This harder understanding is introduced by the existing syntax sugar already. You explain it yourself: reading any "x=y;" one has to know whether "x" is a variable or a function because of that syntax sugar. But 1. what is the difference between a variable and a function? 2. why should one stop introducing further dependencies? Number 1 may sound silly, but Walter has introduced the assignment to functions as means of a call---and thereby diluted the differences between both concepts. In fact "real r='\n';" is already a dilution of what a variable is by means of implicit conversion. Number 2 is only driving the properties of implicite conversions further into the control of the user. "real r='\n';" could very well, and with an apropriate function f, be replaced by "real r=f('\n');" and this with the short hand to "real r=f='\n';"
Sep 22 2006
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Karen Lanrap wrote:
 Stewart Gordon wrote:
 It's distinguishable at the moment by whether the lvalue is a
 variable or a function.

 Trying to add a further dependence on the type of the rvalue
 would make the language more complicated and possibly harder to
 understand. 

This harder understanding is introduced by the existing syntax sugar already. You explain it yourself: reading any "x=y;" one has to know whether "x" is a variable or a function because of that syntax sugar.

Not if one is interested primarily in what it does, rather than how it does it. Which is the whole point of properties. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 23 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Stewart Gordon wrote:

 Not if one is interested primarily in what it does, rather than
 how it does it.  Which is the whole point of properties.

Why has this to be restricted to properties? What are properties at all? Why is a member of a class that is a class with an opCall no property of that class? import std.stdio; class C{ int opCall( int p){ return 2*p; } } class D{ C c; ~this(){ c=new C; } } void main(){ auto d=new D; auto i=d.c=2; } As you might notice, we are right back from where we started.
Sep 23 2006
next sibling parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
Karen Lanrap wrote:
 Stewart Gordon wrote:
 
 Not if one is interested primarily in what it does, rather than
 how it does it.  Which is the whole point of properties.

Why has this to be restricted to properties? What are properties at all?

A form of syntactic sugar designed to be used when it makes sense to the semantics of what is being done. For example: class Matrix { ... uint width() { ... } uint width(int w) { ... } uint height() { ... } uint height(int h) { ... } } then you can do something like Matrix m = new Matrix; m.width = 42; m.height = 105; writefln("%d %d", m.width, m.height); The idea is that you are setting/getting the width and height of m, just as you would be if width and height were member variables of Matrix. Defining them as properties just enables more work to be done, e.g. to adjust the internal data structures to fit the new settings.
 Why is a member of a class that is a class with an opCall no property 
 of that class?

Because it's already a member variable. There's no need for it to be a property as well.
 import std.stdio;
 class C{
     int opCall( int p){
         return 2*p;
     }
 }
 
 class D{
     C c;
     ~this(){
         c=new C;
     }
 }

What kind of destructor is this, eh?
 void main(){
     auto d=new D;
     auto i=d.c=2;
 }
 
 
 As you might notice, we are right back from where we started.

What is what you're trying supposed to achieve over class D { int c(int p) { return 2*p; } } ??? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 24 2006
parent Karen Lanrap <karen digitaldaemon.com> writes:
Stewart Gordon wrote:

 Defining them as properties just enables more work to be done
 What is what you're trying supposed to achieve

Please read my answer to Mike Parkers post.
Sep 24 2006
prev sibling parent reply Mike Parker <aldacron71 yahoo.com> writes:
Karen Lanrap wrote:

 Why has this to be restricted to properties?
 What are properties at all?
 Why is a member of a class that is a class with an opCall no property 
 of that class?

Conceptually, properties do not belong to a class (in the programming sense of 'class') but to a class of objects (in the object oriented design sense of 'class'). People have height and weight. Cars have color. These could all be considered object properties. Can you name an object that has the property of opCall? At the programming level, it is convenient to directly manipulate properties, rather than working with functions which may have cumbersome or inappropriate names. But making properties public and directly accessible is error prone. So a compromise is to manipulate the properties through methods, but hide the method calls behind assignment syntax (foo.prop = 1, i = foo.prop). Some languages provide no support for this at all (C++), some have standard naming conventions for methods but no direct support (Java), and some provide direct support (C#). I think C# got it right, in that property syntax explicitly declares a class member as a property and only members declared as such can be manipulated as properties. D's support for properties is rather weak, IMO, in that it isn't explicit. It doesn't enforce property syntax on property manipulators only. It can also, as in this case, lead to confusion. Just consider that not every class method should be used with property syntax, but only those intended to manipulate properties. Property manipulators should have the name of the property you want to manipulate (it need not be the same name as the actual member variable) and should do what they need to do to set and get a property - nothing more. class Foo { private int _bar; public void bar(int newBar) { _bar = newBar; } public int bar() { return _bar; } }
Sep 24 2006
next sibling parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Mike Parker wrote:

 Cars have color. These could all be considered object
 properties. Can you name an object that has the property of
 opCall?

Assume we have some colors enum COLOR{ LIGHTBLUE, DARKBLUE, RED}; and a car with some colorable parts class Car { Roofliner roof; Seat[4] seats; Carpet carpet; this() { roof= new Roofs.Handmade; seats[0]= new Seats.Handicapped(OVERWEIGHT); seats[1]= new Seats.Standard; seats[2]= new Seats.Auxiliar(LEFT, TINY); // ... Now I want to assign colors to the colorable parts Car car; void main() { car= new Car; car.roof= COLOR.LIGHTBLUE; seats[0]= COLOR.DARKBLUE; seats[1]= COLOR.RED // ... But you say that I am not allowed to do this, because the colorable parts are no properties of the car? I have to write Car car; void main() { car= new Car; with(car) { roof.color= COLOR.LIGHTBLUE; seats[0].color= COLOR.DARKBLUE; seats[1].color= COLOR.RED // ... instead? Thereby explicitely saying that I mean the color each time? How does this fit with "auto c='c';" implicit type inference? Why do I have to write COLOR col= seats[0].color; when it would suffice to write: COLOR col= seats[0]; because of appropriate opCalls?
Sep 24 2006
next sibling parent nobody <nobody mailinator.com> writes:
Karen Lanrap wrote:
 I have to write
 
   Car car;
   void main()
   {
     car= new Car;
     with(car)
     {
       roof.color= COLOR.LIGHTBLUE;
       seats[0].color= COLOR.DARKBLUE;
       seats[1].color= COLOR.RED
     // ...
 
 instead? Thereby explicitely saying that I mean the color each time? 

D supports anonymous structs, unions and enums.
Sep 25 2006
prev sibling next sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
Karen Lanrap wrote:
<snip>
 Now I want to assign colors to the colorable parts
   
   Car car;
   void main()
   {
     car= new Car;
     car.roof= COLOR.LIGHTBLUE;
     seats[0]= COLOR.DARKBLUE;
     seats[1]= COLOR.RED
     // ...
 
 But you say that I am not allowed to do this, because the colorable 
 parts are no properties of the car?

Correct. Such notation would mean setting the roof itself or the seats themselves, not their respective colours. The colour is not the component; it is merely a property of each component.
 <snip>
  Why do I have to write
 
   COLOR col= seats[0].color;
 
 when it would suffice to write:
 
   COLOR col= seats[0];
 
 because of appropriate opCalls?

Two reasons. Firstly, it wouldn't make sense - seats[0] is already a seat, it cannot be a colour at the same time. Secondly, there's nothing appropriate about using opCall for something like this, even if it did work. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Sep 25 2006
prev sibling parent reply Hasan Aljudy <hasan.aljudy gmail.com> writes:
Your example demonstrates very well why overriding assignments shouldn't 
be allowed.

# Car mycar;
# mycar = COLOR.RED; //!!!!!!!

How can a car turn to a red color? This is totally meaningless and bogus.

Color is a property of the car:
# mycar.color = COLOR.RED;

roof is a property of the car, but this doesn't justify using
# mycar.roof = COLOR.RED;
because you're not changing the property roof (well, you're changing its 
state) but rather, you're changing the "color" of the roof; so you're 
changing a property of roof, thus:
# mycar.roof.color = COLOR.RED;

What you're trying to do makes code totally unreadable.

Karen Lanrap wrote:
 Mike Parker wrote:
 
 Cars have color. These could all be considered object
 properties. Can you name an object that has the property of
 opCall?

Assume we have some colors enum COLOR{ LIGHTBLUE, DARKBLUE, RED}; and a car with some colorable parts class Car { Roofliner roof; Seat[4] seats; Carpet carpet; this() { roof= new Roofs.Handmade; seats[0]= new Seats.Handicapped(OVERWEIGHT); seats[1]= new Seats.Standard; seats[2]= new Seats.Auxiliar(LEFT, TINY); // ... Now I want to assign colors to the colorable parts Car car; void main() { car= new Car; car.roof= COLOR.LIGHTBLUE; seats[0]= COLOR.DARKBLUE; seats[1]= COLOR.RED // ... But you say that I am not allowed to do this, because the colorable parts are no properties of the car? I have to write Car car; void main() { car= new Car; with(car) { roof.color= COLOR.LIGHTBLUE; seats[0].color= COLOR.DARKBLUE; seats[1].color= COLOR.RED // ... instead? Thereby explicitely saying that I mean the color each time? How does this fit with "auto c='c';" implicit type inference? Why do I have to write COLOR col= seats[0].color; when it would suffice to write: COLOR col= seats[0]; because of appropriate opCalls?

Sep 25 2006
next sibling parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Mon, 25 Sep 2006 16:49:16 -0600, Hasan Aljudy wrote:

 Your example demonstrates very well why overriding assignments shouldn't 
 be allowed.
 
 # Car mycar;
 # mycar = COLOR.RED; //!!!!!!!
 
 How can a car turn to a red color? This is totally meaningless and bogus.
 
 Color is a property of the car:
 # mycar.color = COLOR.RED;
 
 roof is a property of the car, but this doesn't justify using
 # mycar.roof = COLOR.RED;
 because you're not changing the property roof (well, you're changing its 
 state) but rather, you're changing the "color" of the roof; so you're 
 changing a property of roof, thus:
 # mycar.roof.color = COLOR.RED;
 
 What you're trying to do makes code totally unreadable.

Not to mention it doesn't address the situation when sub-objects have multiple properties... mycar.roof.color = COLOR.RED; mycar.roof.type = SOFT_TOP; you can't do that sort of thing by simply overloading opCall(). mycar.roof = COLOR.RED; mycar.roof = SOFT_TOP; Nah ... doesn't make much sense. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 26/09/2006 10:08:30 AM
Sep 25 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Derek Parnell wrote:
   mycar.roof = COLOR.RED;
   mycar.roof = SOFT_TOP;
 
 Nah ... doesn't make much sense.

Your argument holds for this code too: import std.stdio; enum COLOR{RED}; enum TYPE{SOFT_TOP}; class Car{ void roof( COLOR c) { } void roof(TYPE t) { } } void main(){ auto mycar= new Car; mycar.roof= COLOR.RED; mycar.roof= TYPE.SOFT_TOP; } Now please explain, why this is nearly senseless.
Sep 26 2006
parent Kristian <kjkilpi gmail.com> writes:
On Tue, 26 Sep 2006 11:45:30 +0300, Karen Lanrap <karen digitaldaemon.co=
m>  =

wrote:

 Derek Parnell wrote:
   mycar.roof =3D COLOR.RED;
   mycar.roof =3D SOFT_TOP;

 Nah ... doesn't make much sense.

Your argument holds for this code too: import std.stdio; enum COLOR{RED}; enum TYPE{SOFT_TOP}; class Car{ void roof( COLOR c) { } void roof(TYPE t) { } } void main(){ auto mycar=3D new Car; mycar.roof=3D COLOR.RED; mycar.roof=3D TYPE.SOFT_TOP; } Now please explain, why this is nearly senseless.

I think the assignment operator causes 'trouble' here. You're trying to = = saying that 'roof' is red and soft top, but you're really saying (in ter= ms = of D) that red is assigned to 'roof' and then soft top. Maybe a new = operator would clear things up: mycar.roof IS COLOR.RED; mycar.roof IS TYPE.SOFT_TOP; (Note that lower cased 'is' is a reserved word in D.) As long as there are no multiple properties using the same type, that wi= ll = be unambiguous. A shortcut for this could be: mycar.roof IS COLOR.RED, TYPE.SOFT_TOP; or: mycar.roof IS COLOR.RED AND TYPE.SOFT_TOP; Then you could write sentences like: mycar.roof IS COLOR.RED, STYLE.EXOTIC, AND TYPE.SOFT_TOP; (Hmm, would this break the 'style of D' too much...?)
Sep 26 2006
prev sibling parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Hasan Aljudy wrote:

 What you're trying to do makes code totally unreadable.

It is already possible to write that way---with some inconsistencies. If your argument of inreadability holds at all it also holds for overloading functions---but overloading functions is an accepted technic.
Sep 26 2006
parent reply Mike Parker <aldacron71 yahoo.com> writes:
Karen Lanrap wrote:
 Hasan Aljudy wrote:
 
 What you're trying to do makes code totally unreadable.

It is already possible to write that way---with some inconsistencies. If your argument of inreadability holds at all it also holds for overloading functions---but overloading functions is an accepted technic.

There is nothing inherently unreadable about overloading functions, nor is there anything inherently unreadable about property syntax. The problem is in how you are using these features. Consider this: class MyClass { void print(Object o) { writef(o); } void print(int i) { writef(i); } ... } There is no confusion about the following code: Object o = new Object(); myClass.print(o); myClass.print(10); The method is overloaded, but perfectly readable. You can clearly see by the name that the method prints the argument passed, regardless of type. But that's not going to stop someone from implementing it this way: class MyClass { void print(Object o) { delete o; } void print(int i) { writef(i + 10); } } It's not the overloading that makes the code unreadable, but the implementation. How many users of MyClass will run into bugs because myClass.print(myObj) is deleting their object and not printing it? Or when every integer they output is 10 higher than it should be? The code is not doing what it appears to be, so it is unreadable. What you are doing with properties is the same thing: void main() { car= new Car; car.roof= COLOR.LIGHTBLUE; seats[0]= COLOR.DARKBLUE; seats[1]= COLOR.RED // ... A Roof is *not* a Color. A Seat is *not* a Color. You are abusing the property syntax. The compiler cannot prevent you from such silliness. It is the responsibility of the programmer to follow accepted practice and to make the code clear and understandable. The operator overload opAdd should perform an addition and not a multiplication, but nothing stops you from implementing a multiplication. If you were to do that, myClass + myClass suddenly takes on a meaning other than what is expected and the code becomes unreadable. The same thing is happening with your Car example. The following is how it *should* look: car.roof.color = COLOR.LIGHTBLUE; seats[0].color = COLOR.DARKBLUE; Now the code is clear. Seats have the property of color, and Roofs have the property of color, so assigning a color to those properties makes sense. But assigning a color to a roof directly does not. Just because you *can* do something doesn't mean you *should*. The syntax of the language can help you write readable code, but the compiler isn't a sentient being. It's up to you to stay within the bounds of intended use, name your methods clearly and meaningfully, and to make your code as readable as possible.
Sep 26 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Mike Parker wrote:

 make your code as readable as possible.

Without any measure of readability this requirement is as useful as the word user-friendly. COBOL is known as a language where everything is extremely readable. C and some other languages are known to be more readable than D because they distinguish between pointers ( ^, -> ) and fields ( . ). A dialect of BASIC declares itself to be more readable by allowing the point to be part of identifiers ( "a.b.c" is one legal identifier). Txl replaces "f(g(h(p)))" by "p[h][g][f]". Must I mention APL? ( to me its close to brainf***) Have you ever thaught about the consequences of the "with"-statement? In the sense of "with" would it any more readable to code: prepend( COLOR) append( color){ roof = LIGHTBLUE; seats[0] = DARKBLUE; // ... instead of: roof.color = COLOR.LIGHTBLUE; seats[0].color = COLOR.DARKBLUE; // ...
Sep 26 2006
next sibling parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Karen Lanrap wrote:
 Mike Parker wrote:
 
 make your code as readable as possible.

Without any measure of readability this requirement is as useful as the word user-friendly.

There are measures of readability, but I doubt there is such a measure everyone would agree on.
 In the sense of "with" would it any more readable to code:
 
 prepend( COLOR) append( color){
   roof     = LIGHTBLUE;
   seats[0] = DARKBLUE;
   // ...
 

No it wouldn't be any more readable because it still wouldn't make *any* sense. Roof *is*not* LIGHTBLUE, it's color is LIGHTBLUE, seats[0] is *not* DARKBLUE, it is a Seat and it's color is DARKBLUE.
 instead of:
 
   roof.color     = COLOR.LIGHTBLUE;
   seats[0].color = COLOR.DARKBLUE;
   // ...

I read through this thread and still don't get it why you think that there is something wrong with this.
Sep 26 2006
parent Karen Lanrap <karen digitaldaemon.com> writes:
Ivan Senji wrote:

 I read through this thread and still don't get it why you think
 that there is something wrong with this.

I _feel_ an inconsistency. If I would know that there is something wrong I would post in the main group.
Sep 26 2006
prev sibling next sibling parent reply Bruno Medeiros <brunodomedeiros+spam com.gmail> writes:
Karen Lanrap wrote:
 Mike Parker wrote:
 
 make your code as readable as possible.

Without any measure of readability this requirement is as useful as the word user-friendly.

Readability is subjective, so there cannot be a proper measure of readability. So this point in discussion (whether your overload syntax should be used) is mostly a subjective point. I too am of the opinion that such usage is not very elegant and that the more verbose form: car.roof.color = COLOR.LIGHTBLUE; is preferable. -- Bruno Medeiros - MSc in CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Sep 26 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Bruno Medeiros wrote:

 the more verbose form:
    car.roof.color = COLOR.LIGHTBLUE;
 is preferable.

Maybe, that from these few lines of code you are getting that impression. But what if you are a member of a team that codes colors. Would you be pleased to know, that every third word you code is the word "color"? ... or would you appreciate a mechanism that prevents you from doing so?
Sep 26 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Karen Lanrap wrote:
 Bruno Medeiros wrote:
 
 the more verbose form:
    car.roof.color = COLOR.LIGHTBLUE;
 is preferable.

Maybe, that from these few lines of code you are getting that impression. But what if you are a member of a team that codes colors. Would you be pleased to know, that every third word you code is the word "color"?

What if roof and seat have other properties like name, id, manufacture year: car.roof = LIGHTBLUE; car.roof = 101; //this is an ID car.roof = 1998; //year Call me crazy but that makes no sense. The meaning of terms like: classes, objects, properties, fields are well defined throughout languages like D, Java, C#, C++ ... But your example doesn't make sense in any of those languages. The point is that roof and seat should be objects having subproperties and not just methods emulating properties (not a very good emulation). And to answer the question: no, I wouldn't mind typing color all over the place, but there are workarounds if this bothers someone (define unnamed enum, alias favorite colors...) The problem isn't typing COLOR.something alot, the problem is assigning color to things that aren't colors. (Repeating myself but: roof !is color, and roof.color is color)
Sep 26 2006
parent reply Derek Parnell <derek psyc.ward> writes:
On Tue, 26 Sep 2006 23:13:13 +0200, Ivan Senji wrote:

 Karen Lanrap wrote:
 Bruno Medeiros wrote:
 
 the more verbose form:
    car.roof.color = COLOR.LIGHTBLUE;
 is preferable.

Maybe, that from these few lines of code you are getting that impression. But what if you are a member of a team that codes colors. Would you be pleased to know, that every third word you code is the word "color"?

What if roof and seat have other properties like name, id, manufacture year: car.roof = LIGHTBLUE; car.roof = 101; //this is an ID car.roof = 1998; //year Call me crazy but that makes no sense. The meaning of terms like: classes, objects, properties, fields are well defined throughout languages like D, Java, C#, C++ ... But your example doesn't make sense in any of those languages. The point is that roof and seat should be objects having subproperties and not just methods emulating properties (not a very good emulation). And to answer the question: no, I wouldn't mind typing color all over the place, but there are workarounds if this bothers someone (define unnamed enum, alias favorite colors...) The problem isn't typing COLOR.something alot, the problem is assigning color to things that aren't colors. (Repeating myself but: roof !is color, and roof.color is color)

Ivan is very 'on the mark' here. This is just a simple example but it demonstrates the concept that using overloading in this manner is not helpful to people who *read* programs. Ok, the compiler might be able to sort things out but it doesn't make it easy for humans to do that. Further more, what might this below mean ... car.roof = COLOR.RED; car.roof = COLOR.WHITE; No it doesn't. Using fancy compiler 'tricks' I meant this (more readible version) ... car.roof.topcoat = COLOR.RED; car.roof.undercoat = COLOR.WHITE; Explicitly documenting the subproperties is a guide to help people read the code. Remember, programming languages are really for people to read. Computers do better with machine language. -- Derek Parnell Melbourne, Australia "Down with mediocrity!"
Sep 26 2006
parent reply Derek Parnell <derek psyc.ward> writes:
On Wed, 27 Sep 2006 07:56:48 +1000, Derek Parnell wrote:


  car.roof.topcoat   = COLOR.RED;
  car.roof.undercoat = COLOR.WHITE;

Oops, I forgot to mention that making it easier to write is also a good thing so a syntax like ... with car.roof { .topcoat = COLOR.RED; .undercoat = COLOR.WHITE; } is nice too. -- Derek Parnell Melbourne, Australia "Down with mediocrity!"
Sep 26 2006
parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Derek Parnell wrote:

   with car.roof
   {
      .topcoat = COLOR.RED;
      .undercoat = COLOR.WHITE;
   }
 
 is nice too.

Until someone says: topcoat is _not_ a color. It is concrete material that surely must have a property called color, but it is not a color itself: this code is totally unreadable for me. (By the way: forgetting to delete a point can have desastrous results in D.)
Sep 26 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Karen Lanrap wrote:
 Derek Parnell wrote:
 
   with car.roof
   {
      .topcoat = COLOR.RED;
      .undercoat = COLOR.WHITE;
   }

 is nice too.

Until someone says: topcoat is _not_ a color. It is concrete material that surely must have a property called color, but it is not a color itself: this code is totally unreadable for me.

IMO (and knowing this NG) this is about a point in time where you will stop getting responses to your posts. It usually has something to do with a person refusing to understand a principal as basic as this one. As for the example. It is all up to you: if topcoat is a color property then with car.roof { .topcoat = COLOR.RED; .undercoat = COLOR.WHITE; } else (it is a property of type coat): with car.roof { .topcoat.color = COLOR.RED; .undercoat.color = COLOR.WHITE; }
 
 (By the way: forgetting to delete a point can have desastrous results 
 in D.)

What point?
Sep 26 2006
next sibling parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Ivan Senji wrote:

 IMO (and knowing this NG) this is about a point in time where
 you will stop getting responses to your posts. It usually has
 something to do with a person refusing to understand a principal
 as basic as this one.

I already noticed that this NG is filled with posters refusing to understand simple principles---but willing to press others into principles they believe to be simple. This whole thread showed, that near to none is able to capture that a property might have a complex structure. So complex that it might be best expressed by the most complex structure of D: a class. I asked a question about the principles of the language D---and got some answers led by personal opinions about coding style. How comes that no answerer was able to convince Walter that his particular style is suitable for an entry in the "Style Guide"?
 It is all up to you:

No, it is not. D prohibits me to code the way I think. And the posters in this thread want not only themselves beeing forced to read the name of the same property over and over again, they also force others to code superfluous words---and at the same time they admire that they can replace a pair of parentheses by an equal sign. That's mental inconsistency at its best. Nobody even cared about the fact, that D is also intended for large scale projects which might include british and american style pronounciations, forcing every maintainer to exactly know whether to write color or colour.
 What point?

Ever heard of the module scope operator---or the D-style to separate an operator by one space from its operands?
Sep 26 2006
next sibling parent Mike Parker <aldacron71 yahoo.com> writes:
Karen Lanrap wrote:
 Ivan Senji wrote:
 
 I already noticed that this NG is filled with posters refusing to 
 understand simple principles---but willing to press others into 
 principles they believe to be simple.
 
 This whole thread showed, that near to none is able to capture that 
 a property might have a complex structure. So complex that it might 
 be best expressed by the most complex structure of D: a class.
 

Properties are a well-understood concept across several languages, it is you that are failing to understand them. If, indeed, you do want to use a class as a property nothing is stopping you from doing that. But ask yourself this, if the class were freestanding and *not* a property, would it make sense to assign another type to it? class Roof { ... } Roof myRoof = new Roof(); myRoof = Color.Blue; In D, this will fail to compile, and for good reason. A roof is not a color, so assigning a color to a roof variable makes absolutely no sense whatsoever. The same concept holds true if a Roof object is a property of the car. The roof has properties itself. If you can't be bothered to type car.roof.color, that is not a failure of the language but a personal issue. Dynamically typed languages like Python and Lua allow you to assign different types to the same variable, but D is not dynamically typed.
 I asked a question about the principles of the language D---and got 
 some answers led by personal opinions about coding style. How comes 
 that no answerer was able to convince Walter that his particular 
 style is suitable for an entry in the "Style Guide"?

Properties are not unique to D. There's no reason to include anything about such a feature the style guide. It's a simple concept that many, many, programmers already comprehend.
 
 No, it is not. D prohibits me to code the way I think. And the 
 posters in this thread want not only themselves beeing forced to 
 read the name of the same property over and over again, they also 
 force others to code superfluous words---and at the same time they 
 admire that they can replace a pair of parentheses by an equal 
 sign.

Then perhaps you need to clue in that the way you are thinking about properties in statically typed languages is *wrong*. Just because you think something should be done a certain way doesn't mean that it is the commonly accepted way, nor does it mean it should be supported by the language. I don't know of any language that lets diverse people with different thought processes to code in their own unique style in such a way that the meaning is clear to all who read their code (though Perl surely tries).
 
 That's mental inconsistency at its best.
 
 Nobody even cared about the fact, that D is also intended for large 
 scale projects which might include british and american style 
 pronounciations, forcing every maintainer to exactly know whether 
 to write color or colour.

Name one language that does? How is it even possible for the compiler to accept alternative spellings for the same variable? Some people use the preprocessor in C or C++ to fake it, but it isn't supported directly by either language.
 
 What point?

Ever heard of the module scope operator---or the D-style to separate an operator by one space from its operands?

You can't delete operators in any language and expect the code to work as is. C,C++,Java,C# all have the . operator. C and C++ also have the -> operator. Try deleting those and see if your code compiles. As for spacing, that *is* a personal choice. That gets back to readability in the text file (syntax). All C-based languages allow you to write a+b or a + b. You aren't required to follow any one particular style guide at all -- just recommended to. No one is forcing you to follow commonly accepted standards, or even to use common sense. If you want to continue to say car.roof = Color.Blue, then go right ahead. But later on, when people are confused by your code, you will have only yourself to blame. If you never release any code to the world at large or never work on a team, then it really doesn't matter what you do.
Sep 27 2006
prev sibling next sibling parent Lutger <lutger.blijdestijn gmail.com> writes:
Karen Lanrap wrote:
<snip>
 This whole thread showed, that near to none is able to capture that 
 a property might have a complex structure. So complex that it might 
 be best expressed by the most complex structure of D: a class.

I beg to differ. The point, imo, is not that properties might or might not have a complex structure, but should have a simple structure from the users point of view: you know what it does when you see it used, like the - often abused - get/set idiom.
 I asked a question about the principles of the language D---and got 
 some answers led by personal opinions about coding style. How comes 
 that no answerer was able to convince Walter that his particular 
 style is suitable for an entry in the "Style Guide"?
 
 
 It is all up to you:

No, it is not. D prohibits me to code the way I think. And the posters in this thread want not only themselves beeing forced to read the name of the same property over and over again, they also force others to code superfluous words---and at the same time they admire that they can replace a pair of parentheses by an equal sign. That's mental inconsistency at its best.

I don't think so. The point is writing code that is understandable, by you and by others. The last one might be even more important, see below. Reading the name of the same property over and over is a lesser evil than it not being clear what is used with what: A = B.A is better than A = B where both mean A = A. Syntax should help understand symantics, which is why A = B.A is good syntactic sugar for A = B.A() but A = B is not. This is not 'just' style.
 Nobody even cared about the fact, that D is also intended for large 
 scale projects which might include british and american style 
 pronounciations, forcing every maintainer to exactly know whether 
 to write color or colour.

Understanding code is about conventions, thus it is more intersubjective than subjective. Maybe some way of expressing a problem is more understandable to you or me, but if it goes against the established conventions it is prudent to adapt to a different concept. If a team of programmers need programming constructs to hide their disagreement of spelling, I'd say they have more serious problems to deal with. "Programming is for programmers, not computers." - Bartosz Milewski
Sep 27 2006
prev sibling parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Karen Lanrap wrote:
 Ivan Senji wrote:
 
 IMO (and knowing this NG) this is about a point in time where
 you will stop getting responses to your posts. It usually has
 something to do with a person refusing to understand a principal
 as basic as this one.

I already noticed that this NG is filled with posters refusing to understand simple principles---but willing to press others into principles they believe to be simple.

Well that depends on ones point of view ;)
 
 This whole thread showed, that near to none is able to capture that 
 a property might have a complex structure. So complex that it might 
 be best expressed by the most complex structure of D: a class.

I get this, probably most projects have properties that are classes. And classes are reference types. Allowing opCall to be called in a property style would effectively mean overloading assignment which makes no sense for reference types. No-overloading-of-assignment is a rule in D for a good reason, and allowing to go around this rule would be plain evil.
 It is all up to you:

No, it is not. D prohibits me to code the way I think.

Which new language doesn't make you think (at least sometimes) in a new way? (Change the way you think)
 And the 
 posters in this thread want not only themselves beeing forced to 
 read the name of the same property over and over again, they also 
 force others to code superfluous words---and at the same time they 
 admire that they can replace a pair of parentheses by an equal 
 sign.
 

Superfluous to someone is readable and self-documenting to someone else.
 That's mental inconsistency at its best.

Nowhere it is said that assignment can be overloaded (it can't be), and nowhere it is said that opCall is a property. Things would be inconsistent if a(5) and a.opCall(5) worked and a.opCall = 5; didn't work. This way there is no inconsistency. Mental inconsistencies sometimes mean you have to accept something and/or change the way you think. Changing to D-thinking will free your mind (when compared for example to C++ programming)
 
 Nobody even cared about the fact, that D is also intended for large 
 scale projects which might include british and american style 
 pronounciations, forcing every maintainer to exactly know whether 
 to write color or colour.

And this doesn't have anything to do with anything, ideally a library should have only one name and be consistent with it. But nothing prevents you from having struct color{} alias color colour; And now anyone can write what ever they prefer.
 
 
 What point?

Ever heard of the module scope operator

I get it now.
 or the D-style to 
 separate an operator by one space from its operands?

And now I don't get what this means. But I found out where the story about a "." comes from, Derek accidently left if in his example, and if he or anyone else tried to compile it he would get an error from the compiler about something not being a part of global scope. No disaster.
Sep 27 2006
next sibling parent reply Karen Lanrap <karen digitaldaemon.com> writes:
Ivan Senji wrote:

 No disaster.

Yes because in this case there are no global structures that can capture such an assignment. But are the opinions of posters, who make jokes on the readability of other coders work, worth considering, if those posters are unable to read their own examples properly?
Sep 27 2006
parent Derek Parnell <derek nomail.afraid.org> writes:
On Wed, 27 Sep 2006 21:51:49 +0000 (UTC), Karen Lanrap wrote:

 Ivan Senji wrote:
 
 No disaster.

Yes because in this case there are no global structures that can capture such an assignment. But are the opinions of posters, who make jokes on the readability of other coders work, worth considering, if those posters are unable to read their own examples properly?

I don't like getting personal, Karen, but you are starting to appear to me to be a 'mean-spirited' person. I assume the "posters, who make jokes" is referring to myself. If not, I apologize in advance. I was not making jokes. I was not trying to be mean. I was not trying to criticize you or in any other way give offense. I was trying to understand your point of view and possibly express an alternative. In other words, I was trying to have a polite conversation. I'm sorry that I failed to appear to be doing that. My understanding of your original premise is that you feel that opCall() should be able to be used as an overloadable assignment method, which could then be used to simplify writing code while at the same time not losing the potential for complex processing. While I appreciate the need for such a method, I feel that opCall() is not the best one to use, and that a better 'property' facility would help the D language much more. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 28/09/2006 11:58:11 AM
Sep 27 2006
prev sibling parent reply Derek Parnell <derek nomail.afraid.org> writes:
On Wed, 27 Sep 2006 19:05:24 +0200, Ivan Senji wrote:



 
 What point?

Ever heard of the module scope operator

I get it now.
 or the D-style to 
 separate an operator by one space from its operands?

And now I don't get what this means. But I found out where the story about a "." comes from, Derek accidently left if in his example, and if he or anyone else tried to compile it he would get an error from the compiler about something not being a part of global scope. No disaster.

True, no disaster. However I didn't leave the 'dot' in accidentally. I just made up the syntax on the fly because I forgot that D already has a 'with' construct. I used the 'dot' to show people reading the code which identifiers are effected by the 'with' expression. IMHO, it is a mistake in the current D syntax to not avoid showing this. Sure its fine for the compiler because it can work out which identifiers are effected but for mere humans reading the code it becomes bloody near impossible without lots of effort. Given ... with(Foo) { a = b; c = d; e = f; } who'd know that it actually represented ... Foo.a = b; c = Foo.d; Foo.e = Foo.f; That's why I wrote it as with(Foo) { .a = b; c = .d; .e = .f; } So okay, maybe I should have used a different symbol to represent the 'with' expression, but that doesn't, or shouldn't distract, from the concept that my example was trying to express ... that we can write simpler code that is still readable given the appropriate syntax support. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 28/09/2006 11:46:46 AM
Sep 27 2006
parent Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Derek Parnell wrote:
 True, no disaster. However I didn't leave the 'dot' in accidentally. 

Ok, sorry for my wrong assumption.
 I just
 made up the syntax on the fly because I forgot that D already has a 'with'
 construct. 

Yeah, it doesn't seem that it is used that much, I used it maybe only 15-20 times in real programs (not counting test examples).
 I used the 'dot' to show people reading the code which
 identifiers are effected by the 'with' expression. IMHO, it is a mistake in
 the current D syntax to not avoid showing this. 

I agree with this, your example below shows perfectly what the problem is. The 'dot' is not the best solution because it means global scope. This made me think about the discussions about $ vs. length where one of the suggestions was to turn that into "$.length" where $ would mean "the thing that is shortened". This could apply nicely to with too: with(foo) { $.a = b; c = $.d; $.e = $.f; }
Sep 27 2006
prev sibling parent reply Carlos Santander <csantander619 gmail.com> writes:
Ivan Senji escribió:
 Karen Lanrap wrote:
 ...
    with car.roof
    {
       .topcoat = COLOR.RED;
       .undercoat = COLOR.WHITE;
    }
 
 else (it is a property of type coat):
 
    with car.roof
    {
       .topcoat.color = COLOR.RED;
       .undercoat.color = COLOR.WHITE;
    }
 
 
 (By the way: forgetting to delete a point can have desastrous results 
 in D.)

What point?

What Karen is saying is that your examples should be: with (car.roof) { topcoat = COLOR.RED; undercoat = COLOR.WHITE; } with (car.roof) { topcoat.color = COLOR.RED; undercoat.color = COLOR.WHITE; } -- Carlos Santander Bernal
Sep 27 2006
parent reply Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> writes:
Carlos Santander wrote:
 Ivan Senji escribió:
 Karen Lanrap wrote:
 ...
    with car.roof
    {
       .topcoat = COLOR.RED;
       .undercoat = COLOR.WHITE;
    }

 else (it is a property of type coat):

    with car.roof
    {
       .topcoat.color = COLOR.RED;
       .undercoat.color = COLOR.WHITE;
    }


 (By the way: forgetting to delete a point can have desastrous results 
 in D.)

What point?

What Karen is saying is that your examples should be:

Ooops, of course they should be without that ".", but are you sure that is what Karen is talking about? Hmm, have to reread...
Sep 27 2006
parent Carlos Santander <csantander619 gmail.com> writes:
Ivan Senji escribió:
 Carlos Santander wrote:
 What Karen is saying is that your examples should be:

Ooops, of course they should be without that ".", but are you sure that is what Karen is talking about? Hmm, have to reread...

I suppose. It's the only thing that makes sense (even if it's not the actual point of this conversation). -- Carlos Santander Bernal
Sep 27 2006
prev sibling parent reply Mike Parker <aldacron71 yahoo.com> writes:
Karen Lanrap wrote:
 Mike Parker wrote:
 
 make your code as readable as possible.

Without any measure of readability this requirement is as useful as the word user-friendly. COBOL is known as a language where everything is extremely readable. C and some other languages are known to be more readable than D because they distinguish between pointers ( ^, -> ) and fields ( . ). A dialect of BASIC declares itself to be more readable by allowing the point to be part of identifiers ( "a.b.c" is one legal identifier). Txl replaces "f(g(h(p)))" by "p[h][g][f]". Must I mention APL? ( to me its close to brainf***)

Sorry, our wires are crossed. "readability" in the sense of brace location and other syntactic issues isn't what I'm getting at. I'm talking more about self-documenting code: void a(); void b(); void c(); What do the above methods do? Unless you see the implementation, you have no idea. Function names that are named clearly and are indicative of what they do in a given context should be plenty clear to anyone reading them. You can't divine the details without looking at the implementation, but all you need to know is that a method named 'print' will take its input and format to an output location somewhere. opAdd in the D world clearly is not the overload for the * operator. This is the readability I'm talking about. Abusing the property syntax by trying to assign colors to 'roof' and 'seat' properties, which clearly aren't colors, is unreadable in the sense that it makes the 'roof' and 'seat' properties appear to be Color objects. Someone reading the code cannot see what is going on without looking at the implementation details of the Car class. Whether or not they go cross-eyed from Lisp braces is another issue.
Sep 26 2006
parent Karen Lanrap <karen digitaldaemon.com> writes:
Mike Parker wrote:

 Abusing the property syntax by trying to assign colors to 'roof'
 and 'seat' properties, which clearly aren't colors, is
 unreadable in the sense that it makes the 'roof' and 'seat'
 properties appear to be Color objects.

Syntactical elements cannot be abused. Only coders feel abused when their semantic associations to syntactic elements are disturbed. All you are saying is, that you are unable to spontanuously change the views on your objects. Why is it helping your mental style of reading code if you are forced to change that view with constructs like "with"---or has anybody complains about the "with"-statement. And if so, why don't you accept an "append"-statement?
Sep 26 2006
prev sibling parent reply Ary Manzana <asterite gmail.com> writes:
Mike Parker wrote:
 Karen Lanrap wrote:
 
 Why has this to be restricted to properties?
 What are properties at all?
 Why is a member of a class that is a class with an opCall no property 
 of that class?

Conceptually, properties do not belong to a class (in the programming sense of 'class') but to a class of objects (in the object oriented design sense of 'class'). People have height and weight. Cars have color. These could all be considered object properties. Can you name an object that has the property of opCall? At the programming level, it is convenient to directly manipulate properties, rather than working with functions which may have cumbersome or inappropriate names. But making properties public and directly accessible is error prone. So a compromise is to manipulate the properties through methods, but hide the method calls behind assignment syntax (foo.prop = 1, i = foo.prop). Some languages provide no support for this at all (C++), some have standard naming conventions for methods but no direct support (Java), and some provide direct support (C#). I think C# got it right, in that property syntax explicitly declares a class member as a property and only members declared as such can be manipulated as properties. D's support for properties is rather weak, IMO, in that it isn't explicit. It doesn't enforce property syntax on property manipulators only. It can also, as in this case, lead to confusion. Just consider that not every class method should be used with property syntax, but only those intended to manipulate properties. Property manipulators should have the name of the property you want to manipulate (it need not be the same name as the actual member variable) and should do what they need to do to set and get a property - nothing more. class Foo { private int _bar; public void bar(int newBar) { _bar = newBar; } public int bar() { return _bar; } }

The typical example to give a counterexample for this it the class Circle: class Circle { private double _radius; public void radius(double r) { _radius = r; } public double radius() { return _radius; } public void area(double a) { _radius = sqrt(a/PI); } public double area() { return PI * _radius * _radius; } public void perimeter(double p) { _radius = p / (2*PI); } public double perimeter() { return 2 * PI * _radius; } } So: many properties, just one variable for all of them. And you can see that you can use the radius, perimeter or area as the variable, and use the one you want in your implementation according to which setter/getter you think is going to be used the most. BTW, I don't like the syntax for properties as they are now. If you have a void function that takes a parameter, it could be a property or a "process" that changes internally the instance, but shouldn't be seen as a property. How can you say which one is it? By looking at the class documentation (i.e., you write "this is a setter", "this is a getter", etc.). Neither in Java or in C# you have to document, because the set/get convention in Java or the syntax of C# allows you not to document it, and see it clearly in the code. class Some { void process(int something) { } } If you write: Some s = new Some(); s.process = 1; the compiler shouldn't let you do that, because even the method "process" has the syntax of a property, it is not (meant to be) a property. For me, it should be great to have a syntax similar to: class Circle { public setter void radius(double r) { ... } public getter double radius() { ... } public void process(int some) { ... } } Now you can do: Circle c = new Circle(); c.radius = 2.3; c.process(2); But you can't do: Circle c = new Circle(); c.radius(2.3); c.process = 2; --- Ary
Sep 27 2006
parent reply Mike Parker <aldacron71 yahoo.com> writes:
Ary Manzana wrote:
 Mike Parker wrote:
 Karen Lanrap wrote:

 Why has this to be restricted to properties?
 What are properties at all?
 Why is a member of a class that is a class with an opCall no property 
 of that class?

Conceptually, properties do not belong to a class (in the programming sense of 'class') but to a class of objects (in the object oriented design sense of 'class'). People have height and weight. Cars have color. These could all be considered object properties. Can you name an object that has the property of opCall? At the programming level, it is convenient to directly manipulate properties, rather than working with functions which may have cumbersome or inappropriate names. But making properties public and directly accessible is error prone. So a compromise is to manipulate the properties through methods, but hide the method calls behind assignment syntax (foo.prop = 1, i = foo.prop). Some languages provide no support for this at all (C++), some have standard naming conventions for methods but no direct support (Java), and some provide direct support (C#). I think C# got it right, in that property syntax explicitly declares a class member as a property and only members declared as such can be manipulated as properties. D's support for properties is rather weak, IMO, in that it isn't explicit. It doesn't enforce property syntax on property manipulators only. It can also, as in this case, lead to confusion. Just consider that not every class method should be used with property syntax, but only those intended to manipulate properties. Property manipulators should have the name of the property you want to manipulate (it need not be the same name as the actual member variable) and should do what they need to do to set and get a property - nothing more. class Foo { private int _bar; public void bar(int newBar) { _bar = newBar; } public int bar() { return _bar; } }

The typical example to give a counterexample for this it the class Circle: class Circle { private double _radius; public void radius(double r) { _radius = r; } public double radius() { return _radius; } public void area(double a) { _radius = sqrt(a/PI); } public double area() { return PI * _radius * _radius; } public void perimeter(double p) { _radius = p / (2*PI); } public double perimeter() { return 2 * PI * _radius; } } So: many properties, just one variable for all of them. And you can see that you can use the radius, perimeter or area as the variable, and use the one you want in your implementation according to which setter/getter you think is going to be used the most.

How is that a counter-example? That's exactly how properties are supposed to work. Each property manipulator has the name of the property it is intended to manipulate and they each do only what they need to do to get and set the property. You don't even need to have a member variable at all if you can get away with it. What my example is intended to demonstrate is that you should have one manipulator per property action (get/set) -- not one manipulator for multiple properties as Karen was demonstrating earlier.
Sep 27 2006
parent Ary Manzana <asterite gmail.com> writes:
Mike Parker wrote:
 Ary Manzana wrote:
 Mike Parker wrote:
 Karen Lanrap wrote:

 Why has this to be restricted to properties?
 What are properties at all?
 Why is a member of a class that is a class with an opCall no 
 property of that class?

Conceptually, properties do not belong to a class (in the programming sense of 'class') but to a class of objects (in the object oriented design sense of 'class'). People have height and weight. Cars have color. These could all be considered object properties. Can you name an object that has the property of opCall? At the programming level, it is convenient to directly manipulate properties, rather than working with functions which may have cumbersome or inappropriate names. But making properties public and directly accessible is error prone. So a compromise is to manipulate the properties through methods, but hide the method calls behind assignment syntax (foo.prop = 1, i = foo.prop). Some languages provide no support for this at all (C++), some have standard naming conventions for methods but no direct support (Java), and some provide direct support (C#). I think C# got it right, in that property syntax explicitly declares a class member as a property and only members declared as such can be manipulated as properties. D's support for properties is rather weak, IMO, in that it isn't explicit. It doesn't enforce property syntax on property manipulators only. It can also, as in this case, lead to confusion. Just consider that not every class method should be used with property syntax, but only those intended to manipulate properties. Property manipulators should have the name of the property you want to manipulate (it need not be the same name as the actual member variable) and should do what they need to do to set and get a property - nothing more. class Foo { private int _bar; public void bar(int newBar) { _bar = newBar; } public int bar() { return _bar; } }

The typical example to give a counterexample for this it the class Circle: class Circle { private double _radius; public void radius(double r) { _radius = r; } public double radius() { return _radius; } public void area(double a) { _radius = sqrt(a/PI); } public double area() { return PI * _radius * _radius; } public void perimeter(double p) { _radius = p / (2*PI); } public double perimeter() { return 2 * PI * _radius; } } So: many properties, just one variable for all of them. And you can see that you can use the radius, perimeter or area as the variable, and use the one you want in your implementation according to which setter/getter you think is going to be used the most.

How is that a counter-example? That's exactly how properties are supposed to work. Each property manipulator has the name of the property it is intended to manipulate and they each do only what they need to do to get and set the property. You don't even need to have a member variable at all if you can get away with it. What my example is intended to demonstrate is that you should have one manipulator per property action (get/set) -- not one manipulator for multiple properties as Karen was demonstrating earlier.

Sorry, I misunderstood you. Anyway, I also wanted to slip the comment about properties and methods (processes). :-)
Sep 27 2006
prev sibling parent nobody <nobody mailinator.com> writes:
Karen Lanrap wrote:

 The answer is easy: the opCall for a reference of its own class
 should be disallowed.

...
 That is also easy: no qwert can have its own type as a single 
 parameter. Otherwise show me an example.

I believe the original intention of opCall was to allow constructor (ctor) like behavior for structs which have no ctors. Given that origin I think you will find that if an opCall is defined it is in fact normal for it to have an overload which is its own type as a single parameter: struct Point { private: int x, y; public: /// Create a Point object given coords x and y Point* opCall(int x, int y) { /* ... */ } /// Create a Point object given another Point Point* opCall(Point p) { /* ... */ } }
Sep 22 2006