Hi,

I've updated the RFC on several sections to reflect the discussion on this list.

The following parts have been changed or added:

  - introduced explicit description of abstract methods to be used as
requirements
    specification for traits (useful to access state)
  - moved part about interface propagation to the section of rejected features
  - added a section about common misconceptions i.e. aliasing is not renaming
  - added various syntax proposals

The important parts are included below. The new version of the RFC is available
at  http://www.stefan-marr.de/rfc-traits-for-php.txt
and http://www.stefan-marr.de/artikel/rfc-traits-for-php.html

Some people proposed to implement only a subset of the proposed features,
especially !renaming! and abstract methods and visibility changes has
been mentioned to postpone on
a later version. I disagree on some of them.
At first, there is no renaming :) Hope, we could get this clear in the
next few days.
May be I should change the way of explaining it, but I've added the part about
misconceptions in the first place.
Second, abstract methods is a really common concept, the have the same
semantics like
for classes. So I expect them to be used the same way.
Third, the changes of visibility. Ok, they are nice but not essentially.
Would be ok to leave them out for now.

The next step could be to try to agree on one of the proposed notations?

Kind Regards
Stefan


Express Requirements by Abstract Methods
""""""""""""""""""""""""""""""""""""""""

Since Traits do not contain any state/properties, there is a need to describe
the requirements a Trait will rely on. In PHP it would be possible to utilize
the dynamic language features, but it is a common practice to give this
requirements explicitly.
This is possible with abstract methods like it is used for abstract classes.
::

<?php
trait Hello {
   public function sayHelloWorld() {
     echo 'Hello'.$this->getWorld();
   }
   abstract public function getWorld();
}

class MyHelloWorld {
   private $world;
   use Hello;
   public function getWorld() {
     return $this->world;
   }
   public function setWorld($val) {
     $this->world = $val;
   }
}
?>

The usage of abstract methods allows to state not always obvious relation ships
and requirements explicitly. It is favored over the implicit usage of the
dynamic method resolution and property creation in the context of complex
projects for the sake of readability.

Common Misconceptions
=====================

Aliasing vs. Renaming
---------------------

The presented aliasing operation has not a semantic of renaming.
Instead it does only provide a new name to be able to invoke the original
method with this new name even if the original name was excluded.
::

<?php
trait A {
   public function a() {
     echo 'a';
     $this->b();
   }
   public function b() {
     echo 'b';
   }
}

class Foo {
   use A {
     c => b
   }
}

$foo = new Foo();
$foo->a();            //echos ab
$foo->b();            //echos b
$foo->c();            //echos b
?>

Since it is not renaming the original method b is still available and has not
been influenced at all.

Alternative Keywords for use
""""""""""""""""""""""""""""

The keyword use is already reserved for the new namespace feature.
Thus, alternative keywords already proposed on the mailing list are listed
here::

[1] exhibit
class Foo {
   exhibit Bar;
}

[2] possess
class Foo {
   possess Bar;
}


Alternative Expression of Exclusion
"""""""""""""""""""""""""""""""""""

Some people do not like the notation with the exclamation mark.
Possible alternatives::

[1] not keyword
use Trait {
   not foo1, foo2;
   bar => foo1
}

[2] without keyword
use Trait {
   without foo1, foo2;
   bar => foo1
}

Alternatives for the Aliasing Notation
""""""""""""""""""""""""""""""""""""""

Aliasing is often misunderstood as renaming.
May be some of the following notations will help::

[1] is keyword instead of the arrow
use Trait {
  bar is foo1;  //methodAlias is method
}

Interpretation: ``is`` state something about ``bar``, there is nothing stated
about ``foo1``.

Alternative keyword::

[2] from
use Trait {
   bar from foo1;  //methodAlias from method
}

Or an very explicit variation::

[3] from
use Trait {
   alias bar as foo1;
}

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to