Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:105319 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 74486 invoked from network); 18 Apr 2019 20:01:44 -0000 Received: from unknown (HELO wout5-smtp.messagingengine.com) (64.147.123.21) by pb1.pair.com with SMTP; 18 Apr 2019 20:01:44 -0000 Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.west.internal (Postfix) with ESMTP id C1E5E470 for ; Thu, 18 Apr 2019 13:00:54 -0400 (EDT) Received: from imap26 ([10.202.2.76]) by compute7.internal (MEProxy); Thu, 18 Apr 2019 13:00:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm2; bh=zsfXISIXeiZQ2o58Sl5UGIsZaJM6oK0zk0M8pS2kC bY=; b=ntYwcYZl3sodaWN2C4xKfU0so9RsYUbdqfuTkQ8qlDyN3psN0NfsdyMN1 EY4jPxc4wMJPCCk3wD/IgR03BELl6VUJtVwAn/DrLKsDxa4uCAQqQ+nwl0YK5v1t z6e0lCx74mLCpIHaHayqjVVZFhUwPMc7MiKS8e8Wy8L/A6TOHSU3wUzX0eZhzNJD 0BOQoq6pAFWIIdd8s67ptTQDXYipe8+9vDgRS5btfEMx/LAW1CmFVQbOsF9UTvsg le/nqOwWIwewharZ7rPKU5V3FHA/s/G1F7QiovB3xsExgAo3/XmXpQl1JS81GwW4 Jy4+qRbuuB7MfLzGsugmSJAipWsjg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduuddrfeehgdegjecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhepofgfggfkjghffffhvffutgfgsehtqh ertderreejnecuhfhrohhmpedfnfgrrhhrhicuifgrrhhfihgvlhgufdcuoehlrghrrhih sehgrghrfhhivghlughtvggthhdrtghomheqnecuffhomhgrihhnpehphhhprdhnvghtne curfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdr tghomhenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: by mailuser.nyi.internal (Postfix, from userid 501) id F1790B453A; Thu, 18 Apr 2019 13:00:53 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.1.6-443-g918f9d3-fmstable-20190416v3 Mime-Version: 1.0 X-Me-Personality: 10727885 Message-ID: <3fbb510a-7e2b-4878-babd-bd2be7b7297b@www.fastmail.com> In-Reply-To: References: <6d3be21f-d63a-3fc6-94ee-0bde8e313d66@xs4all.nl> <37bb451f-a1b2-4c69-91e2-f2ab6c4798e7@www.fastmail.com> <76D63EA5-7F6D-43E6-ACC2-E55B5816BEF5@koalephant.com> <03b2e206-750f-4afb-806b-65ff77eb6893@www.fastmail.com> Date: Thu, 18 Apr 2019 13:00:53 -0400 To: internals@lists.php.net Content-Type: text/plain;charset=utf-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] RFC Draft: Comprehensions From: larry@garfieldtech.com ("Larry Garfield") On Tue, Apr 9, 2019, at 3:31 AM, Stephen Reay wrote: >=20 >=20 > > On 5 Apr 2019, at 21:29, Larry Garfield wro= te: > >=20 > > On Thu, Apr 4, 2019, at 10:46 PM, Stephen Reay wrote: > >=20 > >>> Discussion: > >>>=20 > >>> For me, the inability to work with arrays is the big problem with = the second approach. I very very often am type declaring my returns and= parameters as `iterable`, which means I may have an array and not know = it. Using approach 2 means I suddenly really really need to care which k= ind of iterable it is, which defeats the purpose of `iterable`. Calling= methods on arrays, though, I'm pretty sure is out of scope. > >>>=20 > >>> Frankly were it not for that limitation I'd say I favor the chaine= d method style, as while it is more verbose it is also more self-documen= ting. Given that limitation, I'm torn but would probably lean toward op= tion 1. And of course there's the "methods that apply to all traversab= le objects" thing which is its own can of worms I know nothing about. > >>>=20 > >>> (If someone has a suggestion for how to resolve that disadvantage,= I'd love to hear it.) > >>>=20 > >>> Those seem like the potential options. Any further thoughts? Or = volunteers? :-) > >>>=20 > >>> --Larry Garfield > >>>=20 > >>> --=20 > >>> PHP Internals - PHP Runtime Development Mailing List > >>> To unsubscribe, visit: http://www.php.net/unsub.php > >>>=20 > >>=20 > >> (Sorry, sent from wrong address, sending again!) > >>=20 > >> Hi Larry, > >>=20 > >> I=E2=80=99ve mostly ignored this thread until now - I find a lot of= the=20 > >> =E2=80=9Cshorter syntax=E2=80=9D (i.e. the short closures RFC) to s= ound a lot like the=20 > >> arguments =E2=80=9CI don=E2=80=99t like semicolons/it has to be =E2= =80=98pretty'=E2=80=9D that happen=20 > >> in other language communities. > >=20 > > In defense of terse syntax, it's not a question of "pretty". It's a= question of making it feasible to operate at a higher level of abstract= ion. Really, generators didn't offer much of anything that couldn't be = done by defining and building an Iterator-implementing class. They're "= just" syntactic sugar. However, they allow the developer to conceptuali= ze a problem in a different way, and most of the machinery then falls aw= ay. That means I can now think in terms of "call this function, then it= erate the stream it gives me back" and within the function I can just ha= ve normal logic with `yield` floating around as needed. Anything I do t= here *could* be done with an Iterator class; I've done it some weird thi= ngs with Iterators before. But the ability to think in terms of an ad-h= oc stream of values really changes the way you think about the problem, = and in a very good way. > >=20 > > Similarly, short closures isn't about "let's make functions easier t= o write". That's a side effect. They should be thought of more as a wa= y to easily encapsulate "apply this expression to this set of values". = So the advantage is not that > >=20 > > $y=3D 5; > > array_map(fn($x) =3D> $x*$y, $arr); > >=20 > > is less typing than > >=20 > > array_map(function ($x) use ($y) { > > return $x * $y; > > }); > >=20 > > It's that in the first option you don't think about it as a function= , you think about it as an expression applied over a set. That's a high= er-order mental operation, and once you start doing that you can concept= ualize the program in a different, more higher-order, less bug-prone way= . > >=20 > > Just like there's nothing you can do with foreach() that you can't a= lso do with for()... but foreach() lets you think in terms of "just do i= t to everything" rather than think in terms of the machinery of iteratio= n. > >=20 > > I see comprehensions the same way. At one level they're "just" shor= t syntax for generators, but they're more about making it possible to re= ason about your logic at a higher level, in a more declarative fashion. > >=20 > > (There's probably a conference talk in there somewhere, from for to = foreach to iterators to generators to comprehensions, each coming up one= level of abstraction.) > >=20 > >> But the first example you give here, I can see the logical approach= -=20 > >> as you say, it=E2=80=99s a currently-valid foreach statement, wrapp= ed in square=20 > >> brackets. Would it have to be a single line to parse, or could it b= e=20 > >> wrapped when the condition gets longer (yes I know it could just be= come=20 > >> a regular generator then, I=E2=80=99m just wondering about what hap= pens when=20 > >> someone adds a new line in there (in a language that historically=20= > >> doesn=E2=80=99t care about newlines) > >=20 > > The RFC specifically says whitespace is irrelevant. If you want to = break a comprehension across multiple lines, you do you. But if it's ge= tting large enough that it's ugly to read that way it's a good sign you = may want to take a different approach. (A defined function with real fo= reach statements, multiple defined comprehensions that reference each ot= her, etc.) > >=20 > >> I like the second concept a lot too, but how would this cope with f= or=20 > >> example: a userland class implements iterator but *also* defines a=20= > >> `filter(callback $fn): self` method for the exact same purposes wer= e=20 > >> discussing. How is that handled? > >=20 > > I have no idea at the moment. :-) That would be a possible BC issue= . My first thought is that if an iterator defines filter(), map(), etc.= itself then it's overriding the default behavior and can do what it wan= ts, but there's also possible function signature mismatches there. It m= ay just have to be a BC break in those cases. I am open to alternate su= ggestions. (That may push it to PHP 8, which would be unfortunate but if= that's the way it goes, that's the way it goes.) > >=20 > >> On Fri, Apr 5, 2019, at 3:41 AM, Micha=C5=82 Brzuchalski wrote: > >> Hi Larry, > >>=20 > >> pt., 5 kwi 2019 o 03:55 Larry Garfield nap= isa=C5=82(a): > >>=20 > >>>=20 > >>> Advantages: > >>>=20 > >>> * Very compact. > >>> * Works for both arrays and traversables > >>> * Would play very nicely with the proposed spread operator for ite= rables ( > >>> https://wiki.php.net/rfc/spread_operator_for_array). > >>>=20 > >>=20 > >> IMO not nicely cause spread operator in current proposal raises an = error on > >> key preserved traversable[1]. > >> This means example like below would fail > >>=20 > >> $a =3D ['foo' =3D> true, ...[foreach($_GET as $key =3D> $value) yie= ld $key =3D> > >> $value]]; // error > >>=20 > >> [1] https://wiki.php.net/rfc/spread_operator_for_array#string_keys > >=20 > > True; it's not a complete solution. Per the thread on spread string= keys may make a comeback. But I was thinking more of a case of: > >=20 > > $arr =3D ...[foreach ($list as $k =3D> $v) yield $k =3D> $v]; > >=20 > > For those cases where you really do want an array to operate on next= , rather than a generator. If you're in a situation where ... doesn't w= ork, iterator_to_array() still does; it's just more verbose. > >=20 > > --Larry Garfield > >=20 > > --=20 > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: http://www.php.net/unsub.php > >=20 >=20 > Hi Larry, >=20 > Sorry I haven=E2=80=99t replied before now. >=20 > I understand that there is an actual tangible benefit being pursued=20= > here - but so many of the comments seem to be focussed around removing= =20 > every possible character due to some weird belief that less characters= =20 > is automatically =E2=80=9Cbetter=E2=80=9D, and it always reminds of th= e =E2=80=9CI don=E2=80=99t like=20 > semicolons they're ugly=E2=80=9D type comments that always come up in = JS=20 > communities. >=20 > Best of luck! >=20 >=20 > Cheers >=20 > Stephen=20 Um. Isn't that what you just said above, in the email I replied to at l= ength? Like, it's in the quoted text above... --Larry Garfield