Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:37499 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 1292 invoked from network); 6 May 2008 16:30:46 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 6 May 2008 16:30:46 -0000 Authentication-Results: pb1.pair.com header.from=jeff@procata.com; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=jeff@procata.com; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain procata.com from 207.58.169.145 cause and error) X-PHP-List-Original-Sender: jeff@procata.com X-Host-Fingerprint: 207.58.169.145 vps.procata.net Linux 2.5 (sometimes 2.4) (4) Received: from [207.58.169.145] ([207.58.169.145:57113] helo=vps.procata.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 53/6D-22382-9C280284 for ; Tue, 06 May 2008 12:09:46 -0400 Received: from adsl-63-201-158-210.dsl.snfc21.pacbell.net ([63.201.158.210] helo=[192.168.5.38]) by vps.procata.net with esmtp (Exim 4.68) (envelope-from ) id 1JtPjR-0008NT-Nl; Tue, 06 May 2008 12:09:34 -0400 To: Marcus Boerger In-Reply-To: <862660524.20080506162159@marcus-boerger.de> X-Priority: 3 (Normal) References: <48169695.9040803@omegavortex.net> <339714303.20080429114607@marcus-boerger.de> <7dd2dc0b0804290817v3d8de030y1208a88f78c44411@mail.gmail.com> <862660524.20080506162159@marcus-boerger.de> Message-ID: <912CE6DE-22D0-43E6-BB6B-6154980050E5@procata.com> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v919.2) Date: Tue, 6 May 2008 09:09:31 -0700 Cc: "John Carter -X (johncart - PolicyApp Ltd at Cisco)" , "Derick Rethans" , internals@lists.php.net X-Mailer: Apple Mail (2.919.2) X-ACL-Warn: { X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - vps.procata.net X-AntiAbuse: Original Domain - lists.php.net X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - procata.com X-Source: X-Source-Args: X-Source-Dir: Subject: Re: [PHP-DEV] Class Properties in Interfaces? From: jeff@procata.com (Jeff Moore) Hi Marcus, I think this is really specifying implementation details in an interface: > interface Coordinate { > public $coord = __get => getCoord, __set => setCoord, > __isset => hasCoord, __unset => delCoord; > public getCoord(); > public setCoord($val); > public hasCoord(); > public delCoord(); > } This looks to me like the best way to handle this in interfaces: > interface Coord { > abstract $coord; > } I think this example could be simplified if the basic accessor methods didn't have to be explicitly declared: class MyCoord implements Coordinate { protected $_coord; // actual storage for $coord public $coord = __get => $_coord, __set => setCoord, __isset => $_coord, __unset => $coord; // Satisfies the interface public __construct($x, $y) { $this->coord = array($x, $y); // calls setCoord } public setCoord($val) { if (!is_array($val) || count($val) != 2 || !is_numeric($val[0]) || !is_numeric($val[1])) { throw new UnexpectedValueException('Array(x,y) of floats expected'); } $this->_coord = $val; } } One thing about this syntax is that it give PHP a lot of information to optimize the performance of property access. Or you could do this class MyCoord implements Coordinate { public $coord; // satisfies interface } The nice thing about this kind of property is that you can switch between these two implementations over time with out changing how callers use the interface. Maybe there are some things that could be done with syntax on this: public $coord = __get => $_coord, __set => setCoord, __isset => $_coord, __unset => $coord; Can some standard implementation of the __isset and __unset be used to simplify this declaration to something like this? public $coord = __get => $_coord, __set => setCoord; or public $coord __get $_coord __set SetCoord; or to cut down on the underlines... public $coord get $_coord set SetCoord; Additionally, with this syntax, we can allow accessors to have differing visibility, which we cannot do with virtual properties: public $coord get $_coord protected set SetCoord; // Public property with protected setter There are some advantages to this with inheritance, too class Parent { public $foo; } class Child extends Parent { protected $_foo; public $foo get $_foo set SetFoo; function SetFoo($value) { ... } } In this example, a child has added an accessor method to a property defined on a parent without changing the parent. Something you cannot do with virtual properties. I think structural properties would be a useful feature. Best Regards, Jeff On May 6, 2008, at 7:21 AM, Marcus Boerger wrote: > Hello John, > > the main reason really is storage. If you allow storage in interfaces > then you get multiple inheritance with its virtual inheritance > (diamond > style inheritance) issue. That however onlly applies to plain > attributes > and not properties which are usually understood as attributes that > result > in function calls (getter & setter). That said, if PHP had > properties, PHP > could also allow peroperties in interfaces. So the actual question > shoul > dbe why we do not support properties. To give an idea how properties > could > look like: > > interface Coordinate { > public $coord = __get => getCoord, __set => setCoord, > __isset => hasCoord, __unset => delCoord; > public getCoord(); > public setCoord($val); > public hasCoord(); > public delCoord(); > } > > class MyCoord implements Coordinate { > private $_coord = array(0, 0); // actual storage for $coord > public __construct($x, $y) { > $this->coord = array($x, $y); // calls setCoord > } > public getCoord() { > return $this->_coord; > } > public setCoord($val) { > if (!is_array($val) || count($val) != 2 > || !is_numeric($val[0]) || !is_numeric($val[1])) { > throw new UnexpectedValueException('Array(x,y) of floats > expected'); > } > $this->_coord = $val; > } > public hasCoord() { > return isset($this->_coord[0]) || isset($this->_coord[1]); > } > public delCoord() { > $this->_coord = array(0, 0); > } > } > > This tells me two things: > a) Pretty damn complex and in that kind of the opposite of PHP's > usual KISS > approach (Keep It Simple Safe). > > b) Pretty sexy as it gives a hell lot of control and you can document > everything. Check out all the minor details and think of what that > would > allow. > > My conclusion is that even it looks sexy, it might be a bit tooooo > complex. > > A much shorter thing to do might be: > > interface Coord { > abstract $coord; > } > > This would just somehow make sure the attribute $this->coord will be > accessible as a public attribute in the implementing class. The same > rules > as for methods would apply. > > Derick and me discussed solutions around abstract/virtual attributes > a lot > in the passed. They were all refused however. But what we had in > mind also > was more about specifying attributes in an abstract way in classes > so that > they become documentable while being still handled through __get() and > friends. > > marcus > > Tuesday, April 29, 2008, 5:51:30 PM, you wrote: > >> The article explicitly mentions OOP interfaces in a few languages. >> But >> the article, or for that matter any formal definition of an interface >> isn't really what I asked about: >> >> My question was simply: why can't interfaces have properties? >> >> John. > >> ________________________________ > >> From: Nathan Nobbe [mailto:quickshiftin@gmail.com] >> Sent: 29 April 2008 16:17 >> To: John Carter -X (johncart - PolicyApp Ltd at Cisco) >> Cc: internals@lists.php.net >> Subject: Re: Re: [PHP-DEV] Class Properties in Interfaces? > > >> On Tue, Apr 29, 2008 at 6:28 AM, John Carter -X (johncart - PolicyApp >> Ltd at Cisco) wrote: > > >> >> I think I must be missing something here, but this sounds a >> little >> tautological - "we can't do it because it doesn't make sense. >> This is >> because it doesn't make sense" >> >> Certainly most people (myself included) consider interfaces to >> be >> methods only, but I can't find a reason why not, and a >> search-on-wikipedia-instead-of-doing-proper-research appears >> to >> allow >> it: >> http://en.wikipedia.org/wiki/Interface_%28computer_science%29 > > >> the problem with that article, as it pertains to this conversation is >> that it is referring to interfaces as a general concept. >> 'interfaces' >> can be formed in many ways, via extension of an abstract class or >> even >> an expected set of a parameters in an HTTP request... >> getting to the more concrete term 'interface' as it pertains to a >> language keyword, interfaces define a contract; they do not specify >> implementation details. member variables only facilitate the actions >> member functions expose and therefore, they are part of the >> implementation. > >> additionally, one can look to java (and likely others) to see that >> public attributes are not supported on interfaces. here is a >> definition >> from a java5 cert book; >> "When you create an interface, you're defining a contract for >> *what* a >> class can do, without saying anything about how the class will do it. >> An interface is a contract." > >> -nathan > > > > > Best regards, > Marcus > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php >