Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:42043 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 26069 invoked from network); 24 Nov 2008 23:55:09 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 Nov 2008 23:55:09 -0000 Authentication-Results: pb1.pair.com header.from=helly@php.net; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=helly@php.net; spf=unknown; sender-id=unknown Received-SPF: unknown (pb1.pair.com: domain php.net does not designate 85.214.94.56 as permitted sender) X-PHP-List-Original-Sender: helly@php.net X-Host-Fingerprint: 85.214.94.56 aixcept.net Linux 2.6 Received: from [85.214.94.56] ([85.214.94.56:57328] helo=h1149922.serverkompetenz.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id E2/53-26081-ADE3B294 for ; Mon, 24 Nov 2008 18:55:09 -0500 Received: from MBOERGER-ZRH.corp.google.com (236-157.106-92.cust.bluewin.ch [92.106.157.236]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by h1149922.serverkompetenz.net (Postfix) with ESMTP id B8B0411F2F3; Tue, 25 Nov 2008 00:55:03 +0100 (CET) Date: Tue, 25 Nov 2008 00:52:13 +0100 Reply-To: Marcus Boerger X-Priority: 3 (Normal) Message-ID: <45289205.20081125005213@marcus-boerger.de> To: Stefan Marr CC: Christopher Vogt , internals@lists.php.net In-Reply-To: <49203DF2.1020006@stefan-marr.de> References: <002b01c92d67$ae92fdc0$0bb8f940$@de> <79.C8.07308.CDE4C194@pb1.pair.com> <49203DF2.1020006@stefan-marr.de> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Subject: Re: [PHP-DEV] Grafts, Traits, horizontal reuse From: helly@php.net (Marcus Boerger) Hello Stefan, Sunday, November 16, 2008, 4:36:18 PM, you wrote: > Hi, > Christopher Vogt schrieb: >> Hej everybody, >> >> I really liked to see the Grafts proposal. > Well, I'm still in love with the more powerful (because they are > interweaveable(breakable)) Traits ;) >> 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. > 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. Nevertheless, from my perspective forwarding (aka > delegation) is a very common concept in OOP which would be worth to be > supported by a special syntax. >> class QueueTicketPrinter{ >> use Counter as private $counter{ >> public current(); >> public reset(); >> } >> public function takeNumber(){ >> print 'your number is ".$this->counter->current(); >> $this->counter->inc(); >> } >> } > 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? > 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(); > } > But now anonymous grafts aren't possible anymore and actually, Grafts > had been design without an identity own their own. On the other hand, > this notation could introduce the possibility for advanced initialization: > class QueueTicketPrinter{ > private $cntInitValue; > public function __construct($cntValue) { > $this->cntInitValue = $cntValue; > } > private $counter : Counter(cntInitValue) { > public current(); > public reset(); > } > public function takeNumber(){ > print 'your number is ".$this->counter->current(); > $this->counter->inc(); > } > } This is hardly more than delegates. Actually the only thing more you get is hiding stuff which is incompatible to the thing you loose at the same time. That is your grafts do not support interface delegation. So My preference is being able to actually do that (and mixins/traits do). Example: Interface Counter { function current(); function reset(); } Class CounterImpl implements Counter { private $cnt = 0; function current() { return $this->cnt; } function reset() { $this->cnt = 0; } } Class CounterUser implements Counter { delegate Counter $counter; function __construct() { $this->counter = new CounterImpl; } } The keyword delegate makes sure $counter is a member that must implement Counter. Assigning any other value would result in an exception or other error. To make it easier the delegate declaration wcould contain the initialization already and turn the delegate member into a read only member. deletegate Counter $counter = new CounterImpl; >> 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. > Every time you just like to compose a class from different kinds of > behaviors Traits are superior. The use cases discussed in literature are > class hierarchies for collection classes and streams. For both > hierarchies, the interweaving of methods from different traits is a > helpful property to build all variations of semantics. > Kind Regards > Stefan marcus Best regards, Marcus