[PHP-DEV] Re: Character range syntax ".." for character masks

2022-07-29 Thread Guilliam Xavier
On Fri, Jul 29, 2022 at 7:15 AM mickmackusa  wrote:

>
>
> On Monday, July 25, 2022, Guilliam Xavier 
> wrote:
>
>> On Sat, Jul 9, 2022 at 1:56 AM mickmackusa  wrote:
>>
>>> I've discovered that several native string functions offer a character
>>> mask
>>> as a parameter.
>>>
>>> I've laid out my observations at
>>> https://stackoverflow.com/q/72865138/2943403
>>>
>>
>> Out of curiosity, why do you say that strtr() is "not a good candidate
>> because character order matters" (although you give a reasonable example)?
>> Maybe you have some counter-example?
>>
>> Regards,
>>
>> --
>> Guilliam Xavier
>>
>
> I prefer to keep my scope very tight when posting on Stack Overflow.
>
> My focus was purely on enabling character range syntax for native
> functions with character mask parameters.  My understanding of character
> masks in PHP requires single-byte characters and no meaning to character
> order.
>
> When strtr() is fed two strings, they cannot be considered "character
> masks" because the character orders matter.
>
> If extending character range syntax to parameters which are not character
> masks, I might support the feature for strtr(), but ensuring that the two
> strings are balanced will be made more difficult with ranged syntax.
> strtr() will silently condone imbalanced strings.  https://3v4l.org/PY15F
>

Thanks for the clarifications. You're right that the internal
`php_charmask` converts a character list (possibly containing one or more
ranges) into a 256-char *mask*, thus "losing" any original order; so
strtr() actually couldn't use the same implementation (even without
ranges), and a counter-example is `strtr('adobe', 'abcde', 'ebcda')`
(`strtr('adobe', 'a..e', 'e..a')` would trigger a Warning "Invalid
'..'-range, '..'-range needs to be incrementing").

I had seen a parallel with the Unix `tr` command, which *does* support
[incrementing] ranges (e.g. both `echo adobe | tr abcde ABCDE` and `echo
adobe | tr a-e A-E` give "ADoBE", while `echo adobe | tr abcde edcba` gives
"eboda" but `echo adobe | tr a-e e-a` errors "range-endpoints of 'e-a' are
in reverse collating sequence order"), but its implementation doesn't use
character masks indeed (
https://github.com/coreutils/coreutils/blob/master/src/tr.c), and `echo
abracadabra | tr a-f x` gives "xxrxxrx" not "xbrxcxdxbrx"; and it also
supports more things like POSIX character classes...

PS: I find the `strtr(string $string, array $replace_pairs)` form generally
superior to the `strtr(string $string, string $from, string $to)` one
anyway ;)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Character range syntax ".." for character masks

2022-07-25 Thread Guilliam Xavier
On Sat, Jul 9, 2022 at 1:56 AM mickmackusa  wrote:

> I've discovered that several native string functions offer a character mask
> as a parameter.
>
> I've laid out my observations at
> https://stackoverflow.com/q/72865138/2943403
>

Out of curiosity, why do you say that strtr() is "not a good candidate
because character order matters" (although you give a reasonable example)?
Maybe you have some counter-example?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [VOTE] Random Extension Improvement

2022-07-18 Thread Guilliam Xavier
> For example, what about the `$binaryString` argument name?

I would recommend to either keep `$string` (conservative) or rename it
to `$bytes` (consistent with the new function name) [I interpret the
RFCs as the former, but the implementation is currently as the
latter].

About your other mail, I too like the idea to split `getInt(int $min =
UNKNOWN, int $max = UNKNOWN)` into distinct `nextInt()` and
`getInt(int $min, int $max)` [in a subsequent PR, IIUC].

Regards,

--
Guilliam Xavier

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



Re: [PHP-DEV] [VOTE] Random Extension Improvement

2022-07-13 Thread Guilliam Xavier
On Thursday, July 14, 2022, Go Kudo  wrote:

> 2022年7月13日(水) 1:10 Tim Düsterhus :
>
>> Hi
>>
>> On 7/12/22 18:04, Tim Düsterhus wrote:
>> > I also think that both '$string' and '$binary' are appropriate parameter
>> > names in this case, so particular preference from my side.
>>
>> Sorry for the follow-up, there's two mistakes in that sentence. It
>> should read:
>>
>> I also think that both '$string' and **'$bytes'** are appropriate
>> parameter names in this case, so **no** particular preference from my
>> side.
>>
>> Best regards
>> Tim Düsterhus
>>
>
> Hi
>
> I agree with you. I will change the parameter name from `$string` to
> `$bytes` as I don't see any problem.
>
> I will try to explain the changes more rigorously in future proposals.
> Thank you.
>
> Regards,
> Go Kudo
>

Hi,

I was waiting for more opinions but... so here's mine:

I would prefer to keep "$string", as [that's how I read the RFCs, and] when
calling e.g. shuffleBytes('foobar') I don't feel like I'm passing "bytes"
(or "a binary") but a string (to be shuffled byte-wise rather than
character-wise or codepoint-wise, but that's from the function, not the
argument)...
Granted, not compelling, and probably won't matter in practice, but hey ;)

Regards

PS: sent from mobile


-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [VOTE] Random Extension Improvement

2022-07-12 Thread Guilliam Xavier
> > https://wiki.php.net/rfc/random_extension_improvement
>
> Hi Internals.
>
> Currently, the renaming of Randomizer::shuffleString() to
> Randomizer::shuffleBytes() seems acceptable.
>
> I forgot to note the change regarding arguments when I submitted this RFC.
> With this change, the argument was supposed to be changed from `string
> $string` to `string $bytes`.
>
> - https://github.com/php/php-src/pull/8094#discussion_r916630626

For reference, first was
https://github.com/php/php-src/pull/8094/commits/32e83a71eae67fdd822fd12ded5a8c054024a4da#r916058794

> Is this change acceptable? Or should I keep `string $string`?

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



Re: [PHP-DEV] [RFC] Short Closures 2, aka auto-capture take 3

2022-07-01 Thread Guilliam Xavier
On Thu, Jun 30, 2022 at 7:37 PM Arnaud Le Blanc  wrote:
>
> On jeudi 30 juin 2022 18:29:44 CEST Guilliam Xavier wrote:
> > Ah? Sorry, I had interpreted
> > https://github.com/php/php-src/pull/8330/files#diff-85701127596aca0e597bd796
> > 1b5d59cdde4f6bb3e2a109a22be859ab7568b4d2R7318-R7320 as "capture the
> > *minimal* set of variables for *both* arrow functions and short closures",
> > but I was wrong?
>
> No, you are right, the PR changes arrow functions too. But in the RFC we
> decided to not touch the arrow functions for now.

Ah, I see that you have updated the PR indeed:
https://github.com/php/php-src/pull/8330/commits/5bb0a1c8d032666079db5dab94b4b22b2afa9dac
(and thanks for the test).

PS: so the link I gave before is now outdated ^^' I should have given
https://github.com/php/php-src/pull/8330/commits/9dec265adba44dcf9d2cadc05dd5ad842fc4ae66#diff-85701127596aca0e597bd7961b5d59cdde4f6bb3e2a109a22be859ab7568b4d2R7318-R7320

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] Short Closures 2, aka auto-capture take 3

2022-06-30 Thread Guilliam Xavier
On Thu, Jun 30, 2022 at 5:57 PM Arnaud Le Blanc  wrote:
>
> Hi,
>
> On jeudi 30 juin 2022 16:18:44 CEST Robert Landers wrote:
> > Are
> > optimizations going to be applied to single-line arrow functions (I
> > didn't see that in the RFC, but I admittedly didn't look that hard and
> > I vaguely remember reading something about it in one of these
> > threads)? If so, it will probably change some behaviors in existing
> > applications if they were relying on it. Perhaps static analysis tools
> > can detect this and inform the developer.
>
> It is not planned to change the behavior of arrow functions in this RFC. This
> optimization is less important for arrow functions because they don't usually
> assign variables.

Ah? Sorry, I had interpreted
https://github.com/php/php-src/pull/8330/files#diff-85701127596aca0e597bd7961b5d59cdde4f6bb3e2a109a22be859ab7568b4d2R7318-R7320
as "capture the *minimal* set of variables for *both* arrow functions
and short closures", but I was wrong?

I don't see a test like this:

```php
class C {
public function __destruct() { echo 'destructed', PHP_EOL; }
}
$x = new C();
$fn = fn ($a, $b) => (($x = $a ** 2) + ($y = $b ** 2)) * ($x - $y);
echo '- unsetting $x', PHP_EOL;
unset($x);
echo '- calling $fn', PHP_EOL;
var_dump($fn(3, 2));
echo '- unsetting $fn', PHP_EOL;
unset($fn);
echo '- DONE.', PHP_EOL;
```

with current output (https://3v4l.org/ve3BL#v8.1.7):

```
- unsetting $x
- calling $fn
int(65)
- unsetting $fn
destructed
- DONE.
```

where the optimization would make the "destructed" line move up to
just after "- unsetting $x"

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] Short Closures 2, aka auto-capture take 3

2022-06-30 Thread Guilliam Xavier
On Thu, Jun 30, 2022 at 3:26 PM Dan Ackroyd  wrote:
>
> Hi Rowan,
>
> Rowan wrote:
> > For that to work, it would require the variable to be captured by
> > reference, not value.
> > ...
> > The only way for it to work would be using capture by reference (not
> > supported by the proposed short syntax):
>
> I wrote about this before. Some of the words in the RFC are, in my
> opinion, quite inaccurate:
>
> Danack wrote in https://news-web.php.net/php.internals/117938 :
> > Those statements are true for scalar values. They are not true for objects:

But the RFC has been updated since (notably the DateTime example); do
you find the current wording still inaccurate?

> With automatic capturing of variables, for the code example I gave the
> user would want the variable to be captured, and to them it looks like
> it should be, but because of an optimization it is not.

Am I missing something here? To me, it has been explained (and shown)
by Rowan (and me) that the code example you gave would *not* work as
expected *even without the optimization* (for it to work it would need
to either capture by *reference*, or use e.g.
`$some_resource->close();` [or `close($some_resource);`] instead of a
destructor); but maybe we don't "expect" the same behavior in the
first place?

> When the code doesn't work as they expect it to, the programmer is
> likely to add a var_dump to try to see what is happening. Which makes
> it look like their code 'should' work, as their resource object is
> still alive.

This indeed seems a valid point (that adding a
`var_dump($some_resource);` before the `$some_resource = null;`
changes it from "not captured" to "captured", with an effect on its
lifetime). But are there "real" cases where it would *actually*
matter?

> > In fact, the "optimisation" is in my opinion a critical part of the
> > semantics, to avoid the opposite problem:
>
> As I said, I think that problem is a lot easier to explain "either use
> long closures or change your variable name if you don't want it
> captured." than trying to explain "yes, the variable is referenced
> inside the closure, but it's not captured because you aren't reading
> from it".

Same as above.


On Thu, Jun 30, 2022 at 4:19 PM Robert Landers  wrote:
>
> Rowan wrote:
> > No, the captured value is tied to the lifetime of the closure itself,
> not the variable inside the closure.
>
> With the "optimization," it won't be captured at all by the closure,
> possibly causing some resources to go out of scope early.

And it has been explained that conversely, capturing it would possible
cause some resources to "remain in scope" late.

> Are
> optimizations going to be applied to single-line arrow functions (I
> didn't see that in the RFC, but I admittedly didn't look that hard and
> I vaguely remember reading something about it in one of these
> threads)?

Seems so: 
https://github.com/php/php-src/pull/8330/files#diff-85701127596aca0e597bd7961b5d59cdde4f6bb3e2a109a22be859ab7568b4d2R7318-R7320

> If so, it will probably change some behaviors in existing
> applications if they were relying on it. Perhaps static analysis tools
> can detect this and inform the developer.

Here too, do you have a "real" case where it would *actually* matter?

> Here's Dan's code: https://3v4l.org/99XUN#v8.1.7 that he just sent,
> modified to not capture the $some_resource and you can see that it is
> indeed released earlier than if it were captured.

And here it is "un-modified": https://3v4l.org/gZai2 where you see
that calling $fn() (which internally nullifies *its local copy of*
$some_resource) does *not* release; is it really what you expect? are
you creating the closure only to extend the lifetime of
$some_resource?


Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] Short Closures 2, aka auto-capture take 3

2022-06-30 Thread Guilliam Xavier
On Thu, Jun 30, 2022 at 11:20 AM Robert Landers
 wrote:
>
> On Thu, Jun 30, 2022 at 10:19 AM Rowan Tommins  
> wrote:
> >
> > On 29/06/2022 23:31, Dan Ackroyd wrote:
> > > Imagine some code that looks like this:
> > >
> > > // Acquire some resource e.g. an exclusive lock.
> > > $some_resource = acquire_some_resource();
> > >
> > > $fn = fn () {
> > >  // Free that resource
> > >  $some_resource = null;
> > > }
> > >
> > > // do some stuff that assumes the exclusive
> > > // lock is still active.
> > >
> > > // call the callback that we 'know' frees the resource
> > > $fn();
> > >
> > > That's a not unreasonable piece of code to write
> >
> >
> > For that to work, it would require the variable to be captured by
> > reference, not value. Writing to a variable captured by value, like
> > writing to a parameter passed by value, is just writing to a local variable.
> >
> >
> > In fact, the "optimisation" is in my opinion a critical part of the
> > semantics, to avoid the opposite problem:
> >
> > // Acquire some resource e.g. an exclusive lock.
> > $some_resource = acquire_some_resource();
> >
> > $fn = fn () {
> >  // Use a variable that happens to have the same name
> >  // A naive implementation would see $some_resource mentioned, and
> > capture it
> >  // Over-writing the local variable here makes no difference; the
> > closure still holds the value for next time
> >  $some_resource = 'hello';
> > }
> >
> > // Free what we believe is the last pointer, to trigger the destructor
> > unset($some_resource);
> >
> > // If $some_resource gets captured, it can only be released by
> > destroying the closure
> > unset($fn);
> >
> >
> > Regards,
> >
> > --
> > Rowan Tommins
> > [IMSoP]
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: https://www.php.net/unsub.php
> >
>
> > For that to work, it would require the variable to be captured by
> > reference, not value.
>
> I think their suggested code would work (at least currently in PHP) by
> the simple fact they would increase the reference count on that
> object/resource until they set it as null. However, with the
> "optimization," the reference count will never be incremented and thus
> fail to work as defined.
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

No offense, but why don't you just try it? Please see equivalents of:
  - Dan's code: https://3v4l.org/51jXY => doesn't "work"
  - Dan's code with capture by reference (as said by Rowan):
https://3v4l.org/JoUVi => "works"
  - Rowan's code: https://3v4l.org/7ZVv3 => shows the "problem" with capture

PS: I see that Rowan just replied with refcount explanations. I agree
(but am sending this anyway)

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] Exception type hint

2022-06-29 Thread Guilliam Xavier
Hi (note: your message was flagged as spam),

> https://github.com/php/php-src/issues/8843

So I understand it as having a "true code" equivalent for the
`@throws` phpDoc comment (similar to type declarations for `@param`
and `@return`)? which would also be checked at run-time?

Just my 2 cents on that (let's call it "exception specification"):

  1. IMHO, it shouldn't be mixed in the return type declaration (with
a union-like syntax) but separated and independent (e.g. with a
`throws` keyword, and pipes [or commas] between multiple exception
classes)
  2. AFAIK, Java has it (mandatory to compile for "checked
exceptions", sometimes controversial), C++ used to have it
(runtime-checked) but dropped it (and introduced `noexcept` instead);
I don't know of any dynamic language that has it

You would also need to define how it plays with inheritance (and
reflection), and what exactly should happen when a function throws an
exception it didn't "declare"...

PS: I also found some old feature requests:
  - https://externals.io/message/4424
  - https://bugs.php.net/bug.php?id=42251
  - https://bugs.php.net/bug.php?id=62404
  - https://bugs.php.net/bug.php?id=67312

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] [Under Discussion] Random Extension Improvement

2022-06-29 Thread Guilliam Xavier
>> > https://wiki.php.net/rfc/random_extension_improvement
>>
>> I just realized a little thing: in the array_rand() example, for
>> $beforeSingle, it would probably be "more realistic" to omit `, 1`
>> (which is already the default for $num).
>>
>> Note: for `Randomizer::pickArrayKeys(array $array, int $num): array`,
>> it makes sense that $num does *not* have a default value (1 would be
>> "weird" because the method always returns a *list of keys*, and
>> count($array) [via null] would be "useless" because keys are returned
>> *in their original order* [so it would make the method equivalent to
>> array_keys($array) by default]),
>> and that's probably a good thing (it forces to update the call by
>> adding an explicit `, 1` argument and reminds to add a `[0]` or
>> similar on the returned value).
>>
>> An alternative design would be `Randomizer::pickArrayKey(array
>> $array): int|string`, but migrating existing uses with $num != 1 would
>> be harder, so probably not better.
>
> This is certainly a complicated issue.
>
> I proposed the signature `Randomizer::arrayPickKeys(array $array, int $num): 
> array` because it can be solved with the current PHP sugar syntax and the 
> default value of $num is 1 despite the name "arrayPickKeys".
>
> However, this is a bit tricky and may not be user-friendly for the average 
> user.
>
> So, how about adding two methods, `Randomizer::arrayPickKey(array $array): 
> int|string` and `Randomizer::arrayPickKeys(array $array, int $num): array`?
>
> This may seem redundant, but it may avoid user confusion.

Sorry if I wasn't clear: I just suggested to make this little change
in the example:

```diff
-$beforeSingle = array_rand(['foo' => 'foo', 'bar' => 'bar', 'baz' =>
'baz'], 1); // (string) foo
+$beforeSingle = array_rand(['foo' => 'foo', 'bar' => 'bar', 'baz' =>
'baz']); // (string) foo
```

to make it more "realistic".

As concerns the rest (about pickArrayKeys): sorry for the digression,
I was just "thinking out loud", I *don't* want any change there
(first, it makes sense that pickArrayKeys has `int $num` *without* a
default value [even if array_rand has 1]; second, "pickArrayKey" [if
really wanted] is trivial to implement in userland as a wrapper around
pickArrayKeys [but the opposite would not be so], and I don't think
that adding *both* methods to Randomizer is desirable either [better
keep it simple/minimal]).

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] [Under Discussion] Random Extension Improvement

2022-06-28 Thread Guilliam Xavier
> Hi Internals.
>
> Random Extension 5.x has been accepted by a vote of 20(+1)/0. (I made a
> mistake in timing the closing of the vote and thus received one more vote)
> Therefore, voting on the Random Extension Improvement RFC will begin on
> 2022-07-02 as scheduled.
>
> Please check the RFC. This is the last chance to improve the implementation.
>
> https://wiki.php.net/rfc/random_extension_improvement

Hi,

I just realized a little thing: in the array_rand() example, for
$beforeSingle, it would probably be "more realistic" to omit `, 1`
(which is already the default for $num).

Note: for `Randomizer::pickArrayKeys(array $array, int $num): array`,
it makes sense that $num does *not* have a default value (1 would be
"weird" because the method always returns a *list of keys*, and
count($array) [via null] would be "useless" because keys are returned
*in their original order* [so it would make the method equivalent to
array_keys($array) by default]),
and that's probably a good thing (it forces to update the call by
adding an explicit `, 1` argument and reminds to add a `[0]` or
similar on the returned value).

An alternative design would be `Randomizer::pickArrayKey(array
$array): int|string`, but migrating existing uses with $num != 1 would
be harder, so probably not better.

Regards,

--
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] [Under Discussion] Auto-implement Stringable for string backed enums

2022-06-27 Thread Guilliam Xavier
>> Symfony YAML has a `!php/const X` feature, which also works when X is
>> an Enum::CASE; how about a `!php/enum_value` feature?
>
> I submitted something similar today at 
> https://github.com/symfony/symfony/pull/46771

And I see that it has been merged ;)

>> Otherwise, I also like Rowan's suggestion of implementing "internal
>> cast handlers", so that non-strict users could call e.g.
>
> I had a look at gmp for example: cast handlers don't work when calling a 
> function.
> They do work when explicit casting and when doing loose comparisons, but they 
> don't when calling functions

Well it works for `string` at least (even though `GMP` does *not*
implement `__toString`), e.g. https://3v4l.org/cRnnW
The TypeError for `int` may be related to the fact that e.g. `+$gmp`
(or `0 + $gmp`) gives back a GMP (not an int like `(int)$gmp`)?
(But indeed I don't know much about that... nor if it could be made opt-in)

> Rowan's proposals about sets could solve this in a very nice way

Reminded me of e.g.
https://stackoverflow.com/questions/6422380/does-any-programming-language-support-defining-constraints-on-primitive-data-types
(mainly integer ranges, but the concept of "domains" looks similar)

Regards,

--
Guilliam Xavier

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



Re: [PHP-DEV] [VOTE] Stricter implicit boolean coercions

2022-06-24 Thread Guilliam Xavier
> It would have been interesting to get some more feedback on why people
> voted No - some took part in the discussion, but most didn't.

Indeed... Of those who did, I have retained the following arguments
(sorry in advance for any omission, approximation or
misinterpretation):

  - no impact analysis (but seems difficult...)
  - it would increase the discrepancy between e.g. `if ($x)` and
`takes_bool($x)` (already existing for non-scalar $x [okay VS
TypeError], but now for scalar $x too [okay VS deprecation notice])
  - the deprecation should apply to all floats (even 0.0 and 1.0)
because floating-point equality is risky
  - the deprecation should include the string "0" (VS empty "")
because it's a recurrent WTF (and maybe even in all implicit boolean
evaluations [e.g. `if`, `&&` etc.] too)
  - we should rather deprecate `takes_bool($string)` and
`takes_bool($float)` totally (i.e. all strings and floats), and also
`takes_string($bool)` and `takes_float($bool)` (but maybe don't need
to change `takes_bool($int)` at all)

Note: I think that generally there can be arguments in both ways...

> I think the RFC would have helped
> identify obvious bugs

I agree ;(

> thanks to everybody who took part in the discussion, it was an
> interesting experience.

Thank you ;)

> If anybody still wants to give some insight on these reasons or a way to
> improve boolean coercions in another way, I would be happy to hear it.

Sorry I don't have better ideas... Maybe others will?

--
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] [Under Discussion] Auto-implement Stringable for string backed enums

2022-06-23 Thread Guilliam Xavier
Hi Nicolas, thanks for the RFC,

> There are also cases where using "->value" is just not possible. I mention
> attributes in the RFC,

which also mentions
https://wiki.php.net/rfc/fetch_property_in_const_expressions (but with
"For people that use non-strict mode, this extra “->value” is
boilerplate that they'd better remove")

> but we also have a case in Symfony where defining
> service definitions in yaml doesn't work with enums because there is no way
> to express the "->value" part.

Symfony YAML has a `!php/const X` feature, which also works when X is
an Enum::CASE; how about a `!php/enum_value` feature?

Otherwise, I also like Rowan's suggestion of implementing "internal
cast handlers", so that non-strict users could call e.g.
`takes_int(IntEnum::CASE)` as well as
`takes_string(StringEnum::CASE)`; but what about
`takes_string(IntEnum::CASE)`, and
`takes_Stringable(StringEnum::CASE)`?

In any case, several people requested that it should require to be
*opted-in* explicitly; but then [for solutions other than "allowing
user-land to implement Stringable"] we probably also need a way to
test whether a BackedEnum [instance] is "coercible"?

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] Make the iterator_*() family accept all iterables

2022-06-22 Thread Guilliam Xavier
>> https://externals.io/message/117979

>> https://wiki.php.net/rfc/iterator_xyz_accept_array

> Just linking up the previous discussion around this topic:
>
> GH: https://github.com/php/php-src/pull/3293
> ML: https://externals.io/message/102313

Thanks. More discussion happened after the vote had started (as often,
sadly): https://externals.io/message/102562

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] [Under Discussion] Random Extension Improvement

2022-06-21 Thread Guilliam Xavier
On Mon, Jun 20, 2022 at 5:25 PM Christoph M. Becker  wrote:
>
> On 20.06.2022 at 16:44, Go Kudo wrote:
>
> > 2022年6月20日(月) 23:37 Lynn :
> >
> >> On Mon, Jun 20, 2022 at 3:15 PM Guilliam Xavier  >> wrote:
> >>
> >>>> https://wiki.php.net/rfc/random_extension_improvement
> >>>
> >>> Thanks, but I am not sure about your argument in "Classnames are not
> >>> canonicalized": does "PHP applies strict PascalCase to class names"
> >>> (which remains to be proved) really imply to rename *acronyms* (e.g.
> >>> "CombinedLCG" to "CombinedLcg")? especially given existing classes
> >>> like "SimpleXMLElement" (not "SimpleXmlElement"), and that the
> >>> accepted "Class Naming" RFC (https://wiki.php.net/rfc/class-naming)
> >>> voted for "PascalCase except Acronyms" (not "Always PascalCase") --
> >>> excerpts:
> >>
> >> Not specifically directed at this discussion, but perhaps this needs a
> >> revision. HTTPStatus is much harder to read for me than HttpStatus and it's
> >> unclear where the boundary of an acronym starts or stops. If anyone ever
> >> decides to make an RFC for this, you have my vote. These Acronyms are
> >> treated as words and thus should follow the same naming convention. If they
> >> shouldn't be treated as words, write their full name:
> >> HypertextTransferProtocolStatus.
> >
> > I support "PascalCase except Acronyms" for readability, but would like to
> > see this
> > clarified as I get very lost when implementing new features.
> > I think it is necessary because I expect various OO APIs will be added in
> > the future,
> > like cURL.
>
> In my opinion, <https://wiki.php.net/rfc/class-naming> was a bit
> unfortunate.  It may have been better to decide on a case by case basis.
>
> For instance, we have introduced several Curl* classes in PHP 8.0[1],
> and these adhere to the appropriate example in the RFC, although CURL is
> clearly an acronym[2], and the canonical spelling is even cURL.  Maybe
> even worse, the previously introduced CURLFile[3] uses different
> capitalization, and CURLStringFile[4] which was introduced in PHP 8.1 is
> aligned to that spelling.
>
> So, obviously, the RFC didn't have a good impact on some of the namings
> so far.

That seems unfortunate indeed :/ and there are others, e.g.
"XMLReader" but "XmlParser"... Moreover, I see that
https://github.com/php/php-src/blob/master/CODING_STANDARDS.md#user-functionsmethods-naming-conventions
item 7 only says "should", not "must".

I too find "HttpStatus" [or "HTTP_status", for that matter] more
readable than "HTTPStatus" (where I first see "HTTPS" before noticing
that the S actually starts a second word), and "PcgOneseq128XslRr64"
than "PCGOneseq128XSLRR64" (especially if not already familiar with
"PCG" and "XSL-RR")...

So, it may indeed be OK (and preferred?) to "canonicalize" the
proposed class names (just, "PHP applies strict PascalCase to class
names" wasn't a good argument for it).

PS @Go Kudo: please don't be offended, but in general, maybe you
should wait "a bit more" [or even ask] for other opinions, rather than
changing the RFC "too fast" after only one (especially when I said "I
am not sure" and asked a question)

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] [Under Discussion] Random Extension Improvement

2022-06-20 Thread Guilliam Xavier
Hi,

> https://wiki.php.net/rfc/random_extension_improvement

Thanks, but I am not sure about your argument in "Classnames are not
canonicalized": does "PHP applies strict PascalCase to class names"
(which remains to be proved) really imply to rename *acronyms* (e.g.
"CombinedLCG" to "CombinedLcg")? especially given existing classes
like "SimpleXMLElement" (not "SimpleXmlElement"), and that the
accepted "Class Naming" RFC (https://wiki.php.net/rfc/class-naming)
voted for "PascalCase except Acronyms" (not "Always PascalCase") --
excerpts:

| Abbreviations start with a capital letter followed by lowercase
letters, whereas acronyms and initialisms are written according to
their standard notation.

| Good:
| 'CurlResponse'
| 'HTTPStatusCode'

| Bad:
| 'curl_response'
| 'HttpStatusCode'

(Not that I really care but...)

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Make iterator_to_array() accept all iterables

2022-06-20 Thread Guilliam Xavier
On Fri, Jun 17, 2022 at 7:21 PM Tim Düsterhus  wrote:
>
> Hi
>
> On 6/17/22 18:06, Guilliam Xavier wrote:
> >> https://github.com/php/php-src/pull/8819
> >
> > Just so that it can't be said that it hasn't been asked: what about
> > iterator_count(), and iterator_apply()?
>
> I also came across those, while implementing the PR, but I intentionally
> did not touch them to keep the scope simple and because I think they are
> less likely to be used generally.

Okay :)

> - `iterator_apply()` is easily replaced by a foreach loop, because the
> return value is pretty useless, so it is not likely that a nested
> function call is going to be used.

Well the same could be said about `array_walk()`... but anyway :p

> - For `iterator_count()` one could to `count(iterator_to_array($foo))`
> if my proposal is merged. This come with a bit of overhead, but at least
> it's not as clunky as `is_array($foo) ? $foo : iterator_to_array($foo)`

or as `is_array($foo) ? count($foo) : iterator_count($foo)`, for that matter ;)

> If a RFC is desired, then I'd likely include all three of them with a
> vote for each, but I hope my proposal is simple enough to not require an
> RFC.

Well I won't be the one asking for an RFC ^^ (and you're right that
the `array_*` functions are far more numerous and [at least in my
experience] used than the `iterator_*` ones)

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Make iterator_to_array() accept all iterables

2022-06-17 Thread Guilliam Xavier
>https://github.com/php/php-src/pull/8819

Just so that it can't be said that it hasn't been asked: what about
iterator_count(), and iterator_apply()?

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] Short Closures 2, aka auto-capture take 3

2022-06-15 Thread Guilliam Xavier
> > > Because variables are captured by-value, Short Closures can not have
> > > unintended side effects.
> >
> > Those statements are true for scalar values. They are not true for objects:
>
> This is shown in the "No unintended side-effects" section of the RFC.

I'm confused by the last example:

$fn2 = function () use (&$a) { /* code with $a AND $b */ }

Isn't that missing a ", $b" in the `use`?

And like others, I also find that allowing mixing explicit *by-value*
capture with auto-capture is not really needed and even confusing; if
you "expect that explicitly capturing by value will be rare in
practice" you might as well forbid it?

Maybe you don't even need to add explicit [by-reference] capture to
short closures at all, but rather extend *long* closures so that we
can write things like:

$val1 = rand(); $val2 = rand(); $ref = null;
$fn1 = function () use (...) { /* do something with $val1 and $val2 */ };
$fn2 = function () use (&$ref, ...) { $ref = $val1 + $val2; };

(and even if not, at least mention in the RFC that it has been considered)?

By the way, what about *arrow* functions? e.g.

$fn = fn () use (&$ref) => $ref = $val1 + $val2; // assigns and returns

Would that be allowed? Is it really *desirable*?

Regards,

--
Guilliam Xavier

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



Re: [PHP-DEV] Adding new closing tag =?> for keeping trailing newline

2022-06-08 Thread Guilliam Xavier
> Declare statements shouldn't have any impact outside of the file in which
> they appear. Declaring strict types doesn't force other classes that
> interact with the defined class to also use strict types. A declare to
> change how newlines after closing tags are handled within a single file
> forces anything that uses the classes/functions defined in that file to
> know that it handles them in a possibly different ways.

Indeed (via includes)... Also consider this hypothetical example:

```
- 0

- 

- 4
```

Note the use of both ?> and =?> *within the same file*; a declare
would not allow that.

> I personally don't see a need for a new closing tag. I'm not usually swayed
> by the "it adds confusion to the language" and would be against removing
> such a tag if it existed and that was the reason for removing it. However,
> I do think it's something to consider when adding something new to the
> language. In this case, I don't think the positives outweigh the negatives,
> especially in light of the fact it's really easy to accomplish this without
> changes.

I personally am generally in favor of removing "magic" stuff (even if
this isn't exactly proposing that but to add a "straightforward"
alternative).

Other example, consider starting from this:

```
- first
- foo bar
- last
```

Now if you want to "variablize" the `foo` part, just change it to e.g.
``; but for `bar` you have to remember and write e.g. `` (or add a blank line after it [or a trailing
space... no, please don't]), only because it happens to be at the end
of a line (and don't forget to re-change it if you later append a
`qux`)...

PS: An[other] argument against could be something like "please don't
add more things encouraging the use of PHP as a templating engine
(unsafe etc.)", but the main target is *non*-HTML (e.g. Markdown or
raw text) templates.

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Re: Adding new closing tag =?> for keeping trailing newline

2022-06-08 Thread Guilliam Xavier
Hi,

> https://github.com/php/php-src/pull/8708

> https://www.reddit.com/r/PHP/comments/v5le6h/adding_new_closing_tag_for_keeping_trailing/

Thanks for proposing! this "feature" bothered me more than once...
Maybe just 2 days (of internals and Reddit feedback) is a bit early to
"give up" (but I won't blame you either).

FWIW, the Twig templating engine has distinct delimiters for output
({{ ... }}) and control ({% ... %}), and the former does *not* eat
newline; for the latter you can use ~%}
(https://twigfiddle.com/54daye), and there are other "whitespace
control" options
(https://twig.symfony.com/doc/3.x/templates.html#whitespace-control).

For PHP, if we could ignore BC, I would rather have ?> not eat
newline, and add an optional way to do it; but we can't, so I guess
the opposite (e.g. your =?>) is the best we could hope for.

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC][Under discussion] Fetch properties in const expressions

2022-06-03 Thread Guilliam Xavier
On Fri, Jun 3, 2022 at 3:26 PM Robert Landers  wrote:
>
> So, how does this change our mental models when writing PHP? For
> example, I generally consider `const` to be a "compile-time" constant
> (ie, generated/created before any code is actually executed). So would
> this allow code to actually execute before any other code (ie, by
> putting code in a __get()) and thus cause issues due to database
> drivers and etc to not be loaded yet -- or cause them to be loaded
> prematurely?

True but that's already the case since PHP 8.1 and
https://wiki.php.net/rfc/new_in_initializers
(https://github.com/php/php-src/pull/7153), e.g.
https://3v4l.org/MSWi0:

```
class Foo {
public function __construct() {
echo "Side effect!\n";
}
}

const C = new Foo();
```

but as https://externals.io/message/113347#113607 says,
"side-effecting constructors are a terrible idea", and same can be
said for "side-effecting [magic] getters"...

Also note that this only concerns *global* (or namespace-scoped)
constants (which can also be defined "dynamically" with `define()`),
not *class* constants.

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Re: NULL Coercion Consistency

2022-05-30 Thread Guilliam Xavier
On Mon, May 30, 2022 at 4:59 PM Rowan Tommins  wrote:
>
> The actual code in this case ended up in a generic routine that used
> isset() to choose which SQL to generate. An empty string would generate
> a WHERE clause that matched zero rows, but a null would omit the WHERE
> clause entirely, and match *all* rows. So an extra pre-validation on the
> string format might be useful for debugging, but wouldn't result in
> materially different results.

Maybe the routine could use e.g. array_key_exists() rather than
isset()? (anyway, sometimes you *actually* want isset() null behavior,
or use a null default for a parameter as a "not passed" argument...)

> That's actually an interesting observation. It's probably quite common
> to treat empty strings as null when going from input to storage; and to
> treat null as empty string when retrieving again. Importantly, databases
> generally *don't* treat them as equivalent,

Yeah, I only know Oracle to do something as... "clever" as storing an
empty VARCHAR '' as NULL (for "optimization" IIRC) -_-

> so forgetting that
> translation can be a real cause of bugs. I often advocate for string
> columns in databases to allow either null or empty string, but not both
> (by adding a check constraint), so that such bugs are caught earlier.

Same (sometimes you have no choice but allow NULL, e.g. an optional
foreign key, but the referenced primary key is not nullable and should
generally also reject '')

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [Discussion] Expand deprecation notice scope for partially supported callables

2022-05-30 Thread Guilliam Xavier
Hi Dan, just an error in this part:

> Or if support for less than PHP 8.1 can be dropped, using the first
> class callable syntax
> https://wiki.php.net/rfc/first_class_callable_syntax :
>
> if (is_callable(static::methodName(...))) {
> static::methodName();
> }
>
> or
>
> $fn = static::methodName(...);
> if (is_callable($fn)) {
> $fn();
> }

This throws an Error on `static::methodName(...)` [if not callable],
before even passing it to `is_callable()`: https://3v4l.org/m29BK

And yes, code should probably better use a same variable for both the
check and the call, but that could also degrade DX (IDE
autocompletion, static analysis) especially if calling with
arguments...

(the other parts of your message have been answered by Juliette)

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Re: NULL Coercion Consistency

2022-05-30 Thread Guilliam Xavier
On Tue, May 24, 2022 at 10:47 AM Rowan Tommins  wrote:
>
> As an anecdote, I was recently working on a bug involving nulls causing
> unintended behaviour in an API. As part of the clean-up, I changed a
> function signature from getByIdentifer($identifier) to
> getByIdentifer(string $identifier), and during testing, got an error
> because I'd missed a scenario where null was passed. This was a good
> result - it prevented the broken behaviour and alerted me to the case
> that needed fixing. If the parameter had instead been silently coerced
> to an empty string, I would have got neither an error nor the original
> null behaviour, causing a new bug that might have taken much longer to
> track down.
>
> If your RFC as drafted was implemented, I could only have achieved the
> desired check by turning on strict_types=1 for whole sections of the
> application, which would probably require dozens of other fixes, or
> writing an ugly manual check:
>
> function getByIdentifier(?string $identifier) {
>  if ( $identifier === null ) {
>   throw new TypeError("Function doesn't actually accept nulls");
>  }
>  // ...
> }

For this specific example, shouldn't it rather [already] be like this anyway?

function getByIdentifier(string $identifier) {
 if ( $identifier === '' ) {
  throw new InvalidArgumentException("Empty identifier");
 }
 // ...
}

(but I guess you could find actual examples where an empty string is
"valid" and null is not, indeed)

> As I have said previously, I share your concern about the impact of the
> currently planned change, but I don't think loosening the existing type
> rules on user-defined functions is a good solution.

I agree the "issue" looks like different PoV of benefit VS cost, plus
the reticence about going back on the general trend of "more
strictness" (even with strict_types=0).
I'm just worried to see people rather disabling deprecation notices
(via error_reporting, or a custom error handler, or even patching
PHP's source and recompiling their own) than "fixing" the code
(granted, that's not specific to *this* RFC, but somewhat "highlighted" here)


FWIW, to avoid the "risks" of `expr ?? ''` (possibly hiding undefined)
and `(string)expr` / `strval(expr)` (potentially casting "too much"
without errors), I've already seen custom functions like

function null_to_empty_string(?string $string_or_null): string
{ return $string_or_null === null ? '' : $string_or_null; }

(but also its "opposite" empty_string_to_null(string $string): ?string)

Regards,

--
Guilliam Xavier

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



Re: [PHP-DEV] [Discussion] Stricter implicit boolean coercions

2022-05-16 Thread Guilliam Xavier
On Mon, May 16, 2022 at 5:06 PM Andreas Leathley  wrote:
>
> Hello Internals,
>
> After the first discussion about this topic
> (https://externals.io/message/117608) I have created a preliminary
> implementation and an RFC for making implicit boolean type coercions
> more strict:
>
> https://wiki.php.net/rfc/stricter_implicit_boolean_coercions
>
> With this email I'm starting the two week discussion period. I welcome
> any feedback on it and hope to further iron out the implementation if
> needed. I mainly chose the route of introducing a deprecation notice
> because it is in line with other RFCs that have similar goals (like the
> Deprecate implicit non-integer-compatible float to int conversions RFC),
> and it is fairly non-intrusive.
>
> Best regards,
>
> Andreas

Hi Andreas,

Thanks! Am I right that it only affects *type declarations*, and the
"Unaffected PHP Functionality" section could also mention implicit
boolean evaluation in `if`, ternary conditional (?:) and logical
operators (!, &&, ||, and, or, xor)?

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] NULL Coercion Consistency

2022-05-11 Thread Guilliam Xavier
Hi, I can't refrain from replying again...


On Sat, May 7, 2022 at 1:30 PM Mel Dafert  wrote:
>
> It is exactly user-defined functions that this RFC introduces breakage for.
> The behaviour to throw on null in user-defined functions exists since PHP
> 7.0, and is being relied on. Changing these now would introduce behaviour 
> changes
> that are harder to find than new type errors.

Indeed, that's why in the previous thread
(https://externals.io/message/116752#117121) I suggested:

"""
Or maybe (if going directly from error to implicit coercion is deemed too
"risky") the current TypeError in non-strict_types mode (when passing NULL
to a user-defined function expecting a scalar) could first be "demoted" to
some kind of Notice [who said E_STRICT] in 8.2 (along with reverting the
Deprecation added in 8.1 for internal functions) and removed in 9.0?
"""


On Tue, May 10, 2022 at 1:02 AM Craig Francis  wrote:
>
> On 7 May 2022, at 22:11, Jordan LeDoux  wrote:
>
> > What about `int|float`? Which one would it be coerced to?
>
> Good question,
>
> Short answer; today, if you pass the string '4' to a function that uses 
> `int|float`, then it receives `int(4)`:
>
> [...]
>
> Longer answer...
>
>  [...]
>
> That said, and back to your question about `int|float`, because the string 
> '4' is coerced to `int(4)`, I'd prefer NULL to be coerced to `int(0)`.

Is there really need for debate here?
https://wiki.php.net/rfc/union_types_v2#coercive_typing_mode already
says:

"""
If the exact type of the value is not part of the union, then the
target type is chosen in the following order of preference:

  1. int
  2. float
  3. string
  4. bool

If the type both exists in the union, and the value can be coerced to
the type under PHPs existing type checking semantics, then the type is
chosen. Otherwise the next type is tried.
"""

(besides, a numeric string is not the best example, because there's an
exception, e.g. the string '4.0' is coerced to `float(4.0)` rather
than to `int(4)`).


On Tue, May 10, 2022 at 1:13 AM Craig Francis  wrote:
>
> On 8 May 2022, at 12:38, Mark Randall  wrote:
> > On 08/05/2022 11:48, Jordan LeDoux wrote:
> >> This is not the case with null. If you use the unset() function on a
> >> variable for example, it will var_dump as null *and* it will pass an
> >> is_null() check *and* it will pass a $var === null *and* it will return
> >> false for an isset() check. Null loses these qualities if it is cast to
> >> *any* scalar.
> >
> > Fortunately the writing is on the wall for the undefined cases, but that 
> > doesn't take away from your argument.
>
> Yep, I agree, an exception for an undefined variable is probably fine... I'm 
> looking at variables specifically being set to to the NULL value, and how 
> that NULL value is coerced.

No need for an exception, accessing an undefined variable already
triggers a Warning and is going to throw an Error in PHP 9.0
(https://wiki.php.net/rfc/undefined_variable_error_promotion).


PS: about "Java", it has nothing to do; Java type declaration `Foo`
(where Foo is a class/interface) is equivalent to PHP `?Foo` (or
`Foo|null`) i.e. implicit *nullability* (that you cannot even opt-out;
the `@NonNull` annotation only works with SCA/IDE or AOP), the RFC
discussed here is about implicit *coercion of null to scalar*.


Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] [RFC] Exposed parsed value of php.ini numeric directives

2022-05-04 Thread Guilliam Xavier
Hi,

> Proposed in https://github.com/php/php-src/pull/8454
>
> Related PR in WordPress, replicating the `zend_atol()` logic in user-space
> https://github.com/WordPress/wordpress-develop/pull/2660

I guess it could [have ]be[en] useful to Symfony too:
https://github.com/symfony/symfony/blob/c70be0957a11fd8b7aa687d6173e76724068daa4/src/Symfony/Component/HttpFoundation/File/UploadedFile.php#L210-L246

Just not sure whether it should be e.g. `ini_get_size($option)` (like
ini_get) or rather e.g. `ini_parse_size($value)` (more generally
usable).

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-02 Thread Guilliam Xavier
On Mon, May 2, 2022 at 1:57 PM Alexandru Pătrănescu  wrote:
> On Mon, May 2, 2022 at 2:15 PM Guilliam Xavier  
> wrote:
>> I too would rather have "extra" deprecation notices in 8.2 than
>> *sudden errors / silent behavior changes* in 9.0 (for the callable
>> type declaration / the is_callable() function)...
>
> The point is that this is not an usual deprecation, something that will 
> change to an error in the future.
> In the end, it's just a change in behavior with no error before or after. It 
> does not fit the "deprecation".

This has already been said earlier, and answered:

On Wed, Apr 20, 2022 at 12:22 AM Claude Pache  wrote:
> > Le 19 avr. 2022 à 20:20, Andreas Hennings  a écrit :
> > A deprecation warning on is_callable() would imply that in a future
> > version of PHP that call will be illegal.
>
> No,  in the case of `is_callable()`, the deprecation warning will imply that, 
> in a future version of PHP, the behaviour will change.  There are precedents 
> of deprecation warning for changing behaviour: https://3v4l.org/Iqo4N

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Deprecated partially supported callables: should is_callable() throw a deprecation notice ?

2022-05-02 Thread Guilliam Xavier
On Wed, Mar 16, 2022 at 9:57 AM Christian Schneider
 wrote:
>
> Am 16.03.2022 um 06:52 schrieb Juliette Reinders Folmer 
> :
> > I've just been looking in detail at the Partially Supported Callables 
> > deprecation RFC: 
> > https://wiki.php.net/rfc/deprecate_partially_supported_callables
> >
> > The RFC explicitly excludes the `is_callable()` function and the `callable` 
> > type from throwing deprecation notices.
> >
> > [...] I wonder if the decision [...] is the right one (though I understand 
> > the desire to keep [them] side-effect free).
> >
> > Consider these code samples:
> >
> >  function foo(callable $callback) {}
> >  foo('static::method');
> >
> > [...] in PHP 9.0 the function will start throwing a TypeError.
>
> [...] This is a major problem because code which was "just working" directly 
> goes to a TypeError without a migration phase warning about it. This is 
> something I've repeatedly advocated against.
>
> >  if (is_callable('static::method')) {
> >  static::method();
> >  }
> >
> > [...] in PHP 9.0, the behaviour of this code will be silently reversed for 
> > those callbacks which would previously result in `is_callable()` returning 
> > true, which makes this a potentially dangerous change without deprecation 
> > notice.
>
> I agree with you here: Code which silently changes behavior is also a 
> migration hassle.

Hi,

I too would rather have "extra" deprecation notices in 8.2 than
*sudden errors / silent behavior changes* in 9.0 (for the callable
type declaration / the is_callable() function)...

Regards,

-- 
Guilliam Xavier

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



Re: [PHP-DEV] Stricter implicit boolean coercions

2022-04-27 Thread Guilliam Xavier
> > 'on' is only true by "accident" though, because it is a non-empty
> > string, not because of its meaning, and then it is likely that the value
> > 'off' could also be added at some point - which also would be true.
>
> The reason I gave that particular example is that it's the default
> submission value for an HTML checkbox when checked; if it's not checked,
> it has no value at all (not even an empty string), so in that particular
> context there is no corresponding "off".
>

That's why you must test it with isset($_POST['checkbox_name']), *not* with
(bool)$_POST['checkbox_name'] or an implicit conversion.

if ( $nullable_float = type_coerce_or_return_default('?float', $var,
> false) === false ) { throw new TypeError; }
>

Missing parentheses around the assignment (VS the comparison)!


Only allowing the following values would make sense
> from my perspective:
>
> '1' => true
> 1 => true
> 1.0 => true
> '' => false
> '0' => false
> 0 => false
> 0.0 => false
>

Seems a reasonable compromise (between BC and bugs-protection).

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] NULL Coercion Consistency

2022-04-26 Thread Guilliam Xavier
On Tue, Apr 26, 2022 at 12:18 AM Larry Garfield 
wrote:

> On Mon, Apr 25, 2022, at 4:07 PM, Rowan Tommins wrote:
>
> > Off the top of my head, I don't know what other inconsistencies remain,
> > but my point was that in every case so far, internal functions have been
> > adapted to match userland, not vice versa.
>
> 
>
> Internal functions error if you pass excessive arguments to a non-variadic
> function.  User-space functions just ignore the extras.  This is an
> inconsistency that has caused me considerable grief in the past year.
>
> I know Joe has said he wants userspace to become more strict like internal
> on this one.  I will not predict what actually happens.
>
> 
>



A few internal functions have parameters with an `UNKNOWN` default value in
the stubs, e.g.
https://github.com/php/php-src/blob/php-8.1.5/Zend/zend_builtin_functions.stub.php#L35

 function get_class(object $object = UNKNOWN): string {}

documented with a question mark at
https://www.php.net/manual/en/function.get-class.php

get_class(object $object = ?): string

or
https://github.com/php/php-src/blob/php-8.1.5/ext/standard/basic_functions.stub.php#L1558

function mt_rand(int $min = UNKNOWN, int $max = UNKNOWN): int {}

documented with two signatures at
https://www.php.net/manual/en/function.mt-rand.php

    mt_rand(): int
mt_rand(int $min, int $max): int



-- 
Guilliam Xavier


Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-25 Thread Guilliam Xavier
> > Are you proposing to deprecate the implicit `= null` default initializer
> > for untyped properties?
>
> Yes.
>
>
> > Thanks for the recap. For untyped properties, that's the historical
> > behavior. For typed properties, that's explained in
> >
> https://wiki.php.net/rfc/typed_properties_v2#uninitialized_and_unset_properties
> > *. What's the issue?
>
> The issue is that for new users, saying "that's the historical
> behaviour, you just have to learn it" is not very helpful.
>
>
> > * "If a typed property is `unset()`, then it returns to the uninitialized
> > state. While we would love to remove support for the unsetting of
> > properties, this functionality is currently used for lazy initialization
> by
> > Doctrine, in combination with the functionality described in the
> following
> > section."
>
> I think both you and Mark misunderstood my point in bringing this up -
> I'm not complaining about the ability to call unset(), I'm complaining
> that it behaves differently depending how the property was declared.
>
> Look at how the untyped property behaves in this example:
> https://3v4l.org/nClNs The property disappears from var_dump(), but is
> not actually deleted from the object, as seen by it still being private
> when assigned a new value. Given that we have the magic "uninitialized"
> state, and we're proposing to make reading an unset property an error,
> it would make more sense for it to show as '["untyped":"Foo":private] =>
> uninitialized(mixed)'
>

Understood (also https://3v4l.org/DgXJl ). Maybe start a new thread? (this
one is not shown on externals.io, only findable via search)

-- 
Guilliam Xavier


Re: [PHP-DEV] MySQLi Execute Query RFC

2022-04-25 Thread Guilliam Xavier
On Mon, Apr 25, 2022 at 1:05 PM Craig Francis 
wrote:

> On 22 Apr 2022, at 13:09, Guilliam Xavier 
> wrote:
>
> > https://wiki.php.net/rfc/mysqli_execute_query
>
> Thanks. Maybe add (or even start with) an example of mysqli_query(), to
> show how "migrating to safer" would become easier? retro-fitting your
> example of parameterised query:
>
>
>
>
> Thanks Guilliam, that's a good idea.
>
> To keep it short, I've gone with a more traditional use of
> `$db->real_escape_string()` with string concatenation, including a
> classic mistake with missing quotes around integer values :-)
>
> I do like your example with `vsprintf()`, but I needed to replace the "?"
> with "%s" as well, with made it look more complicated than pre-8.1 prepared
> statements, I hope that's ok.
>

Of course that's "ok", you own your RFC ;) I had suggested [v]sprintf for
brevity and similarity with your parameterised query examples and
https://www.php.net/manual/en/mysqli.real-escape-string.php#refsect1-mysqli.real-escape-string-examples
too, but concatenation is probably more "realistic" anyway...

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: LOCK_SH for file_get_contents ?

2022-04-25 Thread Guilliam Xavier
First, hello...

> This has been requested for years (since at least 2009?) but it seems no
> > actual plan has been proposed
> > How about this?
> > since we already have the constant FILE_USE_INCLUDE_PATH , seems it was
> > introduced in PHP5.0.0,
> >
> > 1: FILE_USE_INCLUDE_PATH currently collides with LOCK_SH (they're both
> 1),
> > lets change FILE_USE_INCLUDE_PATH to something that doesn't collide with
> > any of LOCK_SH | LOCK_EX | LOCK_NB
> > for example  (1 << 3) / int(8)
> > 2: change argument #2 from "bool $use_include_path = false" to "int|bool
> > $flags = 0" , treating bool(false) the same as int(0) and bool(true) the
> > same as FILE_USE_INCLUDE_PATH , and support LOCK_SH | LOCK_NB |
> > FILE_USE_INCLUDE_PATH here
> > (i think LOCK_EX could also be supported, but that might be
> controversial,
> > and the use case is certainly limited, if there is one at all)
> >
> > because it's kind of silly, and at times annoying, that file_put_contents
> > support LOCK_EX but file_get_contents does not support LOCK_SH
>
> can we at least change FILE_USE_INCLUDE_PATH to 8 / (1<<3)  ? that would
> allow a userland implementation of file_get_contents to support LOCK_SH and
> FILE_USE_INCLUDE_PATH
>
> The current situation is so bad that FILE_USE_INCLUDE_PATH literally cannot
> be used in strict_mode=1, it's pretty much completely useless since php
> 7.0, so I doubt it'll break anything keeping up with new releases of PHP.


After some search, I assume you're referring to
https://bugs.php.net/bug.php?id=47115 (Request #47115 Can't use flag
LOCK_SH in file_get_contents "similar to file_put_contents can use
LOCK_EX"). I'm more "empathetic" to that than with your mails alone.
Anyway, I doubt FILE_USE_INCLUDE_PATH can be changed to 8, because that's
already FILE_APPEND (and both can be used with file_put_contents()). Here's
the current (PHP 8.1, unchanged since at least 5.6) var_export() of
`array_filter(get_defined_constants(), function ($k) { return
preg_match('/^(FILE|LOCK)_/', $k); }, ARRAY_FILTER_USE_KEY)`:

```
array (
  'LOCK_SH' => 1,
  'LOCK_EX' => 2,
  'LOCK_UN' => 3,
  'LOCK_NB' => 4,
  'FILE_USE_INCLUDE_PATH' => 1,
  'FILE_IGNORE_NEW_LINES' => 2,
  'FILE_SKIP_EMPTY_LINES' => 4,
  'FILE_APPEND' => 8,
  'FILE_NO_DEFAULT_CONTEXT' => 16,
  'FILE_TEXT' => 0,
  'FILE_BINARY' => 0,
)
```

(ignore the last two). Actually it almost looks like it's only "by chance"
that file_put_contents() can use LOCK_EX (2 i.e. 1<<1) together with
FILE_USE_INCLUDE_PATH (1 i.e. 1<<0) and FILE_APPEND (8 i.e. 1<<3)...

That said, [I don't think LOCK_SH = 1 can be changed, but] maybe
FILE_USE_INCLUDE_PATH can be changed to e.g. 32, along with your suggestion
2 (change argument #2 [of file_get_contents()] from `bool $use_include_path
= false` to `int|bool $flags = 0` [*but*] treating `true` like
FILE_USE_INCLUDE_PATH [*rather than 1 i.e. LOCK_SH*] [note sure about
LOCK_NB though])?

(PS: there's also **file()**, which currently supports
FILE_USE_INCLUDE_PATH, FILE_IGNORE_NEW_LINES and FILE_SKIP_EMPTY_LINES...)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [VOTE] Undefined Property Error Promotion

2022-04-25 Thread Guilliam Xavier
Hi Rowan,

(...) Also, there's this non-standard class called
> "stdClass", which unlike standard classes, you can read and write any
> property you like without declaring it,


Better reordered "write and read" I think. Yes, like associative arrays,
stdClass is "dynamic" by design.


> and even if you use unset(),
> you'll never get an error.
>

That's not true, e.g. given `$o = (object)['foo' => 1]; $o->bar = 2;` then
`unset($o->foo, $o->bar);`, trying to read `$o->foo` or `$o->bar` will both
cause an error (like for `$o->qux`); or I'm misunderstanding you?

> You could special case nullable, but then it's an extra rule to learn
> > beyond "typed = needs to be initialized".
>
> I'm more inclined to the opposite: if reading an "undefined" property is
> going to be an error, maybe reading an "uninitialized" one should be
> too, even if you don't declare a type for it.
>

Are you proposing to deprecate the implicit `= null` default initializer
for untyped properties?


> And maybe we should think about exactly what unset() means, and which
> error you're going to get after you use it - is the property "undefined"
> or "uninitialized"? Currently, an untyped property becomes "undefined",
> as though it never existed; but a typed property is still on the object,
> but "uninitialized". Yet either way, assigning a new value brings back
> the declared property, not a dynamic one with the same name:
> https://3v4l.org/nClNs
>

Thanks for the recap. For untyped properties, that's the historical
behavior. For typed properties, that's explained in
https://wiki.php.net/rfc/typed_properties_v2#uninitialized_and_unset_properties
*. What's the issue?

* "If a typed property is `unset()`, then it returns to the uninitialized
state. While we would love to remove support for the unsetting of
properties, this functionality is currently used for lazy initialization by
Doctrine, in combination with the functionality described in the following
section."

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: MySQLi Execute Query RFC

2022-04-22 Thread Guilliam Xavier
 Hi Craig,

> https://wiki.php.net/rfc/mysqli_execute_query
>

Thanks. Maybe add (or even start with) an example of mysqli_query(), to
show how "migrating to safer" would become easier? retro-fitting your
example of parameterised query:

```
$sql_format = "SELECT * FROM user WHERE name LIKE %s AND type IN (%s, %s)";

/* ... */

$sql_raw = vsprintf($sql_format, array_map(fn ($s) => "'" .
$db->real_escape_string($s) . "'", [$name, $type1, $type2]));

foreach ($db->query($sql_raw) as $row) {
print_r($row);
}
```

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Undefined Property Error Promotion

2022-04-19 Thread Guilliam Xavier
On Sat, Apr 16, 2022 at 12:01 AM David Rodrigues 
wrote:

> > $foo[?'maynotexist'] // returns null and emits no warning
>
> In JS we have some like:
>
> foo['maynotexist']
> foo?.['maynotexist']
>
> In PHP could be:
>
> $foo['maynotexist']
> $foo?->['maynotexist']
>

You seem to be confusing two different things (in short, ?-> vs ->?):

  1. In PHP *too* we *already* have "*nullsafe* property access"
$objectThatMayBeNull?->property (but no "nullsafe array access"
$arrayThatMayBeNull?['key'], see
https://wiki.php.net/rfc/nullsafe_operator#future_scope) since PHP 8.0 (see
https://www.php.net/releases/8.0/en.php,
https://www.php.net/manual/en/migration80.new-features.php etc.)
  2. What may be proposed (in another RFC) is something like
$object->?propertyThatMayNotExist and/or $array[?'keyThatMayNotExist']
(call it e.g. "*lenient* property/array access"?) (JS is lenient by default)

But let's not deviate further.

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Add true as type

2022-04-11 Thread Guilliam Xavier
Hi,

On Mon, Apr 11, 2022 at 3:33 PM G. P. B.  wrote:

>
> There are many many many more internal functions in PHP which only return
> true, but only since PHP 8.0.0, and this is due to the huge amount of
> E_WARNING to ValueError/TypeError promotion which has happened.
> These functions previously did return false in certain circumstances, and
> although I agree that changing these to void *would* be the most ideal,
> being able to do this communicating that these functions only return true
> (which means one can ignore the return value) is the first step.
> Moreover, it is even more of a BC break compared to changing something
> which only returns false to void as code like:
> if (always_true(...)){ ... }
> would stop executing this code path.
>
> Not adding true as a type prevents extending methods which return bool to
> always return true to clearly document this within the typesystem.
>

Then you should probably update the RFC to say that, and better examples ;)
Maybe also add an example of "refinement" during inheritance (from `: bool`
to `: true`)?

One more thing: maybe the part about `true|false` being an error (use
`bool`) should be its own subsection, as that's not exactly "redundancy",
and differs from `array|\Traversable` being interchangeable with `iterable`.

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] NULL Coercion Consistency

2022-04-11 Thread Guilliam Xavier
Hi,

> https://wiki.php.net/rfc/null_coercion_consistency

Thanks for the draft.

On Sat, Apr 9, 2022 at 11:30 AM Craig Francis 
wrote:

> On Fri, 8 Apr 2022 at 19:07, Craig Francis 
> wrote:
>
> > On Fri, 8 Apr 2022 at 18:54, Mel Dafert  wrote:
> >
> >> In particular, does this propose changing user-defined functions under
> >> strict_types=0 to accept null for scalar types?
> >>
> >
> > With user defined functions, I think it's up for debate (still a draft),
> > but I think those NULL's should be coerced to the specified type (as
> > documented), where I don't think PHP should be doing type checking under
> > strict_types=0.
> >
>
>
> I've updated the RFC to note that user-defined functions don't cause a
> backwards compatibility issue; but I have added an example to highlight
> the coercion inconstancy:
>

You've updated the **Documentation** section (also: did you mean
"inconsistency" rather than "inconstancy"?) but still not the **Proposal**
(BTW all those sections between "Introduction" and "Proposal" would
probably better be *sub*-sections of a section named "Problem" or "Current
State" or something).

And for the question: (currently) the RFC is named "NULL Coercion
*Consistency*" and the Proposal says "Must keep the spirit of the original
RFC, and *keep user-defined and internal functions consistent*.", which (to
me) implies *not only* reverting the 8.1 deprecation on internal functions
*but also* "changing user-defined functions under strict_types=0 to
[coerce] null for scalar type[ declaration]s" indeed.
In any case, that should be written clear in the RFC (either in "Proposal"
or "Open Issues").

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Undefined Property Error Promotion

2022-04-06 Thread Guilliam Xavier
On Wed, Apr 6, 2022 at 2:37 PM Robert Landers 
wrote:

>
> FWIW, I'd like to see option 2 only because of custom serializers
> and/or object proxies and also because:
>
> > This RFC proposes that accessing an undefined property is rendered
> illegal behaviour
>
> StdClass has *no* defined properties and thus would always throw. But
> I also guess it depends on what you define "undefined" as. Does simply
> doing $obj->prop "define" the property "prop"?
>

The RFC doesn't change the current meaning of "undefined" (or "defined", or
"declared"...), just proposes to throw an Error (while it currently
triggers an E_WARNING).
First sentence of the introduction: "Undefined properties are those that
have not yet been defined either by the presence of a property declaration,
or by adding them to the properties hashmap through direct assignment, or
by having them assigned by an internal function such as json_decode."
`$obj->prop` alone doesn't define the property "prop", but `$obj->prop =
whatever` does.

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Undefined Property Error Promotion

2022-04-06 Thread Guilliam Xavier
Hi Mark,

https://wiki.php.net/rfc/undefined_property_error_promotion
>

[note: the RFC Date has a +1 on the year]

I'm in favor for "fixed" classes (with all properties declared and no
`__get()` magic method),
but somewhat mixed for `stdClass`: as you said, it can come from a
`json_decode()` by default or an `(object)$array` cast, and is kind of
"interchangeable" with `array` (which can come from a `json_decode()` with
`associative: true` / `flags: JSON_OBJECT_AS_ARRAY` or an `(array)$object`
cast);
as such, I wonder if it wouldn't make more sense to rather handle undefined
properties *on stdClass* together with undefined *array keys*?
(the reasoning could even be extended to classes annotated with the
`#[AllowDynamicProperties]` attribute...)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Reflection changes due to allow null + false as standalone types RFC

2022-04-06 Thread Guilliam Xavier
Hi George,

> https://github.com/php/php-src/pull/7546#discussion_r837900447

Thanks for asking (even if voted).

On Tue, Apr 5, 2022 at 2:01 PM Marco Pivetta  wrote:

> Probably best with consistency?
>
>  > - Ignore the Reflection changes of the RFC and align the union type with
> the current behaviour
>
> This one, specifically.
>

I agree with Marco (who I know works on reflection-related projects).

To expand a bit:

when reading the RFC, "the notable exception that `null|false` will produce
a ReflectionUnionType instead of a ReflectionNamedType contrary to other
`null|T` types" seemed legit because
  - `T|false` currently always produces a ReflectionUnionType
  - `null|T` producing a ReflectionNamedType (like `?T`) was only decided
*for backwards-compatibility reasons* [
https://wiki.php.net/rfc/union_types_v2#reflection]
(moreover the initial RFC [https://wiki.php.net/rfc/null-standalone-type]
only proposed standalone `null`, not `false`, so didn't allow `?false`)

but now looking at the implementation, I don't like the special casing.

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [RFC][Under discussion] Deprecate ${} string interpolation

2022-03-31 Thread Guilliam Xavier
Hi Ilija,

On Thu, Mar 31, 2022 at 2:27 PM Ilija Tovilo  wrote:

> Hi everyone
>
> There hasn't been any discussion on this RFC for two weeks. I think
> most concerns have been voiced. The result of the vote will most
> likely come down to the views on backwards compatibility vs cleaning
> up old behavior. The RFC contains an impact analysis and a script to
> fully migrate existing code.
>
> So, unless new concerns are voiced I'd like to put this to a vote in a
> couple of days.
>
> > https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation
>

Just 2 editorial remarks:
  - at the start of the Proposal, the numbered list is rendered like a code
block (preformatted text)
  - the last paragraph before the Conclusion starts with the sentence "The
braces switch from option 3 to 4 because braces are not allowed in option
3": both occurrences of "braces" here should be "parentheses" (or "round
brackets", VS "curly brackets")

Best,

-- 
Guilliam Xavier


Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Guilliam Xavier
> Ah yes, I hadn't considered expanding this RFC to namespaced and global
> constants. Let me mull over implementation syntax for those and include
> them in the RFC. My initial reaction is to not include those in this RFC,
> keeping the scope to just class constants. If there is value in typing
> namespaced and global constants, then another RFC could add those.
>

Yes, it could be simply a mention in a "Future scope" (or even "Unaffected
functionality") section
(and the syntax could indeed be a problem, like for typed local/global
variables...)


> Once I have all these new issues figured out and the RFC updated, I'll
> start that new thread.
>

Looking forward to it =)


Re: [PHP-DEV] Undefined variables and the array append operator

2022-03-30 Thread Guilliam Xavier
Hi Rowan,

Not really a "compelling reason why we should keep this inconsistency", but
I have occasionally relied on array autovivification *for sub-dimensions*,
e.g.:

```
function f(iterable $xs) {
$map = []; // initialization!
foreach ($xs as $x) {
// $map[foo($x)] ??= []; not needed
$map[foo($x)][] = bar($x); // autovivification
}

// Then e.g.:
foreach ($map as $foo => $bars) {
foreach ($bars as $bar) {
/* ... */
}
}
}
```

(adapted from my https://externals.io/message/114595#114611 message in the
"Disable autovivification on false" thread).

On the other hand, I agree that `$undefined[] = $x` looks like a bug... are
both cases the exact same opcode? (if yes, I wouldn't really mind updating
my code, especially for consistency with other "append" operators like .=
or +=, and that could even be an opportunity to rewrite it in a more
"functional" style...)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Typed constants revisited

2022-03-30 Thread Guilliam Xavier
Hi Mark,

I have updated the RFC https://wiki.php.net/rfc/typed_class_constants with
>>> more details and examples from this thread, and updated the RFC status to
>>> Under Discussion. Hopefully the updated RFC helps answer questions and
>>> clarifies what the proposal includes.
>>>
>>
Thanks (I assume that you talked with the original author) -- not sure if
you should have started a new thread with the "[RFC]" tag in the subject?


> I think you should also update the "Supported types" section.
>> Starting with enums, constants can also be objects. Once a good technical
>> solution is found, any object would be supported probably
>> https://wiki.php.net/rfc/new_in_initializers#future_scope
>> I think that only void, never and callable types should not be supported,
>> just like on properties.
>>
>
> I have updated the "Supported types" to list out all types that are
> supported and which types are not supported.
>

A few comments, by subsection:

  - **Supported types**: This corresponds to the types currently allowed
for const values (as well as unions thereof) except it [still] doesn't
mention enums (which internally are classes implementing the `UnitEnum`
interface, and whose values are ultimately of `object` type) although
currently allowed. It also doesn't mention `mixed` (used later in examples).
  - **Strict and coercive typing modes**: I didn't understand it on first
read; I had to read the later "Constant values" section and compare both
with
https://wiki.php.net/rfc/typed_properties_v2#strict_and_coercive_typing_modes
and https://wiki.php.net/rfc/typed_properties_v2#default_values
  - **Inheritance and variance**: Several occurrences of "Class constants"
should probably be "*Typed* class constants". Also, I still think that
`protected bool $isExtinct` is *not* a good parallel to `public const bool
CAN_FLY` (see my previous message).
  - **Constant values**: You should probably remove the `iterable` example
now [and maybe add an `enum` one].


> Constants cannot be objects since objects are mutable, so typed constants
> will not be allowed to be an enum (which is technically an object). A typed
> constant _may_ be an enum value though, so the following example will be
> valid:
>
> ```
> enum Fruit
> {
> case Apple;
> case Banana;
> }
>
> class Colors
> {
> protected const string RED = Fruit::Apple;
> protected const string YELLOW = Fruit::Banana;
> }
> ```
>

This is incorrect, `Fruit::Apple` is of type `Fruit` (ultimately `object`),
not `string`. But it is *not* mutable, and *is* allowed as a const value
currently.

Besides, I realized that the RFC is [only] for *class* constants; what
about *namespaced (and global)* constants?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC][Under discussion] Arbitrary string interpolation

2022-03-28 Thread Guilliam Xavier
Hi,

> A large part of that is because the placeholders are positional rather
> > than named, so you have to keep track of which is which; but by the time
> > you've got named placeholders, you might as well have variable
> > interpolation.
>
> I feel the same way. PHPStorm has a feature that highlights the given
> expression when your cursor is placed on a %s placeholder and vice
> versa. This seems to be the treatment of that symptom.
>

Has "add named placeholders to *printf()" been proposed/discussed before (I
didn't find)?

What about strtr() (e.g. `strtr('The {foo} is {bar}.', ['{foo}' => FOO,
'{bar}' => bar()])`)? (and even templating engines like Twig?)

Anyway, it sometimes baffles me indeed that I can build a string with a
method call like `"...{$foo->bar()}..."` but not with a function call like
`"...{foo($bar)}..."`, and also with complex interpolation via callable
variable like `"...{$foo($bar + baz($qux))}..."` but not with simple
constant like `"...{FOO}..."` or operation like `"...{$foo + 1}..."` :/

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Typed constants revisited

2022-03-28 Thread Guilliam Xavier
> Constants are not abstract in an interface - they must be assigned a
> value. Only classes and methods can be abstract. Within an abstract class
> it is not valid to have an abstract property. Properties can be defined
> `protected int $id;` and optionally assigned a value `protected int $id =
> 5;`, but cannot be `abstract protected int $id;`.
>

That's the *current* state of the language indeed, but to me, [part of]
your proposal looks like introducing "abstract constants"... Maybe I'm
misunderstanding?


> So to me it makes more sense to have constants follow the same syntax as
> properties `public const bool CAN_FLY;` without the `abstract` keyword.
>
> An example:
>
> ```
> abstract class Bird
> {
> public const bool CAN_FLY;
> protected bool $isExtinct;
> ```
>
> This allows for similar behavior, similar requirements, and similar syntax
> - consistency ftw!
>

For similarity/consistency, the `$isExtinct` property should probably be
[`public` and] `static` (actually `readonly` too, but cannot be both).

But, again, we can also see some similarity with `static` *methods*, e.g.:

```
abstract class Bird
{
abstract public const bool CAN_FLY;
abstract public static function isExtinct(): bool;
}
class Dove extends Bird
{
// NOTE: the following two lines are required (in the class definition)
public const bool CAN_FLY = true;
public function static isExtinct(): bool { return false; }
}
// var_dump(Dove::CAN_FLY);
// var_dump(Dove::isExtinct());
```

Besides, an uninitialized property must be initialized before first read,
but is *not* required to be overridden/redefined (with a value) in a child
class; so in this example (still hypothetical):

```
abstract class Bird
{
public const bool CAN_FLY;
public static bool $isExtinct;
}
class Dodo extends Bird
{
// NOTE: the following two lines are commented out
// public const bool CAN_FLY = false;
// public static bool $isExtinct = true;
}
var_dump(Dodo::CAN_FLY);
var_dump(Dodo::$isExtinct);
```

where would the [missing value for constant] error be: on the definition of
class Dodo (like for an unimplemented abstract method), or only when trying
to access Dodo::CAN_FLY (like for an uninitialized property)?


>
> There seems to be interest and good use cases (thanks Sara for the good
> practical example!). At this point I'm going to work on a new RFC with all
> the details and feedback from this discussion.
>
>

Thanks & good luck! =)

-- 
Guilliam Xavier


Re: [PHP-DEV] Typed constants revisited

2022-03-25 Thread Guilliam Xavier
> I intentionally left `abstract` out of `public const bool CAN_FLY;` in the
> `abstract class` for consistency with the implementation with `interface`,
> which would also have to be `public const bool CAN_FLY;`. Currently
> `abstract` is only used in front of methods `abstract function doThing():
> bool;`. Open to discussion - which way is ideal or preferred? That could be
> included as a subset of an RFC vote if a consensus during discussion isn't
> reached.
>

I understand, but note that methods are implicitly abstract in an
interface, but it must be explicit in an abstract class; and since I see
the proposed feature mainly as a "replacement" for abstract static methods
[whose all implementations just return a literal value]... (anyway, not
super important)


Re: [PHP-DEV] Typed constants revisited

2022-03-25 Thread Guilliam Xavier
Hi Mark,

On Wed, Mar 23, 2022 at 11:55 PM Mark Niebergall 
wrote:

> (...)
>
> Another example I often see in my projects could be used with a similar
> example:
>
> ```
> abstract class Bird
> {
> public const bool CAN_FLY;
> public const string FAMILY;
> public function canFly(): bool
> {
> return self::CAN_FLY;
> }
> }
> final class EmperorPenguin extends Bird
> {
> public const bool CAN_FLY = false;
> public const string FAMILY = 'penguin';
> }
> ```
>

I had this "need" too (and used abstract static methods where the
implementations just return a literal value...).

Just 2 remarks: in abstract class Bird, shouldn't it be:
- "*abstract* public const bool CAN_FLY;" (and same for FAMILY)
- "return *static*::CAN_FLY;"
?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC][Under discussion] Deprecate ${} string interpolation

2022-03-15 Thread Guilliam Xavier
Hi Mike, Lynn, and Kamil; I feel like this sub-thread has derailed from the
initial topic... As already said, this RFC is *not* about the general
"variable variables" feature, but about *the `"${...}"` syntax inside
interpolated strings* (i.e. double-quoted or heredoc), which can be
rewritten to either `"{${...}}"` or `"{$...}"` (or even just `"$..."`)
depending on the `...` part (not necessarily a variable variable).
If you want to discuss variable variables (in general), I would suggest
creating a new separate thread.
Regards,


Re: [PHP-DEV] Allowing NULL for some internal functions

2022-02-28 Thread Guilliam Xavier
On Mon, Feb 28, 2022 at 5:41 PM Dik Takken  wrote:

>
> In my view, consistency between internal and userland functions brings a
> lot of value, and not only for the language itself. As soon as internal
> and userland become fully consistent it will become a lot easier to
> write "internal" functions in PHP rather than C. Not only will that make
> developing the standard library easier, it may also make the optimizer
> and JIT compiler more effective. The more consistency the better.
>

Yes, and we see two possible ways to make them consistent w.r.t. handling
of null argument passed into scalar parameter:

1. implicit coercion by default, error with strict_types=1
2. error (independent of strict_types)

AFAIK, internal functions have been doing 1 since like forever, but PHP 7.0
chose 2 for userland functions when introducing scalar parameter type
declarations (see my previous message for history) and PHP 8.1 continued in
that direction by deprecating 1 for internal functions (and planning to
change them to 2 in PHP 9.0).
Call me devil's advocate, but is it too late to discuss revisiting past
decisions and consider changing direction towards 1 for userland functions
(esp. in implications of BC impact)?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] SensitiveParameterValue serialization behavior

2022-02-28 Thread Guilliam Xavier
Hi again,

FWIW, Dan's and Claude's explanations (thanks!) and arguments made me
change my preference to option 1 (i.e. make SensitiveParameterValue not
serializable, period).

Best regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] SensitiveParameterValue serialization behavior

2022-02-25 Thread Guilliam Xavier
On Thu, Feb 24, 2022 at 3:11 PM Tim Düsterhus, WoltLab GmbH <
duester...@woltlab.com> wrote:

> Hi Internals!
>
> during code review of the "Redacting parameters in back traces" RFC [1]
> an issue with the proposed serialization behavior of
> SensitiveParameterValue objects became apparent that was not noticed
> before the RFC went into voting:
>
> The RFC proposed that serialization was allowed, but without including
> the inner value in the serialization data:
>
>  public function __serialize(): array { return []; }
>
> As this operation is lossy, it was proposed that unserialization fails
> and this is what was implemented in the PoC patch:
>
>  public function __unserialize(array $data): void {
>  throw new \Exception('...');
>  }
>
> The decision to allow serialization was to allow existing error handlers
> to work without needing to special case SensitiveParameterValue. However
> it is clearly not useful, if unserialization does not work after all.
> Any error during unserialization is not recoverable.
>
> Please find the thread in the GitHub PR at:
>
> https://github.com/php/php-src/pull/7921#discussion_r813743903
>
> As per Ilija Tovilo's suggestion I'm looping in the Internals list as well.
>
> I see two possible options to remediate this issue:
>
> ---
>
> 1. Disallow both serialization and unserialization.
>
> This will make the serialization issue very obvious, but will require
> adjustments to exception handlers that serialize the stack traces.
>
> 2. Allow unserialization, but poison the unserialized object and
> disallow calling ->getValue() on it.
>
> This would be closer to the original intent of the RFC, but moves the
> issue just somewhere else: The object would not be usable either way.
>
> ---
>
> What would be your preferred option? Feel free to either reply on the
> list or add to the discussion on GitHub.
>
> Thanks!
>
> [1] https://wiki.php.net/rfc/redact_parameters_in_back_traces
>

Hi Tim,

I would prefer option 2 (if possible), to avoid potentially breaking
existing code.
Calls to ->getValue() will be in new code written specifically for
SensitiveParameterValue anyway, and can be wrapped into try-catch, I think?

Best regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Allow null and false as stand-alone types

2022-02-23 Thread Guilliam Xavier
On Sun, Feb 20, 2022 at 6:56 PM G. P. B.  wrote:

> Hello internals,
>
> As a follow up from the "Allow null as a stand-alone type" where the main
> talking point was to also allow false to be used as a stand-alone type, a
> new slightly modified RFC is now proposed:
> https://wiki.php.net/rfc/null-false-standalone-types
>
> The implementation has been updated to reflect the new RFC.
>

The new RFC has a link to implementation and a link to the previous RFC
(which has a link back to the new one) but I had to search for the original
*discussion*, so here it is: https://externals.io/message/116188

(+1 for me, with or without false)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Allowing NULL for some internal functions

2022-02-23 Thread Guilliam Xavier
On Tue, Feb 22, 2022 at 3:59 AM Alexandru Pătrănescu 
wrote:

> On Mon, Feb 21, 2022 at 5:32 PM Craig Francis 
> wrote:
>
> > On Mon, 21 Feb 2022 at 09:04, Christoph M. Becker 
> > wrote:
> >
> > > That "inconsistency" had been introduced with PHP 7.0.0, i.e. right
> when
> > > scalar type declarations have been introduced.  Passing a null to a
> > > non-nullable parameter of a *userland* function throws a TypeError
> > >
> >
> >
> > Thanks Christoph, that's a good way of looking at it.
> >
> > Considering NULL has been passed to these internal function parameters
> for
> > years, for a variety of reasons, and PHP has coerced it into an empty
> > string, integer 0, float 0, or boolean false... I'm wondering if my RFC
> > should focus on matching that expectation, so anyone not using
> > `strict_types=1` does not need to make loads of hard-to-find/unnecessary
> > edits; that way NULL would be treated the same as the other variable
> types
> > (I appreciate arrays and objects don't get coerced, but I don't think
> > anyone expects them to).
> >
>
> Yes, exactly that.
> A few weeks ago when the issue was mentioned again I had to remember by
> trying on 3v4l myself that using null for a string parameter wasn't an
> automatically coerced case when strict_types = 0.
>

For history:
https://wiki.php.net/rfc/scalar_type_hints_v5#behaviour_of_weak_type_checks
(**emphasis** mine):

> A weakly type-checked call to an extension or built-in PHP function has
exactly the same behaviour as it did in previous PHP versions.
>
> The weak type checking rules for the new scalar type declarations are
**mostly** the same as those of extension and built-in PHP functions. The
only **exception** to this is the handling of `NULL`: in order to be
**consistent with our existing type declarations for classes, callables and
arrays**, `NULL` is not accepted by default (...)

In hindsight, maybe that wasn't the most "fortunate" decision... (although,
fair enough, `NULL` was never considered to be "scalar")


>
> In my view, false would have the same problem for those internal functions.
> Why should it be coerced to an empty string?
> https://wiki.php.net/rfc/deprecate_null_to_scalar_internal_arg#proposal is
> all about removing the automatic coercion that was happening for null in
> the internal functions
> Planning that in PHP 9 the type interpretation for internal function will
> be done the same as for user defined functions. Consistency.
>
> (...)
>
> As I mentioned, coercing false to int would be for me almost as bad as
> coercing null to int.
> But when types are not considered important I think it's worth pursuing
> extending the coercion from null to the 4 other types where it's happening
> right now:
> - int as 0,
> - float as 0.0,
> - string as an empty string
> - bool as false.
>

Indeed, that could also be a way to solve the original (PHP 7.0)
inconsistency between internal and user-defined functions
(although PHP 8.1 started to take the opposite route...)


>
> I don't like it and I have no good idea how that would work as it would be
> a pretty big BC break.
>
> Maybe it would be easier to change strict_types to default to 1 in PHP 9
> along with adding the null coercion for null when strict_types is 0 rather
> than inventing a new strict_types value like -1 that would allow null
> coercion as well.
> Starting with a notice in PHP 8.2 when the directive is not present might
> be an interesting starting point. And no more warning for implicit coercion
> when strict_types=0 directive is explicitly defined as it would not change
> anymore in PHP 9.
>

Or maybe (if going directly from error to implicit coercion is deemed too
"risky") the current TypeError in non-strict_types mode (when passing NULL
to a user-defined function expecting a scalar) could first be "demoted" to
some kind of Notice [who said E_STRICT] in 8.2 (along with reverting the
Deprecation added in 8.1 for internal functions) and removed in 9.0?

-- 
Guilliam Xavier


Re: [PHP-DEV] Setting to disable the "Undefined array index" warning

2022-02-15 Thread Guilliam Xavier
On Tue, Feb 15, 2022 at 3:07 PM Rowan Tommins 
wrote:

> On 15/02/2022 12:54, Andreas Leathley wrote:
> > The problem with your way of writing code is that it is ambiguous in
> > meaning, which is why this is a warning.
>
>
> I think that's a good way of looking at it. There's actually quite a lot
> of code hiding a check like "if ($array['key'])"; roughly speaking, it's
> short-hand for:
>
> if ( array_key_exists('key', $array) && $array['key'] !== null &&
> $array['key'] !== false && $array['key'] !== 0 && $array['key'] !== 0.0
> && $array['key'] !== '' && $array['key'] !== [] )
>

Agreed, but you forgot the most "annoying":

&& $array['key'] !== '0'


> Now, if that's what you intended, there's a syntax that's slightly more
> explicit while still being reasonably short: the empty() pseudo-function:
>
> if ( ! empty($array['key']) )
>
> On the other hand, if what you actually meant was this:
>
> if ( array_key_exists('key', $array) && $array['key'] !== null )
>
> Then you might have some bugs lurking, and actually want the isset()
> pseudo-function instead:
>
> if ( isset($array['key']) )
>
> For other cases, you do have to spend a few more characters to be
> explicit, often using the "??" operator; for instance, if you expect
> $array['key'] to be either unset or a boolean, and want this:
>
> if ( array_key_exists('key', $array) && $array['key'] === true )
>
> Then the shortest is probably something like this:
>
> if ( $array['key'] ?? false === true )
>

Mind operator precedence! This is interpreted as:

if ( $array['key'] ?? (false === true) )

(obviously not intended), so you need explicit parentheses:

if ( ($array['key'] ?? false) === true )


I will also note that the "shorthands" (!empty(), isset(), ?? null) will
also "hide" another warning when the $array variable itself is undefined


Re: [PHP-DEV] [VOTE] User Defined Operator Overloads

2022-01-10 Thread Guilliam Xavier
Hi Jordan,

Many thanks for all your replies. But did you miss Côme's mail (maybe
because you weren't direct recipient)? Anyway, here it is again:

On Tue, Jan 4, 2022 at 10:02 AM Côme Chilliet  wrote:

> Hello,
>
> From the RFC:
>
> > If the left operand produces a TypeError due to the parameter types
> listed in the implementation, the operation is not retried with the right
> operand and the error is instead returned immediately. This is to help
> developers encounter errors in their program logic as early as possible.
>
> This feels wrong if I understand correctly.
>
> Let’s say I create a class A and I want to add support for "2 / new A()",
> which by default does not work.
>
> I can do
> class A
> {
>   operator /(int $other, OperandPosition $operandPos): mixed
>  {
> return "example";
>  }
> }
>
> Now someone wants to build on my work, and add a class B that supports
> "new A() / new B()".
>
> class B
> {
>   operator /(A $other, OperandPosition $operandPos): mixed
>  {
> return "example";
>  }
> }
>
> This will not work because it will first try A->{'/'}(B) that throws a
> TypeError? So it means what I was able to do for floats, cannot be done for
> my new classes afterwards? This is inconsistent I think. It also means it
> is not possible to extend any existing class with operators interacting
> with a new class, meaning you can only use operators among classes aware of
> each other, most likely from the same package/library.
>
> Also, this was stated already I think but I did not see an answer, from
> RFC example:
> > class Matrix {
> > public function __construct(readonly public array $value) {}
> >
> > public operator *(Matrix $other, OperandPosition $operandPos): Number
> > {
> > if ($operandPos == OperandPosition::LeftSide) {
> > // Count of my columns needs to match
> > // count of $other rows
> > } else {
> > // Count of my rows needs to match
> > // count of $other columns
> > }
> > }
> > }
>
> The second branch of the if is dead code, as $matrix1 * $matrix2 will
> always call $matrix1->{'*'}($matrix2, LeftSide) and never the other way
> around.
> This means that $operandPos is useless in all cases where operators are
> only typed againts the same type, and points to this design solution being
> wrong.
>
> There is «Why not interfaces?» in the FAQ, does that mean that operators
> cannot be added in interfaces? This is not stated clearly in the RFC.
>
> Also, it is not clear if operator overload will affect comparison
> operations used in core functions such as in_array, sort and so on.
> Does implementing operator == allows using in_array to find an object in
> an array?
> Which of these internal functions use == and which use ===, which is not
> overloadable?
> Does implementing operator <=> allows sorting of arrays containing my
> objects?
>
> Côme
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>
>
I too would be interested in your answers to those.

Best regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Is there an RFC/discussion for ::class being a specific type?

2021-11-19 Thread Guilliam Xavier
>
> For example, this is valid:
>>
>> echo "string"::class;
>>
>
> What! Why is it allowed when it gives the same as string::class, and
> $string::class is an error? https://3v4l.org/hfvXm#v8.1rc3
>

Sorry I forgot the namespace... so it really gives the same as "string".
https://3v4l.org/rlZFF#v8.1rc3
Still surprising... maybe possibly useful for dynamically generated code? :/

-- 
Guilliam Xavier


Re: [PHP-DEV] Is there an RFC/discussion for ::class being a specific type?

2021-11-19 Thread Guilliam Xavier
>
> For example, this is valid:
>
> echo "string"::class;
>

What! Why is it allowed when it gives the same as string::class, and
$string::class is an error? https://3v4l.org/hfvXm#v8.1rc3

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [RFC] Deprecate dynamic properties

2021-10-13 Thread Guilliam Xavier
On Wed, Oct 13, 2021 at 11:17 AM Guilliam Xavier 
wrote:

> Off-topic:
>
> if ( class_exists('\\WeakMap') ) {
>>
>
> People should stop using a leading slash in FQCN *strings*.  \Foo::class
> is "Foo", not "\Foo".  It might work generally but that's asking for
> problems (e.g. for autoloaders).
>
> (Sorry.)
>

And of course I mistyped "leading backslash"... Also externals.io seems to
strip them, so:  \\Foo::class is "Foo", not "\\Foo".


Re: [PHP-DEV] Re: [RFC] Deprecate dynamic properties

2021-10-13 Thread Guilliam Xavier
Off-topic:

if ( class_exists('\\WeakMap') ) {
>

People should stop using a leading slash in FQCN *strings*.  \Foo::class is
"Foo", not "\Foo".  It might work generally but that's asking for problems
(e.g. for autoloaders).

(Sorry.)


Re: [PHP-DEV] Proposal: Adding an ARRAY_FILTER_REINDEX flag to array_values

2021-09-20 Thread Guilliam Xavier
On Sun, Sep 19, 2021 at 3:11 PM tyson andre 
wrote:

> Hi internals,
>
> Currently, array_filter will always return the original keys.
> This often requires an additional wrapping call of
> array_values(array_filter(...)) to reindex the keys and return a list.
> (or applications may not realize there will be gaps in the keys until it
> causes a bug or unexpected JSON encoding, etc.)
>

Hi,

This "issue" is not limited to array_filter(), there's also array_unique()
and even array_diff()/array_intersect() whose variadic signature doesn't
allow to add a flag (I think?)...

PS: and array_column() has the opposite issue...

-- 
Guilliam Xavier


Re: [PHP-DEV] Option for array_column() to preserve keys.

2021-09-08 Thread Guilliam Xavier
Yes please! This has been requested multiple times, for instance:
- https://bugs.php.net/bug.php?id=64493
- https://bugs.php.net/bug.php?id=66435
- https://bugs.php.net/bug.php?id=73735

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] readonly properties

2021-08-18 Thread Guilliam Xavier
>
> >> 2. DateInterval->days
> >>
> >> $interval = (new DateTime())->diff(new DateTime());
> >> var_dump($interval->days); // 0
> >> $refl = (new ReflectionObject($interval))->getProperty('days');
> >> var_dump($refl->isReadOnly()); // false
> >> var_dump($refl->isPublic()); // true
> >> $interval->days = 2;
> >> var_dump($interval->days);  // 0
> >>
> > The DateInterval properties are currently implemented as getters/setters
> on
> > some internal state. Some of those are getter-only, but probably not
> fully
> > immutable.
>
> I was referring to the property "days" only as this is a non writable
> value generated on "DateTime->diff".
>
> As you can see in the snipped it doesn't allow to modify days but it
> also doesn't fail which seems wrong to me.
>
> I don't have much knowledge about internals but would it be possible to
> define "public readonly int|false $days" not using getters/setters and
> keep all other properties as it?
>

Hi,

FWIW, I too agree that [$interval->days, $interval->days = 2,
$interval->days] giving [0, 2, 0] without any warning (or
https://3v4l.org/h8Cju for a variation) seems wrong.

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [RFC] Add parse_query_string as an alternative to parse_str

2021-08-18 Thread Guilliam Xavier
On Fri, Aug 6, 2021 at 9:43 PM Kamil Tekiela  wrote:

> Hi Internals,
>
> Thanks for all the feedback. I have changed the name to http_parse_query as
> it looks like more people prefer that name. I have also updated
> https://wiki.php.net/rfc/parse_str_alternative for 8.2 (sorry for the
> confusion) and I added open points.
> I hear two concerns currently about this RFC. Please note that my intention
> was to provide a simple drop-in replacement. However, I agree that there is
> a lot of room for improvement in this area, so I highly appreciate your
> comments on how we can best tackle these open points.
> I will not open this RFC for voting any time soon, as I want to let the
> conversation run through to see what other options/concerns people have.
> Please feel free to share your comments on what you think is the right path
> to improve this functionality in PHP.
>
> Regards,
> Kamil
>

Hi, thanks for the RFC.

I agree with Rowan in https://externals.io/message/115642 that
http_parse_query() should "mirror http_build_query() as closely as
possible", notably:
  - have a similar signature (except for the first parameter `array|object
$data` becoming `string $query` and the return type `string` becoming
`array`, of course);
  - do not do name mangling (and for your question "what should happen to
mismatched square brackets?": not sure without an example, but I would say
"just keep them as is").

Best regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Nullable intersection types

2021-07-23 Thread Guilliam Xavier
On Fri, Jul 23, 2021 at 11:58 AM Nicolas Grekas 
wrote:

> Hi everyone,
>
> as proposed by Nikita and Joe, I'm submitting this late RFC for your
> consideration for inclusion in PHP 8.1. Intersection types as currently
> accepted are not nullable. This RFC proposes to make them so.
>
> I wrote everything down about the reasons why here:
> https://wiki.php.net/rfc/nullable_intersection_types
>
> Please have a look and let me know what you think.
>
> Have a nice read,
>
> Nicolas
>

Hi Nicolas, thank you for putting this up.  Just two editorial notes:

- "This is because any intersection that contains the null type is
identical to the null type itself.": I don't think that `X` is the
same as `null` but rather like `never` (i.e. the "bottom/empty" type, or
simply "impossible/nonsensical/bogus")?

- "Should brackets around the intersection be: not needed / mandatory /
allow both styles": maybe clearer would be e.g. "forbidden / mandatory /
optional (allow both styles)"?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] intersection types and null for defaults, properties and return types

2021-07-21 Thread Guilliam Xavier
Replying to multiple things:

On Mon, Jul 19, 2021 at 8:16 PM G. P. B.  wrote:

>
> And I find it frankly insulting that in the four month this RFC has been
> published for discussion, with multiple push backs for voting due to bugs
> and me wanting that people know what implementation is - for the most part
> - going to land in php-src, this specific point has not been raised.
>

I'm sorry if you felt it like that (even if maybe not from me personally),
as I had the impression that it *has* been raised, several times:

  - https://externals.io/message/113712#113730 : "Does this miss an
opportunity, though? It's useful to be able to write A|null."
  - https://github.com/php/php-src/pull/6799#issuecomment-804761117 : "Is
there any reason to not allow ?A type?"
  - https://github.com/php/php-src/pull/6799#issuecomment-805175050 :
"However, if I'm not mistaken, you would create the only type that is not
nullable. That feels like an unnecessary edge-case. Would it be very
difficult to at least allow the union of an intersect type with null?"

Even though you replied to each of them (explaining the why, so I didn't
add an extra voice then*), that does look like this specific point was
actually raised in early discussion?

*But I can add my thank you for implementing this feature in the first
place! =)

On Tue, Jul 20, 2021 at 1:07 PM Nikita Popov  wrote:

>
> I don't think there's been any malicious intent here -- it was obvious to
> you and I that not allowing unions implies not allowing nullability, but I
> can see how people less familiar with our type system implementation would
> not make that connection. After all, we do provide the separate ?T syntax,
> even if it is an internal alias for T|null.
>
> It's an unfortunate fact of the RFC process that concerns are sometimes
> only raised when voting starts and people start looking at the
> implementation -- or in this case, when they test the implementation after
> it has landed...
>

Agreed to both points.

On Tue, Jul 20, 2021 at 7:40 PM Jordan LeDoux 
wrote:

>
> For example, in my own projects if I had the need for such a thing, I
> would instead use: X This would enable me to provide
> arbitrarily detailed information about the conditions of the optional
> nature of the data and an implementation of it that was aware of the nature
> of my program. That can't be easily achieved with nulls.
>

Nicolas said: "I know about the null pattern, but it is quite uncommon in
PHP, because "null" works just great usually."
(and I would add that it probably suffers from the lack of generics and/or
tagged unions).

In retrospect, do you think you would argue against
https://wiki.php.net/rfc/nullsafe_operator ? and even
https://wiki.php.net/rfc/nullable_types ?

On Tue, Jul 20, 2021 at 9:19 PM Deleu  wrote:

>
> I don't know if anyone has offered this before, but if making an exception
> for nullable Intersection is on the table, what about putting the null sign
> at the end?
>
> X?
>
> It doesn't seem ambiguous because PHP defines ?X as nullable X. It doesn't
> seem obvious what the ? is doing at the end but at least it doesn't seem
> ambiguous.
>
>>
IIRC one reason the prefix syntax was chosen (for PHP) instead of the
postfix one (from other languages) is to prevent a potential conflict with
hypothetical future generics using a "X" syntax (because "X" would
then have been interpreted as a PHP closing tag).

On Wed, Jul 21, 2021 at 9:05 AM Nicolas Grekas 
wrote:

>
> Thanks Nikita, Joe and the others for opening the possibility of a late
> RFC. I'm going to write one down asap!
>

Thanks, looking forward to the RFC.


Re: [PHP-DEV] intersection types and null for defaults, properties and return types

2021-07-19 Thread Guilliam Xavier
On Mon, Jul 19, 2021 at 4:26 PM Nicolas Grekas 
wrote:

>
> https://github.com/php/php-src/pull/7259
>

Great! Thanks! Interesting how it works out-of-the-box with just this
addition in Zend/zend_language_parser.y:

```diff
 type_expr:
  type { $$ = $1; }
  | '?' type { $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; }
  | union_type { $$ = $1; }
  | intersection_type { $$ = $1; }
+ | '?' intersection_type { $$ = $2; $$->attr |= ZEND_TYPE_NULLABLE; }
 ;
```

On Mon, Jul 19, 2021 at 5:09 PM Dan Ackroyd  wrote:

> nicolas-grekas wrote on the PR:
> > ?X cannot be confused with
>
> It confused me. A compiler might understand it, but as a human I have
> trouble understanding it.
>
> Trowski wrote:
> > The syntax should be either ?(X) or (X)|null
>
> Non-ambiguous syntax is much better than ambiguous syntax.
>

Maybe it's just a matter of habit?
For instance I got used to seeing things like `!$x = f()` (e.g. `if (!$x =
f()) { throw /*...*/; } /* use $x */`) because some CS consider explicit
parentheses in `!($x = f())` redundant (as PHP has a special case that
"overrides" the normal precedence `(!$x) = f()` which would be an error).
If you first consider `X` as a type "unit", then it makes sense to make
it "nullable" by prefixing it with `?`, I think?


>
> But this discussion is moot for 8.1.
>
> This limitation might make intersection types not be considered usable
> by some projects, but the feature freeze is today.
>

Which can also be reversed: "The feature freeze is today, but this
limitation might make intersection types not be considered usable by some
projects"? (playing devil's advocate, I don't master the process)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] intersection types and null for defaults, properties and return types

2021-07-19 Thread Guilliam Xavier
On Mon, Jul 19, 2021 at 4:05 PM Larry Garfield 
wrote:

>
> I can see the argument that "I need something with these two interfaces...
> or nothing" is a valid use case to care about.  However, as Saif noted,
> this is a side effect of the inability to mix union and intersection types.
>
> So, my question would be, how feasible will it be in the future to
> introduce that mixing?  If it's something that is likely to show up in 8.2
> or 8.3, we may be better off going "meh" for now and letting a solution
> fall out naturally later.  If it's something that could take a decade, then
> figuring out a way to special case "or null" in the meantime is probably
> worthwhile.  (I don't know what the best way to do that is.)
>

You made me remember that [we had non-scalar parameter type declarations
since PHP 5, and] we got scalar type declarations and return type
declarations in 7.0 but nullable type declarations "only" in 7.1 (but I
agree).

-- 
Guilliam Xavier


Re: [PHP-DEV] intersection types and null for defaults, properties and return types

2021-07-19 Thread Guilliam Xavier
On Mon, Jul 19, 2021 at 10:41 AM Nicolas Grekas 
wrote:

> Hi all,
>
> I want to bring your attention to a behavior that was mostly overlooked:
>
>1. it is not possible to use an intersection type with an argument that
>defaults to null
>2. it is not possible to use an intersection type with a nullable
>property (nor to make it default to null)
>3. it is not possible to use an intersection type with a nullable return
>type
>
> Actually, 2. was possible until it was "closed" in
> https://github.com/php/php-src/pull/7254
>
> I reported these behavior and you might find some discussion about it in
> https://bugs.php.net/81268
>
> Looking at the past discussion on this list (
> https://externals.io/message/113712) and at the rfc itself (
> https://wiki.php.net/rfc/pure-intersection-types), this was mostly
> overlooked.
>
> That's why I'm posting this message. So that we can have that missing
> discussion here.
>
> To me, we are going to need (userland "we") these capabilities.
>
> It's quite surprising to be "forced" to return something, or "forced" to
> pass a value, when all other types in PHP allow "null". I know about the
> null pattern, but it is quite uncommon in PHP, because "null" works just
> great usually.
>
> I feel like we "just" need to agree on a syntax to make this possible. It
> was first suggested in the related PR to use "?A" (see
> https://github.com/php/php-src/pull/6799#issuecomment-804761117)
>
> This was rejected by the author with the reasoning that (?A) could mean
> (?A) or ?(A) or even (?A)|B.
>
> I personally don't think this ambiguity exists: (?A)|B is strictly the same
> as A, thus ?A cannot also mean A, and I don't get how one could take
> ?A for  (?A)|B.
>

To me, the `|` (instead of `&`) in the original "is it `(?A)|B` or
`?(A)`" was just a blatant typo.
By the way, I think you made a couple of typos yourself:
  - "Actually, 2. was possible until [GitHub PR 7254]": 2. wasn't possible
(as shown in bugsnet #81268), I guess you meant 1. (i.e.
https://github.com/php/php-src/pull/7254/commits/710332aec7adf0f729b927d6bb7ae33c38703ce7
)
  - "(?A)|B is strictly the same as A": looks like you copy-pasted the
original typo ;)
Indeed, `(?A)`, i.e. `(null|A)` (currently both unsupported syntaxes),
is necessarily the same as just `A`.

As for supporting the `?A` syntax, several issues were raised:
  - Ambiguity: We would want the `?` "unary operator" to have a "lower
precedence" than the `&` "binary operator" (like `null|A` or explicit
`null|(A)`), which would be the opposite of familiar `!A` for "true"
operators.  There was also some opposition to "implicit precedence" /
preference for requiring explicit grouping.
  - Inconsistency: The similar `?A|B` syntax was explicitly rejected when
introducing union types.  Moreover the future scope anticipates full
composite types, allowing arbitrary `A|C` (or `(A)|C`).

And the main obstacle to supporting general composite types (whatever the
syntax): Unknown variance/LSP correctness (apparently complex to
specify/implement): George expressed themself in
https://wiki.php.net/rfc/pure-intersection-types#composite_types_ie_mixing_union_and_intersection_types
:

> While early prototyping shows that supporting A|C without any grouping
looks feasible, there are still many other considerations (e.g.
Reflection), but namely the variance rules and checks, which would be
dramatically increased and prone to error.

and in https://github.com/php/php-src/pull/6799#issuecomment-805452895 :

> the issue is less about parsing nor type checking (as my initial
prototype shows although far from done), but the variance rules and checks,
it already needs a different nested loop order to traverse both the parent
and the child type list just for the pure intersection type case, and at
this time I haven't thought deeply about how to handle this nor have really
any idea how to achieve this.

(but someone else may be able to sort that out?)

That said, to me it also feels like the `null` type/value is "special", and
that PHP has a history of "nullability" being more than "just a union where
one of the types is `null`", making "nullable intersection types" desirable
(even without waiting for [hypothetical] full composite types).  But I fear
that most of the previous points still apply...


> Another argument is that ?A might collide with a future syntax. But I
> fail to see how. For sure we create examples of such collisions, but they
> all look constructed to me.
>
> Shouldn't we allow ?A ? Intersection types look unfinished to me without
> compat with nullables.
>
> Cheers,
> Nicolas
>

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] [VOTE] is_literal

2021-07-19 Thread Guilliam Xavier
On Fri, Jul 16, 2021 at 2:47 AM Craig Francis 
wrote:

> Just another day, and another injection vulnerability (please patch):
>
> https://woocommerce.com/posts/critical-vulnerability-detected-july-2021/
>
> If only escaping wasn't being used, so user values did not get included in
> certain strings :-)
>
> diff -r
> woocommerce.5.5.0/includes/data-stores/class-wc-webhook-data-store.php
> woocommerce.5.5.1/includes/data-stores/class-wc-webhook-data-store.php
> 280c280
> < $search  = ! empty( $args['search'] ) ? "AND `name` LIKE '%" .
> $wpdb->esc_like( sanitize_text_field( $args['search'] ) ) . "%'" : '';
> ---
> > $search  = ! empty( $args['search'] ) ? $wpdb->prepare( "AND
> `name` LIKE %s", '%' . $wpdb->esc_like( sanitize_text_field(
> $args['search'] ) ) . '%' ) : '';
>

On Sat, Jul 17, 2021 at 3:45 AM Craig Francis 
wrote:

> On Fri, 16 Jul 2021 at 21:24, Hans Henrik Bergan 
> wrote:
>
> > short of a bug in esc_like(), i don't even see the vulnerability issue in
> > that code?
> >
>
>
> Sorry Hans, I copied the wrong diff.
>
> There were only 2 changes from woocommerce 5.5.0 to 5.5.1.
>
> Like you I was wondering what that diff was doing before posting - I'm
> fairly sure it's just to be consistent with the other lines (which all use
> $wpdb->prepare).
>

I don't think so.  Looking at
https://developer.wordpress.org/reference/functions/sanitize_text_field/ and
https://developer.wordpress.org/reference/classes/wpdb/esc_like/
you can see that they *don't* escape single quotes,
so there was *indeed* an SQL injection vulnerability in that code.

(Which is [one of the reasons] why I avoid WordPress [and especially
third-party themes / plugins] as much as possible.)

-- 
Guilliam Xavier


Re: [PHP-DEV] [VOTE] Deprecations for PHP 8.1

2021-07-05 Thread Guilliam Xavier
On Mon, Jul 5, 2021 at 1:39 PM Mike Schinkel  wrote:

> > On Jul 5, 2021, at 7:14 AM, Rowan Tommins 
> wrote:
> >
> > On 05/07/2021 11:46, Patrick ALLAERT wrote:
> >> Did we ever deprecated something without the immediate intention of
> >> removing it?
> >
> >
> > What would that even mean?
>
> It would mean that although the functions are available and allowed, they
> are not recommended[1].
>
>
> > Surely a deprecation, by definition, is a notice that something is going
> to be removed.
>
> I know that you, and others on this list, have chosen to define
> deprecation as including removal, but that is actually not the accepted
> definition on the web, nor is it in any way a requirement, it is just your
> preference.
>
> Indirectly from Wikipedia and voted as the top answer on StackOverflow
> here[2] (emphasis MINE):
>
> "deprecation is a status applied to software features to indicate that
> they should be avoided, typically because they have been superseded.
> Although deprecated features remain in the software, their use may raise
> warning messages recommending alternative practices, and deprecation MAY
> indicate that the feature will be removed in the future."
>
> So I am arguing for the legitimacy of retaining "deprecated" features if
> their removal would cause significant BC breakage, I'm not just trying to
> be a pendant.
>
> -Mike
> [1] https://whatis.techtarget.com/definition/deprecated
> [2] https://stackoverflow.com/questions/8111774/deprecated-meaning
>

Hi Mike,

Your links speak *in general*. However this is *specifically for PHP*:
https://www.php.net/manual/en/errorfunc.constants.php#errorfunc.constants.errorlevels.e-deprecated-error
(*emphasis* mine)

E_DEPRECATED: Run-time notices. Enable this to receive warnings about
code that *will not work in future versions*.

As for "significant BC breakage", isn't that what major versions are for?
(and with the current release plan, 9.0 would be for end 2025, i.e. 4 years
after 8.1)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Alternative syntax for Nowdoc.

2021-06-30 Thread Guilliam Xavier
Hi,

Maybe other syntax could be used, but I don't know which. In javascript
> only a backtick is used:
> https://developers.google.com/web/updates/2015/01/ES6-Template-Strings .
> But in PHP this is used as eval.
>

Just a precision, because you keep referring to it as "eval", which makes
me "tick" (haha): `$cmd` (i.e. $cmd wrapped in a pair of backticks) is the
same as shell_exec($cmd), not eval($cmd).

(BTW, one of JS "template strings" main selling points is string
substitution / variable interpolation, which is explicitly *not* wanted
with nowdoc [VS heredoc].)

As for the proposal, overall I agree with Rowan -- well, that would not be
exactly like single quotes (regarding [not] escaping them), but still "yet
another way" to write a nowdoc string literal.

PS: "amusingly", the code samples are hard to understand after rendered on
https://externals.io/message/115213

-- 
Guilliam Xavier


Re: [PHP-DEV] [Vote] Partial Function Application

2021-06-30 Thread Guilliam Xavier
On Tue, Jun 29, 2021 at 10:32 PM Levi Morrison via internals <
internals@lists.php.net> wrote:

> On Tue, Jun 29, 2021 at 12:05 PM Larry Garfield 
> wrote:
> >
> > On Tue, Jun 29, 2021, at 1:00 PM, Larry Garfield wrote:
> > > On Tue, Jun 29, 2021, at 12:30 PM, Guilliam Xavier wrote:
> > > > (Extracted from the "Pipe Operator, take 2" thread)
> > > >
> > > > On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield <
> la...@garfieldtech.com>
> > > > wrote:
> > > >
> > > > > [...]  Most of the
> > > > > complexity comes from the initial "this is a function call, oops
> no, it's a
> > > > > partial call so we switch to doing that instead", which ends up
> interacting
> > > > > with the engine in a lot of different places.  [...]
> > > >
> > > > Are you saying that the implementation complexity is mainly due to
> chosing
> > > > a syntax that looks like a function call?  [...]
> > >
> > > From what I understand from Joe, most of the complexity comes from
> > > producing something that isn't a closure but shares the same interface
> > > as a closure (at least that's what it would be in PHP terms), which
> > > then requires lots of special handling throughout the engine.  I don't
> > > fully understand it all myself, TBH.
> > >
> > > I've been pondering if a completely different approach with a prefix
> > > symbol would be able to be less complex, and the simple answer is I
> > > have absolutely no idea.  But we are running low on symbols...
> >
> > Ah, I found the technical details that Joe gave me (right after I hit
> send, of course).  Quoting Joe:
> >
> > "the engine expects certain things to happen, and is designed and then
> optimized around those assumptions ... for example, a stream of INIT, SEND,
> DO_FCALL is not meant to be interrupted, the first fundamental change you
> have to make is making the engine aware that stream of INIT, SEND, + are
> not always followed by DO_FCALL "
> >
> > So yes, it sounds like hooking into the function call process is where
> the complexity comes from.  Which suggests that an approach that works
> using a different syntax that desugars to a closure would avoid that issue,
> but then we need a syntax that wouldn't be ambiguous, and that's getting
> harder and harder to find.  (Nikita's first-class-callables RFC notes some
> of the issues with available symbols, and they're essentially the same for
> partials either way.)  And I've been told that creating closures in the AST
> compiler is Hard(tm)...
>
> Based on what you said, the syntax isn't really the issue. Rather, the
> issue is assumptions about how function calls work at the opcode
> level. Any implementation of only _partially_ doing a function call
> will have to deal with such things in some form. To a degree this is
> inherent complexity.
>

Thanks for clarifications.
IIUC, whatever the syntax, any PFA implementation will need either to hook
into the function call process (current approach) or to create a closure
"from scratch" (which may be actually more complex);
and some degree of [implementation] complexity is conceptually inherent
anyway.
(FCC doesn't need to bind values so might have other options? maybe not...)


> Maybe separate opcodes for every piece of the call would be better in
> that optimizers, etc, won't have expectations around the new opcodes
> and we don't change assumptions about the existing opcodes? I doubt
> that it would be much simpler, but I am curious to know.
>

-- 
Guilliam Xavier


Re: [PHP-DEV] [Vote] Partial Function Application

2021-06-29 Thread Guilliam Xavier
On Tue, Jun 29, 2021 at 11:04 AM Côme Chilliet <
come.chill...@fusiondirectory.org> wrote:

> Le Thu, 17 Jun 2021 08:30:43 -0500,
> "Larry Garfield"  a écrit :
> > > > The ? character was chosen for the placeholder largely because it was
> > > > unambiguous and easy to implement. Prior, similar RFCs (such as the
> > > > original Pipe Operator proposal from several years ago) used the $$
> > > > (lovingly called T_BLING) sigil instead. So far no compelling
> argument
> > > > has been provided for changing the character, so the RFC is sticking
> > > > with ?.
> > >
> > > The main argument for $$ is to be able to have partial methods with
> $$->,
> > > this should be stated in this paragraph.
> >
> > That's not something that was ever brought up in the discussion.
>
> Finally found where I read that, it’s in an other RFC:
>
> https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
>

For the record, Larry replied on this subject:
https://externals.io/message/114770#114785 (second part).

Note that for `$$->foo(/*whatever*/)` the signature couldn't be extracted
(because the class of $$ is unknown).

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [Vote] Partial Function Application

2021-06-29 Thread Guilliam Xavier
(Extracted from the "Pipe Operator, take 2" thread)

On Tue, Jun 29, 2021 at 12:54 AM Larry Garfield 
wrote:

> On Mon, Jun 28, 2021, at 5:30 PM, Olle Härstedt wrote:
>
> > Would a slimmed down version have more support? How about removing the
> > variadic operator, and let the user manually add the lambda for those
> > cases?
>
> I talked with Joe about this, and the answer is no.  Most of the
> complexity comes from the initial "this is a function call, oops no, it's a
> partial call so we switch to doing that instead", which ends up interacting
> with the engine in a lot of different places.
>

Are you saying that the implementation complexity is mainly due to chosing
a syntax that looks like a function call?
If yes, is it also the case for the "First-class callable syntax" RFC?
And does it mean that a different syntax (e.g. with a prefix operator)
would result in a simpler implementation?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Introduce str_left/right In 8.1

2021-06-24 Thread Guilliam Xavier
On Thu, Jun 24, 2021 at 1:17 PM Kamil Tekiela  wrote:

> I am against adding these functions, but for different reasons than Sara
> and George.
> If we add str_left and str_right then there should be a corresponding
> variant in mbstring. The byte-string functions are rarely useful. Adding
> these functions to mbstring unnecessarily complicates the extension for
> little to no gain.
>

So you seem to relate to Christoph's (and Rowan's) point.


> Another point is that if we decide to add them, then we will bikeshed
> forever in an unresolvable manner about the name. Should it be called
> str_left or strleft? Current functions don't have a naming convention, so
> using either variant will be wrong.
>

To be fair, most "strxxx" functions were historically more-or-less copied
from C; most recent additions have been "str_xxx".


> Personally, I find substr to be more clear about the intent. I know that I
> am asking for a part of the string. Whereas str_left doesn't convey an
> action immediately. Without knowing its purpose I wouldn't know if it will
> pad the string from the left, strip characters from left, or take the
> leftmost part of the string.
>

True, I can also imagine bikeshed like "str_leftmost", "str_start",
"str_first[_n]" (and same for rightmost/end/last)...


> Don't take it the wrong way, but I think it's a waste of time to implement
> a function that doesn't even need a polyfill in the userland.
>
> Regards,
> Kamil
>

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Name issue - is_literal/is_trusted

2021-06-24 Thread Guilliam Xavier
On Thu, Jun 24, 2021 at 9:14 AM Scott Arciszewski 
wrote:

> On Thu, Jun 24, 2021 at 2:10 AM Stephen Reay 
> wrote:
>
> > I would absolutely make use of a function that tells me if the string
> given is in fact from something controlled by the developer. But once that
> same string can also include input from the request or the environment or
> whatever by nature of integers, the function becomes useless for the stated
> purpose.
>
> Why not two functions then?
>
> - is_noble_string() -- more restrictive
> - is_noble() -- YOLO
>

I was going to ask basically the same [with different names] a few days ago
("why can't we have both?"), but then remembered
https://externals.io/message/114835#114951 , esp. the end:

"""
And to support having 2 functions, we would need 2 flags on strings. These
flags are limited, and managing 2 flags would affect performance.
"""

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Introduce str_left/right In 8.1

2021-06-24 Thread Guilliam Xavier
On Thu, Jun 24, 2021 at 12:51 AM Sara Golemon  wrote:

>
> [...] I'm
> not going to vote for it though, because it belongs in composer/packagist
> land, not in core.  I've listed the reasons for this in the str_contains()
> threads, feel free to reference those, they're still valid and correct.
>

Sorry I can't find your past message (searched for each of your first name,
last name, username) :/
Anyway, I think you always get the same retort, "if it isn't in core it
won't be used" basically?

PS: I forgot in my previous reply: thank you for writing the polyfills
clear =)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Introduce str_left/right In 8.1

2021-06-24 Thread Guilliam Xavier
On Wed, Jun 23, 2021 at 11:54 PM Rowan Tommins 
wrote:

> On 23/06/2021 22:28, Christoph M. Becker wrote:
> > substr() is about bytes, not characters.  They all may have upvoted the
> > wrong answer.  The only correct answer has just 17 upvotes.
>
>
> Just to out-pedant you, I'll point out that what most people would think
> of as a "character" is neither a byte nor a code point, but a grapheme,
> so I would say *none* of the answers on that page is correct.
>
> $string = 'Zoë'; // "Zoe\u{0308}" not "Zo\u{00EB}"
>
> var_dump(substr($string, -1));
> var_dump(mb_substr($string, -1));
> var_dump(grapheme_substr($string, -1));
>
> string(1) "�"
> string(2) "̈"
> string(3) "ë"
>
> https://3v4l.org/IMoWQ
>

I thought about the same during the night! Just to complete: there's also
iconv_substr() (but with the same result as mb_substr()), and here are two
links to compare: https://3v4l.org/kU9D5 vs https://3v4l.org/pAvB0

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Introduce str_left/right In 8.1

2021-06-23 Thread Guilliam Xavier
On Wed, Jun 23, 2021 at 6:49 PM Sara Golemon  wrote:

> On Wed, Jun 23, 2021 at 9:15 AM Hamza Ahmad 
> wrote:
>
> >
> > Since feature freeze for 8.1 is approaching, I want to request two useful
> > string functions that exist in various languages-especially those that
> run
> > on web servers and used in databases. These are respectively `left();`
> and
> > `right();`
> >
> >
> Sorry, you spent several paragraphs insisting that these are
> common functions, but you didn't explain what they're meant to actually do.
>
> Using some context, I would assume you mean this:
>
> function str_left(string $str, int $len): string {
>   return substr($str, 0, $len);
> }
>
> function str_right(string $str, int $len): string {
>   return substr($str, -$len);
> }
>

I assume the same.


>
> If that's the case, then why?  As you can see, the existing
> functionality available is trivial to write.  You don't even need to know
> any particular amount of math (which I've been recently informed shouldn't
> be a prerequisite to writing software -- shakes fist at clouds).
>
> Am I misunderstanding what these proposed functions should do, or am I
> underestimating the difficulty of typing a zero or negative sign on certain
> keyboards?
>

I think that's more about "semantics" ("conveying intent to readers") than
typing...

That said, I tend to agree with George (but maybe I'm "too" used to seeing
substr()?)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [Vote] make Reflection*#setAccessible() no-op

2021-06-23 Thread Guilliam Xavier
Meanwhile, if anybody knows why the RFC isn't listed on `/rfc`, lemme know
> :D
>

You have to add it manually, cf https://wiki.php.net/rfc/howto 3.4
(yeah...)

Cheers

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Name issue - is_literal/is_trusted

2021-06-23 Thread Guilliam Xavier
On Tue, Jun 22, 2021 at 8:11 PM Craig Francis 
wrote:

>
> The Function:
> - Is a security-based function that prevents Injection Vulnerabilities in
> PHP.
> - Flags strings written by the developer, including when concatenated.
> - Also accepts integer values, which as purely numerical cannot contain
> code/dangerous characters. (Due to technical limitations within PHP, it's
> not possible for these to be flagged as user or developer in the codebase
> itself without performance issues).
>

- `is_safe_from_injections()`?
- `is_secure_against_injections()`?
- `can_be_trusted_to_not_contain_injection_vulnerabilities()`? (okay not
this one)

Alternatively, if integers are too controversial, how about reverting the
implementation to `is_literal()` but provide a function like
`to_literal(int $int): string` (or just a "polyfill" for userland, could be
a one-liner `implode(array_map(fn ($c) =>
['0','1','2','3','4','5','6','7','8','9','-'=>'-'][$c],
str_split((string)$int)))`), so that those `implode(',', [1,2,3])` could
use `implode(',', array_map('to_literal', [1,2,3]))`?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC][DISCUSSION] Match expression v2

2021-06-18 Thread Guilliam Xavier
On Fri, Jun 18, 2021 at 4:24 PM Larry Garfield 
wrote:

> On Thu, Jun 17, 2021, at 1:49 PM, Mark Tomlin wrote:
> > Please excuse the year long bump, but I was hoping to draw some more
> > attention to the implicit "match (true)" case. I'm just a regular user of
> > PHP, nothing too fancy, just one of the many, many people around the
> world
> > who use PHP. When I first started using match statements, I thought it
> was
> > a natural thing that an implicit "match (true)" would just work. I do
> hope
> > that this makes it into PHP 8.1, as that seems like the most obvious next
> > step here and it would be nice for it to make it into the very next
> release.
> >
> > That is all. Thank you very much to Ilija Tovilo for adding the match
> > keyword to the language, and the whole PHP dev team for making this
> > incredible language. PHP has given me a whole career, and I am deeply
> > grateful to you all.
>
> I wrote a separate small RFC for implicit-true match statements (
> https://wiki.php.net/rfc/short-match).  There didn't seem to be a great
> deal of interest, though (https://externals.io/message/112496).
>
> There's not much else to do with that RFC beyond bring it to a vote and
> let the chips fall where they may.  If folks think that's worth doing I can
> do so.  It's not going to be able to scope creep much beyond its current
> minimalism.
>

Before going to vote, I think the RFC should be updated to at least mention
the strict-VS-loose comparison choice (for things like `match {
preg_match(/*...*/) => /*...*/ }`).

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [RFC] is_literal

2021-06-18 Thread Guilliam Xavier
On Fri, Jun 18, 2021 at 12:10 PM Pierre  wrote:

> Le 18/06/2021 à 08:00, Craig Francis a écrit :
> > As there’s been no issues raised with supporting integers, and doing so
> > will help adoption, the implementation will be updated to allow them.
> >
> > Now to choose the name, with the options is_known() from Joe and
> > is_trusted() from Moritz:
> >
> > https://strawpoll.com/bd2qed2xs
> >
> > Keep in mind it might also become a dedicated type in the future.
> >
> > Craig
>
> If I'm understanding this correctly, what you call a literal value is a
> statically written and compiled string, which doesn't originate from a
> user given value, but was hardcoded at some point. If so, even if the
> primary use is of course for security concerns, the realty of what it
> does is not, it's mostly about how a certain variable was defined /
> assigned. How about is_static() or is_value_static() ? Or even
> is_statically_defined() ? There's many options in this path.
>

IIUC, with the addition of integers, the function will return true for e.g.
`'SELECT * FROM foo LIMIT ' . (int)$limit` even if $limit doesn't come from
a "static" value (e.g. random_int() or even `$_GET['limit']`)

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface

2021-06-14 Thread Guilliam Xavier
> Indeed, the current implementation appears to have several problems. So,
> how about the following implementation?
>
> ```php
> interface RandomNumberGenerator
> {
> public function generate(): int;
> }
>
> final class Random
> {
> private RandomNumberGenerator $rng;
> public function __construct(?RandomNumberGenerator $rng = null)
> {
> $this->rng = $rng ?? new XorShift128Plus(random_int(PHP_INT_MIN,
> PHP_INT_MAX));
> }
> public function nextInt(): int {}
> public function getInt(int $min, int $max): int {}
> public function getBytes(int $length): string {}
> public function shuffleArray(array $array): array {}
> public function shuffleString(string $string): string {}
> public function __serialize(): array {}
> public function __unserialize(array $data): void {}
> }
>
> class XorShift128PlusNumberGenerator implements RandomNumberGenerator
> {
> public function generate(): int {}
> public function __serialize(): array {}
> public function __unserialize(array $data): void {}
> }
>
> class MT19937NumberGenerator implements RandomNumberGenerator
> {
> public function generate(): int {}
> public function __serialize(): array {}
> public function __unserialize(array $data): void {}
> }
>
> class SecureNumberGenerator implements RandomNumberGenerator
> {
> public function generate(): int {}
> }
> ```
>
> This is an approach similar to Nikita's `createDefault`. If the
> constructor has a null argument, it uses the default, XorShift128+,
> internally.
>
> Also, whether the Random class is serializable or clonable depends on the
> instance of RandomNumberGenerator being used. This means that when the
> Random class clone is called, the `$rng` member will be implicitly cloned.
>
> How about this?
>

Hello, thanks for thinking again.

A few editorial notes:
- I guess that would be "new XorShift128PlusNumberGenerator" (like the
class name)?
- The non-Secure implementations' stubs are probably missing `public
function __construct(?int $seed = null) {}`?
- The Random class' and non-Secure implementations' stubs are probably
missing `public function __clone(): void {}` (like `__serialize()`)?

That would let us use the API like this:

1. Construction: one of:
- default RNG and seed: `$random = new Random();`
- chosen RNG, default seed: e.g. `$random = new Random(new
MT19937NumberGenerator());`
- chosen RNG and seed: e.g. `$random = new Random(new
MT19937NumberGenerator(1234));`
(no "default RNG, chosen seed", but the default RNG can be documented,
and one could argue that a chosen seed only makes sense with a chosen RNG
anyway)

2. Usage: `$int = $random->nextInt();`, `$percent = $random->getInt(0,
100);`, `$dword = $random->getBytes(4);`, `$shuffledList =
$random->shuffleArray($list);` etc.

I think this is well-consistent with the "pure design" described by Nikita,
and I personally find it both flexible/extensible and easy-to-use =)
(Just beware that the namespace question will probably pop up again.)

PS: I feel like my numerous questions/suggestions (in this thread and the
previous ones) may also have caused some deviations, so I hope that I won't
need more and that other participants will reach a consensus...

Best regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Partial Function Application, take 2

2021-06-11 Thread Guilliam Xavier
Sorry, me again :s  I have tested the examples from
https://wiki.php.net/rfc/partial_function_application on
https://3v4l.org/#focus=rfc.partials and several of them currently give an
error:

- Ex 10: on the line `$c = stuff(?, ?, f: 3.5, ..., p: $point);`
=> Fatal error: Named arguments must come after all place holders
(typo I guess, `$c = stuff(?, ?, ..., f: 3.5, p: $point);` is OK)

- (Ex 11: no error but a typo: `'hi'` vs `'foo'`)

- Ex 16: for the last call `(four(..., d: 4, a: 1))(2, 3);`
=> Fatal error: Uncaught ArgumentCountError: four(): Argument #2 ($b) not
passed
(on the function definition line)
(`(four(..., d: 4, a: 1))(2, 3, 5, 6);` idem,
but `(four(..., d: 4, a: 1))(b: 2, c: 3);` throws an "Unknown named
parameter $b" Error on the call line)
(weird)

- func_get_args() and friends: one the last line `$f(1, 2);` (after `$f =
f(?);`)
=> Fatal error: Uncaught Error: too many arguments for application of f, 2
given and a maximum of 1 expected
(can make sense, e.g. https://externals.io/message/114532#114554 )

- (Callable reference: no error but a typo: `$f` vs `$foo`)

- Optimizations: on the line `$boo = $baz(4, ...);`
=> Fatal error: Uncaught Error: too many arguments and or place holders for
application of Closure::__invoke, 1 given and a maximum of 0 expected
(`$boo = $baz(?);` throws the same error,
but `$boo = $baz(4);` throws a "not enough arguments for implementation of
foo, 4 given and exactly 5 expected" Error,
and `$boo = $baz(...);` makes the subsequent `$boo(5);` throw a "not enough
arguments ..." Error)
(weird, looks like `$bar = $foo(2, ...);` and/or `$baz = $bar(3, ...);`
dropped too many params)

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Partial Function Application, take 2

2021-06-10 Thread Guilliam Xavier
On Thu, Jun 10, 2021 at 7:32 PM Guilliam Xavier 
wrote:

>
>  Since `$null?->whatever(1, 'a')` currently always returns null without
> error, shouldn't `$null?->whatever(?, 'a')` return a closure (with a
> signature built from the placeholders only) that will return null when
> called (i.e. equivalent to `fn (mixed $arg1) => null` here)?
>

Ah, we can also see `$foo?->bar(?)` as simply "desugaring" to `$foo ===
null ? null : $foo->bar(?)`, so the current behavior makes sense too (and
maybe even "more")...  I guess I was confused to get a "null-implying
error" despite using a "null-safe" call syntax :s  (There's also the
possibility of not supporting it, but I guess that would be a lose-lose...)

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Partial Function Application, take 2

2021-06-10 Thread Guilliam Xavier
On Thu, Jun 10, 2021 at 4:34 PM Larry Garfield 
wrote:

> On Thu, Jun 10, 2021, at 3:17 AM, Guilliam Xavier wrote:
> > On Wed, Jun 2, 2021 at 7:47 PM Larry Garfield 
> > wrote:
> >
> > > https://wiki.php.net/rfc/partial_function_application
> >
> > for `$null === null`, is `$c = $null->bar(?);` / `$c =
> > $null::baz(?);` an immediate error, or only later when calling
> `$c($arg)`?
>
> That dies with "call to member function on null" when trying to create the
> partial:
>
> https://3v4l.org/E6MgK/rfc#focus=rfc.partials
>

That makes sense (eager evaluation of non-placeholder "arguments",
including the called-on object).


> > does it
> > support nullsafe calls, e.g. `$foo?->bar(?)`? and if yes, what is the
> > signature of the Closure when `$foo === null`?
>
> I just checked, and it... sort of supports nullsafe.  Rather, if you try
> to partial a method on a null object, you get null back for your closure.
> Then when you try to call it, you get a "cannot invoke null" error.
> Which... I think makes sense.
>
> cf: https://3v4l.org/4XeB3/rfc#focus=rfc.partials


Well I find that unexpected :/


> As a cute side effect, Joe pointed out you could do this:
>
> https://3v4l.org/ERRdY/rfc#focus=rfc.partials


So there's a "workaround", although I wouldn't call it precisely "cute"...


> I wouldn't really call that a feature, but more of a side effect of the
> implementation.  Please don't count on that behavior.
>

I'd rather not indeed ;)  Since `$null?->whatever(1, 'a')` currently always
returns null without error, shouldn't `$null?->whatever(?, 'a')` return a
closure (with a signature built from the placeholders only) that will
return null when called (i.e. equivalent to `fn (mixed $arg1) => null`
here)?

Thanks,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Partial Function Application, take 2

2021-06-10 Thread Guilliam Xavier
On Wed, Jun 2, 2021 at 7:47 PM Larry Garfield 
wrote:

> Hi folks.  After much off-list discussion, iteration, and consideration,
> we have a new draft of PFA ready for review.
>
> The URL is the same:
>
> https://wiki.php.net/rfc/partial_function_application
>

Hi, thanks all for the reworks!  I just thought to something: does it
support nullsafe calls, e.g. `$foo?->bar(?)`? and if yes, what is the
signature of the Closure when `$foo === null` (and does it make a
difference if, inside a function, it was created as a local variable `$foo
= null;` vs received as a typed parameter `?Foo $foo`)?

Related, for `$null === null`, is `$c = $null->bar(?);` / `$c =
$null::baz(?);` an immediate error, or only later when calling `$c($arg)`?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface

2021-06-09 Thread Guilliam Xavier
On Wed, Jun 9, 2021 at 3:16 PM Go Kudo  wrote:

> Thanks Guilliam.
>
> > I'm not sure you really addressed
> https://externals.io/message/114561#114680 ?
>
> I thought I had solved this problem by implementing the
> `RandomNumberGenerator` interface.
>
> Accepting strings and objects as arguments is certainly complicated, but I
> thought it met the necessary requirements.
> From the aspect of static analysis, there seems to be no problem.
>
> Reverting to a full object-based approach would increase the cost of
> providing new RNGs from extensions. I think the string approach is superior
> in this respect.
>

How much more "costly" would it be to define a class (implementing
RandomNumberGenerator) and use its (full) name as the algo identifier?


> Nikita's `createDefault()` approach is certainly good, but I think it is
> still difficult for beginners to understand.
>
> I also thought about it for a while after that, and I think that the
> current implementation is the most appropriate for now. What do you think?
>

I still agree with Nikita that there's a discrepancy between e.g. `new
Random(RANDOM_XXX, $seed)` and `new Random(new CustomRNG(/*custom
args*/))`, which also poses additional questions, e.g.:

- (already pointed out by Jordi) `new Random(new CustomRNG(/*custom
args*/), $seed)` is "illogical" (the passed $seed won't be used) but
"possible" (even if your current implementation throws a ValueError when
$seed is non-null);

- This opens the possibility of "leaking" the RNG "source" (even if no
`public function getRNG()`), e.g.:

```
$rng = new CustomRNG(/*custom args*/);
$r1 = new Random($rng);
$r2 = new Random($rng);
var_dump($r1->nextInt() === $r2->nextInt()); // false (not true), I suppose?
```

or:

```
$rng = new CustomRNG(/*custom args*/);
$r = new Random($rng);
var_dump($r->nextInt()); // 1st of sequence
$rng->generate();
var_dump($r->nextInt()); // 3rd of sequence (not 2nd), I suppose?
```

(possibly in less obvious ways), which may be considered bad or not (but
still a discrepancy vs extension-provided algos).

Again, taking a class name and optional extra args (or an $options array,
like password_hash(), maybe even including 'seed' only for the algos that
need one) to construct, rather than an already constructed object, might be
better?

But that would also "split" the constructor args from the class (increasing
the risk of "mismatch"), and make using anonymous classes less easy, and
maybe we haven't considered all the uses cases (e.g. what about
`Random::getAlgoInfo(CustomRNG::class)`?)... So that might also be worse :/

It would be great to have more insights! (if nobody else speaks up then
let's keep it as is of course)


> > Couldn't the Random class simply implement `public function __clone():
> void` (that would internally do like `$this->rng = clone $this->rng;`)?
>
> Implicitly cloning in areas where the user cannot interfere may cause
> problems when using objects that cannot be cloned.
> However, this may be overthinking it. The reason is that a
> `RandomNumberGenerator` that cannot be cloned should be implemented as algo
> in the first place.
> If there are no objections, I will change the implementation.
>

Ah, true, I hadn't thought about non-clonable implementations... But that's
already the case for `__serialize()` and non-serializable implementations,
right? (But let's wait a bit for possible objections, indeed)


> > Indeed, a decision has to be made. If you throw an exception, we
> wouldn't have the "issue" of different results on 32- vs 64-bit machines,
> but XorShift128+ and Secure would be unusable on a 32-bit machine, right?
>
> I don't see any problem with the current implicit truncation behavior for
> this. Even if a user switches to a 64-bit environment, compatibility can be
> maintained by explicitly truncating the generated values. In addition, most
> of the other methods only use 32bit internally.
> If you are concerned about this, you should probably be concerned about
> the incompatibility with MT_RAND_PHP.
> That problem can also be compensated for with an extension that adds algo.
>

I thought you were "struggling with [this implicit truncation] behavior
when calling nextInt() in a 32-bit environment using a 64-bit RNG [...]
which means that the code loses compatibility with the result of running on
a 64-bit machine"? And you asked if throwing an exception would be
preferable?
Anyway, I personally don't care about 32-bit (but other people may).


> Regards,
> Go Kudo
>

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface

2021-06-09 Thread Guilliam Xavier
>
> Couldn't the Random class simply implement `public function __clone():
> void` (that would internally do like `$this->algo = clone $this->algo;`)?
>

Sorry I meant like `$this->rng = clone $this->rng;`.

PS: Please don't reply to this erratum, but rather to the previous message
;)


Re: [PHP-DEV] Re: [RFC] Under Discussion: Add Random class and RandomNumberGenerator interface

2021-06-09 Thread Guilliam Xavier
uestion?

>
> > I would like to answer a few unanswered questions.
> >
> > > What is bias?
> >
> > I' ve confirmed that the bias issue in mt_rand has already been fixed and
> > is no longer a problem.
> >
> > This implementation copies most of it from mt_rand. Therefore, this
> > problem does not exist.
> >
> > Therefore, an equivalent method to mt_getrandmax() is no longer provided.
>

Great!


> >
> > > uint64 & right-shift
> >
> > This is a specification of the RNG implementation. PHP does not have
> > unsigned integers, but RNG handles unsigned integers (to be precise, even
> > the sign bit is random).
> >
> > As mentioned above, PHP does not have unsigned integers, which means that
> > using the results generated by RNGs may cause compatibility problems in
> the
> > future. To avoid this, a 1-bit right shift is always required (similar to
> > mt_rand()).
>

Good to know, thanks.

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-08 Thread Guilliam Xavier
On Tue, Jun 8, 2021 at 4:09 PM Larry Garfield 
wrote:

> On Tue, Jun 8, 2021, at 5:41 AM, Guilliam Xavier wrote:
>
> > you forgot to update one
> > `explode(?)` to `str_split(?)`, and also, the first `fn($v) =>
> > 'strtoupper'` should be just `'strtoupper'`.
>
> I deliberately made that example extra verbose to show how ugly it can
> get, but I can shorten it.
>

Extra verbose would have been `fn($v) => strtoupper($v)`, there was
obviously a typo (already correct in the second equivalent code fragment).
Anyway, I see you fixed it, and also updated the Haskell section :thumbsup:


>
> > Also, quoting from
> >
> https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
> > :
> >
> > """
> > Both approaches to the pipe operator have their advantages. The $$ based
> > variant allows using more than plain function calls in each pipeline step
> > (e.g. you could have $$->getName() as a step, something not possible with
> > PFA), and is also trivially free. A PFA-based optimization would entail
> > significant overhead relative to simple function calls, unless special
> > optimization for the pipe operator usage is introduced (which may not be
> > possible, depending on precise semantics).
> > """
> >
> > Could you (or Nikita) expand a bit on this (esp. the advantages of the
> PFA
> > approach / disadvantages of Hack's approach)?
>
> It's true PFA doesn't cover every possible RHS of pipes.  In practice, I
> think using the piped value as an object on which to invoke a method is the
> only major gap.  Normally in functional code you would use a lens in that
> case, which (if I am understanding those correctly; that's roughly at the
> edge of my functional understanding) is essentially a function call that
> wraps accessing a property or calling a method so that it feels more
> functional, and thus pipes cleanly.
>
> However, piping with callables has a number of advantages.
>
> 1) The implementation is vastly simpler.  It's simple enough that even I
> can manage it, whereas Hack-style would be more considerably implementation
> work.
>
> 2) I would argue it's more flexible.  Once you start thinking of
> callables/functions in a first class way, producing functions on the fly
> that do what you want becomes natural, and fits better with a
> pipe-to-callable model.  For instance, the comprehension-esque example
> (which I suspect will be one of the most common use cases of pipes) is far
> cleaner with a callable, as it can obviate any question about parameter
> order.
>
> Another example I threw together last night is this proof of concept last
> night, which works when pipes, enums, and partials are combined.  I don't
> think Hack-style would be capable of this, at least not as elegantly.
>
> https://gist.github.com/Crell/e484bb27372e7bc93516331a15069f97
>
> (That's essentially a "naked either monad".)
>
> 3) I disagree that the overhead of arbitrary callables is "significant."
> It's there, but at that point you're talking about optimizing function call
> counts, mostly on partials; unless you're using pipes for absolutely
> everything, go remove an SQL query or two and you'll get a bigger
> performance boost.
>
> 4) Far more languages have callable pipes.  Hack is, as far as I am aware,
> entirely alone in having pipes be combined with a custom expression syntax
> rather than just using functions/callables.  That isn't conclusive proof of
> anything, but it's certainly suggestive.
>
> I'm going to be moving forward with this approach one way or another (if
> for point 1 if nothing else).  I do believe it is the more flexible, more
> robust approach, and fits with the general strategy I recommend of small,
> targeted changes that combine with other small, targeted changes to offer
> more functionality than either of them alone.  That's exactly what we're
> doing here.
>

All good points IMHO.

Thanks!

-- 
Guilliam Xavier


Re: [PHP-DEV] [RFC] Pipe Operator, take 2

2021-06-08 Thread Guilliam Xavier
Hi,

On Tue, Jun 8, 2021 at 12:09 AM Larry Garfield 
wrote:

> On Mon, Jun 7, 2021, at 4:00 PM, Eugene Leonovich wrote:
> > On Mon, Jun 7, 2021 at 9:03 PM Larry Garfield 
> > wrote:
> >
> > > https://wiki.php.net/rfc/pipe-operator-v2
> > >
> > FTR, there are several typos in the "Hello World" examples
> (*strto*t*upper,
> > htmlent*i*ties*). Also, these examples will not work as written because
> > explode() expects two arguments and will fail if you pass only one:
> > https://3v4l.org/tLO0s.
>
> Hm.  You're right.  It used to, but it's been a very long time since
> explode() allowed an empty split, apparently.  I updated the example to use
> str_split, which is what I'd intended to do in this case.  Thanks.
>

Are you thinking to implode()?  Anyway, you forgot to update one
`explode(?)` to `str_split(?)`, and also, the first `fn($v) =>
'strtoupper'` should be just `'strtoupper'`.

About Haskell, rather than (or in addition to) the function composition
[not "concatenation"] (.), I would mention the reverse application operator
(&):
https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Function.html#v:-38-

One thing I note is that even with PFA, some examples still need an arrow
function, e.g. the PSR-7 one:

```
ServerRequest::fromGlobals()
|> authenticate(?)
|> $router->resolveAction(?)
|> fn($request) => $request->getAttribute('action')($request)
/* ... */;
```

while in Hack you would write it as:

```
ServerRequest::fromGlobals()
|> authenticate($$)
|> $router->resolveAction($$)
|> $$->getAttribute('action')($$)
/* ... */;
```

Also, quoting from
https://wiki.php.net/rfc/first_class_callable_syntax#partial_function_application
:

"""
Both approaches to the pipe operator have their advantages. The $$ based
variant allows using more than plain function calls in each pipeline step
(e.g. you could have $$->getName() as a step, something not possible with
PFA), and is also trivially free. A PFA-based optimization would entail
significant overhead relative to simple function calls, unless special
optimization for the pipe operator usage is introduced (which may not be
possible, depending on precise semantics).
"""

Could you (or Nikita) expand a bit on this (esp. the advantages of the PFA
approach / disadvantages of Hack's approach)?

Regards,

-- 
Guilliam Xavier


Re: [PHP-DEV] json_encode indent parameter

2021-06-03 Thread Guilliam Xavier
Hello,

I have seen a similar discussion for var_export(), and the answer was
basically "use a regex". E.g.:

$json = preg_replace_callback(
'/^(?: {4})+/m',
fn ($m) => str_repeat($indent, strlen($m[0]) / 4),
json_encode($data, JSON_PRETTY_PRINT)
);

That said, I wouldn't mind a new indent parameter (but note that allowing
an arbitrary string [not limited to whitespace] might result in invalid
JSON).

Regards,

-- 
Guilliam Xavier


  1   2   >