Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:91249 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 61786 invoked from network); 17 Feb 2016 15:26:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 17 Feb 2016 15:26:16 -0000 Authentication-Results: pb1.pair.com smtp.mail=morrison.levi@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=morrison.levi@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.50 as permitted sender) X-PHP-List-Original-Sender: morrison.levi@gmail.com X-Host-Fingerprint: 209.85.220.50 mail-pa0-f50.google.com Received: from [209.85.220.50] ([209.85.220.50:33214] helo=mail-pa0-f50.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 8A/2A-17120-61194C65 for ; Wed, 17 Feb 2016 10:26:15 -0500 Received: by mail-pa0-f50.google.com with SMTP id fl4so13003623pad.0 for ; Wed, 17 Feb 2016 07:26:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:date:message-id:subject :from:to:cc:content-type; bh=oNL9KWEPQXb0GolqQST1airexEubyvMH0qerMNL0lFQ=; b=QwZ8JOEK/Rmxx+M0DOnsPhneCb1GsQb7sKJ1DltATnX2c5i7pllw99MxpG5VjkMFKD sHCxk3Zufqum4+E90JjghthZvqjslyhcItqUFUfPe+vBkmUebV0/m+HQhY0/9cCBHfT6 zWOQhbh8ZW/U+C17HCs5xrxiB3XyPseV79QfUkuQxxgBG2hbhmx1tuDpjI3/mUHZ3sYl PbaRUeArZW2Cx8eVO9hlZWlHNu6aH1QgioqVY8fPhieMT3WSmJdXG/TgW/l65zDX7L44 f5zkQVotFaJ4MJLWQP5jlipQ11wFoA9IFuXoZfntbOq3bq4pESrT2ceKyVxjGZQcqXRw +rHQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:sender:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=oNL9KWEPQXb0GolqQST1airexEubyvMH0qerMNL0lFQ=; b=FIHHzHwLBzJIbgIthQ0SSe2Jq4POsrPqCL01dpkIUGOqpD1xRY/gpx5MTEAcaD2tTy g8lHBlfulIEVbDuET4AH0YAuqlXIy2/I8rY5uA5MkYYXTD4Dp2Jke26ZG3FKoMIzd7kJ ECZEfESy49u5zEGDRTayZFHZAnmwoearA/LoIwLUbeOIfJ+T+8pRqlLvvDCheukWMUZV /YzXsorfeXEeVMY1GiyZaZFExX8IJ+dwPAHPwPuybHp7cZ+j5oGk3ci/+o6e56L0THa8 hflsovWTfYuotqHkSo7y2lobSGiPv55LfDeQYPKtxFrVORln0ycV4tMD+5OewFXQKuJN Eqzg== X-Gm-Message-State: AG10YOQQJyJg+/gvQFi6fmrdn86lx1Y285fhgLXGlw5XjycXNJtZAMP4UJ7Tf1OAikxispREJ+GqUnyW6UZ0OA== MIME-Version: 1.0 X-Received: by 10.66.132.73 with SMTP id os9mr2406363pab.27.1455722771901; Wed, 17 Feb 2016 07:26:11 -0800 (PST) Sender: morrison.levi@gmail.com Received: by 10.66.163.232 with HTTP; Wed, 17 Feb 2016 07:26:11 -0800 (PST) In-Reply-To: References: Date: Wed, 17 Feb 2016 08:26:11 -0700 X-Google-Sender-Auth: sNxaBFdzTkxp2G8_111a1-64BPc Message-ID: To: Kevin Gessner Cc: internals Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] [RFC] Traits with interfaces From: levim@php.net (Levi Morrison) On Wed, Feb 17, 2016 at 7:25 AM, Kevin Gessner wrote: > Hello internals team! I'd like to propose an RFC to allow traits to > implement interfaces. > > I've noticed s pattern in Etsy's code and elsewhere, where a trait provides > a common implementation of an interface. Classes that use the trait are > required to also explicitly declare the interface to benefit. I propose > that traits be permitted to declare and implement interfaces. Classes that > use such a trait would then implement the interface, as though it were > declared on the class, without declaring the interface explicitly. I am unsure on the particular detail of the class automatically implementing the interface. I want to add my personal experience with traits: every time I create a trait it is to implement an interface. Here is a publicly available [example with OuterIterator](https://github.com/morrisonlevi/Ardent/blob/master/src/Collection/OuterIteratorTrait.php): trait OuterIteratorTrait { abstract function getInnerIterator() : Iterator; function current() { return $this->getInnerIterator()->current(); } function next(): void { $this->getInnerIterator()->next(); } function key() { return $this->getInnerIterator()->key(); } function valid(): bool { return $this->getInnerIterator()->valid(); } function rewind(): void { $this->getInnerIterator()->rewind(); } } This makes it really easy to implement iterators. The class that uses the trait can simply implement `getInnerIterator` and then modify only the methods that differ from standard behavior. Here are a few examples: * https://github.com/morrisonlevi/Ardent/blob/master/src/Collection/HashMapIterator.php * https://github.com/morrisonlevi/Ardent/blob/master/src/Collection/HashSetIterator.php * https://github.com/morrisonlevi/Ardent/blob/master/src/Collection/SortedMapIterator.php * https://github.com/morrisonlevi/Ardent/blob/master/src/Collection/SortedSetIterator.php I can see how it would be nice to allow the trait to officially declare that it implements some interface (in this case Iterator or OuterIterator) which would require that the trait has fully implemented the required methods (or declared them as abstract). This would be a small improvement but helpful. I am less certain about the classes which `use` it automatically inheriting the interfaces. To clarify: I am neither in favor or against that part. Or at least at this stage, anyway.