> On 5 Apr 2019, at 21:29, Larry Garfield <la...@garfieldtech.com> wrote:
> 
> On Thu, Apr 4, 2019, at 10:46 PM, Stephen Reay wrote:
> 
>>> Discussion:
>>> 
>>> 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 kind of 
>>> iterable it is, which defeats the purpose of `iterable`.  Calling methods 
>>> on arrays, though, I'm pretty sure is out of scope.
>>> 
>>> Frankly were it not for that limitation I'd say I favor the chained method 
>>> style, as while it is more verbose it is also more self-documenting.  Given 
>>> that limitation, I'm torn but would probably lean toward option 1.   And of 
>>> course there's the "methods that apply to all traversable objects" thing 
>>> which is its own can of worms I know nothing about.
>>> 
>>> (If someone has a suggestion for how to resolve that disadvantage, I'd love 
>>> to hear it.)
>>> 
>>> Those seem like the potential options.  Any further thoughts?  Or 
>>> volunteers? :-)
>>> 
>>> --Larry Garfield
>>> 
>>> -- 
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>> 
>> 
>> (Sorry, sent from wrong address, sending again!)
>> 
>> Hi Larry,
>> 
>> I’ve mostly ignored this thread until now - I find a lot of the 
>> “shorter syntax” (i.e. the short closures RFC) to sound a lot like the 
>> arguments “I don’t like semicolons/it has to be ‘pretty'” that happen 
>> in other language communities.
> 
> 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 abstraction.  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 conceptualize a problem in a different 
> way, and most of the machinery then falls away.  That means I can now think 
> in terms of "call this function, then iterate the stream it gives me back" 
> and within the function I can just have normal logic with `yield` floating 
> around as needed.  Anything I do there *could* be done with an Iterator 
> class; I've done it some weird things with Iterators before.  But the ability 
> to think in terms of an ad-hoc stream of values really changes the way you 
> think about the problem, and in a very good way.
> 
> Similarly, short closures isn't about "let's make functions easier to write". 
>  That's a side effect.  They should be thought of more as a way to easily 
> encapsulate "apply this expression to this set of values".  So the advantage 
> is not that
> 
> $y= 5;
> array_map(fn($x) => $x*$y, $arr);
> 
> is less typing than
> 
> array_map(function ($x) use ($y) {
>  return $x * $y;
> });
> 
> 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 higher-order 
> mental operation, and once you start doing that you can conceptualize the 
> program in a different, more higher-order, less bug-prone way.
> 
> Just like there's nothing you can do with foreach() that you can't also do 
> with for()... but foreach() lets you think in terms of "just do it to 
> everything" rather than think in terms of the machinery of iteration.
> 
> I see comprehensions the same way.  At one level they're "just" short syntax 
> for generators, but they're more about making it possible to reason about 
> your logic at a higher level, in a more declarative fashion.
> 
> (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.)
> 
>> But the first example you give here, I can see the logical approach - 
>> as you say, it’s a currently-valid foreach statement, wrapped in square 
>> brackets. Would it have to be a single line to parse, or could it be 
>> wrapped when the condition gets longer (yes I know it could just become 
>> a regular generator then, I’m just wondering about what happens when 
>> someone adds a new line in there (in a language that historically 
>> doesn’t care about newlines)
> 
> The RFC specifically says whitespace is irrelevant.  If you want to break a 
> comprehension across multiple lines, you do you.  But if it's getting 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 foreach statements, 
> multiple defined comprehensions that reference each other, etc.)
> 
>> I like the second concept a lot too, but how would this cope with for 
>> example: a userland class implements iterator but *also* defines a 
>> `filter(callback $fn): self` method for the exact same purposes were 
>> discussing. How is that handled?
> 
> 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 wants, but 
> there's also possible function signature mismatches there.  It may just have 
> to be a BC break in those cases.  I am open to alternate suggestions. (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.)
> 
>> On Fri, Apr 5, 2019, at 3:41 AM, Michał Brzuchalski wrote:
>> Hi Larry,
>> 
>> pt., 5 kwi 2019 o 03:55 Larry Garfield <la...@garfieldtech.com> napisał(a):
>> 
>>> 
>>> Advantages:
>>> 
>>> * Very compact.
>>> * Works for both arrays and traversables
>>> * Would play very nicely with the proposed spread operator for iterables (
>>> https://wiki.php.net/rfc/spread_operator_for_array).
>>> 
>> 
>> IMO not nicely cause spread operator in current proposal raises an error on
>> key preserved traversable[1].
>> This means example like below would fail
>> 
>> $a = ['foo' => true, ...[foreach($_GET as $key => $value) yield $key =>
>> $value]]; // error
>> 
>> [1] https://wiki.php.net/rfc/spread_operator_for_array#string_keys
> 
> 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:
> 
> $arr = ...[foreach ($list as $k => $v) yield $k => $v];
> 
> 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 work, 
> iterator_to_array() still does; it's just more verbose.
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

Hi Larry,

Sorry I haven’t replied before now.

I understand that there is an actual tangible benefit being pursued here - but 
so many of the comments seem to be focussed around removing every possible 
character due to some weird belief that less characters is automatically 
“better”, and it always reminds of the “I don’t like semicolons they're ugly” 
type comments that always come up in JS communities.

Best of luck!


Cheers

Stephen 

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to