Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:61024 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 49521 invoked from network); 28 Jun 2012 13:22:42 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Jun 2012 13:22:42 -0000 Authentication-Results: pb1.pair.com header.from=davidkmuir@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=davidkmuir@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.160.42 as permitted sender) X-PHP-List-Original-Sender: davidkmuir@gmail.com X-Host-Fingerprint: 209.85.160.42 mail-pb0-f42.google.com Received: from [209.85.160.42] ([209.85.160.42:34104] helo=mail-pb0-f42.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B6/7D-08168-1AA5CEF4 for ; Thu, 28 Jun 2012 09:22:41 -0400 Received: by pbbrp12 with SMTP id rp12so3339004pbb.29 for ; Thu, 28 Jun 2012 06:22:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=references:in-reply-to:mime-version:content-transfer-encoding :content-type:message-id:cc:x-mailer:from:subject:date:to; bh=TV1VxnPruBOaUMhj6RQKNrIYjDVACRqHGfjvPZY2TzI=; b=ZdoWfi7g9ccm4KrNCEiKslZBd/rJHXHrr1N80lfYsKa3p0a7I6RIUofxS7d5BJcr+a 5fSRzaPiPVGRQ9kNBrYXU+5boBhMr+kz0F7VcZkTK1YiSwYo+MawGWoXm0wHWngXEBif v8sQ/UE8RNbKi0eeiWfhWDBR39Vk7bjrGr1ggkFzt6zsuVt4r5bWVrKzac+qx/Tz/pPD v8HUk4Cjk00ziVXTbq3ozCJ/8FaTaVr/niaiQF7b9rTIAgnlbAUknDsJFncclnSUpLQy BuwZMUs9/DPKuUZci4sCxM9vvW0NmDDjZXvjfEQhTqEFxwRgEGtJWG4DTXypvFL8Ah2f fjqQ== Received: by 10.68.220.163 with SMTP id px3mr7380182pbc.167.1340889758776; Thu, 28 Jun 2012 06:22:38 -0700 (PDT) Received: from [192.168.0.7] (dsl-202-173-152-56.vic.westnet.com.au. [202.173.152.56]) by mx.google.com with ESMTPS id rg10sm2114686pbc.54.2012.06.28.06.22.35 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 28 Jun 2012 06:22:37 -0700 (PDT) References: In-Reply-To: Mime-Version: 1.0 (1.0) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii Message-ID: Cc: PHP internals X-Mailer: iPhone Mail (9B206) Date: Thu, 28 Jun 2012 23:22:31 +1000 To: Sebastian Krebs Subject: Re: [PHP-DEV] List comprehensions and generator expressions for PHP From: davidkmuir@gmail.com (David Muir) I'd assume that array_map() only works with arrays, while list comprehension= should work with anything traversable. David On 28/06/2012, at 10:43 PM, Sebastian Krebs wrote: > Hi, >=20 > Whats the difference to the (already existing) function array_map() (excep= t > the syntax and one more new keyword)? >=20 >> $firstNames =3D array_map(function($user){return $user->firstname;}, > $users); >=20 > Don't want to rewrite every example you gave, but you probably see my poin= t. >=20 > Regards, > Sebastian >=20 > 2012/6/28 Nikita Popov >=20 >> Hi internals! >>=20 >> Python and several other languages include support for list >> comprehensions and generator expressions and I'd like to see something >> similar in PHP too. >>=20 >> I created a hacky proof of concept implementation here: >> https://github.com/nikic/php-src/tree/addListComprehensions. It's >> really dirty, but it implements both features in about ~150 lines of >> code. >>=20 >> Currently I'm using the following syntax: >>=20 >> $firstNames =3D [foreach ($users as $user) yield $user->firstName]; >>=20 >> This code is roughly equivalent to writing: >>=20 >> $firstNames =3D []; >> foreach ($users as $user) { >> $firstNames[] =3D $user->firstName; >> } >>=20 >> You may notice that this particular list comprehension provides the >> same functionality as array_column(), just in a little more >> generalized way. E.g. you could use all of the following without >> having special functions for them all: >>=20 >> $firstNames =3D [foreach ($users as $user) yield $user->firstName]; >>=20 >> $firstNames =3D [foreach ($users as $user) yield $user->getFirstName()]= ; >>=20 >> $firstNames =3D [foreach ($users as $user) yield $user['firstName']]; >>=20 >> It's also possible to explicitly specify a key: >>=20 >> $firstNames =3D [foreach ($users as $user) yield $user->id =3D> >> $user->firstName]; >>=20 >> It is also possible to filter elements using list comprehensions: >>=20 >> $underageUsers =3D [foreach ($users as $user) if ($user->age < 18) >> yield $user]; >> // or just the names >> $underageUserNames =3D [foreach ($users as $user) if ($user->age < >> 18) yield $user->firstName]; >>=20 >> It is also possible to nest multiple foreach loops: >>=20 >> $aList =3D ['A', 'B']; >> $bList =3D [1, 2]; >> $combinations =3D [foreach ($aList as $a) foreach ($bList as $b) >> yield [$a, $b]]; >> // gives: [ ['A', 1], ['A', 2], ['B', 1], ['B', 2] ] >>=20 >> All the above are list comprehensions (or in PHP rather array >> comprehensions), i.e. they create an array as the result. >>=20 >> If this is not needed it is also possible to compute the values lazily >> using generator expressions, which use () instead of []. >>=20 >> $firstNames =3D (foreach ($users as $user) yield $user->firstName); >>=20 >> In this case $firstNames will no longer be an array of first names, >> but instead will be a generator producing first names. >>=20 >> This is handy if you only need to iterate the resulting "list" only >> once as it saves you holding the whole list in memory. >>=20 >> Also it allows you to work with infinite lists easily: >>=20 >> function *naturalNumbers() { >> for ($i =3D 0; ; ++$i) { >> yield $i; >> } >> } >>=20 >> // all natural numbers >> $numbers =3D naturalNumbers(); >> // only the odd ones >> $oddNumbers =3D (foreach ($numbers as $n) if ($n % 2) yield $n); >> // ... >>=20 >> (At this point I wonder whether one should include support for >> for-loops in list comprehensions. So the naturalNumbers() function >> could be replaced with (for ($i =3D 0;; ++$i) yield $i), etc) >>=20 >> So, what do you think? Do we want something like this in PHP? >>=20 >> Nikita >>=20 >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >>=20 >>=20