Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:88107 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 50195 invoked from network); 7 Sep 2015 19:02:51 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 7 Sep 2015 19:02:51 -0000 Authentication-Results: pb1.pair.com header.from=happy.melon.wiki@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=happy.melon.wiki@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.215.42 as permitted sender) X-PHP-List-Original-Sender: happy.melon.wiki@gmail.com X-Host-Fingerprint: 209.85.215.42 mail-la0-f42.google.com Received: from [209.85.215.42] ([209.85.215.42:35859] helo=mail-la0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 71/C2-34134-95FDDE55 for ; Mon, 07 Sep 2015 15:02:50 -0400 Received: by lanb10 with SMTP id b10so55901490lan.3 for ; Mon, 07 Sep 2015 12:02:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:content-type; bh=PvNTlfuaxJzyzpXUAhSUxvytdd1kpE+9CTtmkOnmGa8=; b=B8qydvYBgxlrd7WCWVuSiR/CkslU17kwJ1wmwYB3nWCq/2aHb/4Y26dGPqQ+YF8G6H gRqo7/6WPKGyuPYzrl89WwBGX+JQZx4szxPmA9eJBJcOl5dLNeIrFiY+aZwXlZhoGdii G58YJdUQV7f8aA0mhKnLL43JdqpFK1DBNGlIsdaENSH/RwbK6T7/6k7gOwTwrHsx2u40 NcyC3+K7+muu2IUgBvz3S3TGJIzMSow6TJylK96HcUUb9f6PYkIaL1yqZktZt3qZN3d3 NlQB210PfQUiyWlmPL048+1prWYhTiERI3gEOdiUSLCWoDr+7H73vNG2ZAAiUOvDI0Jj kjkg== X-Received: by 10.152.204.9 with SMTP id ku9mr14190398lac.51.1441652565772; Mon, 07 Sep 2015 12:02:45 -0700 (PDT) MIME-Version: 1.0 Sender: happy.melon.wiki@gmail.com Received: by 10.25.199.215 with HTTP; Mon, 7 Sep 2015 12:02:26 -0700 (PDT) In-Reply-To: <55ED68D2.9020508@dasprids.de> References: <55E4B9AA.9060906@dasprids.de> <09.54.59944.CD76CE55@pb1.pair.com> <55ED68D2.9020508@dasprids.de> Date: Mon, 7 Sep 2015 20:02:26 +0100 X-Google-Sender-Auth: VfwMv_pwitnzSmJXqBcgqjs_AbA Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary=001a1134386e128c5a051f2ce536 Subject: Re: [PHP-DEV] Re: Generic classes and methods RFC From: happy.melon.wiki+gb@gmail.com (George Bond) --001a1134386e128c5a051f2ce536 Content-Type: text/plain; charset=UTF-8 On 7 September 2015 at 11:37, Ben Scholzen wrote: > Hello, > > Hi Ben! >> >> Generics are a feature I'd love to see in PHP. I think this RFC could do >> with a little elaboration, though. >> >> Something that's particularly important to me is if it be possible to >> have default values for type parameters? For example, could I make a >> class like this? >> >> > // note the =, a default value (like function parameters) >> class List >> { >> private $array = []; >> >> // ... >> >> public function append(T $value) { >> $this->array[] = $value; >> } >> } >> >> $integerList = new List; // only accepts integers >> $list = new List; // accepts any value >> >> Here, 'mixed' means any type, like in the PHP manual or in Hack. We >> don't currently have a 'mixed' typehint since we don't need it (you can >> simply omit a typehint for a parameter or return type), but it would be >> useful here. >> >> I'd like it if this was possible, because then you could make existing >> classes use generics without breaking compatibility. It's also more >> beginner-friendly: people who don't know about generics don't have to >> use them, if the class author has made this possible. This is in keeping >> with the "PHP way" where we don't require people to use type hints if >> they don't want them. >> > > I'm not sure if we would need any other default than "mixed". Personally I > think that you should be able to instantiate any generic class which does > not enforce specific types on the hints without any types, which > automatically turns it into a mixed-type generic. That should cover this > use-case pretty easily. > > On a different note, I'm not sure I like the `class Baz` >> syntax. For functions parameters, we put the type name before the >> variable name, e.g. `function foo(int $bar)`. So, could we do the same >> here, i.e. `class <\Bar Foo>`, for consistency? >> > > As written in an earlier mail, the colon came up from another email, I'm > happy to change it if there's a better suggestion. > > > Though that looks a little strange to me. It's two bare identifiers next >> to eachother (`\Bar Foo`), unlike function parameters where the second >> one has a dollar prefix (`\Bar $foo`). Perhaps type variables, like >> regular variables, should have some sort of sigil in PHP? This would >> make it more obvious that something is a type variable and not a class >> name. To take an example from your RFC, consider the following code >> snippet: >> >> class Entry >> { >> // ... >> >> public function __construct(KeyType $key, ValueType $value) >> { >> // ... >> } >> >> // ... >> } >> >> If we hadn't seen the class declaration at the top which makes `KeyType` >> and `ValueType` be type parameters, we might not realise they weren't >> ordinary classes or interfaces when we looked at `__construct`. The >> -Type suffix you've used helps a little, but that's a convention, and >> isn't guaranteed to be used. Also, in some existing projects, there >> might be classes with that suffix. >> >> What if we use some sort of sigil here to make it clear? Say we used %: >> >> class Entry<%KeyType, %ValueType> >> { >> // ... >> >> public function __construct(%KeyType $key, %ValueType $value) >> { >> // ... >> } >> >> // ... >> } >> >> Now, without having to look at the class declaration, we can tell that >> `KeyType` isn't a class name, because it has % in front of it. >> > > I like that idea, as it makes the code easier to understand. I'm wondering > what other people's thoughts about that is. > > Anyway, all that being said: the big challenge with generics is really >> getting someone to do the nitty-gritty of implementing it. It's great >> that you've got an RFC written for this, but unless someone is willing >> to implement it, I fear it may go to waste. But you writing an RFC might >> inspire someone. There is hope! >> > > I hope so as well! > > Hope my thoughts are somewhat helpful. >> >> -- >> Andrea Faulds >> http://ajf.me/ >> > > -- > Ben Scholzen > http://www.dasprids.de > > I'm a fan of the C# syntax for generics ("where" keyword). I think the natural translation of that syntax to PHP would be: class ListOfLoggers extends Enumerable implements ArrayAccess where T implements LoggerInterface { ... } Ie you have "where " and then a block in the same syntax as a normal class extends/implements declaration. The full structure would be: class Foo extends BaseClass implements IGenericInterface, IOtherInterface where TFirst extends OtherBaseClass implements IAnotherInterface where TSecond extends YetAnotherBaseClass implements IYetAnotherInterface, IEvenMoreInterfaces { .... } C# doesn't put a comma between where blocks, which usually catches me out. It's open to bikeshedding whether it would be sensible to require one here (after "implements IAnotherInterface"), and if so whether to allow a trailing comma (after "IEvenMoreInterfaces"). Thoughts? --G --001a1134386e128c5a051f2ce536--