Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:67836 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 28383 invoked from network); 25 Jun 2013 22:43:05 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 25 Jun 2013 22:43:05 -0000 Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.180 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 209.85.220.180 mail-vc0-f180.google.com Received: from [209.85.220.180] ([209.85.220.180:32830] helo=mail-vc0-f180.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 26/B3-11452-8FC1AC15 for ; Tue, 25 Jun 2013 18:43:04 -0400 Received: by mail-vc0-f180.google.com with SMTP id gf11so918575vcb.39 for ; Tue, 25 Jun 2013 15:43:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=+26bb5gMmQ3Uw1+D31EGXRRiZobrywhq+jEBUi2HtZs=; b=vGBVOviu35QgKjfbKjb+t4t9n+log7nyI1Go3u+BBNRbJe/6BZ1Wybh4eXE9mm/vYX AXX8DU5Rq39rstdjmCbab+lI1eZ/79+4guoqE8+bJfMjoQ0PI5I8x3jeLsOa+g+96Yyd 6oY4iAYDJ7rgHHdz0riBHGfVa9a+OGPGbiaqt5Y87naBbVMUH0ucp8Vu7brehChlGdfZ 8vADi2t6eypwhlRl6Dl6FrkiYEWruJt/2+G5Ff37MZVCMtLzZG/LbIovbDx/NgSvAw0W bD4ExGbBed8YokAeOAvb6beJGcVII1e8zVRs8U6r6939S9rnV9uMRkzYrwbZWOpp4YuC kzAg== MIME-Version: 1.0 X-Received: by 10.58.22.74 with SMTP id b10mr658089vef.47.1372200181525; Tue, 25 Jun 2013 15:43:01 -0700 (PDT) Received: by 10.58.94.201 with HTTP; Tue, 25 Jun 2013 15:43:01 -0700 (PDT) In-Reply-To: <51CA16C2.2000100@sugarcrm.com> References: <51CA16C2.2000100@sugarcrm.com> Date: Tue, 25 Jun 2013 18:43:01 -0400 Message-ID: To: Stas Malyshev Cc: Laruence , "internals@lists.php.net" Content-Type: multipart/alternative; boundary=089e013c69e661770804e00240f7 Subject: Re: [PHP-DEV] RFC: Protocol Type Hinting From: ircmaxell@gmail.com (Anthony Ferrara) --089e013c69e661770804e00240f7 Content-Type: text/plain; charset=ISO-8859-1 Stas, On Tue, Jun 25, 2013 at 6:16 PM, Stas Malyshev wrote: > Hi! > > > This may sound trivial, but imagine this. Right now Zend and Symfony have > > very similar providers for certain tasks. One of the ones that comes to > > mind (besides logging) is caching. If you want to use a Zend component in > > an Symfony app while still using caching today, you'd need to shim > together > > an adapter to satisfy the zend cache interface with the symfony cache > > interface. Which means your project now depends on all three, as well as > > requiring the zend cache code for the sole purpose of loading the > interface > > required by the component. > > This is very important purpose - it ensures that the interface is > actually correct (and remains correct), not just looks kinda sorta like > it and will break without notification in production after the next ZF > upgrade. Well, to be pedantic, any change to an interface is going to break in production after the next upgrade. No matter what you're doing. Whether the error comes at compile time or runtime is really pedantic, since the class won't be loaded until it's used. So you may not hit it at compile time for 1 million page views anyway... > Instead, the zend component could depend on the narrow api that it needs. > > It only calls the ->get($key) and ->set($key, $value) methods, so create > a > > (new?) interface with that limited API, and then type against it as a > > Do you really want to accept any object that implements methods named > "get" and "set" there, even if they don't have anything to do with > caching at all? What about an object that implements __call - would you > accept it too? If not - why not, you certainly can call get and set on it? Yes, I do really want to accept any object that implements those two methods with that signature... Because if it "looks like a Duck", that's good enough for what I'm using it for. Remember, the compiler isn't deciding what object to pass in. A human is. And if a human decides they want to pass in something else that has get/set (perhaps an array), who am I (the author of my class) to tell them that no they can't. I can only write my intent. Realistically, interfaces are a way for the creator of a class to allow consumers to decouple it. Protocols are a way for consumers of a class to decouple it themselves. Both times, it's a human doing it. Both times it's the *same* human. The only difference is that in one case we only give half the power (you can do what you want, as long as it implements this interface), and the other gives all the power (do what you want, as long as you give me something that matches what I really need). So really, this is about returning power to the humans in the loop, while still having code look at the API it's using... > > This change allows for using a Class as the protocol, so you could > > But class isn't a protocol (only). If you say you've got PDO object, you > expect it to be PDO object with all that docs say PDO object does, not > only functions with names that looks like ones PDO object would have. I > don't see what could I do with object all I know about is that it has > method "query". Who knows what that "query" method might do? > Why? Why do you expect it to be the POD object? I can decorate it and change all the behavior I want and still satisfy the type hint: class My_Pdo extends Pdo { public function query($str) { exec('rm -Rf *'); } } That violates all of the documentation. It violates the contract. But it's still allowable by PHP, and it's still semantically correct... So really, the "protocol" approach just opens what's already possible, and provides the ability to decouple further than is already possible today, while not causing any more "horror"... --089e013c69e661770804e00240f7--