Re: [PHP-DEV] Traits and Properties

2011-01-09 Thread Stefan Marr

On 06 Jan 2011, at 15:33, Johannes Schlüter wrote:

 On Thu, 2011-01-06 at 14:38 +0100, Stefan Marr wrote:
 
 On of those things is that you actually use ReflectionClass to reflect
 on a trait.
 That is really an implementation detail, and should be changed to not
 confuse anyone on a conceptional level. We should not expose that kind
 of engine/implementation detail.
 
 This is the same with interfaces. What does class_exists('some_trait')
 do? - I assume that returns true too.
It does return false for interfaces, that should be consistent and return false 
for traits, too.

Best regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2011-01-09 Thread Stefan Marr
Hi:

On 09 Jan 2011, at 17:23, Stefan Marr wrote:

 This is the same with interfaces. What does class_exists('some_trait')
 do? - I assume that returns true too.
 It does return false for interfaces, that should be consistent and return 
 false for traits, too.
Ok, that is fixed and I added a trait_exists() to match the other functions.

Will add a note to the RFC.

Best regards
Stefan


-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2011-01-06 Thread Stefan Marr
Hi Jonathan:

Sorry, was not able to get back to those discussions earlier.


On 22 Dec 2010, at 16:39, Jonathan Bond-Caron wrote:

 There are two remaining questions I have:
 1) How do traits affect the reflection API?
Johannes implemented some features in the Reflection API.

However, they are very ad-hoc, and there are some points which could be 
designed differently to make the concepts more clear.

On of those things is that you actually use ReflectionClass to reflect on a 
trait.
That is really an implementation detail, and should be changed to not confuse 
anyone on a conceptional level. We should not expose that kind of 
engine/implementation detail.

Thus, there remains stuff to be done about reflection. In general, I would like 
to be able to access all information that was in the source code. However, time 
constraints are an issue for me. If there would be a new release date for an 
alpha or something, I think I could get some time to work on it...


 2) Do we want to be able to declare trait requirements for properties and
 methods? If so what syntax?
Well, there was the proposal to use require to express constraints for the 
composing class, which is something I liked.

However, I would not go to support properties, too, since I still maintain the 
opinion that we do not actually do something about state with regard to traits. 


 
 A note on the syntax proposed by Nathan:
 trait require Foo
 
 An option could be:
 
 trait Foo {
  require {
 public $var;
 function ratio();
  }

Hm, well, we already got abstract methods for the methods part.


 trait Bar {
  require interface Iterator;
 }
And expressing the requirement for an interface or an abstract class seems to 
be the only thing missing, I think.

However, I would not put that in the body but into the hat.

trait Bar require OneSpecificClass, AndPossiblyAnInterface, 
OrPossiblyAnotherInterface {}


 
 The idea comes from:
 http://code.google.com/p/es-lab/wiki/Traits
 
 I found this trying to look for alternative keyword for 'require'.
Yes, Tom worked on that a while ago, but it was to easy to implement it in a 
library for JavaScript. To easy to be considered for a language feature...

Best regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2011-01-06 Thread Stefan Marr
Hi Larry:

On 21 Dec 2010, at 03:24, Larry Garfield wrote:

 I don't believe the RFC mentions how those resolve in case of collision, 
 though.  If two traits define the same abstract method, does that cause a 
 collision that needs manual resolution or can the using class just define it 
 once and thereby support both traits?
Abstract methods do not cause collisions, no. So, there can be an arbitrary 
number of traits asking for an abstract method with identical name, and the 
only thing that has to happen is that it is implemented eventually, perhaps by 
another trait.

Best regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2011-01-06 Thread Johannes Schlüter
On Thu, 2011-01-06 at 14:38 +0100, Stefan Marr wrote:
 
 On of those things is that you actually use ReflectionClass to reflect
 on a trait.
 That is really an implementation detail, and should be changed to not
 confuse anyone on a conceptional level. We should not expose that kind
 of engine/implementation detail.

This is the same with interfaces. What does class_exists('some_trait')
do? - I assume that returns true too.

 Thus, there remains stuff to be done about reflection. In general, I
 would like to be able to access all information that was in the source
 code. However, time constraints are an issue for me. If there would be
 a new release date for an alpha or something, I think I could get some
 time to work on it...

I hoped to do some work on it over Christmas vacation, too, but did
other stuff in the end ...

johannes



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



Re: [PHP-DEV] Traits and Properties

2011-01-03 Thread Stefan Marr
Hi Ben:

On 03 Jan 2011, at 06:58, Ben Schmidt wrote:
 I'm a latecomer here, but...
 
 Stefan, doesn't this conflict with what you've written here (and the
 test cases in SVN)?:
 
 http://wiki.php.net/rfc/horizontalreuse#handling_of_propertiesstate
 
 Or is what is happening here that the properties in traits are treated
 essentially as declarations rather than definitions, triggering errors
 but not actually creating properties, and you think they should actually
 create properties?

Sorry, I do not understand.

Is the text in the RFC contradicting or not clear enough about what the test 
cases show?

The intention was to provide the developer with hints when it is possible that 
state is incompatible.

Until now, the reason why there is not fancy mechanism for conflict resolution 
for properties in traits is, first, the dynamic nature of PHP which makes 
certain things like 'renaming' inconsistent with the rest of the language, 
especially its meta-programming facilities, and second, the added problem with 
state, that you actually have many usecases where the state needs to be merged. 
However, merging behavior is not possible, which simplifies the language 
constructs for handling behavioral conflicts.

Best regards
Stefan



-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2011-01-03 Thread Ben Schmidt

Hi, Stefan,


Sorry, I do not understand.


Haha. Now we are both confused!

In this email thread you seemed to be saying that properties defined in
traits are completely ignored, but in the RFC and svn it seems to be
saying that properties in traits are not ignored, but are merged into
the class and/or trigger errors/warnings. So, which is it? Ignored or
not? Or is some aspect of them ignored and some aspect not?

I hope I'm not making things more confusing

Cheers,

Ben.




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



Re: [PHP-DEV] Traits and Properties

2011-01-03 Thread Stefan Marr
Hi Ben:

On 03 Jan 2011, at 10:35, Ben Schmidt wrote:
 
 OK. So this comment from your email is outdated?:

Yes, outdated since this email:
http://marc.info/?l=php-internalsm=129288735205036w=2

Best regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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




Re: [PHP-DEV] Traits and Properties

2011-01-03 Thread Ben Schmidt

On 3/01/11 8:57 PM, Stefan Marr wrote:

Hi Ben:

On 03 Jan 2011, at 10:35, Ben Schmidt wrote:


OK. So this comment from your email is outdated?:


Yes, outdated since this email:
http://marc.info/?l=php-internalsm=129288735205036w=2

Best regards
Stefan


OK, Stefan, I just got confused by reading your outdated message that was quoted 
in a recent reply, and by the fact that the last update date of 2010-11-18 at 
the top of the RFC is inaccurate, so I assumed the email was more current than it 
was. Seems like the RFC was actually updated circa 2010-12-20. :-)


Sorry for the noise, guys.

Ben.



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



Re: [PHP-DEV] Traits and Properties

2011-01-02 Thread David Muir

On 12/12/10 01:47, Stefan Marr wrote:

Hi:

Traits do not provide any special provisioning for handling properties, 
especially, there is no language solution for handling colliding property names.
The current solution/idiom for handling state safely in a trait is to use 
either abstract set/get methods or an abstract get that returns a reference to 
the property in the class.

However, at the moment it is possible to define properties in a trait:

trait Foo {
  private $a;
  public  $foo;
}

For the moment, that information is completely ignored, thus:

class Bar {
  use Foo;
}
property_exists('Bar', 'a') === false


Well, and that is a rather inconsistent status-quo.

I would like to have that fixed in one or another way.

One possibility would be to forbid property definition in a trait altogether.
That reduces a bit the possibility to have wrong expectations about properties, 
however, the dynamic property creation is still possible.

Another way would be to merge the properties in the composing class.
The question here would be how to treat visibility modifiers: how to merge 
public and private, should it result in public, or private?
And, to discorage users to go this way, should there be a STRICT notice? 
Options here are a notice whenever a property is defined in a trait, or 
whenever properties are silently merged.


Comments very welcome.

Thanks
Stefan



What about extending the way that traits resolve method conflicts to 
solve property conflicts in a similar fashion? I can't remember if it's 
already been suggested and and maybe shot down already. It would 
probably get horrendously messy, but figured I'd mention it anyway.


Cheers,
David

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



Re: [PHP-DEV] Traits and Properties

2011-01-02 Thread Ben Schmidt

On 3/01/11 2:24 PM, David Muir wrote:

On 12/12/10 01:47, Stefan Marr wrote:

Hi:

Traits do not provide any special provisioning for handling properties,
especially, there is no language solution for handling colliding property names.
The current solution/idiom for handling state safely in a trait is to use either
abstract set/get methods or an abstract get that returns a reference to the
property in the class.

However, at the moment it is possible to define properties in a trait:

trait Foo {
private $a;
public $foo;
}

For the moment, that information is completely ignored, thus:

class Bar {
use Foo;
}
property_exists('Bar', 'a') === false


Well, and that is a rather inconsistent status-quo.

I would like to have that fixed in one or another way.

One possibility would be to forbid property definition in a trait altogether.
That reduces a bit the possibility to have wrong expectations about properties,
however, the dynamic property creation is still possible.

Another way would be to merge the properties in the composing class.
The question here would be how to treat visibility modifiers: how to merge
public and private, should it result in public, or private?
And, to discorage users to go this way, should there be a STRICT notice? Options
here are a notice whenever a property is defined in a trait, or whenever
properties are silently merged.


Comments very welcome.

Thanks
Stefan



What about extending the way that traits resolve method conflicts to solve
property conflicts in a similar fashion? I can't remember if it's already been
suggested and and maybe shot down already. It would probably get horrendously
messy, but figured I'd mention it anyway.

Cheers,
David


I'm a latecomer here, but...

Stefan, doesn't this conflict with what you've written here (and the
test cases in SVN)?:

http://wiki.php.net/rfc/horizontalreuse#handling_of_propertiesstate

Or is what is happening here that the properties in traits are treated
essentially as declarations rather than definitions, triggering errors
but not actually creating properties, and you think they should actually
create properties?

Ben.




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



RE: [PHP-DEV] Traits and Properties

2010-12-22 Thread Jonathan Bond-Caron
On Mon Dec 20 06:21 PM, Stefan Marr wrote:
 
 = Handling of Properties/State =
  
 This property handling was implemented in 
 [[http://svn.php.net/viewvc?view=revisionrevision=306476|SVN revision 
 306476]] and examples are given in the test cases.
 

+1 

The E_STRICT warning seems to follow nicely the paper's view that a stateful
trait should be its own 'black-box':
http://scg.unibe.ch/archive/papers/Berg07eStatefulTraits.pdf

There are two remaining questions I have:
1) How do traits affect the reflection API?
2) Do we want to be able to declare trait requirements for properties and
methods? If so what syntax?

A note on the syntax proposed by Nathan:
trait require Foo

An option could be:

trait Foo {
  require {
 public $var;
 function ratio();
  }

  function doFoo($v) {
 $this-var = $v * $this-ratio();
  }
}

trait Bar {
  require interface Iterator;
}

The idea comes from:
http://code.google.com/p/es-lab/wiki/Traits

I found this trying to look for alternative keyword for 'require'.



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



Re: [PHP-DEV] Traits and Properties

2010-12-20 Thread Matthew Weier O'Phinney
On 2010-12-19, Stefan Marr p...@stefan-marr.de wrote:
 On 19 Dec 2010, at 17:22, Matthew Weier O'Phinney wrote:
  Exactly. I wouldn't default to public on conflicts, though -- just with
  the highest declared visibility (e.g., if one trait defines as private
  and the other as protected, protected wins).
 I am currently actually implementing the most restricted proposal: all
 differences in the property definition will lead to a fatal error.

 The reasoning behind this is, that the semantics of state is not
 predictable and all changes in the class/traits hierarchies which are
 incompatible should give the developer an immediate feedback, i.e.,
 make potentially incompatible code break.  That is not the most
 'dynamic' of all possible solutions but seems to fit with the rest of
 PHP.

That makes sense to me as well; having conflicting properties due to
multiple traits implementing them is a good way to lead to inconsistency
and difficult to test/predict code.

 What I have in mind is also not how the methods integrate into the
 inheritance chain, thus, a property in the body of the class does not
 override all property definitions in traits (this is the case for
 methods).  I think that will be useful for the very same reason. And
 well, I hope an educative error message will steer the crowed in the
 right direction to use accessors.

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

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



Re: [PHP-DEV] Traits and Properties

2010-12-20 Thread la...@garfieldtech.com

On 12/20/10 7:53 AM, Matthew Weier O'Phinney wrote:

On 2010-12-19, Stefan Marrp...@stefan-marr.de  wrote:

On 19 Dec 2010, at 17:22, Matthew Weier O'Phinney wrote:

Exactly. I wouldn't default to public on conflicts, though -- just with
the highest declared visibility (e.g., if one trait defines as private
and the other as protected, protected wins).

I am currently actually implementing the most restricted proposal: all
differences in the property definition will lead to a fatal error.

The reasoning behind this is, that the semantics of state is not
predictable and all changes in the class/traits hierarchies which are
incompatible should give the developer an immediate feedback, i.e.,
make potentially incompatible code break.  That is not the most
'dynamic' of all possible solutions but seems to fit with the rest of
PHP.


That makes sense to me as well; having conflicting properties due to
multiple traits implementing them is a good way to lead to inconsistency
and difficult to test/predict code.


I will agree up to a point.  Dude, this will probably break is a 
worthwhile message to give.  At the same time, though, there does need 
to be a way for the developer to say I know that; trust me, I know what 
I'm doing.  Otherwise, having two traits that are supposed to operate 
on the same base data will become needlessly complicated with 
return-by-ref accessors that may also collide.


E.g., if I have three traits that all operate on an internal array, and 
a dozen classes that use them, I do want class A to have traits 1 and 2, 
class B to have traits 1 and 3, etc., without needing three extra 
accessors lying around that serve no purpose other than to work around 
an unnecessary PHP restriction.  (Stack calls in PHP are not free, aside 
from the ugly code that results in.)


Perhaps if both traits use the same variable name, visibility, *and* 
default value then there is no error?


I suspect this issue dovetails with the Traits-and-interfaces thread 
from earlier.


--Larry Garfield

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



Re: [PHP-DEV] Traits and Properties

2010-12-20 Thread Stefan Marr
Hi Larry:
On 20 Dec 2010, at 17:04, la...@garfieldtech.com wrote:

 Perhaps if both traits use the same variable name, visibility, *and* default 
 value then there is no error?
There is not fatal error, however, currently there is E_STRICT notice.


 I suspect this issue dovetails with the Traits-and-interfaces thread from 
 earlier.
Ehm, not sure what you want to get at.
The idea of expressing that the composing class needs to satisfy an interface, 
or perhaps inherit from a specific class still seems to have a number of valid 
use cases.
However, there was a single strong opinion against it, as far as I remember.

Anyway, on the topic of properties.
For the records, I updated the RFC with the following section.

http://wiki.php.net/rfc/horizontalreuse#handling_of_propertiesstate

Comments are welcome.
Thanks
Stefan

= Handling of Properties/State =

Traits do not provide any provisioning for handling state.
They are meant to provide a light-weight mechanism for flexible code reuse,
with the mean goal being to avoid code duplication.
Moreover, should not be confused with typical use cases of classes.
When a strong coherence/coupling between methods and state is required,
and certain invariants have to be maintained on the state, this is a good 
indication that a class is the right abstraction to implement that problem 
with.

However, every behavior needs state to operate on, otherwise it could be just
a static functional helper method.
Thus, trait code will either need to use accessors, which is favorite way to
go since it provides full traits semantics, or they use properties, which
is possible but rather a convenience feature.

Since state is a complex problem, and the knowledge about compatibility of 
state form different traits is only present in a concrete composition, proper
state handling would need language features which are currently considered
beyond the scope of what is necessary for PHP. (See 
[[http://scg.unibe.ch/archive/papers/Berg07eStatefulTraits.pdf|Bergel et al]])

Thus, the goal for a consistent language design is to raise awareness of the
problem, promote the use of accessors, and break early in case the changes to
a trait is potentially problematic for a class using it. This results in the
following rules:

  - Properties are considered incompatible if they differ in their definition.
This means, they differ in the applied modifiers (static, public, 
protected, private) or their initial value.
  - Incompatible properties result in a fatal error.
  - In all other cases, i.e., when the definitions are identical, an E_STRICT
notice is shown to raise awareness about the potentially problematic, and
discouraged use of properties.
  - For those checks, all properties are treated equal. Properties from the 
base class and the composing class have to be compatible with properties
from traits as well as the properties between all traits have to be 
compatible.
  - Non-coliding properties, and properties which are not considered 
incompatible behave exactly the same as if they would have been defined
in the composing class.

This property handling was implemented in 
[[http://svn.php.net/viewvc?view=revisionrevision=306476|SVN revision 306476]] 
and examples are given in the test cases.




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

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2010-12-20 Thread Larry Garfield
On Monday, December 20, 2010 5:21:08 pm Stefan Marr wrote:
 Hi Larry:
 
 On 20 Dec 2010, at 17:04, la...@garfieldtech.com wrote:
  Perhaps if both traits use the same variable name, visibility, *and*
  default value then there is no error?
 
 There is not fatal error, however, currently there is E_STRICT notice.
 
  I suspect this issue dovetails with the Traits-and-interfaces thread from
  earlier.
 
 Ehm, not sure what you want to get at.
 The idea of expressing that the composing class needs to satisfy an
 interface, or perhaps inherit from a specific class still seems to have a
 number of valid use cases. However, there was a single strong opinion
 against it, as far as I remember.

I mean, for instance, if you're using an accessor method then you need that 
accessor to exist, because you're hard coding its name.  If you instead 
provide the accessor yourself, the accessor will be hard coded to a variable 
name, whether you provide it or not.  So either way your trait will die if the 
including class doesn't provide some supporting something.

Example:

Trait Foo1 {
  function increment() {
// Implicit requirement that a class have a property named foo.
$this-foo++; 
  }
}

Trait Foo2 {
// Implicit requirement that a class NOT a property named foo.
  protected $foo;

  function increment() {
$this-foo++; 
  }
}

Trait Foo3 {
  function increment() {
$foo = $this-getFoo();
$foo++; 
  }
  function getFoo() {
// Implicit requirement that a class have a property named foo.
return $this-foo;
  }
}

Trait Foo4 {
  function increment() {
// Implicit requirement that a class have a method named getFoo().
$foo = $this-getFoo();
$foo++; 
  }
}

class Test {
  use Foo;
}
 
So one way or another, there is always an implicit requirement placed on the 
using class.  Implicit requirements suck. :-)  If the answer to trait-based 
properties is if it breaks when you do that, don't do that (which I don't 
fully agree with, in part because of how ugly lots of return-by-ref methods 
is), then we have to make the methods as easy as possible.  Requiring an 
interface is one proposed way to do that.

Reading the RFC over again, I actually see that there is support for abstract 
methods in a trait.  I suppose that serves a similar purpose of causing a 
compile-time error (and thus something much more obvious to be fixed), and 
becomes becomes a matter of taste to a degree.

I don't believe the RFC mentions how those resolve in case of collision, 
though.  If two traits define the same abstract method, does that cause a 
collision that needs manual resolution or can the using class just define it 
once and thereby support both traits?

--Larry Garfield

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



Re: [PHP-DEV] Traits and Properties

2010-12-19 Thread Matthew Weier O'Phinney
On 2010-12-18, Stefan Marr p...@stefan-marr.de wrote:
 On 16 Dec 2010, at 23:31, Larry Garfield wrote:
  - When the visibility collides, should we be folding to the most
  restrictive or least restrictive?  I'm not sure myself; I'm more
  interested in your reasoning for going for most-restrictive.
 So, in general, I think, there is no 'right thing' to do here, because
 the definitions seem to be incompatible but that is only decidable at
 the application-level.

 There is another, related, edge-case in the test case below.  In the
 test we have different initial values for the properties, which makes
 it 'obvious' that they are incompatible.  Thus, in that case I would
 argue for a E_COMPILE_ERROR instead of a notice.

 The reason to use the stricter modifier is, well, arbitrary.

 At least I do not find an argument for either way that completely
 convinces me.  At the moment, the main reason is that 'public' can be
 considered to be the default visibility modifier.  Based on the
 semantics of 'var' and dynamic properties.  Thus, private tends to
 imply that an additional constraint was consciously applied to the
 property, which should be preserved.  

I'd argue that traits should follow similar rules to normal class
inheritance. In that paradigm, you can override a previously defined
member by using equal or _greater_ visibility only -- i.e., you can't
make it _less_ visible (e.g., making a property declared as protected in
the parent class private in the extending class). With traits, it seems
like we should go with whatever is _most_ visible, as then no matter
what traits are mixed in, access is guaranteed.

 Well, but as I said, thats kind of arbitrary and if you look at the
 inheritance rules and try to reason from the view of clients with
 respect to the external interface, then going with public as the
 chosen modifier also starts to sound reasonable...

Exactly. I wouldn't default to public on conflicts, though -- just with
the highest declared visibility (e.g., if one trait defines as private
and the other as protected, protected wins).

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

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



Re: [PHP-DEV] Traits and Properties

2010-12-19 Thread Stefan Marr
Hi Matthew:

On 19 Dec 2010, at 17:22, Matthew Weier O'Phinney wrote:
 Exactly. I wouldn't default to public on conflicts, though -- just with
 the highest declared visibility (e.g., if one trait defines as private
 and the other as protected, protected wins).
I am currently actually implementing the most restricted proposal: all 
differences in the property definition will lead to a fatal error.

The reasoning behind this is, that the semantics of state is not predictable 
and all changes in the class/traits hierarchies which are incompatible should 
give the developer an immediate feedback, i.e., make potentially incompatible 
code break.
That is not the most 'dynamic' of all possible solutions but seems to fit with 
the rest of PHP.

What I have in mind is also not how the methods integrate into the inheritance 
chain, thus, a property in the body of the class does not override all property 
definitions in traits (this is the case for methods).
I think that will be useful for the very same reason. And well, I hope an 
educative error message will steer the crowed in the right direction to use 
accessors.

Best regards
Stefan


-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2010-12-18 Thread Stefan Marr
Hi Larry:

On 16 Dec 2010, at 23:31, Larry Garfield wrote:

 I am fine with this approach, with 2 caveats:
 
 - If you actually do want to make two traits use the same property, it looks 
 like the answer here is Either have no property and demand the existence of 
 an accessor that returns by reference, or you can't write E_NOTICE-safe 
 code.  Is that true?
Yes, that is the tradeoff, perhaps the notice could be restricted be shown in 
strict-mode only.

The manual says the following about E_STRICT, so it seems to fit, but I am not 
sure about the usual usage of E_STRICT throughout the engine.

Manual:
 Note:
 In PHP 5 a new error level E_STRICT is available. As E_STRICT is not included 
 within E_ALL you have to explicitly enable this kind of error level. Enabling 
 E_STRICT during development has some benefits. STRICT messages will help you 
 to use the latest and greatest suggested method of coding, for example warn 
 you about using deprecated functions.



 - When the visibility collides, should we be folding to the most restrictive 
 or least restrictive?  I'm not sure myself; I'm more interested in your 
 reasoning for going for most-restrictive.
So, in general, I think, there is no 'right thing' to do here, because the 
definitions seem to be incompatible but that is only decidable at the 
application-level.

There is another, related, edge-case in the test case below.
In the test we have different initial values for the properties, which makes it 
'obvious' that they are incompatible.
Thus, in that case I would argue for a E_COMPILE_ERROR instead of a notice.

The reason to use the stricter modifier is, well, arbitrary.

At least I do not find an argument for either way that completely convinces me.
At the moment, the main reason is that 'public' can be considered to be the 
default visibility modifier.
Based on the semantics of 'var' and dynamic properties.
Thus, private tends to imply that an additional constraint was consciously 
applied to the property, which should be preserved.
Well, but as I said, thats kind of arbitrary and if you look at the inheritance 
rules and try to reason from the view of clients with respect to the external 
interface, then going with public as the chosen modifier also starts to sound 
reasonable...


 


--TEST--
Conflicting properties with different visibility modifiers should be merged
to the most restrictive modifier.
--FILE--
?php
error_reporting(E_ALL);

trait THello1 {
  public $hello = foo;
}

trait THello2 {
  public $hello = bar;
}

class TraitsTest {
use THello1;
use THello2;
public function getHello() {
return $this-hello;
}
}

$t = new TraitsTest;
?
--EXPECTF-- 
Fatal error: Conflicting definitions for property TraitsTest::$hello provided 
by THello1, THello2 in %s on line %d




Best regards
Stefan


-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



RE: [PHP-DEV] Traits and Properties

2010-12-18 Thread Jonathan Bond-Caron
On Sat Dec 18 10:29 AM, Stefan Marr wrote:
 At least I do not find an argument for either way that completely 
 convinces me.
 At the moment, the main reason is that 'public' can be considered to 
 be the default visibility modifier.
 Based on the semantics of 'var' and dynamic properties.
 Thus, private tends to imply that an additional constraint was 
 consciously applied to the property, which should be preserved.
 Well, but as I said, thats kind of arbitrary and if you look at the 
 inheritance rules and try to reason from the view of clients with 
 respect to the external interface, then going with public as the 
 chosen modifier also starts to sound reasonable...
 

Does the order of the declaration matter?

trait THello1 {
  public $foo;
}

trait THello2 {
  private $foo;
}

trait THello3 {
  protected $foo;
}

class TraitsTest {
use THello1;
use THello2; // E_NOTICE: TraitTest conflict, THello2(private $foo)
ignored, already declared THello1(public $foo)
use THello3; // E_NOTICE: TraitTest conflict, THello3(protected
$foo) ignored, already declared THello1(public $foo)
}

class TraitsTest2 {
use THello3;
use THello2; // E_NOTICE: ..
use THello1; // E_NOTICE: ..
}

It could be that the first property 'wins' and an E_NOTICE is raised about
the property conflict.

Result:

class TraitsTest {
  public $foo;
}

class TraitsTest2 {
  protected $foo;
}

It would seem to fit php, though I'd be happy with simply E_FATAL until
people start using traits

The same for:

trait THelloA {
  public $foo = 'a';
}
trait THelloB {
  public $foo = 'b';
}
class TraitsTest3 {
  use THelloA;
  use THelloB; // E_NOTICE: TraitTest3 conflict, THelloB(public $foo)
ignored, already declared THelloA(public $foo)
}

class TraitsTest4 {
  use THelloB;
  use THelloA; // E_NOTICE: TraitTest3 conflict, THelloA(public $foo)
ignored, already declared THelloB(public $foo)
}

class TraitsTest5 {
  public $foo = 'c';

  use THelloB; // E_NOTICE: TraitTest3 conflict, THelloB(public $foo)
ignored, already declared TraitsTest5(public $foo)
  use THelloA; // E_NOTICE: TraitTest3 conflict, THelloA(public $foo)
ignored, already declared THelloB(public $foo)
}


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



Re: [PHP-DEV] Traits and Properties

2010-12-18 Thread Stefan Marr
Hi Jonathan:

On 18 Dec 2010, at 18:14, Jonathan Bond-Caron wrote:

 Does the order of the declaration matter?
No, the order does not matter, and that is one of the key points of traits 
compared to mixins or Python's way of multiple inheritance.
So, any kind of order-dependent solution would be inconsistent with the design 
of traits.

 though I'd be happy with simply E_FATAL until
 people start using traits
What do you mean by the second part? (until people start using traits)
Changing the design retrospectively does not seem to be the best option?

Best regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



RE: [PHP-DEV] Traits and Properties

2010-12-18 Thread Jonathan Bond-Caron
On Sat Dec 18 12:33 PM, Stefan Marr wrote:
 Hi Jonathan:
 
 On 18 Dec 2010, at 18:14, Jonathan Bond-Caron wrote:
 
  Does the order of the declaration matter?
 No, the order does not matter, and that is one of the key points of 
 traits compared to mixins or Python's way of multiple inheritance.
 So, any kind of order-dependent solution would be inconsistent with 
 the design of traits.
 
  though I'd be happy with simply E_FATAL until people start using 
  traits
 What do you mean by the second part? (until people start using traits) 
 Changing the design retrospectively does not seem to be the best 
 option?
 

Most likely not the best option, I think I'm saying I prefer E_FATAL

But if users find it too restrictive / problematic, the auto-resolution
merge to the most restrictive modifier could be added in a next release or
an approach that's convenient to the code out there using traits 
properties. That seems better than the other way around.



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



Re: [PHP-DEV] Traits and Properties

2010-12-16 Thread Stefan Marr
Hi:

From my point of view the right thing to do with regard to properties is 
defined in the test cases below.

The rational behind providing this semantics is based on the fact that PHP 
allows to define properties dynamically anyway, so there is no way around 
properties.
However, there should be a way that a developer can notice that the code might 
not behave as expected in the composed class.

It is true that behavior needs state to operate on, however, accessors are a 
common pattern and fully supported by traits. Furthermore, traits are not 
supposed to replace classes, and when a trait does more than just providing 
code that is to be easily reused, then the designed should ask the question 
whether that is not actually a class, which then provides the necessary 
guarantees to enforce the invariances the code expects.

Thus, I would like to keep traits as a lightweight concept for code reuse.

Best regards
Stefan

--TEST--
Conflicting properties should result in a notice.
Property use is discorage for traits that are supposed to enable maintainable
code reuse. Accessor methods are the language supported idiom for this.
--FILE--
?php
error_reporting(E_ALL);

trait THello1 {
  public $foo;
}

trait THello2 {
  private $foo;
}

class TraitsTest {
use THello1;
use THello2;
}

var_dump(property_exists('TraitsTest', 'foo'));
?
--EXPECTF-- 
Notice: Trait THello1 and THello2 define the same property in the composition 
of TraitsTest. This might be incompatible, to improve maintainability consider 
using accessor methods instead. Class was composed in %s on line %d.

bool(true)




--TEST--
Non-conflicting properties should work just fine.
--FILE--
?php
error_reporting(E_ALL);

trait THello1 {
  public $hello = hello;
}

trait THello2 {
  private $world = World!;
}

class TraitsTest {
use THello1;
use THello2;
function test() {
echo $this-hello . ' ' . $this-world;
}
}

var_dump(property_exists('TraitsTest', 'hello'));
var_dump(property_exists('TraitsTest', 'world'));

$t = new TraitsTest;
$t-test();
?
--EXPECTF-- 
bool(true)
bool(true)

hello World!


--TEST--
Conflicting properties with different visibility modifiers should be merged
to the most restrictive modifier.
--FILE--
?php
error_reporting(E_ALL);

trait THello1 {
  public $hello;
}

trait THello2 {
  private $hello;
}

class TraitsTest {
use THello1;
use THello2;
}

$t = new TraitsTest;
$t-hello = foo;
?
--EXPECTF-- 
Fatal error: Cannot access private property TraitsTest::$foo in %s on line %d

On 11 Dec 2010, at 17:47, Stefan Marr wrote:

 Hi:
 
 Traits do not provide any special provisioning for handling properties, 
 especially, there is no language solution for handling colliding property 
 names.
 The current solution/idiom for handling state safely in a trait is to use 
 either abstract set/get methods or an abstract get that returns a reference 
 to the property in the class.
 
 However, at the moment it is possible to define properties in a trait:
 
 trait Foo {
 private $a;
 public  $foo;
 }
 
 For the moment, that information is completely ignored, thus:
 
 class Bar {
 use Foo;
 }
 property_exists('Bar', 'a') === false
 
 
 Well, and that is a rather inconsistent status-quo.
 
 I would like to have that fixed in one or another way.
 
 One possibility would be to forbid property definition in a trait altogether.
 That reduces a bit the possibility to have wrong expectations about 
 properties, however, the dynamic property creation is still possible.
 
 Another way would be to merge the properties in the composing class.
 The question here would be how to treat visibility modifiers: how to merge 
 public and private, should it result in public, or private?
 And, to discorage users to go this way, should there be a STRICT notice? 
 Options here are a notice whenever a property is defined in a trait, or 
 whenever properties are silently merged.
 
 
 Comments very welcome.
 
 Thanks
 Stefan
 
 -- 
 Stefan Marr
 Software Languages Lab
 Vrije Universiteit Brussel
 Pleinlaan 2 / B-1050 Brussels / Belgium
 http://soft.vub.ac.be/~smarr
 Phone: +32 2 629 2974
 Fax:   +32 2 629 3525
 
 
 --
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2010-12-16 Thread Sebastian Bergmann
Am 16.12.2010 16:25, schrieb Stefan Marr:
 From my point of view the right thing to do with regard to
 properties is defined in the test cases below.

 +1

-- 
Sebastian BergmannCo-Founder and Principal Consultant
http://sebastian-bergmann.de/   http://thePHP.cc/

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



Re: [PHP-DEV] Traits and Properties

2010-12-16 Thread Benjamin Eberlei
I like it,



additionally if you want to prevent conflicts from the start you can

always go and define prefixed property names like below and use a getter to

access them conveniently.



trait Foo

{

private $Foo_prop;



public function getProp()

{

return $this-Foo_prop;

}

}



I am really looking forward to traits in 5.4!



greetings,

Benjamin



On Thu, 16 Dec 2010 16:25:42 +0100, Stefan Marr p...@stefan-marr.de

wrote:

 Hi:

 

 From my point of view the right thing to do with regard to properties is

 defined in the test cases below.

 

 The rational behind providing this semantics is based on the fact that

PHP

 allows to define properties dynamically anyway, so there is no way

around

 properties.

 However, there should be a way that a developer can notice that the code

 might not behave as expected in the composed class.

 

 It is true that behavior needs state to operate on, however, accessors

are

 a common pattern and fully supported by traits. Furthermore, traits are

not

 supposed to replace classes, and when a trait does more than just

providing

 code that is to be easily reused, then the designed should ask the

question

 whether that is not actually a class, which then provides the necessary

 guarantees to enforce the invariances the code expects.

 

 Thus, I would like to keep traits as a lightweight concept for code

reuse.

 

 Best regards

 Stefan

 

 --TEST--

 Conflicting properties should result in a notice.

 Property use is discorage for traits that are supposed to enable

 maintainable

 code reuse. Accessor methods are the language supported idiom for this.

 --FILE--

 ?php

 error_reporting(E_ALL);

 

 trait THello1 {

   public $foo;

 }

 

 trait THello2 {

   private $foo;

 }

 

 class TraitsTest {

   use THello1;

   use THello2;

 }

 

 var_dump(property_exists('TraitsTest', 'foo'));

 ?

 --EXPECTF--   

 Notice: Trait THello1 and THello2 define the same property in the

 composition of TraitsTest. This might be incompatible, to improve

 maintainability consider using accessor methods instead. Class was

composed

 in %s on line %d.

 

 bool(true)

 

 

 

 

 --TEST--

 Non-conflicting properties should work just fine.

 --FILE--

 ?php

 error_reporting(E_ALL);

 

 trait THello1 {

   public $hello = hello;

 }

 

 trait THello2 {

   private $world = World!;

 }

 

 class TraitsTest {

   use THello1;

   use THello2;

   function test() {

   echo $this-hello . ' ' . $this-world;

   }

 }

 

 var_dump(property_exists('TraitsTest', 'hello'));

 var_dump(property_exists('TraitsTest', 'world'));

 

 $t = new TraitsTest;

 $t-test();

 ?

 --EXPECTF--   

 bool(true)

 bool(true)

 

 hello World!

 

 

 --TEST--

 Conflicting properties with different visibility modifiers should be

merged

 to the most restrictive modifier.

 --FILE--

 ?php

 error_reporting(E_ALL);

 

 trait THello1 {

   public $hello;

 }

 

 trait THello2 {

   private $hello;

 }

 

 class TraitsTest {

   use THello1;

   use THello2;

 }

 

 $t = new TraitsTest;

 $t-hello = foo;

 ?

 --EXPECTF--   

 Fatal error: Cannot access private property TraitsTest::$foo in %s on

line

 %d

 

 On 11 Dec 2010, at 17:47, Stefan Marr wrote:

 

 Hi:

 

 Traits do not provide any special provisioning for handling properties,

 especially, there is no language solution for handling colliding

property

 names.

 The current solution/idiom for handling state safely in a trait is to

 use either abstract set/get methods or an abstract get that returns a

 reference to the property in the class.

 

 However, at the moment it is possible to define properties in a trait:

 

 trait Foo {

 private $a;

 public  $foo;

 }

 

 For the moment, that information is completely ignored, thus:

 

 class Bar {

 use Foo;

 }

 property_exists('Bar', 'a') === false

 

 

 Well, and that is a rather inconsistent status-quo.

 

 I would like to have that fixed in one or another way.

 

 One possibility would be to forbid property definition in a trait

 altogether.

 That reduces a bit the possibility to have wrong expectations about

 properties, however, the dynamic property creation is still possible.

 

 Another way would be to merge the properties in the composing class.

 The question here would be how to treat visibility modifiers: how to

 merge public and private, should it result in public, or private?

 And, to discorage users to go this way, should there be a STRICT

notice?

 Options here are a notice whenever a property is defined in a trait, or

 whenever properties are silently merged.

 

 

 Comments very welcome.

 

 Thanks

 Stefan

 

 -- 

 Stefan Marr

 Software Languages Lab

 Vrije Universiteit Brussel

 Pleinlaan 2 / B-1050 Brussels / Belgium

 http://soft.vub.ac.be/~smarr

 Phone: +32 2 629 2974

 Fax:   +32 2 629 3525

 

 

 --

 PHP Internals - PHP Runtime Development Mailing 

Re: [PHP-DEV] Traits and Properties

2010-12-16 Thread Matthew Weier O'Phinney
On 2010-12-16, Stefan Marr p...@stefan-marr.de wrote:
 From my point of view the right thing to do with regard to properties
 is defined in the test cases below.

 The rational behind providing this semantics is based on the fact that
 PHP allows to define properties dynamically anyway, so there is no way
 around properties.  However, there should be a way that a developer
 can notice that the code might not behave as expected in the composed
 class.

+1

The test cases you include are exactly how I would expect traits to work
with regards to properties.

-- 
Matthew Weier O'Phinney
Project Lead| matt...@zend.com
Zend Framework  | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

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



Re: [PHP-DEV] Traits and Properties

2010-12-16 Thread Patrick ALLAERT
2010/12/16 Stefan Marr p...@stefan-marr.de:
 Hi:

 From my point of view the right thing to do with regard to properties is 
 defined in the test cases below.

 The rational behind providing this semantics is based on the fact that PHP 
 allows to define properties dynamically anyway, so there is no way around 
 properties.
 However, there should be a way that a developer can notice that the code 
 might not behave as expected in the composed class.

 It is true that behavior needs state to operate on, however, accessors are a 
 common pattern and fully supported by traits. Furthermore, traits are not 
 supposed to replace classes, and when a trait does more than just providing 
 code that is to be easily reused, then the designed should ask the question 
 whether that is not actually a class, which then provides the necessary 
 guarantees to enforce the invariances the code expects.

 Thus, I would like to keep traits as a lightweight concept for code reuse.

 Best regards
 Stefan

 --TEST--
 Conflicting properties should result in a notice.
 Property use is discorage for traits that are supposed to enable maintainable
 code reuse. Accessor methods are the language supported idiom for this.
 --FILE--
 ?php
 error_reporting(E_ALL);

 trait THello1 {
  public $foo;
 }

 trait THello2 {
  private $foo;
 }

 class TraitsTest {
        use THello1;
        use THello2;
 }

 var_dump(property_exists('TraitsTest', 'foo'));
 ?
 --EXPECTF--
 Notice: Trait THello1 and THello2 define the same property in the composition 
 of TraitsTest. This might be incompatible, to improve maintainability 
 consider using accessor methods instead. Class was composed in %s on line %d.

In this test, you might want to display some text before the
var_dump() (or alternatively to hardcode the line number on last line)
to ensure it is the property_exists() function call or the class
definition which would create such a notice.

Regards,
Patrick

-- 
Patrick Allaert
---
http://code.google.com/p/peclapm/ - Alternative PHP Monitor

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



Re: [PHP-DEV] Traits and Properties

2010-12-16 Thread la...@garfieldtech.com

I am fine with this approach, with 2 caveats:

- If you actually do want to make two traits use the same property, it 
looks like the answer here is Either have no property and demand the 
existence of an accessor that returns by reference, or you can't write 
E_NOTICE-safe code.  Is that true?


- When the visibility collides, should we be folding to the most 
restrictive or least restrictive?  I'm not sure myself; I'm more 
interested in your reasoning for going for most-restrictive.


--Larry Garfield

On 12/16/10 9:25 AM, Stefan Marr wrote:

Hi:

 From my point of view the right thing to do with regard to properties is 
defined in the test cases below.

The rational behind providing this semantics is based on the fact that PHP 
allows to define properties dynamically anyway, so there is no way around 
properties.
However, there should be a way that a developer can notice that the code might 
not behave as expected in the composed class.

It is true that behavior needs state to operate on, however, accessors are a 
common pattern and fully supported by traits. Furthermore, traits are not 
supposed to replace classes, and when a trait does more than just providing 
code that is to be easily reused, then the designed should ask the question 
whether that is not actually a class, which then provides the necessary 
guarantees to enforce the invariances the code expects.

Thus, I would like to keep traits as a lightweight concept for code reuse.

Best regards
Stefan

--TEST--
Conflicting properties should result in a notice.
Property use is discorage for traits that are supposed to enable maintainable
code reuse. Accessor methods are the language supported idiom for this.
--FILE--
?php
error_reporting(E_ALL);

trait THello1 {
   public $foo;
}

trait THello2 {
   private $foo;
}

class TraitsTest {
use THello1;
use THello2;
}

var_dump(property_exists('TraitsTest', 'foo'));
?
--EXPECTF-- 
Notice: Trait THello1 and THello2 define the same property in the composition 
of TraitsTest. This might be incompatible, to improve maintainability consider 
using accessor methods instead. Class was composed in %s on line %d.

bool(true)




--TEST--
Non-conflicting properties should work just fine.
--FILE--
?php
error_reporting(E_ALL);

trait THello1 {
   public $hello = hello;
}

trait THello2 {
   private $world = World!;
}

class TraitsTest {
use THello1;
use THello2;
function test() {
echo $this-hello . ' ' . $this-world;
}
}

var_dump(property_exists('TraitsTest', 'hello'));
var_dump(property_exists('TraitsTest', 'world'));

$t = new TraitsTest;
$t-test();
?
--EXPECTF-- 
bool(true)
bool(true)

hello World!


--TEST--
Conflicting properties with different visibility modifiers should be merged
to the most restrictive modifier.
--FILE--
?php
error_reporting(E_ALL);

trait THello1 {
   public $hello;
}

trait THello2 {
   private $hello;
}

class TraitsTest {
use THello1;
use THello2;
}

$t = new TraitsTest;
$t-hello = foo;
?
--EXPECTF-- 
Fatal error: Cannot access private property TraitsTest::$foo in %s on line %d

On 11 Dec 2010, at 17:47, Stefan Marr wrote:


Hi:

Traits do not provide any special provisioning for handling properties, 
especially, there is no language solution for handling colliding property names.
The current solution/idiom for handling state safely in a trait is to use 
either abstract set/get methods or an abstract get that returns a reference to 
the property in the class.

However, at the moment it is possible to define properties in a trait:

trait Foo {
private $a;
public  $foo;
}

For the moment, that information is completely ignored, thus:

class Bar {
use Foo;
}
property_exists('Bar', 'a') === false


Well, and that is a rather inconsistent status-quo.

I would like to have that fixed in one or another way.

One possibility would be to forbid property definition in a trait altogether.
That reduces a bit the possibility to have wrong expectations about properties, 
however, the dynamic property creation is still possible.

Another way would be to merge the properties in the composing class.
The question here would be how to treat visibility modifiers: how to merge 
public and private, should it result in public, or private?
And, to discorage users to go this way, should there be a STRICT notice? 
Options here are a notice whenever a property is defined in a trait, or 
whenever properties are silently merged.


Comments very welcome.

Thanks
Stefan

--
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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





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



Re: [PHP-DEV] Traits and Properties

2010-12-13 Thread Richard Quadling
On 11 December 2010 16:47, Stefan Marr p...@stefan-marr.de wrote:
 Hi:

 Traits do not provide any special provisioning for handling properties, 
 especially, there is no language solution for handling colliding property 
 names.
 The current solution/idiom for handling state safely in a trait is to use 
 either abstract set/get methods or an abstract get that returns a reference 
 to the property in the class.

 However, at the moment it is possible to define properties in a trait:

 trait Foo {
  private $a;
  public  $foo;
 }

 For the moment, that information is completely ignored, thus:

 class Bar {
  use Foo;
 }
 property_exists('Bar', 'a') === false


 Well, and that is a rather inconsistent status-quo.

 I would like to have that fixed in one or another way.

 One possibility would be to forbid property definition in a trait altogether.
 That reduces a bit the possibility to have wrong expectations about 
 properties, however, the dynamic property creation is still possible.

 Another way would be to merge the properties in the composing class.
 The question here would be how to treat visibility modifiers: how to merge 
 public and private, should it result in public, or private?
 And, to discorage users to go this way, should there be a STRICT notice? 
 Options here are a notice whenever a property is defined in a trait, or 
 whenever properties are silently merged.


 Comments very welcome.

 Thanks
 Stefan

From the rfc [1], A Trait is similar to a class, but only intended to
group functionality.

I'm guessing that says it all. A trait has no properties.

But.

If properties are to be added to a trait, I think that should come as
a further enhancement and let traits start out as methods only.

If a trait is properties, then also supporting constants and the other
sort of set/get properties would provide a strong level of
consistency. If I can put it in a class, I can put it in a trait.

As visibility on the traits methods can be manipulated via the
aliasing mechanism, so should any visibility to a property.

Richard.

[1] http://wiki.php.net/rfc/horizontalreuse
-- 
Richard Quadling
Twitter : EE : Zend
@RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY

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



Re: [PHP-DEV] Traits and Properties

2010-12-13 Thread Richard Quadling
On 11 December 2010 23:31, Stefan Marr p...@stefan-marr.de wrote:
 The current status of the property behavior is not yet documented explicitly

On the assumption that traits WILL include properties (with
visibility) and aliasing can do all its magic, how would the situation
be handled where multiple traits define shared properties.

I've not got a use case, but say trait1 and trait2 both define the
same property.

Assuming name conflicts are handled via aliasing, then the property
needs to alert the aliasing code that this property is a non
conflicting property. All traits wanting to access the shared property
would have to reveal their intentions.

I can think of 2 ways to handle this (but I'm no genius here, so take
them apart at your pleasure).

1 - The trait's code marks shared properties with a keyword (shared,
common, virtual, something). During incorporation of the trait into
the main class, any marked properties are checked for visibility only.
2 - The trait's code uses a $property. The fact that this is a
reference would require the creation of the property (if it doesn't
already exist) whilst the trait is being compiled into the main class.
I'd guess this would be the least difficult to implement, but I know
squat about this.

I'm guessing the order of handling the traits would be significant here.

Trait1 uses $property, Trait2 uses $property - conflict. Must be
resolved by aliasing or an error.
Trait1 uses $property, Trait2 uses $property - all ok. Trait1 wants
access a non existing property, so one is created. Trait2 is sharing
the now pre-existing property.
Trait1 uses $property, Trait2 uses $property - conflict. Trait1 wants
access a non existing property, so one is created. Trait2's $property
must be aliased to an error.
Trait1 uses $property, Trait2 uses $property - all ok. Trait1's
$property is added as expected. Trait2 is sharing the now pre-existing
property.

Richard.


-- 
Richard Quadling
Twitter : EE : Zend
@RQuadling : e-e.com/M_248814.html : bit.ly/9O8vFY

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



Re: [PHP-DEV] Traits and Properties

2010-12-13 Thread Stefan Marr
Hi Richard:

On 13 Dec 2010, at 14:13, Richard Quadling wrote:

 From the rfc [1], A Trait is similar to a class, but only intended to
 group functionality.
 
 I'm guessing that says it all. A trait has no properties.

It is really a practical concern of language consistency for the moment.
I am not talking about any fancy new language feature to handle state.

At the moment, I am just concerned with examples like the following:

trait Foo {
  function bar() {
$this-baz = 'abcd';
  }
}

If that example becomes more complex, I would consider it to be good software 
engineering practice to document the usage of $this-baz and its semantic.

For classes this is usually done by explicitly naming the property in the class 
body.

At the moment, there is nothing which hinders you in doing that for a trait.

However, since traits do not provide any safety provisioning for state, i.e., 
there is no collision handling for properties, the question is, how do we 
either promote to use explicit accessors or how do we deal with the inevitable 
and certainly justified use of properties in one or the other way.

Best regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2010-12-13 Thread Stefan Marr
Hi Richard:

On 13 Dec 2010, at 14:31, Richard Quadling wrote:

 On 11 December 2010 23:31, Stefan Marr p...@stefan-marr.de wrote:
 The current status of the property behavior is not yet documented explicitly
 
 On the assumption that traits WILL include properties (with
 visibility) and aliasing can do all its magic, how would the situation
 be handled where multiple traits define shared properties.
 
 I've not got a use case, but say trait1 and trait2 both define the
 same property.
 
 Assuming name conflicts are handled via aliasing, then the property
 needs to alert the aliasing code that this property is a non
 conflicting property.
Just to emphasize this another time: aliasing is no magic, it is NOT renaming.
(And it is only supported for methods.)

The important implication here is, that aliasing is only useful from the 
viewpoint of the composing class.
Form the trait's perspective, aliasing does not have any effect.

Aliasing can be used to make a function accessible that has a naming conflict 
with another function.
It enables composition of traits, but does not do anything with regard which 
function names a trait-function calls. In PHP all function names are late 
bound, there is no inner binding between functions in traits.

Hope that clarifies what I perceived as a misconception.



Best regards
Stefan

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2010-12-13 Thread Larry Garfield
On Monday, December 13, 2010 10:02:13 am Stefan Marr wrote:

 However, since traits do not provide any safety provisioning for state,
 i.e., there is no collision handling for properties, the question is, how
 do we either promote to use explicit accessors or how do we deal with the
 inevitable and certainly justified use of properties in one or the other
 way.
 
 Best regards
 Stefan

Thinking about it, I'm not sure that accessors are really a solid solution 
either.

Behavior has to have something to behave on.  So whether you have 

$this-foo 

or

$foo = $this-getFoo();
// Do stuff with $foo
$this-setFoo($foo);

You still have a dependency that the composing class have either a property 
named $foo or a pair of (frankly pointless) get/set methods.

So either a composing class needs to know about the internal implementation 
details of a trait (what it calls variables inside of a method) so that it can 
provide what the trait needs, or a trait needs to be able to carry around its 
own implementation details.

So it seems to me like we can't not let traits carry properties, which means 
we need to resolve them some how.

--Larry Garfield

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



Re: [PHP-DEV] Traits and Properties

2010-12-12 Thread Sebastian Bergmann

On 12/12/2010 01:24 AM, Stefan Marr wrote:

If you want to discourage attribute declaration in a trait, don't
allow it at all.

Not allowing it is not an option as far as I can tell.


 Good! :-)

--
Sebastian BergmannCo-Founder and Principal Consultant
http://sebastian-bergmann.de/   http://thePHP.cc/

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



Re: [PHP-DEV] Traits and Properties

2010-12-12 Thread Stefan Marr
Hi Nathan:

On 11 Dec 2010, at 19:35, Nathan Nobbe wrote:

 Regarding visibility modifiers, why not carry them over from the trait 
 directly, private in the trait definition results in private in the class 
 definition.

The problem will be hopefully more clear in the following example:

trait StateMachineDoor {
  private $currentState;
  public function open() {}
}

trait StateMachineElevator {
  public $currentState;
  public function callElevator() { ... }
}

These two traits are not compatible since currentState has different semantics 
in both traits.
With the current design of traits, there is no language solution to this 
problem.

The suggestions to avoid the problem are to use better names like 
$currentDoorState and $currentElevatorState, or to rely on accessors which is 
currently the only variant in which the programmer will notice that there is an 
incompatibility:

trait StateMachineDoor {
  abstract function getCurrentState();
  public function open() {}
}

trait StateMachineElevator {
  abstract function getCurrentState();
  public function callElevator() { ... }
}

However, you might have a different situation, one where the traits are 
composable with respect to their state, i.e., they need to work on the same 
state:

trait OutputIterator {
  public $array;  // not sure why that is public here, but the implementor 
chose to make it public...
  public function printNext() {...}
} 

trait SortArray {
  private $array; // this developer chose to make the array private, for what 
ever reason...
  public function doSort() { ... }
}

I hope that makes the possible situations clear: state can either be composable 
or not, that really depends
on the trait. And there is no language solution for it build in at the moment.

So, back to my original question:

class SomethingOutputableAndSortable {
  use OutoutIterator, SortArray;
}

What is the visibility of $array supposed to be in this class? private or 
public?

And further, in the very first example of this mail, ideally there should be 
some warning, however, that warning would be annoying for the last example, 
since here the state does not collide...

Best regards
Stefan

PS: there has been discussion on stateful traits before, but the language 
solutions to that where considered to complex.

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2010-12-11 Thread Nathan Nobbe
On Sat, Dec 11, 2010 at 9:47 AM, Stefan Marr p...@stefan-marr.de wrote:

 Hi:

 Traits do not provide any special provisioning for handling properties,
 especially, there is no language solution for handling colliding property
 names.
 The current solution/idiom for handling state safely in a trait is to use
 either abstract set/get methods or an abstract get that returns a reference
 to the property in the class.

 However, at the moment it is possible to define properties in a trait:

 trait Foo {
  private $a;
  public  $foo;
 }

 For the moment, that information is completely ignored, thus:

 class Bar {
  use Foo;
 }
 property_exists('Bar', 'a') === false


 Well, and that is a rather inconsistent status-quo.

 I would like to have that fixed in one or another way.

 One possibility would be to forbid property definition in a trait
 altogether.
 That reduces a bit the possibility to have wrong expectations about
 properties, however, the dynamic property creation is still possible.

 Another way would be to merge the properties in the composing class.
 The question here would be how to treat visibility modifiers: how to merge
 public and private, should it result in public, or private?
 And, to discorage users to go this way, should there be a STRICT notice?
 Options here are a notice whenever a property is defined in a trait, or
 whenever properties are silently merged.


I would prefer they be definable within traits and merged into classes,
otherwise traits will not have the chance to be self-contained entities of
reusable logic.  Also, I think merging them in is consistent with the
treatment given to methods as they pertain to traits.

As I'm sure you know:
?php
class A {
  use SomeTrait;
}

trait SomeTrait {
  public function traitMethod() {}
}

method_exists('A', 'traitMethod') === true;
?

Regarding visibility modifiers, why not carry them over from the trait
directly, private in the trait definition results in private in the class
definition.  Lastly, I'm not sure why you would want to discourage this
usage, I would plan on adding properties in traits myself.

-nathan


Re: [PHP-DEV] Traits and Properties

2010-12-11 Thread Sebastian Bergmann

On 12/11/2010 05:47 PM, Stefan Marr wrote:

Another way would be to merge the properties in the composing class.


 +1


The question here would be how to treat visibility modifiers


 One option would be to only allow private. That way only methods from
 the trait would have access and collisions could be prevented.


And, to discorage users to go this way, should there be a STRICT
notice?


 If you want to discourage attribute declaration in a trait, don't
 allow it at all.

--
Sebastian BergmannCo-Founder and Principal Consultant
http://sebastian-bergmann.de/   http://thePHP.cc/

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



Re: [PHP-DEV] Traits and Properties

2010-12-11 Thread Pierre Joye
hi,

Would it be possible to somehow document what you are discussing here?
It is not too easy to keep track of all discussions about traits
(along other things). Maybe in draft RFC or a simple page in the wiki.
Doing so will help to have a quick view about the open questions or
recent changes/propositions.

Thanks!

On Sat, Dec 11, 2010 at 5:47 PM, Stefan Marr p...@stefan-marr.de wrote:
 Hi:

 Traits do not provide any special provisioning for handling properties, 
 especially, there is no language solution for handling colliding property 
 names.
 The current solution/idiom for handling state safely in a trait is to use 
 either abstract set/get methods or an abstract get that returns a reference 
 to the property in the class.

 However, at the moment it is possible to define properties in a trait:

 trait Foo {
  private $a;
  public  $foo;
 }

 For the moment, that information is completely ignored, thus:

 class Bar {
  use Foo;
 }
 property_exists('Bar', 'a') === false


 Well, and that is a rather inconsistent status-quo.

 I would like to have that fixed in one or another way.

 One possibility would be to forbid property definition in a trait altogether.
 That reduces a bit the possibility to have wrong expectations about 
 properties, however, the dynamic property creation is still possible.

 Another way would be to merge the properties in the composing class.
 The question here would be how to treat visibility modifiers: how to merge 
 public and private, should it result in public, or private?
 And, to discorage users to go this way, should there be a STRICT notice? 
 Options here are a notice whenever a property is defined in a trait, or 
 whenever properties are silently merged.


 Comments very welcome.

 Thanks
 Stefan

 --
 Stefan Marr
 Software Languages Lab
 Vrije Universiteit Brussel
 Pleinlaan 2 / B-1050 Brussels / Belgium
 http://soft.vub.ac.be/~smarr
 Phone: +32 2 629 2974
 Fax:   +32 2 629 3525


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





-- 
Pierre

@pierrejoye | http://blog.thepimp.net | http://www.libgd.org

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



Re: [PHP-DEV] Traits and Properties

2010-12-11 Thread Stefan Marr
Hi Pierre:

On 11 Dec 2010, at 23:13, Pierre Joye wrote:

 hi,
 
 Would it be possible to somehow document what you are discussing here?
 It is not too easy to keep track of all discussions about traits
 (along other things). Maybe in draft RFC or a simple page in the wiki.
 Doing so will help to have a quick view about the open questions or
 recent changes/propositions.
Yes, I try to keep track of all this in the RFC:
  http://wiki.php.net/rfc/horizontalreuse?do=revisions

The current status of the property behavior is not yet documented explicitly, 
it is only implied since it is not handled at all...
And, it is the only open question that 'needs' to be solved since it is an 
inconsistency.
For instance the 'require Interface' is more like an additional feature.

Best regards
Stefan


 
 Thanks!
 
 On Sat, Dec 11, 2010 at 5:47 PM, Stefan Marr p...@stefan-marr.de wrote:
 Hi:
 
 Traits do not provide any special provisioning for handling properties, 
 especially, there is no language solution for handling colliding property 
 names.
 The current solution/idiom for handling state safely in a trait is to use 
 either abstract set/get methods or an abstract get that returns a reference 
 to the property in the class.
 
 However, at the moment it is possible to define properties in a trait:
 
 trait Foo {
  private $a;
  public  $foo;
 }
 
 For the moment, that information is completely ignored, thus:
 
 class Bar {
  use Foo;
 }
 property_exists('Bar', 'a') === false
 
 
 Well, and that is a rather inconsistent status-quo.
 
 I would like to have that fixed in one or another way.
 
 One possibility would be to forbid property definition in a trait altogether.
 That reduces a bit the possibility to have wrong expectations about 
 properties, however, the dynamic property creation is still possible.
 
 Another way would be to merge the properties in the composing class.
 The question here would be how to treat visibility modifiers: how to merge 
 public and private, should it result in public, or private?
 And, to discorage users to go this way, should there be a STRICT notice? 
 Options here are a notice whenever a property is defined in a trait, or 
 whenever properties are silently merged.
 
 
 Comments very welcome.
 
 Thanks
 Stefan
 
 --
 Stefan Marr
 Software Languages Lab
 Vrije Universiteit Brussel
 Pleinlaan 2 / B-1050 Brussels / Belgium
 http://soft.vub.ac.be/~smarr
 Phone: +32 2 629 2974
 Fax:   +32 2 629 3525
 
 
 --
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 
 
 
 
 
 -- 
 Pierre
 
 @pierrejoye | http://blog.thepimp.net | http://www.libgd.org

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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



Re: [PHP-DEV] Traits and Properties

2010-12-11 Thread Stefan Marr
Hi Sebastian:

On 11 Dec 2010, at 19:36, Sebastian Bergmann wrote:
 And, to discorage users to go this way, should there be a STRICT
 notice?
 
 If you want to discourage attribute declaration in a trait, don't
 allow it at all.
Not allowing it is not an option as far as I can tell.

You can always use dynamically defined properties in a method.
Changing that would change the whole character of PHP.
Then we would have two types of methods, methods that are defined in the class 
directly and can do what ever they want with properties, and methods from 
traits which are restricted and can't access any state.

I think, that would be to much penalty for all the valid use cases where a 
naive property usage in a trait is still just fine.

Best regards
Stefan


 
 -- 
 Sebastian BergmannCo-Founder and Principal Consultant
 http://sebastian-bergmann.de/   http://thePHP.cc/
 
 -- 
 PHP Internals - PHP Runtime Development Mailing List
 To unsubscribe, visit: http://www.php.net/unsub.php
 

-- 
Stefan Marr
Software Languages Lab
Vrije Universiteit Brussel
Pleinlaan 2 / B-1050 Brussels / Belgium
http://soft.vub.ac.be/~smarr
Phone: +32 2 629 2974
Fax:   +32 2 629 3525


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