Hey Amaury,

Good points all around, but one last thing to point out, interfaces only 
declare what *must* be supported by an implementer, properties have no 
"implementation", they just are.  Whereas an accessor *has* an implementation.  
So when you see that an interface has an accessor, you can rely on the fact 
that anyone who implements that interface *must* implement an accessor of the 
given name.

From: amaury.bouch...@gmail.com [mailto:amaury.bouch...@gmail.com] On Behalf Of 
Amaury Bouchard
Sent: Sunday, October 14, 2012 3:23 AM
To: Clint Priest
Cc: Nikita Popov; Benjamin Eberlei; internals@lists.php.net
Subject: Re: [PHP-DEV] [PHP-DEV [RFC] Property Accessors v1.2

You are right, we can define __get() in an interface. So, in the end I will 
shut my mouth.

But still, it's not logical. An interface is a contract which defines the 
capacities of an object. If an interface defines the entry point swim(), we 
know that an object which implements this interface is able to swim. The goal 
is to define what is callable in an implementation (the basics of duck typing: 
if it can swim() and fly(), it's a flying fish).

In PHP, it was decided that interfaces may not include member variables. I 
guess it's a philosophical choice; you give orders to an object, knowing what 
it can do (thanks to the interface). And orders are given by calling methods, 
not by setting properties.

As I understand your explanation, you think it's normal to be able to define 
accessors in an interface, because it means there is some code behind. But from 
my point of view, the implementation (in the PHP interpreter) is not relevant; 
it's a design choice first.

Take a look at this code:
  interface Fooable {
    public $aaa { get; set; }
  }
  class Fooer implements Fooable {
    public $aaa {
      get { /* wathever ... */ }
      set { /* ... you want */ }
    }
  }
  class Bar {
    public function do() {
      $foo = new Fooer();
      $foo->aaa = 3;
    }
  }

The Bar object doesn't care if $aaa is an attribute or an accessor. It is used 
the same way.
So, if we agree that this code is correct, I understand that something like 
"$foo->aaa" is a valid entry point to communicate with an object through an 
interface. TIt means that an API is not only defined by methods.
You can argue that an accessor is different from a property, but again, only 
Fooer knows that, Bar shouldn't have to deal with that.

Then, for me there is two logical choices:
- Forbid accessors in interfaces, as properties are already forbidden.
- Allow accessors in interfaces => allow properties too. But it is a complete 
redefinition of interfaces in PHP.

I saw the link you gave to me. Well, as I said before, there is a lot of good 
ideas in C#, but I think PHP is an opinionated language and we can do our own 
choices (see how namespaces work in a very different way from C++ namespaces, 
for example).


As you point out, __get() implies the choice has already be done. So I shut up 
now   :-)


2012/10/14 Clint Priest <cpri...@zerocue.com<mailto:cpri...@zerocue.com>>


-Clint

On Oct 13, 2012, at 4:21 PM, "Amaury Bouchard" 
<ama...@amaury.net<mailto:ama...@amaury.net>> wrote:
2012/10/13 Clint Priest <cpri...@zerocue.com<mailto:cpri...@zerocue.com>>
Interfaces are used to define what methods must be present, properties are not 
allowed.

Yes, so no one should be correct, right?
I mean, yes the first declaration implies some code; but for the interface, 
it's still a property definition.

You're mixing concepts here, it's an accessor definition, not a property 
definition.  property != accessor, an accessor just happens to look and act 
like a property (which is the point of accessors).

Interfaces define methods, not properties. Fine.
But is an accessor (as defined in the RFC) a method? Or should we consider that 
an accessor definition is valid inside an interface? I would say no, because it 
will be used as a property: outside of the object that implements the accessor, 
nobody know if it's an attribute or an accessor function.

It's the whole point of the RFC (apart from the asymetric visibility, but you 
know my point of view).


So, for me, this code should be incorrect:
  interface Fooable {
    public $abc { get; set; }
  }

Because if an object implements the interface:
  class Fooer implements Fooable {
    public $abc {
      get { /* what you want */ }
      set { /* what you want too */ }
    }
  }

How this code will be used? Like that:
  $foo = new Fooer();
  $foo->abc = 3;
  print($foo->abc);

Everybody will agree with me that $abc is used like a property, not as a 
method. So the language should enforce that.
There is a real issue here; this is not a fad from me.

An accessor is a method and an interface which defines an accessor is 
indicating that the accessor must be implemented by any using the interface.

See: http://msdn.microsoft.com/en-US/library/64syzecx(v=vs.80).aspx

Also, "used like a property" does not mean it is a property, it is a method 
call with the syntax of accessing a property, it is still a method call.

I believe __get() may be declared in an interface and if so, then accessors 
should be as well.

Reply via email to