Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:50999 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 39994 invoked from network); 10 Dec 2010 19:39:31 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Dec 2010 19:39:31 -0000 Authentication-Results: pb1.pair.com smtp.mail=chadfulton@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=chadfulton@gmail.com; sender-id=pass; domainkeys=bad Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.214.174 as permitted sender) DomainKey-Status: bad X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: chadfulton@gmail.com X-Host-Fingerprint: 209.85.214.174 mail-iw0-f174.google.com Received: from [209.85.214.174] ([209.85.214.174:54821] helo=mail-iw0-f174.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 90/10-39602-1F1820D4 for ; Fri, 10 Dec 2010 14:39:31 -0500 Received: by iwn9 with SMTP id 9so6354257iwn.33 for ; Fri, 10 Dec 2010 11:39:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:mime-version:received:in-reply-to :references:from:date:message-id:subject:to:cc:content-type :content-transfer-encoding; bh=OrKBSm/KkDpXxSQ5EeGVlpNe9oP9eNRXQuwQb8590gk=; b=ptWVsLd7a1SyQtbJ5VQb39Ca9qoGtLYIys+9gAkFCuTPVU2Sd9Dqiez9iPl4jEd/xV d6h4MjuUjclCbMxVwFt1rM9DpCAoyXJr+8SMlrQdDa4l6NKy3Z8zmnuQiP6ge+brmwKE ILFfvV91sA9cbJ55efVlmXbV7Il9c/7VQ4P1E= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; b=OfSoLC9axo7EtZOBBTVhwsZz2Q0SRMJHrrWFWZsps39xcs0q564OmPUmGrm5eyrNtn w2u69O5RzDzW2xnQYEa5Du/pJZJ8clbRrYzryYD/I6nuuv6WcQhFAG5E4KtnIoV5oSj8 QIrtQgB1tTutA3lT4cMUcaGTrt1jbKzbpxrA8= Received: by 10.231.200.135 with SMTP id ew7mr847694ibb.77.1292009967499; Fri, 10 Dec 2010 11:39:27 -0800 (PST) MIME-Version: 1.0 Received: by 10.231.170.66 with HTTP; Fri, 10 Dec 2010 11:39:07 -0800 (PST) In-Reply-To: References: <9CD87200-33CB-40BE-A81C-36FD7471F59C@stefan-marr.de> <9A31F2F9-ED6B-4BE5-A6E2-EB4536E8667F@stefan-marr.de> Date: Fri, 10 Dec 2010 11:39:07 -0800 Message-ID: To: Nathan Nobbe Cc: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Traits expecting interfaces implicitly leads to expensive runtime checks From: chadfulton@gmail.com (Chad Fulton) On Fri, Dec 10, 2010 at 10:39 AM, Nathan Nobbe wro= te: > On Fri, Dec 10, 2010 at 11:04 AM, Chad Fulton wrot= e: >> >> On Fri, Dec 10, 2010 at 9:29 AM, Nathan Nobbe >> wrote: >> > On Fri, Dec 10, 2010 at 10:15 AM, Martin Wernstahl >> > wrote: >> > >> >> First i have to say that I am not a PHP internals developer, but as a >> >> user >> >> I think it would maybe be better to just let the trait use the >> >> implements >> >> keyword, and "copy" that to the classes utilizing the trait? >> >> >> > >> > This is actually in the RFC as a rejected proposal >> > >> > http://wiki.php.net/rfc/traits#rejected_features >> > >> > But what I'm talking about is something different. =A0We're not trying= to >> > say >> > 'these are the methods implemented in the trait', rather, 'this trait >> > expects a class it is used with to be of a certain type or implement a >> > certain interface' for the trait to do its job. >> > >> > -nathan >> > >> >> Shouldn't the burden be on the programmer to make sure the trait works >> with the class using it rather than on the compiler? If they try to >> use a trait that requires methods that don't exist, it will error out >> anyway, so it won't be difficult to debug. > > Well I know PHP is a dynamic language but what about all the compile time > features that have come along over the years. =A0The abstract keyword for > example vs. the PHP4 way of implementing an 'abstract' method which was > triggering an error in the default implementation in a base class. > One of the main things a lot of PHP programmers I've worked with hate is > waiting for code to hit production and encountering a runtime error w/ > something that could have been caught at compile time. =A0I know the noti= on of > compile time in a scripting language like PHP is much less removed from t= hat > of C++, Java etc, however there is a notion of it there, obviously. > Also, I would suggest this feature be optional, so there is no need to us= e > it if you don't like it. =A0But for those of us who would like to defer a= s > much type checking to the compiler as possible so we don't need runtime > checks all over our code or prayers that we've tested every line before > production, it would certainly be nice. > Lastly, you may know that traits will allow PHP programmers to move away > from the delegate pattern which is a common workaround to multiple > inheritance at this point. =A0However, in speaking with a colleague over = the > concept I'm proposing yesterday we discovered the delegate model actually > does allow you to specify which class/interface the delegate is used w/, = it > would be sad not to see comparable support in the trait feature which wil= l > mostly eliminate the need for the delegate pattern, see my quick example. > class MainClass { > =A0=A0private $_oDelegate =3D null; > =A0=A0function addDelegate() { > =A0=A0 =A0 =A0$this->_oDelegate =3D new Delegate($this); > =A0=A0} > } > class Delegate { > =A0=A0private function $_oMain =3D null; > =A0=A0/// delegate gets to say what it can be used with via type hinting > =A0=A0function __construct(MainClass $oMainClass) > =A0=A0{ > =A0=A0 =A0$this->_oMain =3D $oMainClass; > =A0=A0} > } > ?> > Imagine how much cleaner this could be w/ traits, yet just as expressive > class MainClass { > =A0=A0use Delegate; > } > trait Delegate require MainClass { > =A0... > } > ?> > -nathan > As a note, I'm not strongly opposed to this proposal, since I don't think it would do any harm. It just seems to me like a "kitchen sink" feature. The issue for me is that traits, as I understand them, are there primarily for horizontal code re-use via compile-time "copy/paste". With that in mind, I feel like the developer is responsible for making sure the methods they copy into their classes make sense, just as they would have to do if they physically copied and pasted them. I think your example above isn't quite what you meant to show, since you're requiring a specific class and not an interface (since PHP only allows one class definition for a class name, you're not gaining anything via traits, since the trait could only be used for that specific class, in which case why not just have the code in the class in the first place?). If we take your example in a more general case using interfaces, I still can't see what the benefit is. All it does is provide a more explicit and immediate error message for developers (e.g. instead of "method not found" error when the bad method call is made at runtime, you get a "classes using trait must implement " at compile time). Again, I'm not against it, but maybe be too much hand holding, since the developer should make sure using the trait makes sense first?