Re: [PHP-DEV] Grafts, Traits, horizontal reuse

2008-11-24 Thread Christopher Vogt
Hej Marcus,

I like your approach. It is clear and simple. It would probably solve
90% of the cases, where delegation is needed.

I want to add that a manually defined method should automatically
overwrite a delegated method of the same name.

But I also want to bring up two reasonable situations your approach does
not cover. Your approach does not allow to delegate only a selection of
methods. This makes sense in order to limit the delegation to known
functionality. To stick to your example, without selective delegation,
new methods added to Counter would be automatically delegated to
CounterUser. This might break things.

A second situation not covered by your approach is renaming of delegated
methods. This can be desirable due to name clashes or name changes for
better understandability.

Of course there is always the fall back to manually implementing
delegation. And your approach alone would already be quite useful
syntactic sugar. But additional syntactic sugar for the two situations
described above would still be nice :).

Another thing. I am not sure if you intended that, but I think
delegation should not force using an Interface definition. Interfaces
are helpful in combination with type hinting, but for people who prefer
duck typing, it is reasonable to not explicitly define them. Let's leave
this choice to the people :).

Best regards

Christopher

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



[PHP-DEV] Re: Fatal error: Call to a member function on a non-object

2008-11-18 Thread Christopher Vogt
Hej,


 echo $user['fullname']; // no error at all, $user['fullname'] === NULL

 Shouldn't this at least trigger a Notice?
 
 Check your error handling settings, probably warnings/notices are disabled.

I now found it in the documentation os the String type
http://php.net/language.types.string

Note: Accessing variables of other types using [] or {} silently
returns NULL.

I created a change request: http://bugs.php.net/bug.php?id=46602

Best regards

Christopher

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



[PHP-DEV] Fatal error: Call to a member function on a non-object

2008-11-17 Thread Christopher Vogt
Hej,

I use PHP 5.2.6. I am refactoring some code to use more
object-orientation. I encounter a problem, where the new object-oriented
version results in a fatal error, where the old array-oriented version
didn't.

I fetch records a database. Sometime it happens that a record does not
exist anymore. Let's assume it's a user, then $user will be NULL.

echo $user['fullname']; // no error at all, $user['fullname'] === NULL

Shouldn't this at least trigger a Notice?

echo $user-get_fullname(); // Fatal error

I agree this should trigger an error, but a Fatal error is a little
too much, I think. It terminates the script leaving the html-document
incomplete. I would prefer a Warning and NULL instead.

Is there any reason against it?

Best regards

Christopher

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



Re: [PHP-DEV] Fatal error: Call to a member function on a non-object

2008-11-17 Thread Christopher Vogt
Hi Kalle,

 I personally don't really mind it, as you got the instanceof and
 typehinting to check for whenever a variable is an object, so I would
 say its more of a user design issue. Fatal errors just requires you to
 refactor your code so your code shouldn't emit such things which I'm
 alright with.

fatal error can also happen caused by a bug. The case described in my
Mail is even rather likely. However a fatal error prevents me from
handling the error using an error_handler. THAT is the problem.

Best regards

Christopher

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



Re: [PHP-DEV] Grafts, Traits, horizontal reuse

2008-11-16 Thread Christopher Vogt
Hej,

 I really liked to see the Grafts proposal.
 Well, I'm still in love with the more powerful (because they are
 interweaveable(breakable)) Traits ;)

I don't think there has to be a choice between Grafts and Traits. They
serve different purposes and I don't see a reason they shouldn't
co-exit. Traits implement code reuse. Code is merged. This is very
powerful but can break code. Grafts implement delegation. This is less
powerful, but can't break, which makes it preferable, whenever possible.

 Actually I think this could be a problem for the conciseness of the
 language. Introducing syntactic sugar for special situations has to be
 done carefully.

In my eyes (well-chosen) syntactic sugar contributes a lot to language
conciseness. And every language decision should be done carefully, right?

 from my perspective forwarding (aka
 delegation) is a very common concept in OOP which would be worth to be
 supported by a special syntax.

I strongly think so.

 I like this idea, but there are still some problems to be solved. The
 major problem with grafts is still the initialization of objects. What
 to do with constructors which require parameter?

Good point. My new suggestion at the end covers it.

 An other issue I see is the question of introducing to much additional
 syntax. It could be reduced to something like:
 
 private $counter : Counter [use] {  //with or without use?
 public current();
 public reset();
 }

I don't see the above having less syntax than my suggestion. as or :
is both syntax. I doubt, I would rather stick to a keyword already in
the language in similar semantics. For Comparison, my suggestion was:

   use Counter as private $counter{
 public current();
 public reset();
   }


 But now anonymous grafts aren't possible anymore and actually, Grafts
 had been design without an identity own their own.

Yes and I don't think anonymous Grafts would be a good idea. They would
make access to grafts complicated and significantly limited including
valid use cases. Being explicit instead of implicit helps here in my eyes.

 On the other hand,
 this notation could introduce the possibility for advanced initialization:
 
 private $cntInitValue;
 public function __construct($cntValue) {
 $this-cntInitValue = $cntValue;
 }
 
 private $counter : Counter(cntInitValue) {
 public current();
 public reset();
 }

I don't think that's a good idea. I admit it's very close to my
suggestion, but now it reached a point, where it does something very
familiar, namely creating an new object, using a very unfamiliar way and
also new syntax. So I make a new suggestion that puts everything much
closer to present PHP:

 class QueueTicketPrinter{
 private $counter {
 public current();
 public restart() from reset();
 };

 public function __construct($cntValue) {
 $this-counter = new Counter( $cntValue );
 }

 public function takeNumber(){
 print 'your number is .$this-current();
 $this-counter-inc();
 }
 }

And two syntax variants:

Variant 1:
 private $counter use {
 public current();
 reset() as public restart();
 };

Variant 2:
 private $counter delegate {
 public current();
 public restart() to reset();
 };


This suggestion requires a new runtime Error/Exception for cases when a
method of QueueTicketPrinter is called that is delegated to a method
that $counter does not implement.

 Every time you just like to compose a class from different kinds of
 behaviors Traits are superior. 

More powerful yes, superior no. Delegation and inheritance (counting
traits as a variant of inheritance) both allow functionality re-use but
both also resemble a trade-off between flexibility and breakability.
Inheritance is more flexible, but can easily break, especially when
inheritance structures grow. Delegation is less flexible, but can't
break (from reuse), even in large structures. So both are justified.

Best regards

Christopher

P.S. I should mention that I do not have any insight of the actual
implementation of PHP. So if I suggest something insensibly hard to
implement, just shout :).

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



[PHP-DEV] Traits,Grafts, horizontal reuse

2008-11-13 Thread Christopher Vogt
Hej everybody,

I had a chat with Stefan about his Traits/Grafts RFC and he suggested we
should rather continue a discussion here.

I really liked to see the Grafts proposal. In traits and regular
inheritance the implementation code of several entities is somehow mixed
and as a result one entities code can break another entities code. The
great thing about Grafts is that the implementation is not mixed. Grafts
are completely independent entities with their own state. I think in
many cases where inheritance or traits seem tempting, complete
encapsulation is actually the cleaner solution.

The Grafts proposal, however, suffered a little from being born out of
traits, I think. Something similar to Grafts is already possible in
current php, but it is not very beautiful. If we start from there
however, Grafts could become very helpful syntactic sugar. Let's look at
current PHP first:

class Counter {
  private $cnt = 0;
  public function inc() {
$this-cnt++;
  }
  public function reset() {
$this-cnt = -1;
$this-inc();
  }
}
class TakeANumberForTheQueue{



, so this is one , but I think it could be even better when it was much
closer to current PHP than suggested in the RFC. Let me explain what I
mean. Graft were born out of the idea of traits. Traits are a variant of
inheritance and a trade-off between single and multiple inheritance with
the goal to reduce code duplication. The problem with inheritance is
that code can break because code from different classes (or traits) is
mixed together

 interfering with  Either kind of inheritance can be very tempting to be
used to reuse functionality.

implement code reuse. Code reuse is tempting but often enough it is not
really necessary to reuse the

comes from the wrong direction and didn't go far enough.

Traits conquer the lacks of single inheritance without giving the full
power of multiple inheritance. Traits are still sort of inheritance.
When a class uses a trait the trait's code can access class
implementation details and vice-vera. This might come in handy at some
point, however I personally lack a good use case for now. Can somebody
provide a sensible use case for traits?

A Problem with code inheritance (single, traits, whatever) is that the
possibility to use inheritance seduces to use it even when it is not
necessarily needed. Stefan's Counter example is a good one.

What I find even more promising than Traits are Grafts.

 I know Grafts where born out of the traits idea, but I want to try to
put them idea a little forward and separate the from the traits idea
even stronger than Stefan already did.

Why do we want Grafts?
Because inheritance can be a problem


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



[PHP-DEV] gnaaa. Hit the submit button too early.

2008-11-13 Thread Christopher Vogt
Gnaaa. Hit the submit button too early. Excuse the rubbish. I will post
the correct mail in a moment.

Christopher

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



[PHP-DEV] Grafts, Traits, horizontal reuse

2008-11-13 Thread Christopher Vogt
Hej everybody,

I had a chat with Stefan about his Traits/Grafts RFC and he suggested we
should rather continue a discussion here.

I really liked to see the Grafts proposal. In traits and regular
inheritance the implementation code of several entities is somehow mixed
and as a result one entities code can break another entities code. The
great thing about Grafts is that the implementation is not mixed. Grafts
are completely encapsulated entities with their own state. I think in
many cases where inheritance or traits seem tempting, complete
encapsulation is actually the cleaner solution.

The Grafts proposal, however, suffered a little from being born out of
traits, I think. Something similar to Grafts is already possible in
current php, but it is not very beautiful. If we start from there
however, Grafts could become very helpful syntactic sugar. Let's look at
current PHP first:

class Counter {
  private $cnt = 0;
  public function inc() {
$this-cnt++;
return $this;
  }
  public function reset() {
$this-cnt = -1;
$this-inc();
return $this;
  }
  public function current(){
   return $this-cnt;
return $this;
  }
}
class QueueTicketPrinter{
  private $counter;
  public __construct(){
$this-counter = new Counter();
  }
  public function takeNumber(){
print 'your number is .$this-counter-current();
$this-counter-inc();
  }
  public function current(){
$this-counter-current();
  }
  public function reset(){
$this-counter-reset();
  }
}

This is a lot of code in QueueTicketPrinter for that it mostly reuses
Counter. Grafts as syntactic sugar could make it look as short as:

class QueueTicketPrinter{
  use Counter as private $counter{
public current();
public reset();
  }
  public function takeNumber(){
print 'your number is .$this-counter-current();
$this-counter-inc();
  }
}

However a problem remains. The methods of counter return $this (aka
implement a fluent interface). One idea that came to my mind to solve
this problem: PHP could provide a keyword fluent that replaces a methods
return value to form a fluent interface i.e. return $this:

class QueueTicketPrinter{
  use Counter as private $counter{
public fluent current();
public fluent reset();
  }
  public function takeNumber(){
print 'your number is .$this-counter-current();
$this-counter-inc();
  }
}

The keyword fluent ignores whatever value the Counter function may
return and returns an the instance of QueueTicketPrinter instead.

Finally, can somebody provide a sensible use case for traits, that
cannot be solved with Grafts? I am sure there is, but I am currently
lacking one.

Cheers

Christopher

P.S. Hope that stupid post before does not make me seem too much like it ;).

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