Re: [PHP-DEV] Straw poll: Naming for `*any()` and `*all()` on iterables

2020-12-21 Thread Pierre

Le 22/12/2020 à 01:48, tyson andre a écrit :

Hi Sara Golemon,


This is probably going to be a terrible idea because it involves a little magic 
but...

"iterable" is already a forbidden userspace class name since it's reserved for 
the psuedo-type which is a union of `Traversable | array`.

What if we went ahead and defined an actual (abstract-final) `iterable` class.  
The parser rules which treat `iterable` as a special type still apply, so we 
never try to match instances of class `iterable`, but what we can do is define 
methods on it.

class Iterable {
     static public function any(iterable $iter, Callable $predicate): bool { 
... }
     static public function all(iterable $iter, Callable $predicate): bool { 
... }
}

Then the API is both 100% searchable (the man page for iterable can explain 
that it's a pseudo-type AND that it has helper methods), and intuitive to 
read/write.

if (iterable::any($iter, fn($elem) => $elem === 'foo')) {

}

My objections to that are:

1. As mentioned in 
https://wiki.php.net/rfc/any_all_on_iterable_straw_poll#rejected_choices , I'd 
objected to static methods in general because it would be inconvenient to 
polyfill
 (magic such as __callStatic or disable_classes might be possible but 
inconvenient and integrate poorly with IDEs/analyzers)

 (if more than 2/3rs of php developers are in favor of more comprehensive 
functionality later on, such as none(), first(), etc.)
2. The name `iterable::any` would make it impossible to polyfill 
iterable::any()/all() in php 8.0 without using PECLS that modify the internals 
of php in unsafe ways (class_alias also forbids 'iterable' as an alias). I'd 
still prefer IterUtils/IterableUtils:: over iterable::.
3. For these reasons, I assume static methods have been fairly unpopular on 
functionality not associated with an object instance, but the main reason may 
be something else.

Also, on an off-topic note, `abstract final` is forbidden for userland classes, 
so making it have those flags would be surprising for uses of Reflection such 
as code stub generators,
but forbidding the constructor would be close enough.
Although I think `abstract final` should be allowed like it is in java,
I think RFCs that proposed allowing `abstract final` failed by a large margin 
years ago and I don't plan to reopen that.

Thanks,
- Tyson


Hello,

This is the kind of reasoning I fully support usually, I do maintain a 
few libraries for multiple PHP versions as most people in this list and 
make things easily polifyllable is something I'm sensible to.


Nevertheless, the language and its standard library has to evolve at 
some point. For enumerable objects PHP terribly lacks a complete and 
convenient API for developers. By putting those methods in the global 
namespace, you make those methods usage much less fluent for many 
developers that uses a decent IDE. It'd be a great thing to have a 
compete OO-based (interface based) API for collection methods. any() and 
all() methods are only the start, in my opinion, of much greater 
improvements in that regard, and I'd very much love to have those 
autocompleted by IDE on pretty much everything that is iterable.


That's just an opinion, I'd love to see it evolve towards an 
object-oriented API.


Regards,

Pierre

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



Re: [PHP-DEV] [RFC] Add is_list(mixed $value): bool to check for list-like arrays

2020-12-21 Thread Ben Ramsey
> On Dec 21, 2020, at 16:15, Mike Schinkel  wrote:
> 
>> On Dec 20, 2020, at 9:09 PM, Ben Ramsey  wrote:
>> 
>>> On Dec 19, 2020, at 19:43, tyson andre 
>>> wrote:
>>> 
>>> It can be useful to verify that the assumption that array keys are
>>> consecutive integers is correct, both for data that is being passed
>>> into a module or for validating data before returning it from a
>>> module. However, because it's currently inconvenient to do that, this
>>> has rarely been done in my experience.
>> 
>> I think there are some places where `is_list()` could be unintuitive to
>> those who don’t understand some of the idiosyncrasies of PHP.
>> 
>> For example, with
>> 
>>$a = ['foo', 'bar', 'baz’];
>> 
>> `is_list()` will return `true`, but if you run `$a` through `asort()`,
>> `is_list()` will return `false` because the keys are no longer
>> consecutive integers, but is there any doubt this is still a list?
>> Maybe in a pure sense, it’s not, but I think this could be confusing.
>> 
>> But now, if we do
>> 
>>$b = array_merge($a, ['qux', 'quux']);
>> 
>> `$b` is now back to being a list, so `is_list($b)` returns `true`.
>> 
>> While I understand the convenience `is_list()` provides--I myself have
>> implemented the opposite of this numerous times (e.g.,
>> `is_dict()`)--it comes close to implying a data type that PHP doesn’t
>> have, and I think this could give a false sense of type-safety-ness
>> when using this function to check whether something is a 0-indexed
>> array.
>> 
>> Cheers,
>> Ben
>> 
> 
> Would either is_zero_based() or is_zero_indexed() be a reasonable
> name instead?
> 
> -Mike
> 
> P.S. See https://en.wikipedia.org/wiki/Zero-based_numbering

I don’t think changing the name changes my concern, but as Tyson
pointed out:

> These idiosyncrasies of php and unintuitive behaviors existed prior
> to this RFC.

I’m generally +1 on this RFC, but as I think about it, maybe there is a
problem with the name. If we choose to introduce a pure list construct
at some point, then `is_list()` may cause confusion (or maybe it won’t,
if it can be made to return `true` for a zero-indexed, standard PHP
array *and* a `list`, whatever that might look like in the language).

Cheers,
Ben





signature.asc
Description: Message signed with OpenPGP


Re: [PHP-DEV] [RFC] Fibers

2020-12-21 Thread Mike Schinkel
> On Dec 21, 2020, at 6:53 PM, Aaron Piotrowski  wrote:
> 
>> On Dec 21, 2020, at 4:33 PM, Mike Schinkel > > wrote:
>> 
>>> On Dec 17, 2020, at 11:30 AM, 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.
>>> 
>> 
>> This is interesting, and potentially very useful.
>> 
>> I am curious about how you propose access to shared memory across fibers?  
>> What will happen if two fibers try to update a $GLOBALS variable at the same 
>> time?  Or a property of the same object?  How will developers manage that?
>> 
>> -Mike
>> 
>> P.S. Have you considered concurrency functionality like in GoLang[1] e.g. 
>> channels, where the mantra is "Do not communicate by sharing memory; 
>> instead, share memory by communicating?"
>> 
>> [1] 
>> https://medium.com/@thejasbabu/concurrency-in-go-e4a61ec96491#:~:text=Do%20not%20communicate%20by%20sharing,race%20conditions%2C%20memory%20management%20etc
>>  > not communicate by sharing,race conditions, memory management etc>.
> 
> Hi Mike,

Thanks for the reply.

> Fibers do not change the single-threaded nature of PHP. Only a single fiber 
> can be running at one time, so memory cannot be modified simultaneously. 
> There are synchronization issues when writing asynchronous code using either 
> stackless or stackful coroutines, as anyone who has worked with AMPHP or 
> ReactPHP can tell you. Multiple fibers (coroutines, green-threads, whatever 
> you want to call them) will interleave execution. 

So if I am to understand correctly, one fiber could block all others, so fiber 
code will need to be well-behaved and not block much like how Node code must 
not block when used as a web server?  If I understand correctly, no need to 
reply about this.

> Multiple interleaved fibers can change object state between pausing and 
> resuming, which I'm guessing is more to what you were concerned about, rather 
> than literal simultaneous modification that can occur with threads.

Correct.

> The RFC does not provide tools to synchronize memory access, as these can be 
> implemented in user space. 

Would it be appropriate of me to ask for a section that discusses how that 
might be done in user space in the RFC, at least with some simple pseudo-code, 
or if is it non-trivial than a link to where it is discussed in depth?  

> Fibers don't provide the entire API, just the "bare-metal" API needed to 
> implement various styles of concurrency in user space code.
> 
> AMPHP provides synchronization tools such as mutexes, semaphores, parcels, 
> and channels in https://github.com/amphp/sync  
> and https://github.com/amphp/parallel . 
> Other libraries could provide similar tools, though perhaps with a different 
> approach. We too like the Go-style of concurrency and look to emulate it in 
> AMPHP v3.

Thanks in advance.

-Mike

Re: [PHP-DEV] [RFC] Add is_list(mixed $value): bool to check for list-like arrays

2020-12-21 Thread tyson andre
Hi Ben,

> I think there are some places where `is_list()` could be unintuitive to
> those who don’t understand some of the idiosyncrasies of PHP.
> 
> For example, with
> 
>     $a = ['foo', 'bar', 'baz’];
> 
> `is_list()` will return `true`, but if you run `$a` through `asort()`,
> `is_list()` will return `false` because the keys are no longer
> consecutive integers, but is there any doubt this is still a list?
> Maybe in a pure sense, it’s not, but I think this could be confusing.
> 
> But now, if we do
> 
>     $b = array_merge($a, ['qux', 'quux']);
> 
> `$b` is now back to being a list, so `is_list($b)` returns `true`.

Yes, that's correct.
These idiosyncrasies of php and unintuitive behaviors existed
prior to this RFC.

It's also confusing when `reset($x)` is not the same thing as `$x[0]`
on a non-empty array with keys 0..n-1 out of order if you're still learning php.

> While I understand the convenience `is_list()` provides--I myself have
> implemented the opposite of this numerous times (e.g.,
> `is_dict()`)--it comes close to implying a data type that PHP doesn’t
> have, and I think this could give a false sense of type-safety-ness
> when using this function to check whether something is a 0-indexed
> array.

It would simplify `is_dict(array $x)` to `count($arr) > 0 && !is_list($arr)`,
and potentially improve performance.

There's already some ways `is_*` doesn't correspond to a data type

- `is_numeric` does not correspond to a data type.
- `is_callable` varies depending on the context where it's called for private 
methods.
- `is_resource` returns false if a resource is closed.
- `is_file` is checking for a path (and readability?) on disk, not a type.

If you do understand what the type checks are doing, it makes it easier to 
check type-safety-ness
in a script (e.g. `if(!is_list(...)){ /*warn*/ }` in a standalone script) or 
with external analyzers.

Thanks,
Tyson

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



Re: [PHP-DEV] Straw poll: Naming for `*any()` and `*all()` on iterables

2020-12-21 Thread tyson andre
Hi Sara Golemon,

> This is probably going to be a terrible idea because it involves a little 
> magic but...
>
> "iterable" is already a forbidden userspace class name since it's reserved 
> for the psuedo-type which is a union of `Traversable | array`.
>
> What if we went ahead and defined an actual (abstract-final) `iterable` 
> class.  The parser rules which treat `iterable` as a special type still 
> apply, so we never try to match instances of class `iterable`, but what we 
> can do is define methods on it.
>
> class Iterable {
>    static public function any(iterable $iter, Callable $predicate): bool { 
>... }
>    static public function all(iterable $iter, Callable $predicate): bool { 
>... }
> }
>
> Then the API is both 100% searchable (the man page for iterable can explain 
> that it's a pseudo-type AND that it has helper methods), and intuitive to 
> read/write.
>
> if (iterable::any($iter, fn($elem) => $elem === 'foo')) {
>
> }

My objections to that are:

1. As mentioned in 
https://wiki.php.net/rfc/any_all_on_iterable_straw_poll#rejected_choices , I'd 
objected to static methods in general because it would be inconvenient to 
polyfill
(magic such as __callStatic or disable_classes might be possible but 
inconvenient and integrate poorly with IDEs/analyzers)

(if more than 2/3rs of php developers are in favor of more comprehensive 
functionality later on, such as none(), first(), etc.)
2. The name `iterable::any` would make it impossible to polyfill 
iterable::any()/all() in php 8.0 without using PECLS that modify the internals 
of php in unsafe ways (class_alias also forbids 'iterable' as an alias). I'd 
still prefer IterUtils/IterableUtils:: over iterable::.
3. For these reasons, I assume static methods have been fairly unpopular on 
functionality not associated with an object instance, but the main reason may 
be something else.

Also, on an off-topic note, `abstract final` is forbidden for userland classes, 
so making it have those flags would be surprising for uses of Reflection such 
as code stub generators,
but forbidding the constructor would be close enough.
Although I think `abstract final` should be allowed like it is in java,
I think RFCs that proposed allowing `abstract final` failed by a large margin 
years ago and I don't plan to reopen that.

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



Re: [PHP-DEV] [RFC] Fibers

2020-12-21 Thread tyson andre
Hi Mike Schinkel,

> This is interesting, and potentially very useful.
> 
> I am curious about how you propose access to shared memory across fibers?  
> What will happen if two fibers try to update a $GLOBALS variable at the same 
> time?  Or a property of the same object?  How will developers manage that?

(I started writing this before Aaron sent a different response)

[Concurrency is not parallelism](text of https://blog.golang.org/waza-talk , 
not the video),
and this RFC isn't adding parallelism to php.
Instead, the RFC is a proposal to make concurrency easier.
The rfc announcement email says that "fibers exist within a single thread".
A fiber would have to explicitly release control to the scheduler after 
modifying a $GLOBALS variable, etc.

As I understand it, this proposal is similar to how concurrency works in node 
for code written in JS - 
https://stackoverflow.com/questions/29977049/how-does-concurrency-work-in-nodejs
(in that there's only one thread, but it's different in that scheduling is done 
manually)

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



Re: [PHP-DEV] [RFC] Fibers

2020-12-21 Thread Aaron Piotrowski

> On Dec 21, 2020, at 4:33 PM, Mike Schinkel  wrote:
> 
>> On Dec 17, 2020, at 11:30 AM, 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.
>> 
> 
> This is interesting, and potentially very useful.
> 
> I am curious about how you propose access to shared memory across fibers?  
> What will happen if two fibers try to update a $GLOBALS variable at the same 
> time?  Or a property of the same object?  How will developers manage that?
> 
> -Mike
> 
> P.S. Have you considered concurrency functionality like in GoLang[1] e.g. 
> channels, where the mantra is "Do not communicate by sharing memory; instead, 
> share memory by communicating?"
> 
> [1] 
> https://medium.com/@thejasbabu/concurrency-in-go-e4a61ec96491#:~:text=Do%20not%20communicate%20by%20sharing,race%20conditions%2C%20memory%20management%20etc
>  
> .

Hi Mike,

Fibers do not change the single-threaded nature of PHP. Only a single fiber can 
be running at one time, so memory cannot be modified simultaneously.

There are synchronization issues when writing asynchronous code using either 
stackless or stackful coroutines, as anyone who has worked with AMPHP or 
ReactPHP can tell you. Multiple fibers (coroutines, green-threads, whatever you 
want to call them) will interleave execution. Multiple interleaved fibers can 
change object state between pausing and resuming, which I'm guessing is more to 
what you were concerned about, rather than literal simultaneous modification 
that can occur with threads. The RFC does not provide tools to synchronize 
memory access, as these can be implemented in user space. Fibers don't provide 
the entire API, just the "bare-metal" API needed to implement various styles of 
concurrency in user space code.

AMPHP provides synchronization tools such as mutexes, semaphores, parcels, and 
channels in https://github.com/amphp/sync  and 
https://github.com/amphp/parallel . Other 
libraries could provide similar tools, though perhaps with a different 
approach. We too like the Go-style of concurrency and look to emulate it in 
AMPHP v3.

Cheers,
Aaron Piotrowski



Re: [PHP-DEV] [RFC] Fibers

2020-12-21 Thread Mike Schinkel
> On Dec 17, 2020, at 11:30 AM, 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.
> 

This is interesting, and potentially very useful.

I am curious about how you propose access to shared memory across fibers?  What 
will happen if two fibers try to update a $GLOBALS variable at the same time?  
Or a property of the same object?  How will developers manage that?

-Mike

P.S. Have you considered concurrency functionality like in GoLang[1] e.g. 
channels, where the mantra is "Do not communicate by sharing memory; instead, 
share memory by communicating?"

[1] 
https://medium.com/@thejasbabu/concurrency-in-go-e4a61ec96491#:~:text=Do%20not%20communicate%20by%20sharing,race%20conditions%2C%20memory%20management%20etc.

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



Re: [PHP-DEV] [RFC] Short-match

2020-12-21 Thread Mike Schinkel



> On Dec 16, 2020, at 12:49 PM, Ben Ramsey  wrote:
> 
>> On Dec 16, 2020, at 10:54, Mike Schinkel  wrote:
>> 
>> If we allow "switch {...}" to represent  "switch (true){...}" then the value 
>> switch compares will be hidden and less obvious to a developer if they are 
>> forgetting to consider switch's evaluation behavior. For some people this 
>> would increase the WTF factor.
> 
> How does `"switch (true){...}"` cause less surprise than `"switch {...}”` for 
> loose comparisons? IMO, seeing the boolean value `true` causes more 
> confusion, since it matches any truthy value but the constant value in the 
> expression is a bool.

I believe I must have worded it such that you misunderstood what I was writing.

In fact, what you wrote is the point I was trying to get across.  Sorry for my 
poor phrasing.

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



Re: [PHP-DEV] [RFC] Add is_list(mixed $value): bool to check for list-like arrays

2020-12-21 Thread Mike Schinkel
> On Dec 20, 2020, at 9:09 PM, Ben Ramsey  wrote:
> 
>> On Dec 19, 2020, at 19:43, tyson andre 
>> wrote:
>> 
>> It can be useful to verify that the assumption that array keys are
>> consecutive integers is correct, both for data that is being passed
>> into a module or for validating data before returning it from a
>> module. However, because it's currently inconvenient to do that, this
>> has rarely been done in my experience.
> 
> I think there are some places where `is_list()` could be unintuitive to
> those who don’t understand some of the idiosyncrasies of PHP.
> 
> For example, with
> 
>$a = ['foo', 'bar', 'baz’];
> 
> `is_list()` will return `true`, but if you run `$a` through `asort()`,
> `is_list()` will return `false` because the keys are no longer
> consecutive integers, but is there any doubt this is still a list?
> Maybe in a pure sense, it’s not, but I think this could be confusing.
> 
> But now, if we do
> 
>$b = array_merge($a, ['qux', 'quux']);
> 
> `$b` is now back to being a list, so `is_list($b)` returns `true`.
> 
> While I understand the convenience `is_list()` provides--I myself have
> implemented the opposite of this numerous times (e.g.,
> `is_dict()`)--it comes close to implying a data type that PHP doesn’t
> have, and I think this could give a false sense of type-safety-ness
> when using this function to check whether something is a 0-indexed
> array.
> 
> Cheers,
> Ben
> 

Would either is_zero_based() or is_zero_indexed() be a reasonable name instead?

-Mike

P.S. See https://en.wikipedia.org/wiki/Zero-based_numbering 




Re: [PHP-DEV] Follow up on Octal literal RFC

2020-12-21 Thread G. P. B.
On Mon, 21 Dec 2020 at 19:36, G. P. B.  wrote:

> Now, onto the weird special case, which looks like a bug in the
> implementation of base_convert() as
> var_dump(base_convert('O', 8, 10));
> Will emit the following deprecation warning (but only if the starting base
> is 8):
> Deprecated: Invalid characters passed for attempted conversion, these have
> been ignored in %s on line %d
> string(1) "0"
> But when using octdec() it doesn't.
>

Correction, this is not the case. I was mistakenly using 'O' (capital o
instead of zero) in the test case.
This does not emit a deprecation notice.

Best regards,

George P. Banyard


[PHP-DEV] Follow up on Octal literal RFC

2020-12-21 Thread G. P. B.
Hello internals,

The implementation for the RFC still hasn't landed due to some helpful
remarks made by Tyson Andre.

The issues lie not with the core functionality itself but how to amend
extensions which have a notion of numeric string literals.  I have added
test cases for the extension but some of the behaviour is rather
surprising.  I'll try to detail them below, but they are all hopefully
covered with a test case in my PR. [1]

GMP:
According to the GMP extension the following strings are valid numbers:
var_dump(gmp_init('0x'));
var_dump(gmp_init('0X'));
var_dump(gmp_init('0b'));
var_dump(gmp_init('0B'));
all evaluate to 0, but
var_dump(gmp_init(''))
Is not and will throw a TypeError.

Filter:
According to the filter extension the following strings are valid numbers
var_dump(filter_var('0x', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX));
var_dump(filter_var('0X', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_HEX));
and evaluate to 0, but, the following octals
var_dump(filter_var('O', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL));
var_dump(filter_var('', FILTER_VALIDATE_INT, FILTER_FLAG_ALLOW_OCTAL));
Are invalid and will evaluate to false, the case '0' is debatable if it
should be considered a valid integer, but the following case is also
invalid according to the filter extension:
var_dump(filter_var("010", FILTER_VALIDATE_INT));
As it is interpreted as an octal number and not decimal.

Base conversion functions in standard math lib:
We'll be looking at base_convert() as it exhibits the same behaviour than
bindec(), octdec(), and hexdec() (except for one case which will be covered
later)
// Binary to decimal:
var_dump(base_convert('0b', 2, 10));
var_dump(base_convert('0B', 2, 10));
var_dump(base_convert('', 2, 10));
// Octal to decimal:
var_dump(base_convert('0o', 8, 10));
var_dump(base_convert('0O', 8, 10));
var_dump(base_convert('', 8, 10));
// Hexadecimal to decimal
var_dump(base_convert('0x', 16, 10));
var_dump(base_convert('0X', 16, 10));
var_dump(base_convert('', 16, 10));
These all evaluate to 0 (for base_convert it will be a string and thus "0",
for the explicit functions it will return an integer).

Now, onto the weird special case, which looks like a bug in the
implementation of base_convert() as
var_dump(base_convert('O', 8, 10));
Will emit the following deprecation warning (but only if the starting base
is 8):
Deprecated: Invalid characters passed for attempted conversion, these have
been ignored in %s on line %d
string(1) "0"
But when using octdec() it doesn't.


As you can see, the behaviour is rather suboptimal and inconsistent. I can
see a couple of ways on how to handle this:

   1. Make the octal prefix behave according to the respective extension,
   thus no BC, but more surprising results.
   2. Make the octal prefix behaviour of GMP and filter extension sane (as
   base_convert and co, already supports it) and leave the current behaviour
   for Hex (and Binary for GMP)
   3. Same as 2, but warn for these edge cases such that we can error out
   in PHP 9
   4. Make BC break in PHP 8.1, and remove all the edge cases for GMP and
   the Filter extension, what to do with base_convert() and co would still be
   up to debate.
   5. Something else?


On top of this, I wonder if for the filter extension if we should be adding
the following flags: FILTER_FLAG_ALLOW_EXPLICIT_OCTAL and
FILTER_FLAG_ALLOW_IMPLICIT_OCTAL to remove ambiguity and deprecate later
the usage of FILTER_FLAG_ALLOW_OCTAL without at least one of the above two
flags. (one could also add a flag to allow leading 0 for decimal numbers.)

Hope to hear your thoughts about this.

Best regards,

George P. Banyard

[1] https://github.com/php/php-src/pull/6360


Re: [PHP-DEV] Straw poll: Naming for `*any()` and `*all()` on iterables

2020-12-21 Thread Sara Golemon
On Sat, Dec 19, 2020 at 2:24 PM tyson andre 
wrote:

> I've created a straw poll for the naming pattern to use for `*any()` and
> `*all()` on iterables.
> https://wiki.php.net/rfc/any_all_on_iterable_straw_poll
>
>
This is probably going to be a terrible idea because it involves a little
magic but...

"iterable" is already a forbidden userspace class name since it's reserved
for the psuedo-type which is a union of `Traversable | array`.

What if we went ahead and defined an actual (abstract-final) `iterable`
class.  The parser rules which treat `iterable` as a special type still
apply, so we never try to match instances of class `iterable`, but what we
can do is define methods on it.

class Iterable {
static public function any(iterable $iter, Callable $predicate): bool {
... }
static public function all(iterable $iter, Callable $predicate): bool {
... }
}

Then the API is both 100% searchable (the man page for iterable can explain
that it's a pseudo-type AND that it has helper methods), and intuitive to
read/write.

if (iterable::any($iter, fn($elem) => $elem === 'foo')) {

}


Re: [PHP-DEV] Re: Straw poll: Naming for `*any()` and `*all()` on iterables

2020-12-21 Thread Larry Garfield
On Sun, Dec 20, 2020, at 5:56 PM, tyson andre wrote:
> Hi Mark Randall,
> 
> > These functions make sense. However I think we need to give renewed 
> > consideration to:
> > 
> > $itr->all();
> > $itr->some(...);
> 
> That wouldn't help for arrays, which would be the most common use case 
> - I don't remember seeing an RFC for 
> https://github.com/nikic/scalar_objects and that is a much larger 
> language change.
> 
> This also wouldn't help if I wanted something that could be used on any 
> Traversable.
> Currently, there's no support for default methods for interfaces such 
> as Iterator/IteratorAggregate - I think I saw some discussion of that.
> (e.g. to check for any()/all() on generators, user-defined classes, etc)
> Backwards compatibility of method signatures with the same names that 
> were written before default methods were added would be a concern, 
> though.
> (https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html)

Related: I am planning to get back to the pipe operator at some point during 
the 8.1 cycle; right now the only blocker is finishing the partial function 
application RFC (which is partially completed, no pun intended, but currently 
lagging due to lack of time; Ilija was working on it but is focused on enums at 
the moment).  Assuming pipe passes (since the feedback was quite positive last 
time with the caveat of wanting partials first), that would open up the 
potential for functions that return iterator-expecting functions to be used in 
pipes.  To wit:

function i_map(callable $fn): callable {
  return function (iterable $list) use ($fn) {
foreach ($list as $k => $v) {
  yield $fn($v, $k);
}
  }
}

$any_iterable |> i_map($some_callable) |> i_filter($other_callable) |> 
any($boolean_check);

That would obviate the need to have proper methods on iterables as the 
combination of |> and higher order functions gives a similarly chainable syntax 
without the need to think about what objects have what methods on them at 
compile time.

It's not perfect, but I think it's a good solution to a long-standing 
challenge.  (Whether or not such higher order functions belong in the standard 
lib is debatable; it probably depends on what the performance difference is.)

--Larry Garfield

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



Re: [PHP-DEV] [RFC] [Discussion] Measuring maximum execution time based on wall-time

2020-12-21 Thread Máté Kocsis
Hi Rowan and Peter,

Tangentially, can this be considered a bug in FPM's handling? I appreciate
> the speed boost FPM brought over CGI, but the more I work with it the less
> I like the way it functions (but that is a separate conversation).
>

No, I don't think so, since FPM terminates the child process by sending a
SIGTERM (rather
than a SIGKILL), it seems that it does the right thing based on the source
code. But I'd
appreciate it if someone more familiar with FPM or process management could
verify
my assumptions.

 Actually, this may be part of the confusion: I'm not sure what you're
> referring to by "distributed systems", so don't know whether I'm
> included in the set of developers you're picturing here.


My definition of "distributed system" is when there is a network boundary
between components of an application. Practically speaking, this is the case
when the application code and the database/cache/sessions etc. are on
different servers.

So, again, it comes down to whether this is a "last resort" setting, or
> something you'd expect to be invoked regularly.


Yes, I certainly imagine it as a last resort possibility which could
supersede
FPM's "request_terminate_timeout" or the other external timeout
mechanisms that are currently in use. In fact, "max_execution_wall_timeout"
is not effective alone, it has to be used in cooperation with other timeout
settings either on the caller (PHP) or the callee (e.g. database) side,
since external
calls cannot be cancelled midway by PHP. That said, setting cURL, socket
etc.
timeouts is still highly encouraged as a regular countermeasure. My purpose
with
this RFC is to improve the last safety net we have (real execution
timeout), which I find
suboptimal in its current form.

You missed the key part of the quote you replied to here, which is
> "return partial results". My point was not about the *formatting* of the
> error, but that its *content* might need to be application-specific.


Ah, sorry, I did really miss it! I think my answer still holds though: if
there is such a requirement, developers can ignore this ini setting (or
explicitly set its
value to 0, if necessary). Probably this is a good example why we should
not make
wall-clock time based measurement the default of "max_execution_time".
Otherwise,
I think my proposal would offer a solution for the 90% of the problems
we currently
have due to the way how "max_execution_time" works.

It might be useful to expand on this in the RFC, remembering that
> "RSHUTDOWN" doesn't mean anything to a userland developer. Will
> "finally" blocks be run? Destructors? Will the error handler be invoked?
> I know the answers are probably "the same as the current timeout
> setting", but spelling it out would help to picture when this feature
> might or might not be useful.


I absolutely agree, and I'll try to elaborate as soon as I touch the RFC
again, most probably
today. Your answer is true, it is "the same as the current timeout
setting". However, I was
considering the possibility to throw an exception in case of the new
timeout, but I think
this task would be more suitable for a PHP 9.0 release where we could
convert fatal errors
to exceptions where it would make sense.

Máté


Re: [PHP-DEV] [RFC] [Discussion] Measuring maximum execution time based on wall-time

2020-12-21 Thread Peter Bowyer
On Fri, 18 Dec 2020 at 16:43, Máté Kocsis  wrote:

> Also, please
> be aware that the timeout is a clean shutdown
> mechanism, so shutdown handlers and the already
> mentioned RSHUTDOWN functions are triggered. On the other hand, fpm's
> timeout doesn't invoke any of them.
>

Tangentially, can this be considered a bug in FPM's handling? I appreciate
the speed boost FPM brought over CGI, but the more I work with it the less
I like the way it functions (but that is a separate conversation).

Peter