Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:35694 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 54300 invoked by uid 1010); 21 Feb 2008 15:02:46 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 54285 invoked from network); 21 Feb 2008 15:02:46 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 21 Feb 2008 15:02:46 -0000 Authentication-Results: pb1.pair.com header.from=cschneid@cschneid.com; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=cschneid@cschneid.com; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain cschneid.com from 195.141.85.117 cause and error) X-PHP-List-Original-Sender: cschneid@cschneid.com X-Host-Fingerprint: 195.141.85.117 uf1.search.ch Linux 2.6 Received: from [195.141.85.117] ([195.141.85.117:35384] helo=smtp.rim.ch) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id E2/BA-21621-4929DB74 for ; Thu, 21 Feb 2008 10:02:45 -0500 Received: from localhost (localhost [127.0.0.1]) by rolig.search.ch (Postfix) with ESMTP id AA74237936F for ; Thu, 21 Feb 2008 16:02:41 +0100 (CET) Received: from smtp.rim.ch ([127.0.0.1]) by localhost (search.ch [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 10791-05 for ; Thu, 21 Feb 2008 16:02:39 +0100 (CET) Received: from [192.168.1.72] (ultrafilter-i [192.168.85.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by rolig.search.ch (Postfix) with ESMTP id 69D623792DB for ; Thu, 21 Feb 2008 16:02:39 +0100 (CET) Message-ID: <47BD928E.8080006@cschneid.com> Date: Thu, 21 Feb 2008 16:02:38 +0100 User-Agent: Thunderbird 1.5.0.12 (X11/20060911) MIME-Version: 1.0 To: internals Mailing List References: <47BD207C.2080905@chiaraquartet.net> In-Reply-To: <47BD207C.2080905@chiaraquartet.net> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Virus-Scanned: amavisd-new at search.ch Subject: Re: Trait aliasing syntax suggestions From: cschneid@cschneid.com (Christian Schneider) Gregory Beaver wrote: > Here is a slightly clearer syntax for trait instantiation and for > aliasing/removing method names from traits: > > trait foo ... > > class B > { > trait foo {unset bing, bar as bing}; > trait bar; > } I like the approach to reuse identifiers (trait both in declaration and use, clearly links the two) and unset/as (avoids new keywords). Some more thoughts: - I've seen Stefan Marr's remarks about aliasing != renaming but the only explanation I could find in the thread was about user perception (along the line of "... would expect all uses of the function to be renamed ..."). I don't think aliasing really helps here. I can see two use cases for aliasing: 1) An interface uses a different name than the trait implements. Not sure that's a software design problem trait should try to solve. 2) There is a clash with an existing function in the class. Then one would have to both alias and exclude the trait function name anyway (which is the same as renaming) PLUS you'd have the problem of trait classes calling the 'wrong' functions again. Maybe someone can shed light on why aliasing is preferable to renaming after all. - I think the whole 'how to avoid clashes' discussion is missing one important point: Being able to override functions defined in a trait is a *feature*, not a bug. It's the same as with inheritance, i.e. if I override functions I can enhance but also break existing code. IMHO Traits should be a simple mechanism giving the developer the freedom to do the wrong thing ;-) Or more seriously: If you want to have encapsulated functionality used in multiple places I'd use delegates a la foo_traitemu::bar(). - The exclusion model is missing a way to include only specific functions. To me this seems as useful as being able to exclude functions. So my favourite solution (apart from allowing include in class definitions ;-)) would be trait foo { ... } ... class B { trait foo; # All functions from foo trait bar(a); # Only function a from bar trait qux(not b); # Everythign but function b trait quux(c as d); # Include c but rename it to d trait quuux(not b, c as d); # Combination of the above } Note: The inclusion of specific functions acts as if a "not *" (while * doesn't really need to be implemented neither for inclusion nor exclusion IMHO) was given first. Another detail: The implementation of the parser changes should still allow a class or function called "trait", i.e. "trait" should only be a keyword at specific positions in the source to avoid unneccesary BC breaks. The current patch has this BC problem. - Chris