[PHP-DEV] Re: [VOTE] Straw poll: Using namespaces for *any() and *all() on iterables

2021-02-02 Thread tyson andre
Hi internals,

> I've started voting on 
> https://wiki.php.net/rfc/any_all_on_iterable_straw_poll_namespace 
> Voting starts on 2021-01-19 and ends on 2021-02-02. 
> 
> This is an 11-way Single Transferable Vote poll on the choice of namespace,
> to ensure that all proposed namespaces (and similar namespaces) for global 
> functions were represented
> after a lot of discussion.
> (Votes for each ranking choice must be selected and submitted one by one 
> because these are independent HTML forms,
> writing down your choice of ranks elsewhere before submitting may be faster)
> 
> The choices for this poll were announced a few days ago in 
> https://externals.io/message/112558 "Straw poll: Naming for `*any()` and 
> `*all()` on iterables",
> which has some additional discussion on arguments for/against the proposed 
> namespace choices.
> 
> - Additional discussion on namespaces can also be found in the initial RFC 
> announcement - https://externals.io/message/111756

Voting on the straw poll 
https://wiki.php.net/rfc/any_all_on_iterable_straw_poll_namespace has closed.
Of the top two options, 

- 12 voters had ranked `PHP\iterable` before the global namespace 
  (including not listing the latter in their vote).
- 11 voters had ranked the global namespace ahead of `PHP\iterable`
  (including not listing the latter in the vote).
- One voter included neither in their ranked choices.

See 
https://stv-results.theodorejb.me/php/?rfc=any_all_on_iterable_straw_poll_namespace
for a simulation of the voting process with the same result
(previously brought up for attributes syntax in 
https://externals.io/message/111630#111659)

I plan to update the RFC and implementation soon, with a secondary vote with 
two options: `PHP\iterable\any()` vs `PHP\iterable\any_value()`

Thanks,
- Tyson

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



Re: [PHP-DEV] [RFC] Fibers

2021-02-02 Thread Niklas Keller
Hey Nikita,

Thank you for the proposal. Ergonomics of async I/O in PHP certainly leave
> something to be desired right now, and improvements in this area are
> welcome.
>
> Despite your explanations in the RFC and this thread, I'm still having a
> hard time understanding the purpose of the FiberScheduler.
>
> My current understanding is that the FiberScheduler is a special type of
> fiber that cannot be explicitly scheduled by the user -- it is
> automatically scheduled by Fiber::suspend() and automatically un-scheduled
> by Fiber::resume() or Fiber::throw(). It's the fiber that runs between
> fibers :) Does that sound accurate?
>

Yes, that's accurate. Fibers are used for cooperative multi-tasking and
there's usually a single scheduler responsible for the scheduling. Multiple
schedulers would block each other or busy wait. So having multiple
schedulers is strongly discouraged in long running applications, however,
it might be acceptable in traditional applications, i.e. PHP-FPM. In
PHP-FPM, multiple schedulers partially blocking each other is still better
than blocking entirely for every I/O operation.


> What's not clear to me is why the scheduling fiber needs to be
> distinguished from other fibers. If we want to stick with the general
> approach, why is Fiber::suspend($scheduler) not Fiber::transferTo($fiber),
> where $fiber would be the fiber serving as scheduler (but otherwise a
> normal Fiber)? I would expect that context-switching between arbitrary
> fibers would be both most expressive, and make for the smallest interface.
>

There are a few reasons to make a difference here:

- SchedulerFibers are run to completion at script end, which isn't the case
for normal fibers.
- Terminating fibers need a fiber to return to. For schedulers it's fine if
a resumed fiber terminates, for normal fibers it should be an exception if
the scheduler fiber terminates without explicitly resuming the suspended
fiber.
- Keeping the previous fiber for each suspension point is complicated if
not impossible to get right and generally complicates the implementation
and cognitive load, see following example:

main -> A -> B -> C -> A (terminates) -> C (previous) -> B (terminates) ->
C (previous, terminates) -> main

In the example above, the previous fiber linked list from C back to main
needs to be optimized at some point, otherwise A and B need to be kept in
memory and thus leak memory until C is resumed.

I'm sure Aaron can present a few other reasons to keep the separation.


> The more limited alternative is to instead have Fiber::suspend() return to
> the parent fiber (the one that resume()d it). Here, the parent fiber
> effectively becomes the scheduler fiber. If I understand right, the reason
> why you don't want to use that approach, is that it doesn't allow you to
> call some AMP function from the {main} fiber, create the scheduler there
> and then treat {main} just like any other fiber. Is that correct?
>

Correct, this wouldn't allow top-level Fiber::suspend(). It would also make
the starting / previously resuming party responsible for resuming the fiber
instead of the fiber being able to "choose" the scheduler for a specific
suspension point. One fiber would thus be effectively limited to a single
scheduler.

Best,
Niklas


Re: [PHP-DEV] Re: [RFC] Enumerations, Round 2

2021-02-02 Thread Larry Garfield
On Fri, Jan 29, 2021, at 11:15 AM, Larry Garfield wrote:

> And we're back again.  The RFC has been updated with a steady stream of 
> smaller improvements based on feedback and testing, and is now in its 
> Final Form(tm) (we think).  The only major change worth noting is that 
> we renamed things. :-)
> 
> An enum with no scalar backing is now called a Pure Enum, made up of 
> Pure Cases.  One that does have backing values is called a Backed Enum, 
> made up of Backed Cases.  That change is mainly to allow for future 
> expansion to non-scalar backing static values, should the use case 
> arise.  Reflection was also reworked a bit to make it more logical.
> 
> https://wiki.php.net/rfc/enumerations
> 
> At this point, Ilija and I consider the RFC done and ready for a vote.  
> Baring any major issues being brought up, we plan to start the vote in 
> the first half of next week, probably Tuesday-ish.  If you have any 
> other bug reports or tweaks, please speak now or forever hold your 
> patches.
> 
> --Larry Garfield

Based on feedback from Nikita we've made three last changes to Naming 
Things(tm).

1) IterableEnum is back to "UnitEnum", which is the superset of Pure enums and 
Backed enums.  
2) The reflection classes were renamed accordingly.
3) We clarified that tryFrom() will behave "as you'd expect" if passed an 
incorrect type, given strong vs weak mode.

And a few other inconsequential word tightenings.

Baring any other revelations, voting starts tomorrow.

--Larry Garfield

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



Re: [PHP-DEV] [VOTE] Dump results of expressions in `php -a`

2021-02-02 Thread Bob Weinand
Hey Tyson,

> Am 02.02.2021 um 03:35 schrieb tyson andre :
> 
> Hi Bob Weinand,
> 
>>> Am 20.01.2021 um 01:55 schrieb tyson andre :
>>> 
>>> Hi internals,
>>> 
>>> Voting has started on 
>>> https://wiki.php.net/rfc/readline_interactive_shell_result_function
>>> on 2021-01-19, and ends on 2021-02-02.
>>> 
>>> This RFC proposes to dump the results of non-null expressions using 
>>> var_dump/var_export() by default in `php -a` (the interactive shell).
>>> Additionally, this adds a new function 
>>> `readline_interactive_shell_result_function` to the readline PHP module.
>>> This function only affects interactive shells - it can optionally be used 
>>> to set or clear a closure when `extension_loaded('readline') === true`,
>>> but that closure would only be called in interactive shells (i.e. php -a).
>>> (That closure would be called instead of the native implementation with the 
>>> snippet of code that was evaluated and the expression's result,
>>> if a php statement contained a single expression such as `2+2;` or `$x = 
>>> [1,2];` (that could be used as the expression of a return statement)
>>> - Dumping of expression results can be disabled using an ini setting or at 
>>> runtime 
>>> 
>>> Thanks,
>>> - Tyson
>> 
>> Hey Tyson,
>> 
>> My main concern in this iteration of the RFC is: what happens with 
>> big/deeply nested objects?
>> They tend to spew tons of lines if var_dump()'ed. Do we have reasonable 
>> depth/output limitations in default dumping mode?
>> 
>> I'm often enough using php -a to do some quick ad-hoc processing (example, 
>> read a big json file, and then access a value; instantiating a mediawiki bot 
>> framework and calling replace on it; ...).
>> 
>> It's really cool to have any interactive feedback at all, but please, at 
>> least by default, limit the output. (An example is the JS REPL in browser 
>> console - it shows you a minimal preview of the object, and then you can 
>> expand with your mouse. Obviously with a pure cli application, this needs 
>> different - intuitive - navigation.)
>> 
>> As it currently stands, this makes php -a unusable in any but the simplest 
>> cases, without just disabling the whole feature.
>> 
>> I like the whole feature, but the missing output limitation (I have yet 
>> enough nightmares from var_dump()'ing the wrong object filling my shell with 
>> tons of irrelevant information… I don't need that potentially happening on 
>> every single evaluated expression)
>> 
>> Thus I'm voting no, for now.
> 
> As-is, the entire object or string would be dumped with var_export/var_dump 
> to stdout.
> 
> Thoughts on the adding following output truncation mechanism 
> (for the default C result dumper implementation)
> before printing the results of the returned expression 
> (the user output continues to be untruncated, and the existence of cli.pager 
> would not affect this mechanism in case the binary is not actually a pager)?
> For arrays/objects used with var_dump - the equivalent of 
> `ob_start(); var_dump($result); $result = ob_get_clean();` 
> would have to be used first from C since var_dump still writes to the output 
> buffer (php_printf(), etc.)

var_dump() tends to be quite intensive in newline usage. I don't think 
var_dump() (as is) is the best mechanism to print. At least I'd use one 
property/one array argument = single line instead of two lines.
Additionally, when dumping a nested object, it's more valuable to see as much 
as possible from the primary object rather than the deep nesting.


> I'd omitted output truncation from the RFC because I wasn't sure how many 
> people 
> would consider it excessive to include a limit on var_dump output, and there 
> was little feedback before the RFC vote started.

Yeah, sorry for the late comment on that :-)

> The simplest implementation would be to truncate to a byte limit and append 
> `...` if truncated, 
> but the main concern that's been brought up is the approximate number of 
> lines.
> Obviously, there'd be a value in truncating the output if there were to be 
> megabytes of output,
> though exactly what settings make sense as a default would vary.

As mentioned a section earlier, there should be limits according to the 
nesting-level … e.g. if it's the top-level value, a string may have 20 lines 
printed and array and objects as well. And array entries/properties should then 
be in a single line or take up to max ... 20 / count(properties or array 
entries) lines (width before truncation can be determine from terminal width), 
which then can be mostly in one line flattened output.
The general rule here should be, show me my object/array at hand and give me a 
brief overview of what's nested within - and if I'm interested in detail, let 
me (manually) output that object.
Also consider, when dumping strings within (nested) arrays/objects to replace 
newlines with \n, for nicer display.

> C would not print anything (e.g. `=> `) or even call var_dump/var_export if 
> the limits were set to 0.
> 

[PHP-DEV] Re: Proposal: Adding a RewindableKeyValueIterator type allowing mixed/repeated keys

2021-02-02 Thread tyson andre
Hi internals,

> Currently, there don't seem to be any internal classes that can be used to 
> store a copy of the keys and values of an arbitrary Traversable.
> 
> - This would help in eagerly evaluating the result of a generator in a memory 
> efficient way that could be exactly stored and reused 
>   e.g. `return $this->cachedResults ??= new 
> \RewindableKeyValueIterator($this->innerResultsGenerator());`
>   https://externals.io/message/108767#108797
> - This would be useful to exactly represent the keys of sequences with 
> repeated keys (e.g. `yield 'first'; yield 'second';` implicitly uses the key 
> `0` twice.)
> - This would be convenient to have to differentiate between 1, '1', and true.
> - This would be useful if php were to add internal global functions that act 
> on iterables and return Traversables with potentially repeated keys based on 
> those iterables,
>    e.g. map(), filter(), take(), flip(), etc
> - If PHP were to add more iterable methods, being able to save an immutable 
> copy of a traversable's result would be useful for end users.
> - If PHP were to add a Map (ordered hash map with null/any 
> scalar/arrays/objects as keys) class type in the future,
>   and that implemented IteratorAggregate, the return type of getIterator() 
> would need something like RewindableKeyValueIterator.
> - The lack of a relevant datatype is among the reasons why classes such as 
> SplObjectStorage are still an Iterator instead of an IteratorAggregate. (and 
> backwards compatibility)
> 
> ```
> final class KeyValueSequenceIterator implements Iterator {
>     // loop over all values in $values and store a copy, converting
>     // references in top-level array values to non-references
>     public function __construct(iterable $values) {...}
>     public static function fromKeyValuePairs(iterable $entries): self {...} 
> // fromKeyValuePairs([[$key1, $value1]])
>     public function rewind(): void {...}
>     public function next(): void {...}
>     public function current(): mixed {...}
>     public function key(): mixed {...}
>     public function valid(): bool {...}
>     // and __debugInfo, __clone(), etc.
> }
> ```

This has been updated - the preferred name is CachedIterable.
It turns out InternalIterator is generally more efficient, 
and SplFixedArray is already using that.
The implementation is pretty much done - 
https://github.com/php/php-src/pull/6655

```
/**
 * Internal class that can be used to eagerly evaluate and store a copy
 * of the keys and values of an arbitrary Traversable.
 * Keys can be any type, and keys can be repeated.
 */
final class CachedIterable implements IteratorAggregate, Countable
{
public function __construct(iterable $iterator) {}
public function getIterator(): InternalIterator {}
public function count(): int {}
public static function fromPairs(array $pairs): CachedIterable;

public function __serialize(): array {}  // [$k1, $v1, $k2, $v2,...]
public function __unserialize(array $data): void {}

// useful for converting iterables back to values
public function keys(): array {}
public function values(): array {}
// useful to efficiently get offsets at the middle/end of a long iterable.
public function keyAt(int $offset): mixed {}
public function valueAt(int $offset): mixed {}
// dynamic properties are forbidden
}
```

Any other comments?

Thanks,
- Tyson

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



Re: [PHP-DEV] [RFC] Fibers

2021-02-02 Thread Nikita Popov
On Thu, Dec 17, 2020 at 5:30 PM Aaron Piotrowski  wrote:

> Hello everyone!
>
> I would like to introduce an RFC for adding full-stack fibers to PHP:
> https://wiki.php.net/rfc/fibers
>
> Fibers are primarily used to implement green-threads or coroutines for
> asynchronous I/O. Fibers are similar to threads, except fibers exist within
> a single thread and require cooperative scheduling of the fibers by the
> process. Since fibers do not require a full CPU context switch, they are
> lightweight and more performant than multi-processing or threading for
> awaiting I/O.
>
> An implementation as an extension is at https://github.com/amphp/ext-fiber
>
> Fibers are a complex feature. The RFC contains many examples and links to
> code using fibers to help explain and demonstrate what is possible, however
> I’m certain many more questions and concerns will arise. Looking forward to
> feedback and discussion.
>

Hi Aaron,

Thank you for the proposal. Ergonomics of async I/O in PHP certainly leave
something to be desired right now, and improvements in this area are
welcome.

Despite your explanations in the RFC and this thread, I'm still having a
hard time understanding the purpose of the FiberScheduler.

My current understanding is that the FiberScheduler is a special type of
fiber that cannot be explicitly scheduled by the user -- it is
automatically scheduled by Fiber::suspend() and automatically un-scheduled
by Fiber::resume() or Fiber::throw(). It's the fiber that runs between
fibers :) Does that sound accurate?

What's not clear to me is why the scheduling fiber needs to be
distinguished from other fibers. If we want to stick with the general
approach, why is Fiber::suspend($scheduler) not Fiber::transferTo($fiber),
where $fiber would be the fiber serving as scheduler (but otherwise a
normal Fiber)? I would expect that context-switching between arbitrary
fibers would be both most expressive, and make for the smallest interface.

The more limited alternative is to instead have Fiber::suspend() return to
the parent fiber (the one that resume()d it). Here, the parent fiber
effectively becomes the scheduler fiber. If I understand right, the reason
why you don't want to use that approach, is that it doesn't allow you to
call some AMP function from the {main} fiber, create the scheduler there
and then treat {main} just like any other fiber. Is that correct?

Regards,
Nikita


Re: [PHP-DEV] Re: [RFC] Object-scope RNG implementation

2021-02-02 Thread Go Kudo
Hi Alex

First, let me apologize for my poor English skills. It may contain rude
expressions, but it is not s intentional.

> The closest library I know and used when I had that need you mentioned is
a userland implementation: https://github.com/paragonie/RandomLib

This seems to be actively maintained, but is a fairly object-oriented-like
implementation.

> The library is organized nicely with a Generator class that depends on
constructor of a source for randomness.

This seems to be a more object-oriented implementation.

This RFC also initially proposed an object-oriented implementation, but due
to the redundancy of the implementation and interoperability issues with
existing code, it was changed to a procedural-based implementation. (But it
is not as elegant as this library.)

https://wiki.php.net/rfc/object_scope_prng?rev=1610185985

And perhaps, if we want to provide an object-oriented implementation, it
would be preferable to separate it into a new dedicated module instead of a
standard module. Currently, it is implemented in the standard module for
the convenience of modifying existing functions.

Is this what you envision the whole thing to look like in the end?

```php

final class RandomGenerator
{
public function __constrct(RandomSourceInterface $source): void {}
public function randomInt(int $min, int $max): int {}
public function randomFloat(): float {}
public function randomBytes(int $size): string {}
public function randomString(int $size, string $characters): striing {}
// compatibility for some functions.
public function arrayShuffle(array &$array): bool {}
public function stringShuffle(string $string): string {}
public function arrayRandom(array $array, int $num = 1):
int|string|array {}
}

interface RandomSourceInterface
{
public function getBytes(int $size): string;
}

class RandomXorShift128PlusSource implements RandomSourceInterface {}
class RandomMT19937Source implements RandomSourceInterface {}
class RandomLibsodiumSource implements RandomSourceInterface {}
class SecureOsSpecificSource implements RandomSourceInterface {}
```

While this is certainly an appropriate object-oriented implementation, it
raises the following concerns.

- This implementation is much more complex than the PHP built-in random
number generator implementation.

Probably, many users will continue to use `mt_srand()` / `mt_rand()` in the
future. This can lead to dangerous implementations that rely on global
state.
This RFC does not go that far, but we are considering deprecating
`mt_srand()` and `mt_rand()` in the future (much further down the road).
In order to achieve this, I believe it is necessary to implement it in a
way that does not compromise usability.

- There are interoperability problems with existing functions.

It is difficult to notice that `shuffle()`, `str_shuffle()`, and
`array_rand()` rely on dangerous internal MT states, and it becomes
difficult to fix them.

I hope this RFC will move forward. Thanks for your input.

Regards,
Go Kudo

2021年1月27日(水) 22:24 Alexandru Pătrănescu :

>
> On Tue, Jan 26, 2021 at 8:06 PM Go Kudo  wrote:
>
>> RFCs have been reorganized and radically rewritten.
>> https://wiki.php.net/rfc/object_scope_prng
>>
>> The implementation is unchanged, but the background has been explained in
>> more detail and the execution speed has been re-verified with PHP 8.1-dev.
>>
>> The proposal seems to have been received relatively positively by
>> externals, but there hasn't been much reaction. I'm unsure when I should
>> start voting on this RFC.
>>
>> Regards,
>> Go Kudo
>>
>> 2021年1月9日(土) 19:00 Go Kudo :
>>
>> > Hi internals.
>> >
>> > I think I'm ready to discuss this RFC.
>> > https://wiki.php.net/rfc/object_scope_prng
>> >
>> > Previous internals thread: https://externals.io/message/112525
>> >
>> > Now is the time to let me know what you think.
>> >
>> > Regards,
>> > Go Kudo
>> >
>>
>
> Hi  Go Kudo,
>
> The closest library I know and used when I had that need you mentioned is
> a userland implementation: https://github.com/paragonie/RandomLib,
> created by Anthony Ferrara and not maintained by Paragon Initiative
> Enterprises.
> The library is organized nicely with a Generator class that depends on
> constructor of a source for randomness. The source has just a simple method
> to obtain a specific number of bytes and that's all.
>
> I think the naming is what needs more input here. I'm thinking we can also
> have:
> - a random bytes source/generator that can be very similar with what you
> propose: an interface, multiple internal classes, allowing userland extra
> classes.
> - a random generator class that would have multiple useful methods like:
> randomInt($min, $max), randomFloat(), randomBytes($size),
> randomString($size, $possibleCharacters) etc.
>
> As for namings, calling them
> - RandomGenerator final class that accepts at constructor a
> - RandomSource interface with one method getBytes($size) implemented by
> 

Re: [PHP-DEV] Travis CI migration?

2021-02-02 Thread Matteo Beccati
Hi,

On 01/02/2021 21:15, Stanislav Malyshev wrote:
> Hi!
> 
>> Any news here?  Tomorrow PHP 7.3.27 will be tagged, likely without any
>> Travis-CI build to confirm that it's not broken on Linux.
> 
> I have however a 7.3 build here:
> https://travis-ci.com/github/smalyshev/php-src/builds/215525375 that
> looks fine.

likewise:

https://revive.beccati.com/bamboo/browse/PHP-SRC8-TESTS-897

Sorry it took a while as I broke the build script when PHP-8.0 was
branched and I hadn't had time to check and fix it.


Cheers
-- 
Matteo Beccati

Development & Consulting - http://www.beccati.com/

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