Why are opCall's not implicitely assignable?

Ary Manzana asterite at gmail.com
Wed Sep 27 07:20:28 PDT 2006


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



More information about the Digitalmars-d-learn mailing list