Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:51004 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 61172 invoked from network); 10 Dec 2010 22:17:44 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 10 Dec 2010 22:17:44 -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.196 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.196 mail-iw0-f196.google.com Received: from [209.85.214.196] ([209.85.214.196:45333] helo=mail-iw0-f196.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 66/81-51279-707A20D4 for ; Fri, 10 Dec 2010 17:17:43 -0500 Received: by iwn36 with SMTP id 36so1835044iwn.11 for ; Fri, 10 Dec 2010 14:17:40 -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=2vrI6VIKo/rHiaG65bO5SXvlqhwnCcjD6Mhln6hz7kk=; b=ab4K0tKnxRiWoMDmOUBzf2zFWd40FNgjxlEs5bP/7HzWSBlTYAZHvv8QrMu9ZEzpaW wj3QmvD5Kf5IE2E/ZyL0Jrf9cecDexNd8RtH3QpcAlDrBzw6lzwVI8RnSZpjacQ7sej4 H7+xKY/ytlYieYH0rUJ1+VucXqf/EDega5vGs= 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=mueD5ahpLyyzyM1nyXBFJerQ4QMPCij5mbDqeyZt/NlWZdg8S9WOxL5LlqRuMycCmf F9Ro3awOOgeppqz6ar57QTMX0TfTf9ZssKk4Q8uFnCvNlshXuWyko+1u1KMY1c40jJ7/ iMhMJnC6CEhx9u2vxZo6yHgIvB3+TDIAbWNb0= Received: by 10.231.85.137 with SMTP id o9mr81041ibl.27.1292019460731; Fri, 10 Dec 2010 14:17:40 -0800 (PST) MIME-Version: 1.0 Received: by 10.231.170.66 with HTTP; Fri, 10 Dec 2010 14:17:20 -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 14:17:20 -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 1:00 PM, Nathan Nobbe wrot= e: >> >> 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. > > Copy & paste itself leads to duplicated unmaintainable code, so traits ar= e > introduced (among other reasons) to prohibit this practice. =A0Why not ta= ke it > a step further and let a trait definition be as expressive as possible, > eliminating ambiguity, right out of the gate? > >> >> 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?). > > In retrospect Chad, that's a good point, and perhaps there is no reason t= o > allow marking of classes as required by traits. > >> >> 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). > > Exactly, catch it at compile time rather than runtime, that's all it is > really, just like the benefit of discovering a given subclass doesn't > implement a given abstract method so that I don't go any further and run > code guaranteed not to work. > >> >> 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? > > Couldn't the same be said for a developer extending an abstract class, or > implementing an interface? =A0And also, a developer is to look through th= e > entire definition of a trait to know which methods it's going to depend o= n? > =A0I know abstract is there as Stefan showed, but as we've both observed = that > approach can get messy quickly. > -nathan > I think that you make a convincing argument. Thinking more about your Iterator example, this idea makes a lot of sense and could be quite useful. Also, I was wrong about requiring a class. It could be very useful, especially if it is an internal class (e.g. ArrayObject) which might have many children, and of course in this case the parent can't be changed. I think the require keyword works well.