Re: [PHP-DEV] Requiring GPG Commit Signing

2024-04-02 Thread Andreas Heigl

Hey List, Hey Derick

Am 02.04.24 um 16:15 schrieb Derick Rethans:

Hi,

What do y'all think about requiring GPG signed commits for the php-src
repository?


In general I think it is a good idea to do GPG signed commits. But in 
terms of security the idea is to be able to authenticate a user. But the 
only thing we truly and reliably can do is connect a github account to a 
commit. Whether that commit author is actually Jane Doe or Karl Napp is 
still not necessarily proven.


So if we want to make sure that something like XY doesn't happen, we 
have to add some additional restrictions to those GPG keys.


If it is just to have signed commits: I am absolutely in favour.

Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] is this thing on?

2024-03-04 Thread Andreas Heigl

Hey Folks.

Am 05.03.24 um 00:11 schrieb dan...@daniil.it:

The VSC part from github (hosting our code), can very easily be ported. Issues, 
discussions etc can not.

With the ongoing enshittification of most of the Internet due to advertising 
and tracking, we'd be negligent not hosting and owning our own content 
(including our issue tracker, but that ship has sailed now).


PHP actually recently moved from a self-hosted VCS to github due to a 
hack that compromised php's source code, moving back to a self-hosted 
instance seems like a downgrade.


However, if that's being discussed, it can be done properly, i.e. with a 
self-hosted gitlab instance, which also provides issues, projects, CI, 
basically the full devops experience, that would be the perfect chance 
to also move the mailing list and php wiki to gitlab (which is how many 
FOSS projects work currently, I.e. wayland, xorg, mesa, pipewire, asahi 
use the gitlab.freedesktop.org gitlab instance, arch linux has its own 
gitlab instance (which is also used for RFCs)).




Email has been around for half a century. Will things like Slack, Discord, and 
the like still be operational and allow access to our archives in another 25 
years? I'm almost certain it won't be.


No one is proposing to move the issue tracker to discord, slack or 
telegram: those are messengers, and should not be used as support forums 
for such a major language, mainly because they're non-indexable.


Regards,
Daniil Gentili

If I have learned one thing in decades of software development and 
emergency management it is:


Never change a process in an emergency

Processes are there to help in emergencies. They provide stable ways to 
process information. And in any case, any decission taken in an 
emergency situation will be influenced by the wish to fastly overcome 
the emergency and not by the wish to optimize the process.


Also discussions about whether a process is necessary or not or needs to 
be changed wastes resources that can help solve the problem.


That said: It is fine to discuss whether the mailinglists are the best 
thing to foster communication about the development of PHP - when the 
mailinglist is working fine.


When the mailinglist is broken (and it'S not that that happens every 
other week) the only discussion is either about the development of PHP 
or how one can help to fix the issue.


Some things didn't go well. Some things did go well. We (meaning those 
that fixed and still fix the issues at hand) might come together for a 
retrospective once everything works fine again and see what can be 
improved to help avoid such a situation the next time.


Once that is done and everything works fine I am looking forward to an 
RFC proposing better ways to communicate about all the aspects of 
developing PHP in a worldwide distributed community of volunteers.


Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] What's up with emails?

2024-02-22 Thread Andreas Heigl
On 22 February 2024 17:49:10 CET, Derick Rethans  wrote:
> On Thu, 22 Feb 2024, mjec wrote:
> 
> > On Thu, 2024-02-22 at 10:29 -05:00, Alain D D Williams  
> > wrote:
> >> On Thu, Feb 22, 2024 at 09:05:22AM -0500, Derick Rethans wrote:
> >> 
> >>> Gmail is rejecting emails after we moved the servers without telling us 
> >>> why, in enough detail to do anything about it.
> >> 
> >> I run other mail lists and have had similar problems with gmail recently.
> > 
> > Gmail explicitly tightened their requirements for senders this month, so 
> > while it's likely the server change is related, it may not be the entire 
> > cause.
> > 
> > Specifically, they require:
> > 
> > - valid spf, with specific rules for quarantining email that has @gmail.com 
> > From but doesn't pass spf
> > - valid dkim
> > - dmarc configured if the server sends more than 5k emails to Gmail
> 
> We should have all of that though?
> 
> > 
> > They also equivocally indicate a requirement for ARC and a List-Id header.
> 
> We have a List-Id header, but I've not even heard of ARC. It is on our list 
> to investigate though. Our SMTP logs definitely don't say anything about this 
> though.
> 
> > This is all at https://support.google.com/a/answer/81126.
> > 
> > I think ARC is a must; without it we'll never get to passing dkim at least, 
> > even if we rewrite from so spf passes.
> 
> But SPF is now passing? The postmaster tools show this:
> 
> Date  DKIM success rate   SPF success rateDMARC success rate
> 15 Feb 2024   100.0%  100.0%  0.0%
> 16 Feb 2024   100.0%  100.0%  0.0%
> 17 Feb 2024   100.0%  100.0%  0.0%
> 18 Feb 2024   100.0%  100.0%  0.0%
> 19 Feb 2024   100.0%  100.0%  100.0%
> 20 Feb 2024   100.0%  100.0%  100.0%
> 
> > I'm happy to pitch in to help getting this configured if that's helpful, 
> > though I'm also very conscious that too many cooks is often a greater harm 
> > than good when it comes to administration. But reach out if you think I can 
> > be helpful.
> 
> We could definitely use some people that now email delivery.

The main issue is that the things came together:

Us moving to a new listserver and
Gmail introducing new ways of fighting spam.

The later is what makes life hars now and would also have caused trouble on the 
old server.

We are currently in the process of implementig all of the stuff that gmail 
expects us to have.

The last ones are ARC and one-click unsubscribe.

If you want to know more about the hoops we have to jump in addition to moving 
the list to a new server check out 
https://blog.google/products/gmail/gmail-security-authentication-spam-protection/

Cheers

Andreas


--
Andreas Heigl


Another test-Email

2024-02-15 Thread Andreas Heigl

Feel free to disregard.
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Testemail No 4

2024-02-14 Thread Andreas Heigl

Disregard this test email.


--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Test 3

2024-02-14 Thread Andreas Heigl

test 3
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] [VOTE] [RFC] Final anonymous classes

2023-12-03 Thread Andreas Heigl

Am 03.12.23 um 19:34 schrieb Larry Garfield:

On Sun, Dec 3, 2023, at 10:34 AM, Derick Rethans wrote:

On 3 December 2023 14:49:12 GMT, Nikita Popov  wrote:

On Sun, Dec 3, 2023, at 11:40, Daniil Gentili wrote:

Hi all,

I've just opened voting for the final anonymous classes RFC @
https://wiki.php.net/rfc/final_anonymous_classes.

Voting started now, and will run until December 18th 2023, 00:00 GMT.


For the record, I've voted against this proposal because I believe it should 
have gone with option 2, that is to *always* make anonymous classes final.

It makes very little sense to me that everyone needs to explicitly mark their anonymous 
classes as final just because there is a class_alias loophole that could, in theory, have 
been used to extend anonymous classes in the past. Especially given that there is no 
evidence of this "feature" being used in the wild (or if there is such 
evidence, it was not presented in the proposal).

Regards,
Nikita

I agree with this, and would also say that this RFC is the most thin
one I've seen.

There is no reasoning, or examples, or pretty much anything else in it.


I have also voted no for the same reasons as above.  A more fleshed out RFC 
that goes default-final (which would then enable the engine optimizations 
mentioned) I would probably vote yes for.  Though one could debate if that 
should be saved for 9.0 just to be safe.  (Which I'd also be fine with.)


I also voted NO for the same reason.

But also because I am missing a few things in the RFC.

I am especially missing a reasoning as to why final for anonymous 
classes is a thing in the first place. What pain is this RFC adressing? 
(Apart from not being able to write `new final class{}`)


Also I'd expect all the relevant information from the discussion to be 
in the RFC so that we can figure out what the main points were without 
having to dig through Mailinglists or PRs.


Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org  https://hei.gl/where |
|https://hei.gl/pubkeyandreas |
+-+

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



Re: [PHP-DEV] Adding a donate link to the PHP website

2023-12-01 Thread Andreas Heigl

Hey Ben

On 01.12.23 01:04, Ben Ramsey wrote:

On Nov 30, 2023, at 02:45, Andreas Heigl  wrote:

On 30.11.23 09:39, James Titcumb wrote:

On Thu, 30 Nov 2023 at 07:28, Andreas Heigl mailto:andr...@heigl.org>> wrote:

[...snip...]

I suppose that is actually nothing that an RFC can do as I imagine that
everyone from the PHP Group needs to support this and even an RFC
wouldn't legally be able to change anything in regards to that.
Surely, everyone who has contributed (i.e. has voting karma) has the 
opportunity to vote, and therefore, if they choose not to vote, that is surely 
their choice. I don't know the ins and outs of it, but I'd have thought an RFC, 
well advertised, with plenty of time to ensure as many people can vote who have 
rights to.


What I meant by that is that the members of "The PHP Group" are currently the 
copyright holders. From a legal point of view no RFC can change that. The only way to 
change that would be for the PHP Group to transfer their copyright to someone else. What 
an RFC *can* do though is *propose* that the PHP Group transfers their copyright to the 
PHP Foundation.

Though I'm lo lawyer, so ¯\_(ツ)_/¯



I have spoken at length with a lawyer about this, and the TL;DR version is that 
every contributor owns the copyright on their specific contributions, if the 
contributions are copyrightable. Some contributions (typo fixes, white space 
changes, etc.) aren’t copyrightable, but anything more significant that is the 
contributor’s own work belongs to them.

In other words, even though the license statement says the copyright belongs to 
The PHP Group[^1] or Zend Technologies Ltd.[^2], technically, these copyrights 
only apply to the specific code contributed by these organizations or 
contributed by people for these organizations (through work-for-hire or by 
legally transferring the copyright to them).

Contributing to an open source project is NOT an implicit transfer of your 
copyright to the project. To do this, every contributor needs to sign a CLA 
that specifies they are transferring their copyright to The PHP Group.

What is implied, however—and I’m told this is how most courts in the US and 
outside would view it—is assignment of license. When someone contributes to an 
open source project, they own the copyright on their contributions, but unless 
they specify a different license that covers their contributions, it’s implied 
that they are granting use of their contributions under the same license as the 
project. In this way, the contributor can’t later demand to have their 
copyrighted code removed; it’s under the terms of the same license, which can't 
be revoked.

Once a copyright statement is placed on a source file, there’s a bunch of legal 
reasons why you cannot change or remove that copyright statement. In general, 
you should keep all copyright statements added to a source file and never 
change one that already exists on a source file. Just look at the file header 
on any WebKit[^3] source file. WebKit even specifies that you add a copyright 
notice to each file where you make “significant” changes.[^4]

With this in mind, it would be more proper to update the general copyright 
notice to something like this:

 Copyright (c) 2023 and later, The PHP Foundation and contributors. All 
rights reserved.
 Copyright (c) 1999-2023, The PHP Group and contributors. All rights 
reserved.

Since no reassignment of copyright is taking place, we don’t run into any major 
legal issues, and this tells a true and accurate story. The PHP Group were 
stewards of the project until 2023, at which point the community recognized The 
PHP Foundation as the new stewards of the project, and through all of this time 
(since 1999), the various copyrights have been owned by their respective owners 
(i.e., contributors).

If you look at the file headers on ICU source code, you can see that Unicode, 
Inc. made a similar change in 2016.[^5]

All this said… I am in favor of making this change.

I also have a lot more to say on this, as I’ve been considering opening up an 
RFC on just this topic. I had intended to reach out to Zend first (through 
Matthew Weier O’Phinney), but I haven’t done that yet, so this is the first 
time anyone from Zend has seen these ideas. My apologies. :-)

The PHP source code is interesting in that it is covered by two licenses: the 
PHP License[^6] and the Zend Engine License.[^7] This is an historical artifact 
of the early days of PHP when it was conceivable that other companies might 
develop their own engines for PHP, but we know how this story ends: for all 
intents and purposes, the Zend Engine is PHP and PHP is the Zend Engine. Yes, 
I’m aware of alternatives (with very limited adoption), and no, they don’t 
matter for this discussion.

Both the PHP License and Zend Engine License are based on the BSD 4-clause 
“Original” license,[^8] and as a result, neither are compatible with the 
GPL.[^9][^10] In fact,

Re: [PHP-DEV] Adding a donate link to the PHP website

2023-11-30 Thread Andreas Heigl



On 30.11.23 09:39, James Titcumb wrote:


On Thu, 30 Nov 2023 at 07:28, Andreas Heigl <mailto:andr...@heigl.org>> wrote:

[...snip...]



I suppose that is actually nothing that an RFC can do as I imagine that
everyone from the PHP Group needs to support this and even an RFC
wouldn't legally be able to change anything in regards to that.


Surely, everyone who has contributed (i.e. has voting karma) has the 
opportunity to vote, and therefore, if they choose not to vote, that is 
surely their choice. I don't know the ins and outs of it, but I'd have 
thought an RFC, well advertised, with plenty of time to ensure as many 
people can vote who have rights to.


What I meant by that is that the members of "The PHP Group" are 
currently the copyright holders. From a legal point of view no RFC can 
change that. The only way to change that would be for the PHP Group to 
transfer their copyright to someone else. What an RFC *can* do though is 
*propose* that the PHP Group transfers their copyright to the PHP 
Foundation.


Though I'm lo lawyer, so ¯\_(ツ)_/¯

Cheers

Andreas
--
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Adding a donate link to the PHP website

2023-11-29 Thread Andreas Heigl
 in any way to make this happen.

Cheers

Andreas

--
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Array functions with strict comparison

2023-11-14 Thread Andreas Hennings
On Tue, 14 Nov 2023 at 18:49, Robert Landers  wrote:
>
> On Tue, Nov 14, 2023 at 1:39 PM Andreas Hennings  wrote:
> >
> > Hello Robert,
> >
> > On Tue, 14 Nov 2023 at 11:09, Robert Landers  
> > wrote:
> > >
> > > Andreas,
> > >
> > > Just out of curiosity, what is the use case for this? I can't really
> > > think of a practical case where strict checking is needed for these
> > > functions. Usually, you have a really good idea of what is in the
> > > arrays when writing the code and can handle any edge cases (like
> > > nulls, empty strings, etc) long before you reach for these functions.
> >
> > I could ask the reverse question: When do you ever need a non-strict 
> > comparison?
> > I think in most modern php development, you would prefer the strict
> > comparison version simply because it is more simple and predictable.
> >
> > But for real examples.
> > One thing I remember is array_diff($arr, [null]) to remove NULL
> > values, without removing empty strings.
> > Perhaps we could say this is a special case that could be solved in
> > other ways, because we only remove one value.
> >
> > Another thing is when writing reusable general-purpose functions that
> > should work for all arrays.
> > The caller might know the types of the array values, but the developer
> > of the reusable function does not.
> >
> > Another problem is if your arrays contain anything that is not
> > stringable. like objects and arrays.
> >
> > Maybe I will remember other examples that are more practical.
> >
> > Btw, as a general note on strict vs non-strict:
> > In some cases you want a "half strict" comparison, where '5' equals 5,
> > but true does NOT equal '1'.
> > But for now I am happy to focus on pure strict comparison.
> >
> > Andreas
> >
> >
> > >
> > > Robert Landers
> > > Software Engineer
> > > Utrecht NL
> > >
> > > --
> > > PHP Internals - PHP Runtime Development Mailing List
> > > To unsubscribe, visit: https://www.php.net/unsub.php
> > >
>
> Hello Andreas,
>
> > Another problem is if your arrays contain anything that is not
> > stringable. like objects and arrays.
>
> array_udiff() comes to mind here, is there a reason that doesn't work?
> It would allow you to 'half-equals' things as well, if you want.

Yes this would work, with a callback that does strict diff.
But this is going to be much slower than a native array_diff() for large arrays.
Also, array_udiff() is weird in that it it expects a sorting
comparator function rather than a boolean comparator function.

>
> > I could ask the reverse question: When do you ever need a non-strict 
> > comparison?
>
> You actually answer your own question :)
>
> > where '5' equals 5,
>
> One of the most beautiful things about PHP is that null == 0 == false,
> or '5' == 5 == 5.0, or 1 == true == 'hello world', which is so
> incredibly handy in web-dev that to ignore it is inviting bugs.

One problem of == in php and in javascript is that it is not transitive.
And I would argue in most cases it does a lot more casting than we
need, in a way that can be perceived as surprising.

> Headers may or may not be set, form values may or may not be set, JSON
> documents may or may not be missing keys/values, etc. How everything
> is coerced is extremely well documented and very obvious after working
> with PHP for a while.

I imagine a user study would come to a different conclusion than "very obvious".
But ok.

Anyway, time for an RFC.

(I was going to write more, but I should protect this list from my
preaching and arguing)

Andreas

>
> I'm reminded of this principle in PHP, quite often:
>
> > Be conservative in what you do, be liberal in what you accept from others.
>
> Robert Landers
> Software Engineer
> Utrecht NL

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



Re: [PHP-DEV] Array functions with strict comparison

2023-11-14 Thread Andreas Hennings
On Tue, 14 Nov 2023 at 02:08, David Gebler  wrote:
>
> On Sun, Nov 12, 2023 at 8:20 PM Andreas Hennings 
> wrote:
>
> > So to me, this alone is an argument to implement this natively.
> > The other argument is that it is kind of sad how the current functions
> > don't behave as one would expect.
>
>
> I'd expect there to be a larger and proportionately increasing performance
> difference between array_diff versus array_udiff with callback or a
> userland array_diff_strict function the larger the datasets you feed in.
> But I'm not sure how common either the use case of diffing arrays of 25,000
> or 250,000 elements might be, or needing this comparison to be strict
> equality. I suspect the use case where both these conditions apply is very
> rare.

The idea is to use the new functions in general-purpose algorithms
without worrying about type coercion or scaling.

>
> But if you want to create an RFC, please go for it. You could add an extra
> parameter to these functions after the input arrays, which was a flag for
> strict comparison. Whether such a thing with a default value of non-strict
> (so not BC breaking) would be considered preferable to new global
> functions, I'm not sure. I'd probably go with new functions but maybe
> someone else will weigh in with their thoughts.

The extra parameter does not really work for array_diff() or
array_intersect(), because these have variadic parameters.
Or at least it would not be "clean".
Technically we could just check if the last parameter is an array or
not, and if not, we use it as a control flag.
But I don't really like it that much, I prefer clean signatures.

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



Re: [PHP-DEV] Array functions with strict comparison

2023-11-14 Thread Andreas Hennings
Hello Robert,

On Tue, 14 Nov 2023 at 11:09, Robert Landers  wrote:
>
> Andreas,
>
> Just out of curiosity, what is the use case for this? I can't really
> think of a practical case where strict checking is needed for these
> functions. Usually, you have a really good idea of what is in the
> arrays when writing the code and can handle any edge cases (like
> nulls, empty strings, etc) long before you reach for these functions.

I could ask the reverse question: When do you ever need a non-strict comparison?
I think in most modern php development, you would prefer the strict
comparison version simply because it is more simple and predictable.

But for real examples.
One thing I remember is array_diff($arr, [null]) to remove NULL
values, without removing empty strings.
Perhaps we could say this is a special case that could be solved in
other ways, because we only remove one value.

Another thing is when writing reusable general-purpose functions that
should work for all arrays.
The caller might know the types of the array values, but the developer
of the reusable function does not.

Another problem is if your arrays contain anything that is not
stringable. like objects and arrays.

Maybe I will remember other examples that are more practical.

Btw, as a general note on strict vs non-strict:
In some cases you want a "half strict" comparison, where '5' equals 5,
but true does NOT equal '1'.
But for now I am happy to focus on pure strict comparison.

Andreas


>
> Robert Landers
> Software Engineer
> Utrecht NL
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

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



Re: [PHP-DEV] Array functions with strict comparison

2023-11-12 Thread Andreas Hennings
On Sat, 11 Nov 2023 at 20:43, Andreas Hennings  wrote:
>
> Hello David,
>
> On Sat, 11 Nov 2023 at 20:04, David Gebler  wrote:
> >
> > On Sat, Nov 11, 2023 at 6:05 PM Andreas Hennings 
> > wrote:
> >
> > > Hello internals,
> > > I noticed that array functions like array_diff(), array_intersect()
> > > etc use weak comparison.
> > >
> > >
> > That's not quite correct. Using the example of array_diff, the comparison
> > is a strict equality check on a string cast of the values. So
> > array_diff([""], [false]) will indeed be empty
> > but array_diff(["0"],[false]) will return ["0"].
>
> Thanks, good to know!
> So in other words, it is still some kind of weak comparison, but with
> different casting rules than '=='.
> Still this is not desirable in many cases.
>
> >
> > Tbh any use case for whatever array function but with strict comparison is
> > such an easy thing to implement in userland[1] I'm not bothered about
> > supporting it in core. But that's just me. I don't generally like the idea
> > of adding new array_* or str_* functions to the global namespace without
> > very good cause. There is a precedent for it though, in terms of changes
> > which have gone through in PHP 8, such as array_is_list or str_starts_with.
>
>
> I would argue that the strict variants of these functions would be
> about as useful as the non-strict ones.
> Or in my opinion, they would become preferable over the old functions
> for most use cases.
>
> In other words, we could say the old/existing functions should not
> have been added to the language.
> (of course this does not mean we can or should remove them now)
>
> Regarding performance, I measure something like factor 2 for a diff of
> range(0, 500) minus [5], comparing array_diff() vs array_diff_strict()
> as proposed here.
> So for large arrays or repeated calls it does make a difference.

Some more results on this.
With the right array having only one element, i can actually optimize
the userland function to be almost as fast as the native function.
However, if I pump up the right array, the difference becomes quite bad.


function array_diff_userland(array $array1, array $array2 = [], array
...$arrays): array {
if ($arrays) {
// Process additional arrays only when they exist.
$arrays = array_map('array_values', $arrays);
$array2 = array_merge($array2, ...$arrays);
}
// This is actually slower, it seems.
#return array_filter($array1, fn ($value) => !in_array($value,
$array2, TRUE));
$diff = [];

foreach ($array1 as $k => $value) {
// Use non-strict in_array(), to get a fair comparison with
the native function.
if (!in_array($value, $array2)) {
$diff[$k] = $value;
}
}
return $diff;
}

$arr = range(0, 500);
$arr2 = range(0, 1500, 2);

$dts = [];

$t = microtime(TRUE);
$diff_native = array_diff_userland($arr, $arr2);
$t += $dts['userland'] = (microtime(TRUE) - $t);
$diff_userland = array_diff($arr, $arr2);
$t += $dts['native'] = (microtime(TRUE) - $t);
assert($diff_userland === $diff_native);

// Run both again to detect differences due to warm-up.
$t = microtime(TRUE);
$diff_native = array_diff_userland($arr, $arr2);
$t += $dts['userland.1'] = (microtime(TRUE) - $t);
$diff_userland = array_diff($arr, $arr2);
$t += $dts['native.1'] = (microtime(TRUE) - $t);
assert($diff_userland === $diff_native);

// Now use a right array that has no overlap with the left array.
$t = microtime(TRUE);
$arr2 = range(501, 1500, 2);
$diff_native = array_diff_userland($arr, $arr2);
$t += $dts['userland.2'] = (microtime(TRUE) - $t);
$diff_userland = array_diff($arr, $arr2);
$t += $dts['native.2'] = (microtime(TRUE) - $t);
assert($diff_userland === $diff_native);

var_export(array_map(fn ($dt) => $dt * 1000 * 1000 . ' ns', $dts));

I see differences of factor 5 up to factor 10.

So to me, this alone is an argument to implement this natively.
The other argument is that it is kind of sad how the current functions
don't behave as one would expect.


>
> Regarding the cost of more native functions:
> Is the concern more about polluting the global namespace, or about
> adding more functions that need to be maintained?
> I can see both arguments, but I don't have a clear opinion how these
> costs should be weighed.

The most straightforward option seems to just name the new functions
like array_diff_strict() etc.
But I am happy for other proposals.

>
> Cheers
> Andreas
>
>
>
> >
> > [1] Example:
> >
> > function array_diff_strict(array $array1, array ...$arrays): array
> > {
> > $diff = [];
> > foreach ($array1 as $value) {
> > $found = false;
> &

Re: [PHP-DEV] Array functions with strict comparison

2023-11-11 Thread Andreas Hennings
Hello David,

On Sat, 11 Nov 2023 at 20:04, David Gebler  wrote:
>
> On Sat, Nov 11, 2023 at 6:05 PM Andreas Hennings 
> wrote:
>
> > Hello internals,
> > I noticed that array functions like array_diff(), array_intersect()
> > etc use weak comparison.
> >
> >
> That's not quite correct. Using the example of array_diff, the comparison
> is a strict equality check on a string cast of the values. So
> array_diff([""], [false]) will indeed be empty
> but array_diff(["0"],[false]) will return ["0"].

Thanks, good to know!
So in other words, it is still some kind of weak comparison, but with
different casting rules than '=='.
Still this is not desirable in many cases.

>
> Tbh any use case for whatever array function but with strict comparison is
> such an easy thing to implement in userland[1] I'm not bothered about
> supporting it in core. But that's just me. I don't generally like the idea
> of adding new array_* or str_* functions to the global namespace without
> very good cause. There is a precedent for it though, in terms of changes
> which have gone through in PHP 8, such as array_is_list or str_starts_with.


I would argue that the strict variants of these functions would be
about as useful as the non-strict ones.
Or in my opinion, they would become preferable over the old functions
for most use cases.

In other words, we could say the old/existing functions should not
have been added to the language.
(of course this does not mean we can or should remove them now)

Regarding performance, I measure something like factor 2 for a diff of
range(0, 500) minus [5], comparing array_diff() vs array_diff_strict()
as proposed here.
So for large arrays or repeated calls it does make a difference.

Regarding the cost of more native functions:
Is the concern more about polluting the global namespace, or about
adding more functions that need to be maintained?
I can see both arguments, but I don't have a clear opinion how these
costs should be weighed.

Cheers
Andreas



>
> [1] Example:
>
> function array_diff_strict(array $array1, array ...$arrays): array
> {
> $diff = [];
> foreach ($array1 as $value) {
> $found = false;
> foreach ($arrays as $array) {
> if (in_array($value, $array, true)) {
> $found = true;
> break;
> }
> }
> if (!$found) {
> $diff[] = $value;
> }
> }
> return $diff;
> }

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



[PHP-DEV] Array functions with strict comparison

2023-11-11 Thread Andreas Hennings
Hello internals,
I noticed that array functions like array_diff(), array_intersect()
etc use weak comparison.

E.g.
array_diff([0, '', false, null], [null])
only leaves [0].

This makes these functions useless for a number of applications.
Also it can lead to unpleasant surprises, if a developer is not aware
of the silent type casting.

For BC reasons. the existing functions have to remain as they are.
Also, most of them don't really have a place for an extra parameter to
tell them to use strict comparison.

So, as a solution, we would have to introduce new functions.

Has anything like this been proposed in the past?
How would we name the new functions?
Should they be functions or static methods like StrictArray::diff(..)?

I could post an RFC but I want to get some feedback first.

Kind regards
Andreas

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



Re: [PHP-DEV] Passing null to parameter

2023-11-10 Thread Andreas Leathley

On 10.11.23 12:33, Craig Francis wrote:

On 10 Nov 2023, at 10:54, Alex Wells  wrote:

PHPStan does find 
them:https://phpstan.org/r/38fc1545-2567-49b9-9937-f275dcfff6f5


It does not:

https://phpstan.org/r/c533ff42-80e4-4309-9751-1ec79e359946


Psalm does give you a PossiblyInvalidArgument here, PHPStan will likely
detect this soon too, as both static analyzers are covering more and
more ground. Also note that in your example $q could be an array
(leading to a fatal error in the code)from the request data, which is
why checking types thoroughly (not just coercing them with strval) can
be helpful in avoiding unexpected situations and deciding how to handle
such situations, instead of yolo-ing it.


Re: [PHP-DEV] Introducing 2 new modes to round function

2023-07-21 Thread Andreas Heigl
On 21 July 2023 21:38:03 CEST, Marco Pivetta  wrote:
> Hey Jorg,
> 
> What is the reason for using this over these?
> 
>  * https://www.php.net/manual/en/function.ceil.php
>  * https://www.php.net/manual/en/function.floor.php
> 
>
Hey Marco

floor and ceil convert a float to the next int.

round can also convert to the next decimal-,level.

round(16, -1) will round to 20 whereas round(12, -1) will be 10. And tuere's no 
way currently to make the first one 10 and the second one 20.

Cheers

Andreas
> 
> On Fri, 21 Jul 2023, 21:26 Jorg Sowa,  wrote:
> 
> > Hello internals!
> >
> > I would like to propose introducing two new modes to the function
> > `round()`: PHP_ROUND_DOWN and PHP_ROUND_UP.
> >
> > Those modes are highly requested as you can see by the comments on round
> > documentation page. First comment mentioning about those modes has 309
> > votes as of today. Introducing those 2 modes would be complementing to the
> > rounding in this function.
> >
> > Round documentation: https://www.php.net/manual/en/function.round.php
> > My implementation: https://github.com/php/php-src/pull/11741
> >
> > I'm not sure if such minor improvement requires RFC, but as someone may
> > have some concerns I create this thread to get your feedback.
> >
> > Kind regards,
> > Jorg
> >


--
Andreas Heigl

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



Re: [PHP-DEV] [VOTE] Interface Default Methods

2023-07-03 Thread Andreas Heigl

Hey Michał

On 03.07.23 13:32, Michał Marcin Brzuchalski wrote:

Hi Levi,

pon., 3 lip 2023 o 02:11 Levi Morrison  napisał(a):


Chatter on the [Interface Default Methods RFC][1] has been quiet for
the past 6 days, and the feature freeze deadline is fast approaching
for PHP 8.3, so I'm moving this to vote. It'll be open for two weeks
as usual.

Thanks to everyone who discussed weaknesses in the RFC during the
discussion phase.

   [1]: https://wiki.php.net/rfc/interface-default-methods



I voted "yes", my personal use case waits for this feature. My use
case example:

https://gist.github.com/brzuchal/89e9481bbd34a6ce3d95a68eabff038b


I've added two already possible solutions to that as comments.


With interface default methods I'd no longer need traits that implement a
single or in rare cases 2 methods that
use their respective methods returning objects and iterate in Generator
fashion over a paginated result set.
This is not an issue if there is one implementation of the interface but
when I decorate to apply some:
* caching
* logging
* failover


That requires that you are in control over both the interface AND the 
implementation. In which case you probably do not need an interface and 
the Trait would be enough (using `abstract public function` in traits 
works after all)


So you could even skip the implements part.

As the interface should be designed specifically to be 
implementation-agnostic, adding implementation to the interface is 
counter-productive.


Adding abstract methods to a trait and then just adding the traits is no 
issue at all especially when you are in control of the interface AND the 
implementation.


When you are NOT in control of the interface... well, you can't expect 
to have a default implementation and I am already looking forward to the 
complaints that it is great to have a default implementation, but not 
*that* one.


There is a reason why the respective construct in Rust (which was 
mentioned in the RFC) is called a Trait and not an Interface.


So to decouple the contract from the implementation it is necessary that 
no implementation is part of the contract.




then the trait has to be attached to every class besides that it has to
exist which is an additional symbol here.


Stop using `implements` at all and solely rely on `use`.

My 0.02€

Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [VOTE] Interface Default Methods

2023-07-02 Thread Andreas Heigl

Am 03.07.23 um 02:11 schrieb Levi Morrison:

Chatter on the [Interface Default Methods RFC][1] has been quiet for
the past 6 days, and the feature freeze deadline is fast approaching
for PHP 8.3, so I'm moving this to vote. It'll be open for two weeks
as usual.

Thanks to everyone who discussed weaknesses in the RFC during the
discussion phase.

   [1]: https://wiki.php.net/rfc/interface-default-methods


I've voted "no" on this RFC for one simple reason:

For me an interface is about the abstraction of a contract. It defines 
how different parts of code interact with one another without having to 
know about the implementation.


With this RFC we are adding implementation details to the abstraction.

That requires knowledge about the implementation of different parts of 
the code. Which we do not have when defining an interface.


If we have this knowledge then we are not defining an interface but an 
implementation were some implementation details need to be overwritten 
depending on business-logic. That is what an abstract class is there for.


And TBH: I do not really care whether there are other languages that 
think that is a good idea: For me it is not.


If one needs default implementations of an interface: Use Traits. But 
leave the contract abstract. ANd if you need to declare some methods to 
be implemented while others are fixed: Use abstract classes.


My 0.02€

Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org  https://hei.gl/where |
|https://hei.gl/pubkeyandreas |
+-+

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



Re: [PHP-DEV] RFC1867 (multipart/form-data) PUT requests

2023-06-27 Thread Andreas Heigl
.. you get the picture)


One additional function in global namespace and then we can use one of 
the request-objects that are already out in the wild. I don't think 
there's a need to invent the wheel again.


The advantage might be that no matter how many calls to `request()` you 
will always get the same result. The Request as it came in.


Just my 0.02€

Cheers

Andreas
--
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Expression code blocks

2023-06-22 Thread Andreas Hennings
Hello Ilija,

On Sat, 17 Jun 2023 at 13:27, Ilija Tovilo  wrote:
>
> Hi Andreas
>
> On Fri, Jun 16, 2023 at 9:23 PM Andreas Hennings  wrote:
> >
> > Hello list,
> > I don't know if something like this was already proposed in the past,
> > I did not find anything.
> >
> > Sometimes it would be nice to have a code block inside an expression, like 
> > this:
> >
> > public function f(string $key) {
> > return $this->cache[$key] ??= {
> > // Calculate a value for $key.
> > [...]
> > return $value;
> > }
> > }
>
> This has been discussed a few years back when match expressions were
> proposed. I originally wanted to include support for code blocks along
> with expressions to offer a more complete alternative to switch
> statements. The other major use-case for block expressions are arrow
> functions.
>
> Unfortunately, a general solution seems suboptimal due to the subtle
> semantic differences. See this message for my detailed thought
> process.
>
> https://externals.io/message/109941#109947

I looked at this and I think all of this can be solved.

About ambiguity with existing code blocks:
I think we should prepend a new keyword like "expr".
I was a bit hesitant to introduce a new keyword, but I think it is the
cleanest solution.
So it becomes `$x = expr {return 5;};`.

For the return syntax, let's simply use `return`, instead of a new
language construct like "<=".

About return being required or not:
Let's do the same as in a regular function body:
- If return value is omitted, an implicit NULL is returned.
- IDEs / static analysis can look at the wider context and complain if
it thinks a return value should be added or omitted. PHP can simply
ignore the problem.

This means that the following will be true:
assert(NULL === expr {});
assert(NULL === expr {return;});
assert(NULL === expr {return NULL;});


>
> I believe it would be best to address blocks for match arms and arrow
> functions separately.

The new syntax could be used in all 3 cases:

$y = match ($x) {
  1 => expr {},  // IDE complains, but PHP does not care.
}

$fn = fn () => expr {};  // Totally ok.
$fn = fn (): array => expr {}; // Error at runtime when it is executed.
$fn = fn (bool $arg): array => expr {if ($arg) return [];};  //
Possible error at runtime when it is executed.

We could also declare a return type on the expr, like so:
But I don't see a big advantage.

$x = expr: array {return [];};


We can also use generators:

$generator = expr {yield 'A'; yield 'B';};
assert($generator instanceof \Generator);


>
> I don't believe blocks for general expressions are that useful in PHP
> due to the lack of block scoping.

We could introduce block scoping for that specific language feature.
And even without it, to me these expression blocks would still be useful.

If the default is "use all by ref, leak all", it would feel more like
other language constructs like foreach(), if/else etc.
If the default is "capture all by value", it would feel more like a
short closure.

Perhaps there could be something to control the capturing type.
E.g. a `use` part?
expr {..}  // Capture all by value, don't leak inner variables.
expr use () {..}  // Capture nothing.
expr use ($x) {..}  // Capture specific variable $x, by value.
expr use (*) {..}  // Capture all by value, don't leak.
expr use (&*) {..}  // Capture all by reference, leak all?

Or we could have different keywords:

expr {..} // Capture all by reference, leak all inner variables.
scope {..} // Capture all by value, don't leak.


I personally think mostly of uses cases with cache and ??=.
These exist a lot within Drupal, both with runtime cache and persistent cache.
With the expression block these could be shortened like this:

$x = $runtime_cache['x']
  ??= $persistent_cache['x']
  ??= {
... // Calculate value for x.
return $value;
  };

I could also see it used in generated code that behaves as a huge
nested expression.



> Your suggestion to make the block a
> separate closure could avoid that (as well as the optimizer issue
> mentioned below) but comes with new issues, like making modification
> of captured values impossible without by-ref capturing. It seems
> confusing that fn {} is auto-executed while fn() {} isn't, as the
> former looks like a shortened version of the latter. fn() => fn {}
> would also look quite weird. match ($x) { 1 => fn {} } seems ok,
> except for being somewhat lengthy.
>
> On another note, the vote for blocks in short closures has failed
> lately (https://wiki.php.net/rfc/auto-capture-closure).
>
> The message above also addresses the syntax ambiguity you mentioned.
> The {} syntax would be unambiguous in the most useful contexts (e.g.
> function para

Re: [PHP-DEV] Expression code blocks

2023-06-22 Thread Andreas Hennings
Hello Rowan, Ilja,
(sorry I did not see these replies sooner, I do some forwarding but it failed)

On Sat, 17 Jun 2023 at 16:59, Rowan Tommins  wrote:
>
> On 17/06/2023 12:26, Ilija Tovilo wrote:
> > I don't believe blocks for general expressions are that useful in PHP
> > due to the lack of block scoping. Your suggestion to make the block a
> > separate closure could avoid that (as well as the optimizer issue
> > mentioned below) but comes with new issues, like making modification
> > of captured values impossible without by-ref capturing.
>
>
> I've been pondering various things in this space for a while,
> particularly since the last auto-capture closures RFC. I haven't quite
> coalesced on a coherent concept, but there are a few things that I think
> inter-relate:
>
> * Opting into block-scoped variables, while retaining full access to the
> outer scope, like JS "let"
> * Code blocks as some kind of first-class thing, distinct from closures

I think this would be my preferred option.
We would have to discuss how variables are scoped and captured, but I
could myself being happy with different options.

Currently variables from outside in short closures are auto-captured
by value, and nothing leaks outside:
https://3v4l.org/mdJvM
I would be happy if it works the same for expression code blocks.

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



[PHP-DEV] Expression code blocks

2023-06-16 Thread Andreas Hennings
Hello list,
I don't know if something like this was already proposed in the past,
I did not find anything.

Sometimes it would be nice to have a code block inside an expression, like this:

public function f(string $key) {
return $this->cache[$key] ??= {
// Calculate a value for $key.
[...]
return $value;
}
}

Currently, to achieve the same, we have two options which both add
overhead both in code verbosity and in performance:
1. Call another method or closure after the ??=.
2. Use if (isset(...)) instead of the ??= shortcut. This results in
repetition of other parts of the expression, because the if/else
cannot be inside the expression.

E.g. this is option 1 with a closure:

public function f(string $key) {
return $this->cache[$key] ??= (function () use ($key) {
// Calculate a value for $key.
[...]
return $value;
})();
}

Option 1 with a real method would look like this:

public function f(string $key) {
return $this->cache[$key] ??= $this->calc($key);
}
private function calc(string $key) {
// Calculate a value for $key.
[...]
return $value;
}


The `{}` syntax seems like the most obvious choice at first, but I
think it would not work.

Statement groups with curly brackets are already possible right now,
see https://www.php.net/manual/en/control-structures.intro.php, but
they are not really useful for anything: They cannot be used as
expressions, they don't have their own return value, and they don't
isolate their variables.

Another option would be a special keyword before the curly block.
We could introduce a new keyword like `expr`, or use an existing one like `fn`.

$x = 4 + fn {return 3;};
// or
$x = 4 + expr {return 3;}

The compiler/interpreter could either convert the block into a
closure, or treat it as a new language feature, which might bring
performance benefits.


Any thoughts?
-- Andreas

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



Re: [PHP-DEV] Declaration-aware attributes

2023-05-30 Thread Andreas Hennings
On Tue, 30 May 2023 at 22:45, Larry Garfield  wrote:
>
> On Tue, May 30, 2023, at 7:34 PM, Andreas Hennings wrote:
> > On Tue, 30 May 2023 at 19:12, Larry Garfield  wrote:
> >>
> >> I've run into this issue in my attribute library as well 
> >> (https://github.com/Crell/AttributeUtils).  What I do there is allow 
> >> attributes to opt-in to a callback method via interface.  For example:
> >>
> >> #[\Attribute]
> >> class AttribWithName implements FromReflectionClass
> >> {
> >> public readonly string $name;
> >>
> >> public function __construct(?string $name = null)
> >> {
> >> if ($name) {
> >> $this->name = $name;
> >> }
> >> }
> >>
> >> public function fromReflection(\ReflectionClass $subject): void
> >> {
> >> $this->name ??= $subject->getShortName();
> >> }
> >> }
> >
> > So it is technically from outside it is a setter, whereas from inside
> > it is not really.
> > Technically, this means you need a version of the attribute object
> > that can exist without the values from the reflector.
> > The constructor needs to initialize some "stub" values, until the
> > setter is called.
> > Every other method also needs to support the case when the setter has
> > not been called yet, or possibly throw an exception.
> > Also, your property type has to allow null, so `?string`, not `string`.
>
> Except the property type is not null above?  The argument is, but not the 
> property.  (I could use CPP here with a null value instead, if we had 
> asymmetric visibility.)

True!
My conception of readonly was distorted by the same static analysis
tools that you complained about earlier!
https://3v4l.org/CUgYv
I think a more accurate label would be "write once".

>
> Also, if the interface is called by the reflection system itself as part of 
> getInstance() then yes, we can guarantee that it's been run, just like we can 
> guarantee the constructor has run.

The concern was that you can also construct the attribute object with
a regular `new AttribWithName()` expression, and then you can omit the
->fromReflection() call.
But we could say it is part of the contract that you have to call the
method before the object is fully operational.

>
> >> (Side note: This is why static analysis tools that forbid writing to 
> >> readonly properties except from the constructor are wrong; it's also an 
> >> example of where asymmetric visibility would be superior to readonly.  But 
> >> I digress.)
> >
> > Technically there is no guarantee that the setters will be called
> > before any other method, and only once.
> > If these methods can write on readonly properties, then any method can.
> > Unless we somehow mark these methods as special.
>
> There's nothing special about readonly properties there.  An uninitialized 
> non-readonly property is no more or less susceptible to still being 
> uninitialized when you need it.  Singling out readonly here is just dumb, and 
> exacerbates the problems of readonly.
>
> > On the other hand, a wither method with "clone with" should be allowed
> > to work on readonly properties.
> > You could rewrite your method like this, once we have clone with:
> > (or use the old-school syntax but without readonly)
> >
> > public function withReflector(\ReflectionClass $subject): static
> > {
> > return ($this->name !== NULL)
> > ? $this
> > : clone $this with (name: $subject->getShortName();
> > }
> >
> > Then in the discovery code:
> >
> > $attribute = $reflectionClass->getAttributes()[0]->newInstance();
> > $attribute = $attribute->withReflector($reflectionClass);
>
> In that library I actually have several opt-in post-constructor setup 
> routines.  The documentation covers them all.  Making them all withers would 
> be just needlessly slow.  Basically it's an example of a "mutable and then 
> locked" object, which I emulate by virtue of only calling the setup methods 
> from the library, and using readonly properties.
>
> >> That's why I think an opt-in interface is the way to go.  It also avoids 
> >> any confusion around the constructor parameters, which is, based on this 
> >> thread, a confusing area. :-)
> >
> > What do you think about a placeholder syntax to avoid confusion with a
> > skipped parameter?
> > Like
> >
> > #[A('x', ?', 'y')]
>
> Oh g

Re: [PHP-DEV] Declaration-aware attributes

2023-05-30 Thread Andreas Hennings
On Tue, 30 May 2023 at 19:12, Larry Garfield  wrote:
>
> I've run into this issue in my attribute library as well 
> (https://github.com/Crell/AttributeUtils).  What I do there is allow 
> attributes to opt-in to a callback method via interface.  For example:
>
> #[\Attribute]
> class AttribWithName implements FromReflectionClass
> {
> public readonly string $name;
>
> public function __construct(?string $name = null)
> {
> if ($name) {
> $this->name = $name;
> }
> }
>
> public function fromReflection(\ReflectionClass $subject): void
> {
> $this->name ??= $subject->getShortName();
> }
> }

So it is technically from outside it is a setter, whereas from inside
it is not really.
Technically, this means you need a version of the attribute object
that can exist without the values from the reflector.
The constructor needs to initialize some "stub" values, until the
setter is called.
Every other method also needs to support the case when the setter has
not been called yet, or possibly throw an exception.
Also, your property type has to allow null, so `?string`, not `string`.

I usually try to avoid this, this is why I proposed the constructor parameter.
This way, the object is never in an incomplete state.

(Side note: Personally I use the naming convention from*() for static
factory methods. I might use set*() for this one, but then again, it
is only a setter from the outside.)

>
> (Side note: This is why static analysis tools that forbid writing to readonly 
> properties except from the constructor are wrong; it's also an example of 
> where asymmetric visibility would be superior to readonly.  But I digress.)

Technically there is no guarantee that the setters will be called
before any other method, and only once.
If these methods can write on readonly properties, then any method can.
Unless we somehow mark these methods as special.

On the other hand, a wither method with "clone with" should be allowed
to work on readonly properties.
You could rewrite your method like this, once we have clone with:
(or use the old-school syntax but without readonly)

public function withReflector(\ReflectionClass $subject): static
{
return ($this->name !== NULL)
? $this
: clone $this with (name: $subject->getShortName();
}

Then in the discovery code:

$attribute = $reflectionClass->getAttributes()[0]->newInstance();
$attribute = $attribute->withReflector($reflectionClass);

>
> My preference would be for something along those lines to be implemented in 
> core.
>
> Importantly, we *MUST NOT* design it such that the reflection object gets 
> assigned to a property of the attribute.  Reflection objects are not 
> serializable.  Attributes will frequently be cached.  That means it forces 
> the attribute author to make the property nullable AND then unset it sometime 
> before the attribute gets serialized, or it will break.  That's a no-go.

There could be ways around this problem, but I agree we should avoid
it on design level.

>
> That's why I think an opt-in interface is the way to go.  It also avoids any 
> confusion around the constructor parameters, which is, based on this thread, 
> a confusing area. :-)

What do you think about a placeholder syntax to avoid confusion with a
skipped parameter?
Like

#[A('x', ?', 'y')]

>
> My second preference would be the ReflectionAttribute::inProgress() call in 
> the constructor, or something like that.  I like that less because it's a 
> stateful call, but it would also reduce the issue with readonly properties 
> (as in the example above) by making both alternatives available in the 
> constructor, so maybe it's an acceptable tradeoff.

I would like to avoid anything that is stateful or that leaves an
incomplete stub object.
(But I think I made this clear enough, so..)

>
> I can see an argument either direction here.
>
> --Larry Garfield
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

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



Re: [PHP-DEV] Let ReflectionMethod keep track of original class

2023-05-30 Thread Andreas Hennings
On Tue, 30 May 2023 at 18:48, Larry Garfield  wrote:
>
>
>
> --
>   Larry Garfield
>   la...@garfieldtech.com
>
> On Tue, May 30, 2023, at 2:42 AM, Andreas Hennings wrote:
> > Hello list,
> > this proposal will be useful in combination with "Declaration-aware 
> > attributes"
> >
> >
> > Problem
> > 
> > Currently, ReflectionMethod is not aware of the original class, if the
> > method is declared in a parent class.
> > Methods that are called during a discovery algorithm that need to
> > process a method with its original class typically need two
> > parameters:
> >
> > function processMethod(\ReflectionClass $class, \ReflectionMethod $method) 
> > {..}
> >
> >
> > Proposal
> > 
> > Let a ReflectionMethod object keep track of the original class.
> > Introduce a new method ReflectionMethod->getOriginalClass() to retrieve it.
> >
> > class B {
> >   function f($x) {}
> > }
> > class C extends B {}
> >
> > foreach ([
> >   // There are different ways to get a reflection method object, all
> > of them track the original class.
> >   new ReflectionMethod('C', 'f'),
> >   (new ReflectionClass('C'))->getMethod('f'),
> >   (new ReflectionMethod('C', 
> > 'f'))->getParameters()[0]->getDeclaringFunction(),
> > ] as $rm) {
> >   // The following won't change:
> >   assert($rm->class === 'B');
> >   assert($rm->getDeclaringClass()->getName() === 'B');
> >   // New method:
> >   assert($rm->getOriginalClass()->getName() === 'C');
> >
> >
> > Alternatives
> > ==
> >
> > At first I thought we might introduce a new class like
> > "VirtualReflectionMethod" which behaves as if the method was declared
> > on the child class. But this is awkward.
> >
> > I think the ->getOriginalClass() is much simpler.
>
>
> I would not be opposed to this.  I don't know that I have any use cases for 
> it, but I'd be open to it.

You can search in your favourite project's /vendor/ directory for
methods with two or more parameters that receive reflector objects.

"function .*\(.*Reflection\w+ \$\w+, .?Reflection\w+ \$\w+"

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

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



Re: [PHP-DEV] [RFC] [Discussion] Add new function `array_group`

2023-05-30 Thread Andreas Hennings
On Tue, 30 May 2023 at 18:27, Boro Sitnikovski  wrote:
>
> Hi,
>
> Thank you for your thoughts.
>
> > I would say the more common desired behavior is the one in your first
> > example. And even for that we don't have a native function.
>
> This Google search might give more insight into the number of discussions 
> about a grouping functionality: 
> https://www.google.com/search?q=php+group+elements+site:stackoverflow.com

All of the examples I looked at are asking for the first kind of
grouping, that can be implemented as in your first example.
In all the examples, if two items are equal, they end up in the same group.

In your proposed behavior, equal items can end up in distinct groups
depending on their original position in the source array.
I don't see any questions or examples that ask for this.

-- Andreas

>
> > Your behavior can be implemented in userland like so:
> > https://3v4l.org/epvHm
>
> Correct, but then again, we can also implement 
> `array_map`/`array_filter`/etc. in userland :)
>
> > I think you need to make a case as to why the behavior you describe
> > justifies a native function.
>
> Similar to my previous answer, but also in general - ease of access and also 
> performance.
>
> > E.g. if you find a lot of public php code that does this kind of grouping.
> >
> > I personally suspect it is not that common.
> >
> > Cheers
> > Andreas
> >
> >
> > On Tue, 30 May 2023 at 17:08, Boro Sitnikovski  wrote:
> >>
> >> Hey,
> >>
> >> Thanks for the suggestion.
> >>
> >> For the previous case in the code, I added these in a Gist to not clutter 
> >> here too much:
> >>
> >> 1. The first example corresponds to 
> >> https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_manual_group-php
> >> 2. The second example corresponds to 
> >> https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_array_group-php
> >> 3. Another example, addressing the problem of increasing subsequences is 
> >> very simple with `array_group`: 
> >> https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_array_incr_subseqs-php
> >>
> >> Best,
> >>
> >> Boro
> >>
> >>> On 30.5.2023, at 16:57, Andreas Hennings  wrote:
> >>>
> >>> Hello Boro,
> >>> I think you should include the "expected result" in your code examples.
> >>> Maybe this is in your patch file, but I don't think we want to look at
> >>> that for discussion.
> >>>
> >>> Cheers
> >>> Andreas
> >>>
> >>> On Tue, 30 May 2023 at 13:35, Boro Sitnikovski  
> >>> wrote:
> >>>>
> >>>> Hello all,
> >>>>
> >>>> As per the How To Create an RFC instructions, I am sending this e-mail 
> >>>> in order to get your feedback on my proposal.
> >>>>
> >>>> I propose introducing a function to PHP core named `array_group`. This 
> >>>> function takes an array and a function and returns an array that 
> >>>> contains arrays - groups of consecutive elements. This is very similar 
> >>>> to Haskell's `groupBy` function.
> >>>>
> >>>> For some background as to why - usually, when people want to do grouping 
> >>>> in PHP, they use hash maps, so something like:
> >>>>
> >>>> ```
> >>>>  >>>> $array = [
> >>>> [ 'id' => 1, 'value' => 'foo' ],
> >>>> [ 'id' => 1, 'value' => 'bar' ],
> >>>> [ 'id' => 2, 'value' => 'baz' ],
> >>>> ];
> >>>>
> >>>> $groups = [];
> >>>> foreach ( $array as $element ) {
> >>>>   $groups[ $element['id'] ][] = $element;
> >>>> }
> >>>>
> >>>> var_dump( $groups );
> >>>> ```
> >>>>
> >>>> This can now be achieved as follows (not preserving keys):
> >>>>
> >>>> ```
> >>>>  >>>> $array = [
> >>>> [ 'id' => 1, 'value' => 'foo' ],
> >>>> [ 'id' => 1, 'value' => 'bar' ],
> >>>> [ 'id' => 2, 'value' => 'baz' ],
> >>>> ];
> >>>>
> >>>> $groups = array_group( $array, function( $a, $b ) {
> >>>> return $a['id'] == $b['id'];
> >>>> } );
> >>>> ```
> >>>>
> >>>> The disadvantage of the first approach is that we are only limited to 
> >>>> using equality check, and we cannot group by, say, `<` or other 
> >>>> functions.
> >>>> Similarly, the advantage of the first approach is that the keys are 
> >>>> preserved, and elements needn't be consecutive.
> >>>>
> >>>> In any case, I think a utility function such as `array_group` will be 
> >>>> widely useful.
> >>>>
> >>>> Please find attached a patch with a proposed implementation. Curious 
> >>>> about your feedback.
> >>>>
> >>>> Best,
> >>>>
> >>>> Boro Sitnikovski
> >>>>
> >>
>

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



Re: [PHP-DEV] [RFC] [Discussion] Add new function `array_group`

2023-05-30 Thread Andreas Hennings
Here we go,
https://3v4l.org/KsL3o


function array_group(array $arr1, callable $compare): array {
$groups = [];
$group = [];
$prev = NULL;
foreach ($arr1 as $value) {
if ($group && !$compare($prev, $value)) {
$groups[] = $group;
$group = [];
}
$group[] = $value;
$prev = $value;
}
if ($group) {
$groups[] = $group;
}
return $groups;
}

On Tue, 30 May 2023 at 18:21, Andreas Hennings  wrote:
>
> Thank you, this clarifies and it confirms my initial assumption of
> what you are proposing.
> So you want to slice an array by comparing adjacent values.
>
>
> My personal feedback:
> I think the need for the grouping behavior you describe is not common
> enough that it needs its own native function.
> I would say the more common desired behavior is the one in your first
> example. And even for that we don't have a native function.
>
> Your behavior can be implemented in userland like so:
> https://3v4l.org/epvHm
>
>
> $arr1 = array(1,2,2,3,1,2,0,4,5,2);
>
> $groups = [];
> $group = [];
> $prev = NULL;
> foreach ($arr1 as $value) {
> if ($group && $prev > $value) {
> $groups[] = $group;
> $group = [];
> }
> $group[] = $value;
> $prev = $value;
> }
> if ($group) {
> $groups[] = $group;
> }
>
> print_r($groups);
>
>
> If needed, the comparison function can be separated out and passed as
> a parameter.
> So the array_group() function with a comparison callback parameter can
> be implemented in userland.
>
> I think you need to make a case as to why the behavior you describe
> justifies a native function.
> E.g. if you find a lot of public php code that does this kind of grouping.
>
> I personally suspect it is not that common.
>
> Cheers
> Andreas
>
>
> On Tue, 30 May 2023 at 17:08, Boro Sitnikovski  wrote:
> >
> > Hey,
> >
> > Thanks for the suggestion.
> >
> > For the previous case in the code, I added these in a Gist to not clutter 
> > here too much:
> >
> > 1. The first example corresponds to 
> > https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_manual_group-php
> > 2. The second example corresponds to 
> > https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_array_group-php
> > 3. Another example, addressing the problem of increasing subsequences is 
> > very simple with `array_group`: 
> > https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_array_incr_subseqs-php
> >
> > Best,
> >
> > Boro
> >
> > > On 30.5.2023, at 16:57, Andreas Hennings  wrote:
> > >
> > > Hello Boro,
> > > I think you should include the "expected result" in your code examples.
> > > Maybe this is in your patch file, but I don't think we want to look at
> > > that for discussion.
> > >
> > > Cheers
> > > Andreas
> > >
> > > On Tue, 30 May 2023 at 13:35, Boro Sitnikovski  
> > > wrote:
> > >>
> > >> Hello all,
> > >>
> > >> As per the How To Create an RFC instructions, I am sending this e-mail 
> > >> in order to get your feedback on my proposal.
> > >>
> > >> I propose introducing a function to PHP core named `array_group`. This 
> > >> function takes an array and a function and returns an array that 
> > >> contains arrays - groups of consecutive elements. This is very similar 
> > >> to Haskell's `groupBy` function.
> > >>
> > >> For some background as to why - usually, when people want to do grouping 
> > >> in PHP, they use hash maps, so something like:
> > >>
> > >> ```
> > >>  > >> $array = [
> > >> [ 'id' => 1, 'value' => 'foo' ],
> > >> [ 'id' => 1, 'value' => 'bar' ],
> > >> [ 'id' => 2, 'value' => 'baz' ],
> > >> ];
> > >>
> > >> $groups = [];
> > >> foreach ( $array as $element ) {
> > >>$groups[ $element['id'] ][] = $element;
> > >> }
> > >>
> > >> var_dump( $groups );
> > >> ```
> > >>
> > >> This can now be achieved as follows (not preserving keys):
> > >>
> > >> ```
> > >>  > >> $array = [
> > >> [ 'id' => 1, 'value' => 'foo' ],
> > >> [ 'id' => 1, 'value' => 'bar' ],
> > >> [ 'id' => 2, 'value' => 'baz' ],
> > >> ];
> > >>
> > >> $groups = array_group( $array, function( $a, $b ) {
> > >> return $a['id'] == $b['id'];
> > >> } );
> > >> ```
> > >>
> > >> The disadvantage of the first approach is that we are only limited to 
> > >> using equality check, and we cannot group by, say, `<` or other 
> > >> functions.
> > >> Similarly, the advantage of the first approach is that the keys are 
> > >> preserved, and elements needn't be consecutive.
> > >>
> > >> In any case, I think a utility function such as `array_group` will be 
> > >> widely useful.
> > >>
> > >> Please find attached a patch with a proposed implementation. Curious 
> > >> about your feedback.
> > >>
> > >> Best,
> > >>
> > >> Boro Sitnikovski
> > >>
> >

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



Re: [PHP-DEV] [RFC] [Discussion] Add new function `array_group`

2023-05-30 Thread Andreas Hennings
Thank you, this clarifies and it confirms my initial assumption of
what you are proposing.
So you want to slice an array by comparing adjacent values.


My personal feedback:
I think the need for the grouping behavior you describe is not common
enough that it needs its own native function.
I would say the more common desired behavior is the one in your first
example. And even for that we don't have a native function.

Your behavior can be implemented in userland like so:
https://3v4l.org/epvHm


$arr1 = array(1,2,2,3,1,2,0,4,5,2);

$groups = [];
$group = [];
$prev = NULL;
foreach ($arr1 as $value) {
if ($group && $prev > $value) {
$groups[] = $group;
$group = [];
}
$group[] = $value;
$prev = $value;
}
if ($group) {
$groups[] = $group;
}

print_r($groups);


If needed, the comparison function can be separated out and passed as
a parameter.
So the array_group() function with a comparison callback parameter can
be implemented in userland.

I think you need to make a case as to why the behavior you describe
justifies a native function.
E.g. if you find a lot of public php code that does this kind of grouping.

I personally suspect it is not that common.

Cheers
Andreas


On Tue, 30 May 2023 at 17:08, Boro Sitnikovski  wrote:
>
> Hey,
>
> Thanks for the suggestion.
>
> For the previous case in the code, I added these in a Gist to not clutter 
> here too much:
>
> 1. The first example corresponds to 
> https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_manual_group-php
> 2. The second example corresponds to 
> https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_array_group-php
> 3. Another example, addressing the problem of increasing subsequences is very 
> simple with `array_group`: 
> https://gist.github.com/bor0/b5f449bfe85440d96abd933b9f03b310#file-test_array_incr_subseqs-php
>
> Best,
>
> Boro
>
> > On 30.5.2023, at 16:57, Andreas Hennings  wrote:
> >
> > Hello Boro,
> > I think you should include the "expected result" in your code examples.
> > Maybe this is in your patch file, but I don't think we want to look at
> > that for discussion.
> >
> > Cheers
> > Andreas
> >
> > On Tue, 30 May 2023 at 13:35, Boro Sitnikovski  wrote:
> >>
> >> Hello all,
> >>
> >> As per the How To Create an RFC instructions, I am sending this e-mail in 
> >> order to get your feedback on my proposal.
> >>
> >> I propose introducing a function to PHP core named `array_group`. This 
> >> function takes an array and a function and returns an array that contains 
> >> arrays - groups of consecutive elements. This is very similar to Haskell's 
> >> `groupBy` function.
> >>
> >> For some background as to why - usually, when people want to do grouping 
> >> in PHP, they use hash maps, so something like:
> >>
> >> ```
> >>  >> $array = [
> >> [ 'id' => 1, 'value' => 'foo' ],
> >> [ 'id' => 1, 'value' => 'bar' ],
> >> [ 'id' => 2, 'value' => 'baz' ],
> >> ];
> >>
> >> $groups = [];
> >> foreach ( $array as $element ) {
> >>$groups[ $element['id'] ][] = $element;
> >> }
> >>
> >> var_dump( $groups );
> >> ```
> >>
> >> This can now be achieved as follows (not preserving keys):
> >>
> >> ```
> >>  >> $array = [
> >> [ 'id' => 1, 'value' => 'foo' ],
> >> [ 'id' => 1, 'value' => 'bar' ],
> >> [ 'id' => 2, 'value' => 'baz' ],
> >> ];
> >>
> >> $groups = array_group( $array, function( $a, $b ) {
> >> return $a['id'] == $b['id'];
> >> } );
> >> ```
> >>
> >> The disadvantage of the first approach is that we are only limited to 
> >> using equality check, and we cannot group by, say, `<` or other functions.
> >> Similarly, the advantage of the first approach is that the keys are 
> >> preserved, and elements needn't be consecutive.
> >>
> >> In any case, I think a utility function such as `array_group` will be 
> >> widely useful.
> >>
> >> Please find attached a patch with a proposed implementation. Curious about 
> >> your feedback.
> >>
> >> Best,
> >>
> >> Boro Sitnikovski
> >>
>

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



Re: [PHP-DEV] [RFC] [Discussion] Add new function `array_group`

2023-05-30 Thread Andreas Hennings
Hello Boro,
I think you should include the "expected result" in your code examples.
Maybe this is in your patch file, but I don't think we want to look at
that for discussion.

Cheers
Andreas

On Tue, 30 May 2023 at 13:35, Boro Sitnikovski  wrote:
>
> Hello all,
>
> As per the How To Create an RFC instructions, I am sending this e-mail in 
> order to get your feedback on my proposal.
>
> I propose introducing a function to PHP core named `array_group`. This 
> function takes an array and a function and returns an array that contains 
> arrays - groups of consecutive elements. This is very similar to Haskell's 
> `groupBy` function.
>
> For some background as to why - usually, when people want to do grouping in 
> PHP, they use hash maps, so something like:
>
> ```
>  $array = [
> [ 'id' => 1, 'value' => 'foo' ],
> [ 'id' => 1, 'value' => 'bar' ],
> [ 'id' => 2, 'value' => 'baz' ],
> ];
>
> $groups = [];
> foreach ( $array as $element ) {
> $groups[ $element['id'] ][] = $element;
> }
>
> var_dump( $groups );
> ```
>
> This can now be achieved as follows (not preserving keys):
>
> ```
>  $array = [
> [ 'id' => 1, 'value' => 'foo' ],
> [ 'id' => 1, 'value' => 'bar' ],
> [ 'id' => 2, 'value' => 'baz' ],
> ];
>
> $groups = array_group( $array, function( $a, $b ) {
> return $a['id'] == $b['id'];
> } );
> ```
>
> The disadvantage of the first approach is that we are only limited to using 
> equality check, and we cannot group by, say, `<` or other functions.
> Similarly, the advantage of the first approach is that the keys are 
> preserved, and elements needn't be consecutive.
>
> In any case, I think a utility function such as `array_group` will be widely 
> useful.
>
> Please find attached a patch with a proposed implementation. Curious about 
> your feedback.
>
> Best,
>
> Boro Sitnikovski
>

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



Re: [PHP-DEV] Declaration-aware attributes

2023-05-30 Thread Andreas Hennings
On Tue, 30 May 2023 at 15:14, Stephen Reay  wrote:
>
> (Resending to the list without all the history because qmail complained about 
> message size)
>
>
> >>
> >> Hi Andreas,
> >>
> >> I too have wondered (and I think asked in room11?) about such a concept. 
> >> >From memory the general response was “just do it in userland with a 
> >> wrapper” so its good to see someone else is interested in this being part 
> >> of the language.
> >>
> >> While I agree that it’s most useful if the `Reflector` instance is 
> >> available in the constructor, I’m not keen on the proposed magic 
> >> “skipping” of arguments as you suggest. It seems way too easy to confuse 
> >> someone (particularly if the attribute class itself has reason to be 
> >> instantiated directly in code)
> >
> > Good point! Almost made me change my mind completely. But I already
> > changed it back :)
> >
> > When instantiating in code, the "real" signature would have to be
> > used, and the reflector argument passed explicitly.
>
>
> That’s kind of my point: it’s not super intuitive why (or the specifics of 
> how) it’s being skipped when it’s an attribute, vs when it’s instantiated 
> from code. What if someone specifies an argument with the same name? If they 
> specify args without names, can they just use null for that? Etc.

I agree it could be confusing.
But for the named args, I think it is quite obvious:

#[Attribute]
class A {
  public readonly array $moreArgs;
  public function __construct(
public readonly string $x,
// Reflector parameter can be last required parameter, BUT
#[AttributeDeclaration] public readonly \ReflectionClass $class,
// Optional parameters have to be after the required reflector parameter.
public readonly ?string $y = NULL,
// Variadic parameter must be last.
string ...$moreArgs,
  ) {
$this->moreArgs = $moreArgs;
  }
}

#[A('x', 'y', 'z')]  // -> new A('x', $reflector, 'y', 'z')
#[A(x: 'x', y: 'y')]  // -> new A('x', $reflector, 'y')
#[A(x: 'x', class: new ReflectionClass('C'))]  // -> new A('x', new
ReflectionClass('C'))

We _could_ say that explicitly passing a value for the reflector in an
attribute declaration is forbidden.
Or we allow it, then an explicit value would simply overwrite the
implicit value.

If we use placeholder syntax, the above examples would look like this:

#[A('x', ?, 'y', 'z')]  // -> new A('x', $reflector, 'y', 'z')
#[A(x: 'x', class: ?, y: 'y')]  // -> new A('x', $reflector, 'y')
#[A(x: 'x', class: new ReflectionClass('C'))]  // -> new A('x', new
ReflectionClass('C'))


>
> > This would be
> > useful for unit tests that want to replicate the realistic behavior.
> > Also it guarantees that the code of the attribute class can really
> > count on this value to not be null, no matter how the class is
> > instantiated.
> >
> >
>
> I would expect that whether the Reflector object is required is simply a 
> matter of whether or not the parameter is nullable.
> If it’s not nullable, then yes, the explicit instantiation call will need to 
> supply it at the correct location. If it’s only required when created from 
> attribute usage, then it would accept null, and the constructor would have 
> appropriate logic to handle that.
>

Yes.
But I would expect the common practice to be to make it required,
because then the constructor code will be simpler.

>
>
> >>
> >> I think a better approach would be to suggest authors put the parameter at 
> >> the *end* of the parameter list, so that no ‘skipping' is required when 
> >> passing arguments without names (or put it where you like if you’re always 
> >> using named arguments)
> >
> > If I understand correctly, the proposal would technically not change,
> > we just add a recommendation.
>
> Technically, yes “my way” would work fine with the proposal you’ve suggested, 
> if I choose to always put the parameter marked by #[ReflectionContext] last.

As above, the problem with this would be optional and variadic
parameters, which have to come after a required reflector parameter.

>
> I’m just concerned about confusing usage if “insert this parameter anywhere” 
> is the ‘recommended’ (i.e. documented example) way to use this feature.
>
> Even with that concern, I still prefer this to most other solutions mentioned 
> so far, for the same reasons: they’re all some degree of magic.
>
> The only other solution I can think of that’s less “magic” and more explicit, 
> is (and I have no idea if this is even feasible technically) to introduce a 
> builtin trait for attribute classes to use, providing a protected method or 
> propert

Re: [PHP-DEV] Declaration-aware attributes

2023-05-30 Thread Andreas Hennings
On Tue, 30 May 2023 at 05:22, Stephen Reay  wrote:
>
>
>
> > On 30 May 2023, at 07:48, Andreas Hennings  wrote:
> >
> > Hello internals,
> > I am picking up an idea that was mentioned by Benjamin Eberlei in the past.
> > https://externals.io/message/110217#110395
> > (we probably had the idea independently, but Benjamin's is the first
> > post where I see it mentioned in the list)
> >
> > Quite often I found myself writing attribute classes that need to fill
> > some default values or do some validation based on the symbol the
> > attribute is attached to.
> > E.g. a parameter attribute might require a specific type on that
> > parameter, or it might fill a default value based on the parameter
> > name.
> >
> > Currently I see two ways to do this:
> > 1. Do the logic in the code that reads the attribute, instead of the
> > attribute class. This works ok for one-off attribute classes, but it
> > becomes quite unflexible with attribute interfaces, where 3rd parties
> > can provide their own attribute class implementations.
> > 2. Add additional methods to the attribute class that take the symbol
> > reflector as a parameter, like "setReflectionMethod()", or
> > "setReflectionClass()". Or the method in the attribute class that
> > returns the values can have a reflector as a parameter.
> >
> > Both of these are somewhat limited and unpleasant.
> >
> > I want to propose a new way to do this.
> > Get some feedback first, then maybe an RFC.
> >
> > The idea is to mark constructor parameters of the attribute class with
> > a special parameter attribute, to receive the reflector.
> > The other arguments are then shifted to skip the "special" parameter.
> >
> > #[Attribute]
> > class A {
> >  public function __construct(
> >public readonly string $x,
> >#[AttributeContextClass]
> >public readonly \ReflectionClass $class,
> >public readonly string $y,
> >  ) {}
> > }
> >
> > $a = (new ReflectionClass(C::class))->getAttributes()[0]->newInstance();
> > assert($a instanceof A);
> > assert($a->x === 'x');
> > assert($a->class->getName() === 'C');
> > assert($a->y === 'y');
> >
> > Note that for methods, we typically need to know the method reflector
> > _and_ the class reflector, because the method could be defined in a
> > base class.
> >
> > #[Attribute]
> > class AA {
> >  public function __construct(
> >#[AttributeContextClass]
> >public readonly \ReflectionClass $class,
> >#[AttributeContextMethod]
> >public readonly ReflectionMethod $method,
> >  ) {}
> > }
> >
> > class B {
> >  #[AA]
> >  public function f(): void {}
> > }
> >
> > class CC extends B {}
> >
> > $aa = (new ReflectionMethod(CC::class, 
> > 'f))->getAttributes()[0]->newInstance();
> > assert($a->class->getName() === 'CC');
> > assert($a->method->getName() === 'f');
> >
> > ---
> >
> > Notice that the original proposal by Benjamin would use an interface
> > and a setter method, ReflectorAwareAttribute::setReflector().
> >
> > I prefer to use constructor parameters, because I generally prefer if
> > a constructor creates a complete and immutable object.
> >
> > 
> >
> > Thoughts?
> >
> > -- Andreas
> >
> > --
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: https://www.php.net/unsub.php
> >
>
> Hi Andreas,
>
> I too have wondered (and I think asked in room11?) about such a concept. 
> >From memory the general response was “just do it in userland with a wrapper” 
> so its good to see someone else is interested in this being part of the 
> language.
>
> While I agree that it’s most useful if the `Reflector` instance is available 
> in the constructor, I’m not keen on the proposed magic “skipping” of 
> arguments as you suggest. It seems way too easy to confuse someone 
> (particularly if the attribute class itself has reason to be instantiated 
> directly in code)

Good point! Almost made me change my mind completely. But I already
changed it back :)

When instantiating in code, the "real" signature would have to be
used, and the reflector argument passed explicitly. This would be
useful for unit tests that want to replicate the realistic behavior.
Also it guarantees that the code of the attribute class can really
count on this value to not be null, no matter how the class is
instantiated

[PHP-DEV] Let ReflectionMethod keep track of original class

2023-05-29 Thread Andreas Hennings
Hello list,
this proposal will be useful in combination with "Declaration-aware attributes"


Problem

Currently, ReflectionMethod is not aware of the original class, if the
method is declared in a parent class.
Methods that are called during a discovery algorithm that need to
process a method with its original class typically need two
parameters:

function processMethod(\ReflectionClass $class, \ReflectionMethod $method) {..}


Proposal

Let a ReflectionMethod object keep track of the original class.
Introduce a new method ReflectionMethod->getOriginalClass() to retrieve it.

class B {
  function f($x) {}
}
class C extends B {}

foreach ([
  // There are different ways to get a reflection method object, all
of them track the original class.
  new ReflectionMethod('C', 'f'),
  (new ReflectionClass('C'))->getMethod('f'),
  (new ReflectionMethod('C', 'f'))->getParameters()[0]->getDeclaringFunction(),
] as $rm) {
  // The following won't change:
  assert($rm->class === 'B');
  assert($rm->getDeclaringClass()->getName() === 'B');
  // New method:
  assert($rm->getOriginalClass()->getName() === 'C');


Alternatives
==

At first I thought we might introduce a new class like
"VirtualReflectionMethod" which behaves as if the method was declared
on the child class. But this is awkward.

I think the ->getOriginalClass() is much simpler.


--- Andreas

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



[PHP-DEV] Re: Declaration-aware attributes

2023-05-29 Thread Andreas Hennings
I just notice a flaw in my thinking.

On Tue, 30 May 2023 at 02:48, Andreas Hennings  wrote:
>
> Note that for methods, we typically need to know the method reflector
> _and_ the class reflector, because the method could be defined in a
> base class.

This is true when doing a discovery using attributes.
However, PHP does not know the original class when we call (new
ReflectionClass('C'))->getMethod('f')->getAttributes().
So it cannot pass the original class into the attribute constructor.

Currently, only the userland code that does the discovery knows the
original class.

We would need a type of method reflector that keeps track of the original class.
This could well be its own separate RFC.
Once this is done, we no longer need to pass the class as a separate argument.

So to keep this RFC independent, we should only pass the reflector
object where ->getAttributes()[*]->newInstance() was called on.
Then if in a separate RFC we keep track of the original class in
ReflectionMethod, the same information will be available when the
method reflector is injected into an attributes.

This also means that the ReflectionAttribute object needs to keep a
reference of the original reflector.
And if it does that, we can as well provide a method to return it.

assert((new ReflectionClass('C'))->getAttributes()[0]->getReflector()->getName()
=== 'C');

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



Re: [PHP-DEV] Declaration-aware attributes

2023-05-29 Thread Andreas Hennings
Thanks for the feedback!

On Tue, 30 May 2023 at 03:43, Dusk  wrote:
>
> On May 29, 2023, at 17:48, Andreas Hennings  wrote:
> > Quite often I found myself writing attribute classes that need to fill
> > some default values or do some validation based on the symbol the
> > attribute is attached to.
> > E.g. a parameter attribute might require a specific type on that
> > parameter, or it might fill a default value based on the parameter
> > name.
>
> +1. This is a substantial limitation in the attribute system.
>
> > Currently I see two ways to do this:
> > 1. Do the logic in the code that reads the attribute, instead of the
> > attribute class. This works ok for one-off attribute classes, but it
> > becomes quite unflexible with attribute interfaces, where 3rd parties
> > can provide their own attribute class implementations.
> > 2. Add additional methods to the attribute class that take the symbol
> > reflector as a parameter, like "setReflectionMethod()", or
> > "setReflectionClass()". Or the method in the attribute class that
> > returns the values can have a reflector as a parameter.
>
> I see a third way which introduces less "magic":

Actually, these two options are what is possible with the current
version of PHP, but it requires to write php code to solve these
problems each time.
The actual proposal in terms of "language design" solution was further
below in my email :)


>
> 3.a. Add a method to ReflectionAttribute which retrieves the target of the 
> attribute as an appropriate reflection object. (Sadly, the obvious name 
> "getTarget" is already taken; I'll call it "getReflectionTarget" for now.)
>
> 3.b. Add a static method to ReflectionAttribute which, when called within an 
> Attribute constructor which is being called by 
> ReflectionAttribute::newInstance(), returns the ReflectionAttribute object 
> which is being instantiated.
>
> These features could be used together to set a default property on an 
> attribute based on its target, e.g.
>
> #[Attribute(Attribute::TARGET_PROPERTY)]
> class PropertyAnnotation {
>   public string $name;
>
>   public function __construct(?string $name = null) {
> $this->name = $name ?? 
> ReflectionAttribute::underConstruction()->getReflectionTarget()->getName();
>   }
> }
>
> Another variant that comes to mind is:
>
> 3.b. Add a new flag to attributes which causes the ReflectionAttribute object 
> to be passed to the constructor as the first argument, e.g.
>
> #[Attribute(Attribute::TARGET_PROPERTY | Attribute::WHO_MADE_ME)]
> class PropertyAnnotation {
>   public string $name;
>
>   public function __construct(ReflectionAttribute $attr, ?string $name = 
> null) {
> $this->name = $name ?? $attr->getReflectionTarget()->getName();
>   }
> }
>
> This is a little messier because it can't be used "under the covers" by an 
> attribute base class, but it accomplishes the same goals.

This is close to the parameter attribute I proposed.
The benefit of the parameter attribute is that a developer can clearly
see which parameter will be skipped for regular arguments.

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



[PHP-DEV] Re: Declaration-aware attributes

2023-05-29 Thread Andreas Hennings
A big TBD would be the new attribute classes we need to mark these parameters.
Perhaps we could use just one attribute class, e.g.
"AttributeDeclaration", and use the parameter type to determine which
part of the declaration is expected.

Also, if an attribute is allowed on different symbol types, then these
parameters could be made nullable, or allow multiple types.
Of course some combinations would be ambiguous, e.g.
`\ReflectionClass|\ReflectionMethod`.

#[Attribute(Attribute::TARGET_METHOD, Attribute::TARGET_PROPERTY,
Attribute::TARGET_CLASS_CONSTANT)]
class A {
  public function __construct(
public readonly string $x,
#[AttributeDeclaration] public readonly \ReflectionClass $class,
#[AttributeDeclaration] public readonly ?\ReflectionMethod $method,
#[AttributeDeclaration] public readonly
?\ReflectionClassConstant|\ReflectionProperty $constantOrProperty,
public readonly string $y,
  ) {}
}

On Tue, 30 May 2023 at 02:48, Andreas Hennings  wrote:
>
> Hello internals,
> I am picking up an idea that was mentioned by Benjamin Eberlei in the past.
> https://externals.io/message/110217#110395
> (we probably had the idea independently, but Benjamin's is the first
> post where I see it mentioned in the list)
>
> Quite often I found myself writing attribute classes that need to fill
> some default values or do some validation based on the symbol the
> attribute is attached to.
> E.g. a parameter attribute might require a specific type on that
> parameter, or it might fill a default value based on the parameter
> name.
>
> Currently I see two ways to do this:
> 1. Do the logic in the code that reads the attribute, instead of the
> attribute class. This works ok for one-off attribute classes, but it
> becomes quite unflexible with attribute interfaces, where 3rd parties
> can provide their own attribute class implementations.
> 2. Add additional methods to the attribute class that take the symbol
> reflector as a parameter, like "setReflectionMethod()", or
> "setReflectionClass()". Or the method in the attribute class that
> returns the values can have a reflector as a parameter.
>
> Both of these are somewhat limited and unpleasant.
>
> I want to propose a new way to do this.
> Get some feedback first, then maybe an RFC.
>
> The idea is to mark constructor parameters of the attribute class with
> a special parameter attribute, to receive the reflector.
> The other arguments are then shifted to skip the "special" parameter.
>
> #[Attribute]
> class A {
>   public function __construct(
> public readonly string $x,
> #[AttributeContextClass]
> public readonly \ReflectionClass $class,
> public readonly string $y,
>   ) {}
> }
>
> $a = (new ReflectionClass(C::class))->getAttributes()[0]->newInstance();
> assert($a instanceof A);
> assert($a->x === 'x');
> assert($a->class->getName() === 'C');
> assert($a->y === 'y');
>
> Note that for methods, we typically need to know the method reflector
> _and_ the class reflector, because the method could be defined in a
> base class.
>
> #[Attribute]
> class AA {
>   public function __construct(
> #[AttributeContextClass]
> public readonly \ReflectionClass $class,
> #[AttributeContextMethod]
> public readonly ReflectionMethod $method,
>   ) {}
> }
>
> class B {
>   #[AA]
>   public function f(): void {}
> }
>
> class CC extends B {}
>
> $aa = (new ReflectionMethod(CC::class, 
> 'f))->getAttributes()[0]->newInstance();
> assert($a->class->getName() === 'CC');
> assert($a->method->getName() === 'f');
>
> ---
>
> Notice that the original proposal by Benjamin would use an interface
> and a setter method, ReflectorAwareAttribute::setReflector().
>
> I prefer to use constructor parameters, because I generally prefer if
> a constructor creates a complete and immutable object.
>
> 
>
> Thoughts?
>
> -- Andreas

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



[PHP-DEV] Declaration-aware attributes

2023-05-29 Thread Andreas Hennings
Hello internals,
I am picking up an idea that was mentioned by Benjamin Eberlei in the past.
https://externals.io/message/110217#110395
(we probably had the idea independently, but Benjamin's is the first
post where I see it mentioned in the list)

Quite often I found myself writing attribute classes that need to fill
some default values or do some validation based on the symbol the
attribute is attached to.
E.g. a parameter attribute might require a specific type on that
parameter, or it might fill a default value based on the parameter
name.

Currently I see two ways to do this:
1. Do the logic in the code that reads the attribute, instead of the
attribute class. This works ok for one-off attribute classes, but it
becomes quite unflexible with attribute interfaces, where 3rd parties
can provide their own attribute class implementations.
2. Add additional methods to the attribute class that take the symbol
reflector as a parameter, like "setReflectionMethod()", or
"setReflectionClass()". Or the method in the attribute class that
returns the values can have a reflector as a parameter.

Both of these are somewhat limited and unpleasant.

I want to propose a new way to do this.
Get some feedback first, then maybe an RFC.

The idea is to mark constructor parameters of the attribute class with
a special parameter attribute, to receive the reflector.
The other arguments are then shifted to skip the "special" parameter.

#[Attribute]
class A {
  public function __construct(
public readonly string $x,
#[AttributeContextClass]
public readonly \ReflectionClass $class,
public readonly string $y,
  ) {}
}

$a = (new ReflectionClass(C::class))->getAttributes()[0]->newInstance();
assert($a instanceof A);
assert($a->x === 'x');
assert($a->class->getName() === 'C');
assert($a->y === 'y');

Note that for methods, we typically need to know the method reflector
_and_ the class reflector, because the method could be defined in a
base class.

#[Attribute]
class AA {
  public function __construct(
#[AttributeContextClass]
public readonly \ReflectionClass $class,
#[AttributeContextMethod]
public readonly ReflectionMethod $method,
  ) {}
}

class B {
  #[AA]
  public function f(): void {}
}

class CC extends B {}

$aa = (new ReflectionMethod(CC::class, 'f))->getAttributes()[0]->newInstance();
assert($a->class->getName() === 'CC');
assert($a->method->getName() === 'f');

---

Notice that the original proposal by Benjamin would use an interface
and a setter method, ReflectorAwareAttribute::setReflector().

I prefer to use constructor parameters, because I generally prefer if
a constructor creates a complete and immutable object.



Thoughts?

-- Andreas

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



Re: [PHP-DEV] RFC [Concept] - Interface Properties

2023-05-28 Thread Andreas Heigl

Hey all

On 28.05.23 13:52, David Gebler wrote:

On Sun, May 28, 2023 at 10:33 AM Rowan Tommins 
wrote:


I don't follow. If a property is public, then code outside the class can
rely on being able to access it. That seems to me to be a contract between
the class and its users, not an implementation detail - e.g. removing the
property, or changing its type, would be a compatibility break. A property
can also be inherited from a base class, at which point there is a contract
that all descendants of that base class will have the property available.
So it seems logical that that contract could also be included in an
interface.



That's why you can declare constants in an interface (a static final
property, to use the lexicon of Java) which we can already do in PHP. At
the point you want to bring mutable state into an interface, it's a design
smell that what you want, really, is an abstract class or perhaps
composition.

A couple of languages do allow mutable properties on interfaces, TypeScript
being one of them, so yes it's not an unheard of feature - but in TS/JS
it's a lot more idiomatic to directly access properties than it is in PHP.
I'm not too familiar with C# personally but I have a vague recall that the
idea of properties on interfaces there is more akin to the property hooks
RFC than Nick's proposal here. And although I'm a little uncomfortable with
encouraging getters and setters on interfaces, I'm fully behind property
hooks, I hope that RFC passes.

PHP already has the sufficient design tools to follow SOLID principles and
established design patterns well. If this RFC was in the language tomorrow,
you wouldn't be able to do anything you can't already do and do more
safely, more robustly, with behavioural interfaces and traits.


For me an Interface defines a contract.

When the creator of an interface thinks that adding a public (and 
possibly readonly) property to that contract then I can not really see 
where the problem is.


It allows access to the internal state? Yes. As do getters and setters 
that can already be declared in an interface.


It allows breaking established design patterns? Well... People are very 
creative in working around what they feel are restrictions.


With providing readonly properties we made it possible to not have to 
declare getters for properties. But that means that accessing those 
properties can no longer be part of a contract provided by an interface. 
So IMO we need a solution to that dilemma for interfaces.


being able to declare public properties via an interface makes only 
sense to me then.


Just my 0.02€

Cheers

Andreas--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Re: [VOTE] PHP Technical Committee

2023-05-12 Thread Andreas Heigl

Hey Arvids, Hey all

On 12.05.23 17:48, Arvids Godjuks wrote:

On Fri, 12 May 2023 at 18:12, Andreas Heigl  wrote:


Hey Larry, Hey all

On 12.05.23 16:42, Larry Garfield wrote:

On Fri, May 12, 2023, at 11:57 AM, Jakub Zelenka wrote:

On Fri, Apr 28, 2023 at 11:00 AM Jakub Zelenka  wrote:


Hi,

The vote is now open for the RFC about introduction of the PHP

Technical

Committee:

https://wiki.php.net/rfc/php_technical_committee

Regards



The voting ended with 10 yes votes and 21 no votes. It means that the

RFC

has been declined. Thanks for voting.

Regards

Jakub


For those who voted no, I would kindly ask: What is your alternative?

We have an organizational/structural problem.  This isn't really

debatable.  An eager new contributor was just bullied out of contributing,
and the one process we have for dealing with it (RFCs) failed miserably to
handle the situation.


Ignoring the problem is a bad option.  If the TC proposal isn't your

preferred way to address it, OK, what is?  "Do nothing, it's OK if people
occasionally get bullied out of contributing" is not an answer.

The internals list has not only recently "failed" miserably. That is not
to say that it has been like that since time immemoriable and should
therefore stay like that. On the contrary.

But we already have a group that has "the say" in PHP. The PHP Group is
mentioned in each and every source-file as they are the licence-holder.

Instead of adding another group I would rather see that existing group
to be filled with new life.

Whether that is the right group to tell people in the internals list off
is IMO questionable.

In essence to me the internals list is a group that discusses technical
topics regarding PHPs sources. The outcome and the vote whether
something will become part of the code is then voted on in an RFC. That
is a rather democratic process. When people are not able to convince the
majority of the voters that their idea is a good idea for the PHP
sources then it might not be a good idea. Having a group of people with
elevated privileges in that process is against that long lived and
established current process. And it looks like internals is not yet at
that point.

Having a group of people that make sure that the tone on the list is
civil, on-topic and inviting to newcomers is a different story. But that
was not what the vote was about.

So for me there already is an elevated group that has a bit more to say
regarding the PHP-sources as they are the once "owning" the licence.
Adding a second group with elevated privileges regarding code-decissions
will not help in keeping the mailinglist civilised and welcoming.

On a sidenote: I'd rather try to find a new solution for the PHP Group
as licence holder. So the idea of having an elected comitee that coupd
perhaps replace the PHP Group was tempting!

So my alternative would be for everyone to every now and then reread
https://github.com/php/php-src/blob/master/docs/mailinglist-rules.md

And as a second step to make internals more welcoming and inclusive
might be to have people keep an eye on the tone that can intervene when
the debate gets too heated. Those IMO need to be respected people and
their influence is in those matters purely on keeping the tone civilized
and not have a veto right in regards to code. The internals list and in
the end the vote on an RFC should have the last say in regards to code.

My 0.02€

Cheers

Andreas

--
,,,
   (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-----+



Hello Andreas!

I think what Larry is asking are ideas on actual solutions,  what steps
should be made and working out how those recent situations should have been
solved/handled. Really it does not matter if will it be PHP Group or some
called something else. There has been a lot of discussion off the list in
communities among PHP developers and nobody considers the recent events as
something that should have happened.

The time to "let's throw around some ideas" has passed. The current
situation highly reminds me of the year prior to the introduction of the
RFC process: this going down a hill at a rapid pace and a lot of people
yelling "la la la la" while plugging their ears.
The world has cha

Re: [PHP-DEV] Re: [VOTE] PHP Technical Committee

2023-05-12 Thread Andreas Heigl

Hey Larry, hey all

On 12.05.23 17:36, Larry Garfield wrote:

On Fri, May 12, 2023, at 3:12 PM, Andreas Heigl wrote:


[...]



In essence to me the internals list is a group that discusses technical
topics regarding PHPs sources. The outcome and the vote whether
something will become part of the code is then voted on in an RFC. That
is a rather democratic process. When people are not able to convince the
majority of the voters that their idea is a good idea for the PHP
sources then it might not be a good idea. Having a group of people with
elevated privileges in that process is against that long lived and
established current process. And it looks like internals is not yet at
that point.


Again, not the topic at hand.  The TC proposal did not change the feature approval RFC 
process, at all.  It was very explicit about that.  It was about non-feature decisions 
that are highly technical.  Those simply do not make sense to apply casual direct 
democracy to.  To take the recent example, there's probably only about 10 people who have 
any meaningful input to give on "should this include statement be here or over 
here."  The other 990 or so RFC voters, quite honestly, do not have anything 
meaningful or useful to say, and most probably don't even understand the question.  And I 
include myself in that category.  On decisions like that, *please do not ask me, I have 
nothing useful to contribute*.


In other projects I work on these purely technical decissions and 
discussions are solved using CodeReviews (or Pair/MobProgramming).


That doesn't indeed require an RFC.

But in the specific case that we seem to try to solve here - at least 
from what I have seen and read - I doubt that any CodeReview or entity 
could have made that less messy.


So I'm still not convinced that we need a special group of people - 
apart from the already special group of amazing people that are doing a 
shitload of great stuff for the language.


And the rest is pretty already nicely described in the 
CONTRIBUTING.md[1] file.


For example:

> Discuss any significant changes on the list before committing and get 
confirmation from the release manager for the given branch.


or

> If you "strongly disagree" about something another person did, don't 
start fighting publicly - take it up in private email.


So in essence we already have the group of people - and they are even 
elected: The release-managers.


So no need to elect another body

My 0.02€

Cheers

Andreas

[1] 
https://github.com/php/php-src/blob/master/CONTRIBUTING.md#git-commit-rules

--
  ,,,
 (o o)
+---------ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Re: [VOTE] PHP Technical Committee

2023-05-12 Thread Andreas Heigl

Hey Larry, Hey all

On 12.05.23 16:42, Larry Garfield wrote:

On Fri, May 12, 2023, at 11:57 AM, Jakub Zelenka wrote:

On Fri, Apr 28, 2023 at 11:00 AM Jakub Zelenka  wrote:


Hi,

The vote is now open for the RFC about introduction of the PHP Technical
Committee:

https://wiki.php.net/rfc/php_technical_committee

Regards



The voting ended with 10 yes votes and 21 no votes. It means that the RFC
has been declined. Thanks for voting.

Regards

Jakub


For those who voted no, I would kindly ask: What is your alternative?

We have an organizational/structural problem.  This isn't really debatable.  An 
eager new contributor was just bullied out of contributing, and the one process 
we have for dealing with it (RFCs) failed miserably to handle the situation.

Ignoring the problem is a bad option.  If the TC proposal isn't your preferred way to 
address it, OK, what is?  "Do nothing, it's OK if people occasionally get bullied 
out of contributing" is not an answer.


The internals list has not only recently "failed" miserably. That is not 
to say that it has been like that since time immemoriable and should 
therefore stay like that. On the contrary.


But we already have a group that has "the say" in PHP. The PHP Group is 
mentioned in each and every source-file as they are the licence-holder.


Instead of adding another group I would rather see that existing group 
to be filled with new life.


Whether that is the right group to tell people in the internals list off 
is IMO questionable.


In essence to me the internals list is a group that discusses technical 
topics regarding PHPs sources. The outcome and the vote whether 
something will become part of the code is then voted on in an RFC. That 
is a rather democratic process. When people are not able to convince the 
majority of the voters that their idea is a good idea for the PHP 
sources then it might not be a good idea. Having a group of people with 
elevated privileges in that process is against that long lived and 
established current process. And it looks like internals is not yet at 
that point.


Having a group of people that make sure that the tone on the list is 
civil, on-topic and inviting to newcomers is a different story. But that 
was not what the vote was about.


So for me there already is an elevated group that has a bit more to say 
regarding the PHP-sources as they are the once "owning" the licence. 
Adding a second group with elevated privileges regarding code-decissions 
will not help in keeping the mailinglist civilised and welcoming.


On a sidenote: I'd rather try to find a new solution for the PHP Group 
as licence holder. So the idea of having an elected comitee that coupd 
perhaps replace the PHP Group was tempting!


So my alternative would be for everyone to every now and then reread 
https://github.com/php/php-src/blob/master/docs/mailinglist-rules.md


And as a second step to make internals more welcoming and inclusive 
might be to have people keep an eye on the tone that can intervene when 
the debate gets too heated. Those IMO need to be respected people and 
their influence is in those matters purely on keeping the tone civilized 
and not have a veto right in regards to code. The internals list and in 
the end the vote on an RFC should have the last say in regards to code.


My 0.02€

Cheers

Andreas

--
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] [Discussion] Clone with

2023-04-19 Thread Andreas Hennings
On Tue, 18 Apr 2023 at 22:01, Bob Magic  wrote:
>
> > [1] In fact if the right hand side of with may be an expression that
> > evaluates to an array, folks wouldn't need to learn new syntax at all:
> >
> > $newProperties = [ "foo" => "bar" ];
> > clone $object with $newProperties;
> >
> > and
> >
> > clone $object with [ "foo" => "bar" ];
>
> in my opinion this is sick, as in awesome. the {} version makes no sense to
> me unless the language gains $var = {} ; to skip $var = (object)[];

I think the {...} is meant to be simply an "argument list", not a value.
But yes having an array here would add some flexibility. It would also
give us argument unpacking for free.

I wonder what this means for performance.
Will the expression always be evaluated as an array first, and then
applied, or can php do a "shortcut" where it internally treats it as
an argument list, even though the syntax implies array?
The different will be small, but it could become relevant if called
many times over.

-- Andreas

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



Re: [PHP-DEV] [RFC] [Discussion] Clone with

2023-04-18 Thread Andreas Hennings
> The biggest advantage of Nicolas' proposal over “clone with” is that it could 
> be made part of the interface contract whether a method modifies the object 
> state. So the PSR-7 ResponseInterface could look like the following:
> [..]
> public clone function withStatus($code, $reasonPhrase = '');

If this is the main argument, I think I would prefer a more general
"readonly" modifier on methods.

public readonly function withStatus($code, $reasonPhrase = ''): static;

> One cannot control whether $this should really be cloned: e.g. if a property 
> should only be modified based on certain conditions (e.g. validation), the 
> object would potentially be cloned in vain, resulting in a performance loss.

Exactly. I would say "conditionally clone", e.g. only clone if there
is a change, or if we don't already have a cached instance with this
value.

I think the "clone with" is much more flexible because we can call
this anywhere, not just in a dedicated method.

This said, I do agree with some of the benefits of the "Alternative" proposal.

-- Andreas


On Mon, 17 Apr 2023 at 08:32, Máté Kocsis  wrote:
>
> Hi Everyone,
>
> Quite some time after mentioning the "clone with" construct the first time
> (at the end of the
> https://wiki.php.net/rfc/write_once_properties#run-time_behaviour section),
> finally I managed to create a working implementation for this feature which
> would make it possible to properly modify readonly properties
> while simplifying how we write "wither" methods:
> https://wiki.php.net/rfc/clone_with
>
> Regards,
> Máté Kocsis

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



Re: [PHP-DEV] [RFC] [Discussion] Clone with

2023-04-18 Thread Andreas Hennings
Hello Máté, internals,
I have been waiting for this to happen :)
Some feedback

> However, in some cases it would be useful to reference property names as 
> expressions, e.g. when one needs to use “clone with” in a foreach loop where 
> the index is the property name and the loop variable is the value to be 
> assigned. This is also possible using a slightly more verbose syntax:

What about argument unpacking?
I don't know if we can combine this with ":" syntax or only with "=>".

clone $object with {
  ...$arr,
  ...['a' => 'A', $b => 'B'],
  ...(function () {yield 'x' => 'X';})(),
  c: 'C',  // or
  d => 'D',  // No mixing of ':' and '=>', we have to choose one.
}

If we want to go crazy in the future:
(This would require another language feature of inline code blocks
with return value or behaving as generator)

clone $object with {
  ...{
yield 'a' => 'A';
yield 'b' => 'B';
  },
  ...{
return ['c' => 'C'],
  }
}

-- Andreas

On Mon, 17 Apr 2023 at 08:32, Máté Kocsis  wrote:
>
> Hi Everyone,
>
> Quite some time after mentioning the "clone with" construct the first time
> (at the end of the
> https://wiki.php.net/rfc/write_once_properties#run-time_behaviour section),
> finally I managed to create a working implementation for this feature which
> would make it possible to properly modify readonly properties
> while simplifying how we write "wither" methods:
> https://wiki.php.net/rfc/clone_with
>
> Regards,
> Máté Kocsis

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



Re: [PHP-DEV] Re: Improving Mailing-List interactions - was: [PHP-DEV] Moving PHP internals to GitHub

2023-04-13 Thread Andreas Heigl



On 13.04.23 10:50, Tim Düsterhus wrote:

Hi

On 4/13/23 10:46, Andreas Heigl wrote:

DMARC is less of a concern, because the list apparently already performs
DMARC mangling for a policy that is not 'none'


Apart from (possibly) modifying the body and the subject line which then
breaks the DKIM signature which then breaks DMARC ;-)



I understand how DKIM and DMARC works. For users with a DMARC policy of 
quarantine or reject the list manager already performs DMARC mangling:


The 'From' header is changed from the original 'From' header and instead 
the list address is put there. Now the DMARC policy of the original 
sender no longer applies and instead the DMARC policy of the list is 
used (which does not exist).


You can see happening with the email from "Mikhail Galanin via 
internals" that was sent roughly 10 minute ago.


Then we should probably change that so that emails from a domain with 
DMARC set to 'none'  are also not changed.


As that just means that DMARC is enabled, the receiving mailserver 
should just not quarantine or reject the message but instead inform the 
sender about the problem.


With the current settings the sender receives issues and the clients 
also report that the DKIM signature is invalid.


Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Re: Improving Mailing-List interactions - was: [PHP-DEV] Moving PHP internals to GitHub

2023-04-13 Thread Andreas Heigl

Hey

On 13.04.23 10:38, Tim Düsterhus wrote:

Hi

On 4/13/23 10:29, Andreas Heigl wrote:

1. Remove modification of the emails on the lists server so that DKIM
and DMARC will finally work


Yes, please, but for different reasons:

Filtering is much more reliably performed using the 'list-id' header 
compared to a Subject prefix and not having the prefix in the Subject 
makes the INBOX more tidy when also having the [RFC] or [VOTE] prefixes. 
Also clients apparently can't decide whether to put the 'Re' before or 
after the prefix.


DMARC is less of a concern, because the list apparently already performs 
DMARC mangling for a policy that is not 'none'


Apart from (possibly) modifying the body and the subject line which then 
breaks the DKIM signature which then breaks DMARC ;-)


Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


[PHP-DEV] Improving Mailing-List interactions - was: [PHP-DEV] Moving PHP internals to GitHub

2023-04-13 Thread Andreas Heigl

Hey all

On 12.04.23 22:44, Larry Garfield wrote:

On Wed, Apr 12, 2023, at 6:42 PM, Rowan Tommins wrote:



Which brings me back to my earlier point: I wonder how much of the
reaction is really about e-mail itself, and how much is just the
documentation and sign-up forms you encounter *before* you hit the list.
Because if it's the latter, migrating the entire community to a new
platform won't help - we'll still suck at introducing anyone to that
platform - and most of what we need is someone who's good with words to
update some website copy.


I agree, and it's a common pattern, both here and in the earlier thread about 
deprecations/evolution.

Problems exist.  Both with the mailing list setup we have, and the 
evolution/deprecation process.  It's not reasonable to deny either.

But so often, people lead with "and here's why we should rm -rf and start over" or "and here's 
why you're all terrible" or other extremely not-helpful "suggestions."  That poisons the well, 
and totally saps any energy for working on the things that can and should be improved incrementally.

It makes me very sad, because if someone were actually to volunteer to overhaul 
the mailing list signup process and verify that it actually, you know, works 
reliably, there's a good chance they'd be greeted with open arms.  (And a fair 
amount of access skepticism I'm sure, but still, it's no secret that we'd 
benefit from that.)  But that's not what happens.



I would like to take this as a first step:

As I already do have access to the lists-server I'm happy to work on 
improving the lists usability.


So far I see three different things:

1. Remove modification of the emails on the lists server so that DKIM 
and DMARC will finally work

2. Improve/Update the interfaces of https://www.php.net/mailing-lists.php
3. Update (or possibly completely remove?) https://www.php.net/unsub.php

The latest is linke in the added footer that would be removed by step 1 
and that should be unnecessary anyhow as the list-unsubscribe header 
already should provide the email-clients with a way to show an 
unsubscribe button right in the email.


Any volunteers helping are welcome!

And please do voice concerns regarding point 1

Cheers

Andreas

--
  ,,,
 (o o)
+---------ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Moving PHP internals to GitHub

2023-04-12 Thread Andreas Heigl



On 12.04.23 16:12, Alex Wells wrote:

On Wed, Apr 12, 2023 at 4:57 PM Marco Pivetta  wrote:


FYI: https://externals.io/message/87501#87501

Also: wow, that was 7 years ago?! :O

That was exactly my thought as well...




Thanks. I've completely missed this while searching for an alike thread :)

But as you mentioned, it's been 7 years. Many things and people have
changed. Particularly, PHP has already "vendor locked in" itself into
GitHub; and there's now a specific solution from them - GitHub discussions,
created specifically to tackle the issues with discussions in GitHub
issues. They're not perfect, but hey, neither are mailing lists.


The vendor lock-in is one of the biggest issues that I see with the 
PHP-project.


Adding the main discussion platform to the locked resources is probably 
not one of the best ideas.


Just my 0.02€

Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Moving PHP internals to GitHub

2023-04-12 Thread Andreas Heigl

Hey Alex.

On 12.04.23 15:52, Alex Wells wrote:

Hey.

PHP currently uses internals@lists.php.net for communication. That includes
mostly RFCs (or their votings, or their pre-discussion) and sometimes
questions about the implementation or possible bugs.

While emailing definitely works, it's not the best UX out there. Here are
some immediate flaws which make the process harder than it should be:
  - having to subscribe to a mailing list to even see the discussions
  - supporting public archives such as externals.io to expose discussions to
the public for those who aren't subscribed and keep historical data
  - having to learn the specific, uncommon rules of replying: bottom
posting, word wrapping, removing footers. It's not to say any of those
rules are complex or hard to follow; it's that they're basically
inapplicable outside of emails, so they're usually not known by newcomers.
Also popular emailing clients don't do any of that automatically, making
each reply tedious.


Those rules are written down in 
https://github.com/php/php-src/blob/master/docs/mailinglist-rules.md and 
are in essence a modified version of one of the main rules of the 
internet https://www.rfc-editor.org/rfc/rfc1855


Yes: Most web-based mailinterfaces do not care about those basic rules 
of the internet - why that is is a separate discussion - but there are a 
lot of email-clients around that do care about those.



  - no way of editing a message. Mistakes will always be made, so being able
to quickly fix them would be nice


Email is no quickly written chat. You should read what you wrote, use 
your spell-checker and be 100% sure that that is what you want to 
express. That allows a much more clear and focused discussion as people 
will make sure they have expressed what they wanted with enough time. It 
also reduces the possibility of heated discussions (reduces! not 
eliminates! (-; )

  - no formatting, especially code blocks. Sure, they are possible through
HTML, but there's no single common way which all of the emailing clients
will understand - like Markdown


What do you need formatting for? And most of us can read markdown in 
plaintext emails as well...



  - no reactions - it's hard to tell whether something is supported or not.
This includes both the initiative being discussed and the replies that
follow. Sure, you can usually kind of judge the general narrative based on
the replies, but it's not always clear what's in favor. There are usually
many divergent branches of discussions and it's unknown what's supported
the most.


It's a discussion. A :thumbs-up: is not helpful. And if you want to do 
that: Send an email with exactly that.


The discussion lives from meaningful interaction. Not a thumbsup/down 
echochamber


Based on those issues and PHP, I propose moving the discussions elsewhere -
to some kind of modern platform. Since this is quite a big change in the
processes used, I imagine an RFC would be needed. But before I do that I
want to measure the reactions. If it goes well, I'll proceed with an RFC
draft.


There have been a number of discussions over the years and all came to 
the conclusion that no other medium provided the means that the list 
wanted - at that time. Apart perhaps from NNTP (Did I mention that the 
mailinglists are available via NNTP? or at least should be. If not I 
might have to check the colobus integration...)


There are basically two choices here - a messenger-like platform (i.e.
Slack, Teams) or a developer focused platform like GitHub. While messengers
certainly work, they're more focused on working with teammates rather than
actual discussions. They usually don't have a simple way to navigate
publicly and are poor at separating multiple topics into threads. Some
projects use them for that purpose, but it's usually a worse experience
than what GitHub provides.

GitHub is already used by PHP for both the source code and the issues, so
that is a good candidate, especially since it's a platform designed to
handle cases like this. Also, that should be a much easier transition now
that the source and issues were moved to GitHub.

Also, to be clear: I'm not proposing to remove all PHP mailing lists; some
of them are one way (i.e. notifications for something) so they should
definitely stay that way. Some of them might not even be used anymore.
However, I want this change to affect all two-way (discussion) mailing
lists if possible. Also, this does not include moving RFCs themselves to
GitHub, only the discussion that happens via email.

What are your thoughts?


I assume you already checked the mailinglist-archive and stumbled upon 
https://externals.io/message/87501#87643


I might have missed the new takes that weren't discussed there or that 
might have changed since that discussion.


At least apart from "there are a lot of new people around" and "the new 
people don't want to learn the rules"


Looking forward to your TL

Re: [PHP-DEV] Future stability of PHP?

2023-04-11 Thread Andreas Leathley

On 11.04.23 15:56, Jeffrey Dafoe wrote:

So turn off the deprecation warnings for now. They're just a heads up that
behaviour is going to change in the future, with PHP 9.

I doubt you'd prefer not to be aware of the change well in advance.

Oh, absolutely. We run those "on" in our dev and QA environments but off in 
production. I'm referring to the work required to mitigate the removal once we plan to 
migrate to 9. Although our codebase is old, we are funded to keep the code up to date. 
It's just that a handful of the changes, such as removing dynamic properties, has such a 
large impact and such a questionable benefit.


Removing dynamic properties has multiple benefits - from avoiding
typos/mistakes (which before were completely silent) from being able to
refactor objects in PHP in general (after PHP9) to be more efficient.
The RFC (https://wiki.php.net/rfc/deprecate_dynamic_properties) details
those benefits quite well, if there were no benefits it would hardly
have passed. This is one of the no-brainer changes for me, as the
upgrade path with the attribute is so easy and there are so many benefits.

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



Re: [PHP-DEV] Future stability of PHP?

2023-04-10 Thread Andreas Leathley

On 10.04.23 01:44, Deleu wrote:

Over the course of PHP 7 and 8, there were significant concerns on how
problematic PHP deprecations and breaking changes were. Now we're starting
to see the result of such concerns being ignored. This isn't the first time
someone mentions on PHP internals that it's getting harder and harder to
stay with PHP, but it's never really received with an open mind. It's
either "you don't have to run deprecation-free code" or "you've had years
to get rid of that deprecation error, tough luck if you didn't".

I love PHP and I built my career around it. I have zero interest in
starting from scratch in another language, but I've lost count on how many
projects, friends and companies around me have already made the switch to
Typescript. It's getting harder and harder to argue in favour of staying
with PHP.


The PHP ecosystem even just in the last 10 years has changed completely,
with composer, more mature frameworks, easily usable independent
components and even static analyzers. For me that ecosystem is the big
value proposition of PHP, in addition to a good standard library.
Typescript has a completely different value proposition, and the
language itself is usually not the deciding factor, as there is so much
more to it.

Only through the deprecations and the type system does PHP even offer
some similar features as Typescript - like type checks and the
possibility of a static analyzer. If all these changes would not have
happened, people likely would argue even more that they had to switch to
Typescript, because of the missing type safety in PHP. Nowadays there
are even tools now like Rector that can help you automatically upgrade
your codebase - that is also a new value proposition. My projects were
affected by all the new warnings, deprecations etc. over the years, but
I found countless bugs because of those (and many bad choices - is
count($string) really what I wanted?). The language warning you when you
are likely doing something with little sense is a huge value proposition
- otherwise why are people using Typescript instead of Javascript?

It would be interesting to know why some people are having such huge
problems upgrading their applications, as I think those would often be
good stories with something to learn in them. So to the original poster
or other people with big problems when upgrading, writing a blog article
detailing what happened would be helpful to evaluate if the PHP project
could improve something, or even why something broke. And just as a
sidenote: I never have more things breaking than when trying to upgrade
a JS/TS-project, because of changes in NodeJS, because of slight breaks
in dependencies, etc. To me that clearly works better in PHP, but
experiences can differ.

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



Re: [PHP-DEV] Array spread append

2023-04-05 Thread Andreas Hennings
> I have the feeling I'm missing something, but how would this compare to
array join

Array join does neither append nor replace if a numeric index already exists.
But you can do [...$arr0, ...$arr1].
https://3v4l.org/CIinR

print json_encode([
[...['a', 'b'], ...['c', 'd']],  // [a, b, c, d]
array_merge(['a', 'b'], ['c', 'd']),  // [a, b, c, d]
['a', 'b'] + ['c', 'd'],  // [a, b]
array_replace(['a', 'b'], ['c', 'd']),  // [c, d]
]);

(I wish we could use yaml for these outputs)


> $arr[...] = $arr2;

Using spread in the array index would be different from current usage
of the spread operator.
But it could be a nice alternative to `$arr = [...$arr, $arr2]`, as it
does not require to repeat the first variable.
So I am not against it.


--- Andreas

On Thu, 6 Apr 2023 at 00:36, Juliette Reinders Folmer
 wrote:
>
> On 6-4-2023 0:12, Vorisek, Michael wrote:
> > Hello,
> >
> > I would like to open a discussion for 
> > https://github.com/php/php-src/issues/10791 .
> > [https://opengraph.githubassets.com/a23cb565cc8acac6a33ecab5d9ee68a46f046a1ffe215501673156e506695430/php/php-src/issues/10791]<https://github.com/php/php-src/issues/10791>
> > Array spread append · Issue #10791 · 
> > php/php-src<https://github.com/php/php-src/issues/10791>
> > Description Currently spread operator can be used for almost anything. But 
> > not for array append. I propose the following to be supported:  > [1, 2]; $arr2 = [3, 4]; $arr[...] = $arr2; // ...
> > github.com
> > Appending N elements to an array is quite common language usage pattern and 
> > I belive it should be supported natively for shorter syntax, language 
> > consistency and performance.
> >
> > I am unable to implement it, but I am ready to help with RFC.
> >
> > Michael Vorisek
>
> I have the feeling I'm missing something, but how would this compare to
> array join (which is already available and is actually shorter than this) ?
>
> $arr += $arr2;
>
> Smile,
> Juliette
>
>

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



Re: [PHP-DEV] [RFC] Saner array_(sum|product)()

2023-02-20 Thread Andreas Hennings
Hello,
the RFC seems like a good idea to me.
However, I do not see any mention of plus operator on arrays, e.g. ['a' =>
'A'] + ['b' => 'B']. The array_reduce() would support this, but I think
array_sum() would not, because of the return type. I just think this should
be made more explicit.
-- Andreas

On Mon, 13 Feb 2023, 02:48 G. P. B.,  wrote:

> Hello internals,
>
> If there are no further feedback I intend on opening the vote for this
> tomorrow.
>
> Best regards,
>
> George P. Banyard
>


Re: [PHP-DEV] 'Uninitialized' creates a lot of cluttering

2023-02-13 Thread Andreas Heigl

Hey all.

On 13.02.23 13:12, Robert Landers wrote:
[...]

What is the point of marking the type of a property, other than to prevent 
mistakes?


In non-strict mode, it coerces quite nicely. For example, a string to
an integer or an integer to a string. These aren't "mistakes" but
making use of the language features.


For a type of ?int, null is indeed a valid value; but so is 0, and -1, and so 
on. Why should the language assume that one default, among all the 
possibilities, if you don't specify any?


I hope we can all agree that `null` is the absence of a value. Now we
currently have two different meanings of "absence of a value" which is
super annoying sometimes.
We have two different "things" that currently return a NULL value. 
Similar to a function with a void returntype still returning NULL.



Perhaps we need to think about introducing "undefined" to make that 
clearer? But what is actually clearer than throwing an error when trying 
to access something that is undefined...


https://stackoverflow.com/questions/5076944/what-is-the-difference-between-null-and-undefined-in-javascript

So how complicated would it be to throw that same error when assigning 
the return type of a void function to a variable?


Cheers

Andreas

--
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Path to Saner Increment/Decrement operators

2023-01-31 Thread Andreas Heigl

Hey All

On 01.02.23 07:20, Mark Baker wrote:

On 23/01/2023 14:06, G. P. B. wrote:

However, the whole point of this RFC is to*remove*  cognitive burden for
developers, so they don't even need to be aware of this "feature" and not
get surprised when it kicks in.



Moreover, by your logic, you wouldn't care if we removed support for
alphanumeric strings and only let the PERL increment kick in for purely
alphabetical.
While convenient for you, someone might actually use this feature on
alphanumeric strings, and we're back to "why is my use case being removed
while that other just as weird one remains".


I make no judgement on alphanumeric strings, other than I can't see any 
use case for it myself, so I won't allow my objection be considered 
hypocritical; and your definition of my use case as "weird" is highly 
judgemental.



Bijective numeration using the letters of the alphabet has a long and 
ancient tradition, pre-dating our modern numeric Hindu-Arabic system 
using base 10 for place/value notation by many centuries. The Abjadi 
system used the 28 letters of the Arabic alphabet; similarly the ancient 
Greeks and Hebrews, the Armenians; by Russia until the early 18th 
Century (each culture using their own alphabet). It's ironic that the 
Romans used a very different system, even though our modern western 
alphabet is based on the Roman alphabet.


These civilisations didn't consider their alphabetic numeral system 
"weird".



How many of the irregularities and idiosyncracies of alphanumeric 
strings could be resolved by not trying to cast them as a numeric value 
before increment/decrement; but by treating them consistently as 
strings? It would resolve the discrepancy with "5d9"; although not with 
"0xf9".


The thing that I consider "weird" and that I would really love to see 
addressed in a future version of PHP is that the increment of strings 
only works with a-z|A-Z while there are a lot of other alphabets where 
that should work similar. See https://3v4l.org/k0Nti for such an example.


Incrementing a *string*  is something that people should only do when 
they know what they are doing. That numeric strings are incremented one 
way and other strings another one is indeed something that can irritate 
people. And due to the missing type-system in former times it made 
sense. But given the by now available type-system using a "sane" 
increment could be as easy as `++(int)$var`.


That way it is clear that whatever is in the variable $var should be 
treated as integer (or float) and be incremented after the conversion


That way the already existing feature - it is clearly specified in the 
documentation and seems to be specified there for the last 20+ years - 
would stay the same while still allowing people to easily make sure that 
the increment way they expect is used.


Yes! That would mean that `$i = "9"; echo ++$i` would output `A`, 
whereas `echo ++(int)$i` would output `10`. But I find that very 
intuitive and sane.


Just my 0.02€

Cheers

Andreas


--
   ,,,
      (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Deprecate ldap_connect with host and port as separate arguments

2023-01-27 Thread Andreas Heigl

On 27.01.23 17:28, Christoph M. Becker wrote:

On 27.01.2023 at 17:06, Levi Morrison via internals wrote:


On Fri, Jan 27, 2023 at 8:54 AM Larry Garfield  wrote:


On Fri, Jan 27, 2023, at 3:00 AM, Andreas Heigl wrote:


I think it would be a good idea to deprecate calling ldap_connect with 2
parameters host and port.


This would require an RFC, obviously, but it seems reasonable to me.  "Variable meaning 
parameters" was always a bad idea, and cleaning them up is a good idea.>

I disagree that this needs an RFC. The docs have long-said it's
deprecated; adding a deprecation message _in code_ to match shouldn't
require an RFC.


In my opinion, a dedicated RFC would be overkill, but it could be added
to the deprecations for PHP 8.3 RFC[1] what doesn't require much effort
(feel free to add it, Andreas), 


Done.

Cheers

Andreas

--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


[PHP-DEV] Deprecate ldap_connect with host and port as separate arguments

2023-01-27 Thread Andreas Heigl

Hey Folks.

I think it would be a good idea to deprecate calling ldap_connect with 2 
parameters host and port.


Wait: What?

Currently there are three ways one can call ldap_connect.

1. With a string $ldap_uri
2. With a string $host and an int $port,
3. With even more parameters for those that did compile PHP with OracleLDAP.

The 3rd way of calling it is not even documented in the docs as it is a 
very niche edge-case that would only confuse most people.


The 2nd way of calling the function is based on the since some years 
deprecated underlying ldap_open function. Internally we already moved to 
the underlying ldap_initialize-function that requires passing an 
LDAP-URI. For that we are already converting the passed host and port 
into an LDAP-URI of the form 'ldap://$host:$port'.


This already illustrates one of the issues that this way of calling the 
function implies: It is not possible to use ldaps as a schema using that 
way of calling ldap_connect as it will always use ldap as schema. No 
matter which port is passed.


A second reason why I think we should deprecate calling ldap_connect 
with two parameters is, that it does not allow one to pass multiple 
ldap-servers as it is possible using the LDAP-URI.


This is for sure a BC-break but in my opinion a rather small one as 
there are not many users actually using it and there is a clear and easy 
migration path for those that use it: Instead of calling


ldap_connect($host, $port)

one calls

ldap_connect("ldap://$host:$port??369;)

Also most of the users should not be affected at all as they are using 
3rd party libraries that are already only using an LDAP-URI when calling 
ldap_connect like Laminas\Ldap or Symfony\Ldap


The documentation at https://www.php.net/ldap_connect also explicitly 
states (for some time by now) that using host and port is considered 
deprecated.


Named parameters btw also only support ldap_connect(uri: 
'ldap://example.com') and ldap_connect(host:'example.com', port:369) 
will throw an error.


There already is a PR open[1] that implements the deprecation so that 
for the upcoming PHP8 releases each call to ldap_connect with 2 
parameters would emit a deprecation message so that people have enough 
time to adapt their code before we can actually remove using two 
parameters in the next major release.


Thanks for your comments.

Cheers

Andreas

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

--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Unicode Text Processing

2022-12-16 Thread Andreas Heigl

Hey

On 16.12.22 16:21, Tim Düsterhus wrote:

Hi

On 12/16/22 14:28, Derick Rethans wrote:

Question 2 is that class.  I know folks have been clammoring for a
`String` class for some time and this actually fills that niche quite
well.  A part of me wonders if we can overload it a little to provide
a psuedo locale of "binary" so that users can, optionally, treat it
like a more generalized String class in specific cases, storing a
normal `char*` zend_string under the hood in that case.  Possibly as a
specialzation tree.


An alternative could be to just have this as an implementation detail,
in case the associated locale/collation is C/root. Then nobody needs to
worry about it, *but* it would mean implementing everything twice. Which
I am not too keen on, especially because we have such a wide array of
operations on strings already.



I rather not see this either, because if a 'Text' object may contain 
binary data, the type safety is lost and users cannot rely on "'Text' 
implies valid UTF-8" (see sibling thread).


Does Text contain valid UTF-8? Or valid Unicode? As IIRC the idea was to 
internally use UTF-16 as encoding.


In the end the internal encoding should be irrelevant to the user as 
long as we can assert that __toString() returns a Unicode-String in a 
valid encoding. And I'm with you that UTF-8 might be the best choice for 
that.


Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Unicode Text Processing

2022-12-15 Thread Andreas Heigl

Hey Derick, Hey all.

On 15.12.22 16:34, Derick Rethans wrote:

Hi,

I have just published an initial draft of the "Unicode Text Processing"
RFC, a proposal to have performant unicode text processing always
available to PHP users, by introducing a new "Text" class.

You can find it at:
https://wiki.php.net/rfc/unicode_text_processing

I'm looking forwards to hearing your opinions, additions, and
suggestions — the RFC specifically asks for these in places.


Thanks for tackling this immense topic.

I see a few challenges in the approach. My first question was: Why do we 
need a new implementation of the ICU library? Creating a userland 
implementation that wraps the currently existing mb-string and ICU 
functions into a class that allows better usability shouldn't add that 
much of a performance penalty. And including the mb-string and the intl 
extension by default wouldn't hurt.


That way there would be no added maintenance burden on the core developers.

In addition to that it looked to me that there are multiple things mixed 
up in this Text-class. If we want a Text-class to handle Unicode strings 
in a better way, why does the string itself need to be Locale-aware? The 
string itself is a collection of Unicode-Codepoints referencing 
Characters and Graphemes. Does the string itself need to be aware of a 
locale to aid in sorting? It needs to be aware of the internal 
normalization form for character-comparison for sure. But I would rather 
see a Normalizer handle normalization of the Text-content instead of the 
Text-class handling that itself. Similarily I'd see the Transliteration 
done by a separate class. Which then strongly looks similar to the 
Intl-extension. Which brings me back to the question: Do we really need 
a second Intl-extension in the core?


I'm ambivalent about this. On the one hand it could make some things for 
sure easier. On the other hand it adds burden onto the core-developers 
that could be avoided by providing the intl (and mb-string) extension by 
default instead of having to add them separately. And then find a group 
if people willing to build a userland implementation.


And yes, I know the intl-extension is everything but easy to use. 
Especially in the quirky edge-cases regarding Transliteration and 
Normalization. But the issue usually isn't using it but finding the 
appropriate documentation on the ICU page. Helping the ICU to improve on 
that documentation would also be a huge benefit. To all those trying to 
use the Intl-extension right now.


But that's just my 0.02€

Cheers

Andreas


cheers,
Derick






--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Revisiting RFC: Engine Warnings -- Undefined array index

2022-12-13 Thread Andreas Leathley

On 13.12.22 13:53, Dan Liebner wrote:

It breaks my app. Does that count?


This sounds like you completely ignore notices in your application yet
elevate warnings to exceptions/errors. It would be better to log both
notices and warnings without generating exceptions/errors, and look
through those logs from time to time, to see possible issues (and
nothing would currently break that way). I used to suppress notices in
my applications too, but after logging them it was my experience that
notices can usually be easily avoided and often hint at oversights /
possible improvements.


Here's another suggestion:
Make accesses to undefined array keys (objects, variables, etc) return a
new `undefined` primitive. That way, developers who are focused on writing
concise, readable code can continue to write and maintain code manageably,
and developers who are keen on writing a lot of code in a more "strict"
manner can handle undefined array key accesses consistently, without having
to rely on configuration settings.


That would likely be a major change and break in the language (which is
usually frowned upon), but if you have a clear concept, you can create
an RFC for it and start a discussion.

I do think that your view on "concise, readable code" would in my mind
be code which is more prone to bugs and unclear in its intentions. If an
array index possibly does not exist and you check its value, it would
already be unclear to me if you mean to check for its existence, or for
a null value, or for a non-empty string, or something else. Making it
clear the index might not exist gives a reader more information, and
making the expected types (and checks) clearer in general is not an
exercise to be strict for fun, but to avoid bugs because of unexpected
values.

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



Re: [PHP-DEV] Revisiting RFC: Engine Warnings -- Undefined array index

2022-12-13 Thread Andreas Leathley

On 13.12.22 11:01, Robert Landers wrote:

intended: ($a['foo'] ?? null) || ($a['bar'] ?? null)
Further, writing code like this increases the number of opcodes needed
to perform relatively simple logic by ~150%, increasing end-user
latency and spending CPU cycles somewhat needlessly.

I think it is quite the opposite: calling the error handler because of
E_NOTICE (or now E_WARNING) is quite the additional overhead, and if
projects just ignore E_NOTICE their applications will be slowed down
because of that, while fixing the code will avoid the error handler
altogether. Just because something is longer to write in a programming
language also does not make it necessarily slower. But if you have any
actual measurements why using the null coalescing operator would slow
down code in general that would be something useful to share.

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



Re: [PHP-DEV] Please allow an out of readonly properties

2022-12-04 Thread Andreas Heigl

Hey there

On 03.12.22 23:55, Karoly Negyesi wrote:

They refuse to compromise even on documentation issues. I am totally
helpless. Not sure what could be done?


When people design their systems and use final, private or readonly, 
they have a reason for that. They have a plan on how their library 
should be used and also how their library should not be used.That is the 
API that is exposed via public methods that is described in the 
documentation.


When *your* code can only make use of a library by tweaking these 
constraints, you are using the library in a way that is not intended by 
the authors.


There can be two reasons to that: Either you know exactly what you are 
doing and you are willing to risk that the way you are using said 
library might break with every patch version as the internal workings 
might change.


HERE BE DRAGONS: I sometimes actually need to do that (even with a 
library I wrote myself) but instead of using reflection I then tend to 
use monkey-patching in that case and actually rewrite the code of the 
lib on installation. That way the execution is faster as I do not rely 
on reflection but can access a public property directly.


Or - and that is most of the time the case - you are using the library 
wrong or even using the wrong library.


And as you already contacted the authors and they declined your request 
to change their API, the chances are high, that you are using their 
Library in an unintended way.


In that case you should reconsider what you are doing. Am I using the 
right library? Why could I be using the library wrongly? How can I 
change my code to use the provided API of the library?



In the end it always boils down to: Check whether your usecase is what 
the library is intended to solve. And if there is no way around 
rewriting upstream code: You are on your own! You can not rely upon 
anything. Not even language features. You are not using upstream code, 
you are abusing it.


My 0.02 €

Cheers

Andreas



On Sat, Dec 3, 2022 at 2:48 PM Marco Pivetta  wrote:


Talk to the designers then: bringing your own political issues up to the
programming language/tooling only makes it worse long-term, for everyone 

On Sat, 3 Dec 2022, 23:45 Karoly Negyesi,  wrote:


I do not have the luxury of designing my own system. I am forced to use
upstream. I can't help it and given the history of private usage and the
refusal on relaxing them I do not see this improving with the readonly. At
all.

On Sat, Dec 3, 2022 at 2:42 PM Marco Pivetta  wrote:


Terrible idea: reflection is mostly introspection tooling, and doesn't
really bend the rules of the type system, other than crossing scope (it
"sees" more).

Please consider designing your system to consider the constraints of
`readonly` properties, or design the constraints to fit your system instead.

Marco Pivetta

https://twitter.com/Ocramius

https://ocramius.github.io/


On Sat, 3 Dec 2022 at 23:39, Karoly Negyesi  wrote:


Hello,

If push comes to shove, private properties can be changed with
reflection.

Readonly properties can't.

Please add a readonly toggle to reflection.

Thanks

Karoly Negyesi







--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+
| GPG-Key: https://hei.gl/keyandreasheiglorg  |
+-+


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] Re: Increase maximum size of an uploaded file to 50Mbyte

2022-09-08 Thread Andreas Heigl

Hey all.

On 08.09.22 12:35, Jakub Zelenka wrote:

On Wed, Sep 7, 2022 at 3:28 PM Christoph M. Becker 
wrote:


On 07.09.2022 at 15:57, Misha wrote:


We spend a lot of time to increase limits for uploads file in PHP. Can we
increase it in php.ini?

Current value is 2Mb. Its so small value, when photo image can take 8Mb

on

iPhone X.
We should increase it to 50Mb, because DevOps engineers do useless work
trying to change it.

I have prepared PR for it https://github.com/php/php-src/pull/9315


I'm not against increasing the sizes, but 50MB might be too much.

Anyway, only changing the php.ini files doesn't make sense in my
opinion, since they're probably only used on Windows, and they should
reflect the actual default values[1].



  It's true that those particular ini files are not directly used on Linux
but distros often base their changes on them and the distro provided ones
are actually used. So it means that main defaults in main.c are most likely
not used. Although I agree they should be changed too so it is consistent.


No matter which value we preset, it will most certainly not be adequate.

So people *will* have to set it according to their needs. And if they 
didn't so far, then they are happy with the current setting.


Don't get me wrong: I'm not against changing that value.

But is it really an issue that needs solving? It's a default value of a 
configuration file. When I'm unhappy with the default, I change it to a 
more suitable value. When I'm not able to do that... perhaps I should 
leave my fingers not only from the config file...


My 0.02€

Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] RFC json_validate() - status: Under Discussion

2022-08-26 Thread Andreas Leathley

On 26.08.22 11:00, Michał Marcin Brzuchalski wrote:

A `json_decode()` is a substitute that IMO solves 99% of use cases.
If I'd follow your logic and accept every small addition that handles 1% of
use cases, somebody will raise another RFC
for simplexml_validate_string or yaml_validate and the next
PhpToken::validate.
All above can be valid if we trust that people normally validate 300MB
payloads to do nothing if they DON'T fail and there is nothing strange
about that.


There is already a way to validate XML in PHP, and Yaml or PHP is
something within the control of a PHP programmer, while JSON is mostly
used as a format for communication in APIs, so you never know what you
get. If with a new function it becomes much easier to defend against a
Denial-of-Service attack for some parts of a JSON API, then this can be
a good addition just for security reasons.

But this reason, which most resonates with me, is currently missing in
the RFC, so I would suggest to add that fast / efficient validation of a
common communication format reduces the attack surface for
Denial-of-Service attacks.

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



Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-08 Thread Andreas Heigl

Hey Marco.

On 08.08.22 10:14, Marco Pivetta wrote:

Heyo Andreas, Casper,

On Mon, 8 Aug 2022 at 10:03, Andreas Heigl  wrote:


Hey Casper.

On 08.08.22 09:54, Casper Langemeijer wrote:

Hi all,

In the discussion I sometimes see the terminology 'readonly' and

'writable' being used. This is confusing because when the property is an
object that itself is mutable, there is nothing read-only about it.


The terminology in the RFC seems right to me, and overall it seems solid.

However, I'm not convinced this RFC is solving a real issue. I could not

find any reasoning in the RFC, except that Swift has a very similar
language feature.




To me it solves the topic of making a property readable but not
writeable from the public while still allowing it to be written to
within the private or protected context.

So enforcing usage of a public setter-metbhod but not having to use a
getter.

Soemthing like this

final class Foo
{
  public private(set) string $username;

  public function changeUsernameTo(string $newUsername): self
  {
  if (! newUsernameIsUnique($newUsername) {
  throw new RuntimeException('The username is not unique');
  }
  $this->username = $newUsername;

  return $this;
  }
}


readonly only solves that for immutable properties but there currently
is no way of solving that for mutable properties.



Similar question as Casper here: I use `readonly` properties aggressively,
and I try to make the state as immutable as possible.

In the **extremely** rare cases where `public get` and `private set` are
needed, I rely on traditional getters and setters, which are becoming
extremely situational anyway, and still work perfectly fine.
If that doesn't work, then PHPStan/Psalm allow declaring `@private`,
`@internal`, `@phpstan-internal` or similar mechanisms to restrict scope
access. `qossmic/deptrac` also works wonders here, compared to PHP. >
In fact, I'm writing so few getters and setters these days, that I don't
see why I'd need getter and setter semantics to creep into the language,
especially mutable ones, not even with the reflection improvements.


Your use case might not need them (though actually you are needing them, 
you just don't use them as language feature but via the static-analysis 
annotation)


But when discussing language features we should always keep ALL users of 
the language in mind. And if a feature helps in providing ways to build
more stable code on the language level then we should think about that 
from a point of view of *all* users.


And when the feature is already used via static-analysis then why not 
implement that for use by *everyone* and not only those that have static 
analysis in their CI toolchain.


Just my 0.02€

Cheers

Andreas
--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-08 Thread Andreas Heigl

Hey Casper.

On 08.08.22 09:54, Casper Langemeijer wrote:

Hi all,

In the discussion I sometimes see the terminology 'readonly' and 'writable' 
being used. This is confusing because when the property is an object that 
itself is mutable, there is nothing read-only about it.

The terminology in the RFC seems right to me, and overall it seems solid.

However, I'm not convinced this RFC is solving a real issue. I could not find 
any reasoning in the RFC, except that Swift has a very similar language feature.



To me it solves the topic of making a property readable but not 
writeable from the public while still allowing it to be written to 
within the private or protected context.


So enforcing usage of a public setter-metbhod but not having to use a 
getter.


Soemthing like this

final class Foo
{
public private(set) string $username;

public function changeUsernameTo(string $newUsername): self
{
if (! newUsernameIsUnique($newUsername) {
throw new RuntimeException('The username is not unique');
}
$this->username = $newUsername;

return $this;
}
}


readonly only solves that for immutable properties but there currently 
is no way of solving that for mutable properties.


Just my 0.02€

Cheers

Andreas

--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-08 Thread Andreas Heigl

Hey Larry, hey all

On 07.08.22 21:01, Larry Garfield wrote:

On Sun, Aug 7, 2022, at 5:54 AM, Lynn wrote:

On Sun, Aug 7, 2022 at 12:34 PM Rowan Tommins 
wrote:


Can you expand on where you think the ambiguity / implicitness is? As I
understand it, the RFC is proposing exactly three new combined access
levels:

- "public private(set)"
- "public protected(set)"
- "protected private(set)"

Although aesthetically it will take a bit of getting used to, it seems to
me pretty clear that the first means "mostly public, but private if you
want to set it", and so on.

The only thing I can think of that could be described as "implicit" is
that accessing a property by reference is considered a "set" operation,
which I'm not sure how any implementation could avoid.



Personally for me it's the syntax. Reading "public private", "public
protected", or "protected private" reads really weird `public private(set)
static self $property`. In the end it makes sense if you know what it
means, otherwise it's probably confusing. I really like this RFC and I feel
like this might just be the way to go forward, but I have my doubts about
how many more keywords can be realistically added before it becomes a
problem.


What syntax would avoid having the visibility keyword repeated?  if you want "public get, private 
set" behavior, I don't know how that could be done without having the words "public" and 
"private" both appear somewhere.

Also note, since using private(set) is mutually exclusive with readonly, that the 
resulting keyword list is about the same length as the existing "public readonly 
string $foo" that has cropped up frequently with PHP 8.1.  So... yes it's another 
keyword, but it's not more keywords that can exist simultaneously.  And moving the 
keyword to the right (a la C#) wouldn't make it any shorter; if anything it would be even 
more keystrokes.

Very close in size, same in complexity:

public readonly string $foo
public private(set) string $foo


In my opinion those are actually two different things.

One is allowing a variable to be publicly readably and writeable. But it 
can only be set once. Every subsequent call to setting a new value will 
fail.


The other is allowing different scopes for reading and writing the 
variable. The variable can be read publicly but can only be set from 
within the current class-context. But setting it from the current class 
context can happen multiple times.


So it should indeed be possible to combine both possibilities:

public(get) private(set) readonly string $foo;

My 0.02€

Cheers

Andreas

--
  ,,,
         (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Add json_encode indent parameter

2022-07-05 Thread Andreas Heigl



On 05.07.22 11:38, Jakub Zelenka wrote:

On Tue, Jul 5, 2022 at 8:37 AM Andreas Heigl  wrote:


Hey all.

On 05.07.22 02:04, Peter Cowburn wrote:

On Mon, 4 Jul 2022 at 11:11, Jakub Zelenka  wrote:


On Mon, Jul 4, 2022 at 8:38 AM Timon de Groot 
wrote:


Hi internals,

If the rest also thinks the RFC is good to go, I suggest we start a

vote

coming week.
As this is my first RFC, I'm not so sure how this typically gets kicked
off, so I'd like to know what I need to do!



You just need to change status in RFC to Voting and in voting section

set

the date range and add doodle poll - you can basically copy it from one

of

the open RFC's (see for example code in
https://wiki.php.net/rfc/fetch_property_in_const_expressions ). Then

you

just need to send email to internals with subject prefixed with

[RFC][VOTE]

or similar. As noted you need to do it today or latest tomorrow. Feel

free

to let me know if you are too busy or something is not clear.

I would recommend not to do any last time changes as in such case you
should probably give an extra time for dicusion which means it won't

make

the feature freeze and will have to wait for another year. In my

opinion it

is good as it is. The tabs can be later added as an extra flag. If the

flag

is set, we could just change default value for indent to 1 and use tabs

but

it would be still possible for users to set indent size if they wish. I
think that's something that makes most sense to me and doesn't impact

the

current RFC in any way.

Regards

Jakub



My thoughts might be firmly in the realms of "too little, too late" since
the vote is open already, so by all means choose to ignore.


I'll be on the same lines!

What I would have prefered is instead of a the new parameter $indent
having a numerical value to have a string value.

That would have allowed the following:

  json_encode($data, indent: "");

or

  json_encode($data, indent: "\t");

That would have made the tabs vs. spaces very easy and people can also
add whatever they want to set for one indentation. Think about setting
dots for making the spaces visible for some formatted output or whatever
else people might think of.



The problem with this approach is that we either need to validate it (which
is probably not a big deal but you still have just option or using spaces
or tabs) or we allow invalid JSON to be produced from this function which I
think it's not a good idea and should not be part of json_encode because,
as its name suggests, that function is just for encoding JSON and not some
random format. My guess is that it would be even less likely to pass and I
would certainly vote against it.

I think if this RFC fails, we could maybe allow number or validated string
and also do that auto setting of flag if set as suggested.


Then perhaps adding a separate function "json_format" would be the 
better approach?


Keep `json_encode` to *only* encode json into a "binary" format (and 
then it's irrelevant whether that's spaces or tabs) and explicitly use a 
different function to handle possible formatting topics with different 
spaces, tabs whatever-else-one-might-find-adequate


Cheers

Andreas

--
  ,,,
 (o o)
+---------ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


Re: [PHP-DEV] [RFC] Add json_encode indent parameter

2022-07-05 Thread Andreas Heigl

Hey all.

On 05.07.22 02:04, Peter Cowburn wrote:

On Mon, 4 Jul 2022 at 11:11, Jakub Zelenka  wrote:


On Mon, Jul 4, 2022 at 8:38 AM Timon de Groot 
wrote:


Hi internals,

If the rest also thinks the RFC is good to go, I suggest we start a vote
coming week.
As this is my first RFC, I'm not so sure how this typically gets kicked
off, so I'd like to know what I need to do!



You just need to change status in RFC to Voting and in voting section set
the date range and add doodle poll - you can basically copy it from one of
the open RFC's (see for example code in
https://wiki.php.net/rfc/fetch_property_in_const_expressions ). Then you
just need to send email to internals with subject prefixed with [RFC][VOTE]
or similar. As noted you need to do it today or latest tomorrow. Feel free
to let me know if you are too busy or something is not clear.

I would recommend not to do any last time changes as in such case you
should probably give an extra time for dicusion which means it won't make
the feature freeze and will have to wait for another year. In my opinion it
is good as it is. The tabs can be later added as an extra flag. If the flag
is set, we could just change default value for indent to 1 and use tabs but
it would be still possible for users to set indent size if they wish. I
think that's something that makes most sense to me and doesn't impact the
current RFC in any way.

Regards

Jakub



My thoughts might be firmly in the realms of "too little, too late" since
the vote is open already, so by all means choose to ignore.


I'll be on the same lines!

What I would have prefered is instead of a the new parameter $indent 
having a numerical value to have a string value.


That would have allowed the following:

json_encode($data, indent: "");

or

json_encode($data, indent: "\t");

That would have made the tabs vs. spaces very easy and people can also 
add whatever they want to set for one indentation. Think about setting 
dots for making the spaces visible for some formatted output or whatever 
else people might think of.


And setting the "indent" parameter would always implicitly set the flag 
"JSON_PRETTY_PRINT" (as it doesn't make sense to not have that set).


The current way of just being able to set a number of spaces to indent 
or to use a flag for tabs is a bit fiddly at best and does make adding 
accessibility a second class citizen. Therefore I will vote against this 
current implementation.


Cheers

Andreas
--
  ,,,
 (o o)
+---------ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


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

2022-06-20 Thread Andreas Leathley

The vote has been closed, the RFC has been declined with 14 to 3 votes.

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. My
assumption is that most didn't find this important enough, especially if
strict types is not affected. While I think the RFC would have helped
identify obvious bugs (and I find the current behavior of PHP with
boolean coercions less than ideal), I can see an argument for voters to
not see it as something important enough to change the language, as the
problems this RFC would have highlighted can be avoided altogether.

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.
Otherwise thanks to everybody who took part in the discussion, it was an
interesting experience.

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



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

2022-06-05 Thread Andreas Leathley

Hello Internals,

I opened the vote about Stricter implicit boolean coercions as
announced. The vote will run until 2022-06-20.

Discussion: https://externals.io/message/117732
RFC: https://wiki.php.net/rfc/stricter_implicit_boolean_coercions

Best regards,

Andreas Leathley


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

2022-05-31 Thread Andreas Leathley

I have amended the RFC on
https://wiki.php.net/rfc/stricter_implicit_boolean_coercions to address
the feedback I got so far, I also added an overview of scalar type
coercions to give a better sense of how these changes fit in with
current type coercion behavior, and I added a Future Scope section with
my plans to at some point do a follow-up RFC to make the implicit scalar
type coercion behavior available to PHP developers explicitly and why
that might make sense.

Does anyone have any more feedback or questions on this, or something
that is not considered? If not, I would start voting on Sunday (5th of
June), but I am happy to extend the discussion time if needed.

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



Re: [PHP-DEV] [RFC][Under discussion] Create a global login system for php.net

2022-05-29 Thread Andreas Heigl

Hey All.

On 28.05.22 11:53, Aaron Junker wrote:

Hi all,

I would like to start the discussion on my RFC for creating a global login 
system on php.net: https://wiki.php.net/rfc/global_login.

When you have feedback to a specific point of the RFC, please use the 
corresponding number used in the RFC.


I do have my issues with the general RFC.

The idea to have one login system to all parts of the PHP internals 
ecosystem seems tempting for sure. But as you pointed out in the 
introduction, there are 9 different services - partly rather old ones - 
that would require some work to make SSO work. Some of them we have 
control over, some of them we do not (as those are external applications 
that we are using. Fiddling with their sourcecode might be possible but 
will leave us more or less unable to update the tools)


So moving those applications that we have control over towards SSO will 
bind resources. And not only now, but also in the future as those tools 
might need updates as well.


Resources though, espechialy for infrastructure, are a very rare good!

In addition I would say that we can assume the edit.php.net to be dead 
after we moved documentation from SVN to git. So that is awesome as that 
means "one down" and we couldn't already find someone to modify 
edit.php.net to work with git instead of SVN. So that's great news!


But the bad news is, that there is also the colobus system which powers 
the NNTP-server backend that a number of people use to interact with the 
mailing-list. Which also has an authentication and would therefore need 
to be switched. So we are back at 9 services. And we switched one that 
is completely under our control to one that isn't as we are merely using 
a (rather old by now) service.


And there might even be more than those.

So what I'm trying to bring across here is that this task will bind a 
lot of resources with a gain that I'm not sure is worth the effort. And 
instead of binding people working on resources that improve the life of 
a few (those working on these quirky systems) I'd rather see those 
resources spent where they improve the life of all PHP-Developers. Like 
improving the docs, triaging bugs, answering questions on 
StackOverflow/Room11/PHPC/Whatever else there is.


In addition to that I would like to raise my concerns over using GitHub 
login for everything (Topic 1.2).


GitHub is a company based in the US and therefore bound to US law. That 
already means that people from certain countries can not (easily) 
collaborate and are therefore also excluded from contributing in any way 
to PHP[1]. In addition to those regulations directly by GitHub some 
countries are blocking access to GitHub on their own account which means 
that Developers from Russia or China will have a harder time 
contributing to PHP due to the fact that they are not able to login into 
any system.


Are we aware of that?

On the other hand maintaining our own SSO-Solution will bind even more 
resources... See above.


In addition: The number of different logins is usually rather small per 
person. And keeping track of the different systems and passwords via a 
PasswordManager should solve most of the day-to-day hassle. Having a 
central place though to document the hassle would be a very helpful 
addition to the PHP ecosystem!


My 0.02€

Cheers

Andreas - The one having struggled for some years with just *one* 
infra-change.



[1] 
https://docs.github.com/en/site-policy/other-site-policies/github-and-trade-controls#on-which-countries-and-territories-are-us-government-sanctions-applied


Best regards
Aaron Junker



--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


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

2022-05-24 Thread Andreas Leathley

On 24.05.22 15:33, Dan Ackroyd wrote:

"When discussion ends, and a minimum period of two weeks has passed"
Fyi, the two weeks is a minimum, and almost certainly not enough time
for subtle BC breaking RFCs like this.


I explicitely stated that to make it clear that this should be
considered a discussion period. I am not trying to circumvent anything,
just make it clear that now is the time to discuss this. And I am ready
to fully discuss this, as hopefully I have shown so far.

I am also not sure what you mean with "subtle BC breaking RFCs". How is
this RFC subtly BC breaking? It introduces a deprecation notice, that is
it - for one that is not subtle, it is explicit, and it does not break
BC except for introducing said notice. Is that not the very minimal BC
break you can achieve to highlight a possible problem in code?



I think you should really explicitly list what the changes are in a
single table rather than in sentences.


What do you think is unclear, and what would you include in such a
table? In the Proposal section I listed all values which are considered
allowed, and I tried to include more examples there too to highlight the
outcome. The behavior is not changed by this RFC.




Would you want to know when a value like -375, “false” or NaN
is given to a typed boolean (and coerced to true) in a codebase?

Yes.

Which is why I always use both PHPStan and Psalm to detect those types
of things where those types of bugs are important.

Also, strict mode is great.


Even when using PHPStan and Psalm you can encounter such a value, for
example coming from a form, or an API. Using strict mode is a
possibility, but also a big hammer - so how do you coerce a value coming
from a form in strict mode? With an explicit coercion like (bool) or
boolval()? Because there you might also be losing information
unexpectedly - I do have some ideas to enable implicit coercions in
strict mode, because you might not want to convert "failed" from an API
to true by using explicit coercions, in my applications I would prefer
to at least notice or even throw an exception in such cases, and the
programming language streamlining this could be helpful.




In one application recently I actually had the string "false" (coming
from a form transmission) being passed to a boolean argument and leading
to true, which definitely was unintended.

But "false" is a perfectly sensible thing to pass as a string in an
API (as HTTP is a string based protocol). As is 'faux' if your API is
used by French speaking programmers.

You need an layer of code that converts from strings to the precise
types your API needs, rather than just passing values straight
through.


That sounds good in theory, but it is the exact thing that is so hard in
practice, when dealing with forms, APIs, different programming
languages, different human languages, different input formats, changing
code, etc. I am not against writing great code and checking all values
all the time, but I do think this is not the reality.


Although this change would probably detect some bugs, it's not at all
obvious that the amount of pain would be worth it.

A lot of applications out there aren't being constantly developed.
Instead they are in maintenance mode, where there isn't a programmer
dedicated to constantly work on it. There would be lots of function
calls to check, and some of them would need code to be modified to
maintain the existing behaviour. And all of that would seem to be
subtle work, prone to mistakes.


Earlier you argued that there is no need to detect -375, "false" or NaN
being coerced to a boolean type, because one can use strict mode and
static analyzers, now you argue that legacy applications would have too
much work generated by this RFC. But I don't quite understand why: This
RFC introduces deprecation notices, not TypeErrors. It does not force
legacy applications to change anything, it just points out boolean
coercions that seem dodgy. If these deprecation notices provide little
value in the upcoming years, there is no need to promote them to a
TypeError, they could even be removed again - but I do think they will
provide value and often point out bugs, so much so that a TypeError will
seem reasonable at some point in the future, but there really is no
hurry in escalating it. For now just being able to notice these boolean
coercions would make a huge difference.

--
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-24 Thread Andreas Leathley

On 23.05.22 20:58, Juliette Reinders Folmer wrote:

All in all, I largely agree with the flaws in this proposal as
previously pointed out by Christian Schneider in the preliminary
discussion. And I don't see those concerns addressed in the RFC (other
than making it more explicit what the actual intended change is).


I amended the RFC and tried to address and include all of your points,
as well as made it clearer what the intention of the RFC is. Adding the
behavior of the filter extension was a sensible addition, I didn't even
think of its special behavior before you mentioned it, and going into
more detail about the other boolean coercions in PHP was also something
that needed a more explicit section in the RFC, as it has been brought
up by different people in different contexts already and I seem to have
prematurely dismissed its importance so far.

If you still think other concerns are not addressed I would be happy to
know about them.

--
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-23 Thread Andreas Leathley

On 23.05.22 22:54, G. P. B. wrote:

I don't like this RFC as it introduces special coercion semantics for
boolean *only* in a function (+ typed properties (well at least I hope it
impacts typed properties)) context.

The obvious other context is the logical one with conditional statements
and/or boolean operators (&&, ||, etc.) where it is pretty typical to do if
($string) {} and use $string as a boolean value.
Having this be true in some contexts and false in others, depending on the
content of the string is far from ideal.
However, implicit coercion to bool can also arise when doing comparisons
where one of the operands is null or bool.
In this case which semantics should be used?


The problem is that coercion to a typed boolean is not the same as
checking an expression for truthiness. It is somewhat related, but when
there is a coercion to a typed boolean only scalar values can be
coerced, which makes a big difference. Something like

if ([''])

is basically the same as

if ([''] == true)

which is why I call it checking for truthiness. Yet

$obj->booleanProperty = [''];

will lead to a type error. So there is a clear difference there already.
I also think the expectation is a different one - something like

if ($string)

is, as far as I have seen, most often used to check if a string it not
empty. Yet if you do

$obj->booleanProperty = $string;

you then seem to specifically want to end up with a boolean type, not do
a fuzzy check for truthiness. To me that is a very different situation
where I actually find the current behavior surprising, in that is does
not matter at all what scalar value I give a typed boolean, it will be
happy with anything, and if it was a long string that was converted to
boolean, you do possibly lose information. That can easily happen if
someone changes a property from a string to boolean, but still assigns
it a string somewhere.

As soon as you use operators like && or || the intention becomes clearer
again:

$obj->booleanProperty = $string && $string2;

There you are not passing the string directly to a boolean property, you
are checking an expression, and you can even do

$obj->booleanProperty = $array && $array2; // cannot pass an array to a
boolean, but you can check an array (or two) for truthiness / not being
empty


Can this prevent bugs, for sure, but within the function context we already
have a tool to deal with these sorts of issues with strict_types.


But could you not argue the same for integers too? Why when you pass a
string to an int parameter does it check if it is numeric, and not
auto-coerce "hello" to 0? That is different behavior too, and one can
use strict_types or explicit coercions instead. My argument is not that
the proposal in this RFC is somewhat elegant or solves deep-rooted
issues in the language. Similar to the numeric checks for int parameters
I am interested in this for purely practical reasons. If somewhere in
your application the integer -376 is passed to a boolean property (and
coerced to true), would you not rather know about it? Is it not likely a
bug, or at least an oversight? Would it not be easier on developers to
know that only 7 scalar values are considered "unambigous" when passing
to a typed boolean, and that they would be informed if they pass
something else?

I already rewrote the passage about raising this to a TypeError, where I
state that this should be determined later when there is sufficient
experience with these deprecation notices, and for me that is not really
urgent - if this just remains an unintrusive deprecation notice for the
next 10 years that would be fine with me. But I am convinced this will
be a useful notice in many applications, where bugs can be found that
otherwise would have stayed hidden for a very long time.

I appreciate your feedback, and if I can improve anything about the RFC
I am open to ideas. I think your RFCs for the type system have made PHP
a much better language, and you seem to think about the big picture of
the types in PHP, which is important for the language. This RFC might
seem like a niche specific change and it does not affect much of PHP
itself, but to me that could be what makes it a useful addition - if it
mainly reveals bugs in applications, couldn't that be enough of a reason
in favor of it?

--
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-23 Thread Andreas Leathley

On 23.05.22 20:58, Juliette Reinders Folmer wrote:

This RFC worries me as, in my opinion, it makes PHP's behaviour more
surprising and inconsistent, not less.

It also raises the cognitive complexity for developers by yet another
level.

1. It introduces a new interpretation of boolean type coercion, which
is only applied against type declarations.
2. This new interpretation is not consistent with "normal" boolean
type coercion, not consistent with strict types (no coercion) and also
not consistent with what is considered a valid boolean value by the
Filter extension.


I am not sure what you mean by "normal" boolean type coercion and how it
would be inconsistent with those. The RFC does not change the behavior
of boolean type coercions, it just points out possibly surprising coercions.

The filter extension has its very own interpretation of how to validate
a boolean which is completely incompatible with how PHP does implicit
type coercions already. Yet people using the filter extension are not
affected by this RFC at all, they have already chosen their way to
convert a value to boolean. But comparing the filter extension with the
implicit type conversion does show how dangerous it can be to for
example switch from FILTER_VALIDATE_BOOLEAN (with
FILTER_NULL_ON_FAILURE) to the implicit boolean conversions from PHP:
with the filter extension "false", "off" and "no" are converted to
false, while all these values are silently converted to true by implicit
boolean conversion by PHP. People switching from the filter extension to
the built-in types of PHP have another way of shooting themselves in the
foot, and it is easy to miss the change in behavior.


While I agree that the current behaviour of PHP can hide bugs, I fear
that even more bugs will be introduced when PHP contains yet a third
form of coercion to boolean and the type coercion used is dependent on
the context.


Assuming from the rest of your response, I am assuming you mean
"truthiness" comparisons, like in if statements and other expressions.
Those are already different from coercions to typed booleans and have
different semantics. In an if statement you can check for truthiness
with any type, while a typed boolean only accepts scalar values. I am
seeing an advantage of further separating those use cases, as a
misconception seems to exist that a check for truthiness is just a
conversion to boolean. Having clearer semantics would actually lower
cognitive complexity from my perspective - knowing that only 7 values
are considered sensible for a typed boolean and getting a notice for any
other values makes it a lot clearer how it behaves and when I as a
developer will get warned.


I fear this will only lead to more bugs, not less (because people new
to PHP will learn the "type declaration" based boolean coercion rules
and assume they apply everywhere).


But they would actually apply anywhere, as far as I know: My suggested
allowed values for typed booleans can be used in if statements and lead
to the exact same behavior.


I also fear that for code bases which do not (yet) use scalar type
declarations, this will be one more argument not to introduce scalar
type declarations (while they should).


My suggestion is far less impactful for "legacy" codebases compared to
the other scalar type checking - an "int" parameter only accepting valid
numbers and leading to a TypeError otherwise is a much bigger hurdle
from my perspective than introducing a deprecation notice for a suspect
boolean type coercion. I cannot really believe that "failed" not being
auto-coerced to true will be the straw that breaks the camels back in
legacy codebases. And again: It is just a deprecation notice, I even
amended the RFC to say that this being elevated to a TypeError will have
to be decided after the impact of the deprecation notices become clear,
not now. My goal is not necessarily to be as strict as possible but
rather point out to developers where something might be going wrong.


I'd say that for this RFC to be acceptable it would need to apply to
all implicit type coercions to boolean. However, the BC-break that
would cause and the fall-out of this for non-greenfields codebases is
just too huge, which, to me, makes this RFC a very strong no-no.


I will amend the RFC to show how typed booleans already have their own
type coercions that are not the same as the truthiness checks in if or
similar expressions - thanks for pointing that out and showing that
there is some confusion there that might benefit from a clearer
explanation. Changing how truthiness is evaluated in PHP makes no sense
to me though, and I don't think such a drastic step is necessary to get
a lot of benefits.

If you have further feedback, I would be happy to hear it. So far I have
not gotten much feedback, and most of it was going towards being
positive, so being able to get to know the other perspective would help
to address it in the RFC and improve it overall.

--
PHP Internals - PHP Runtime 

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

2022-05-17 Thread Andreas Leathley

On 17.05.22 11:18, Jordi Boggiano wrote:


Thanks for the RFC. I think it's overall a good idea, especially for
cases like "false" => true, and arguably for ints >1/<0, but my gut
feeling is the string=>bool deprecation will lead to a lot of pain.

I definitely see this being done in many places where you expect any
string value to be true and an empty string to be false (without
consideration for the "false" case which is more common in config
style use cases).

I don't know what you could do to improve this without making the RFC
useless though. I wish these things could be tried out in alpha or
even up to early RC builds so we could hopefully get community
feedback in before deciding whether it's worth the pain inflicted or not.


For what its worth, I already found some bugs in the php-src tests where
a function definition was probably changed at some point and a string
was passed to a bool argument which was obviously not intended, or where
a weird value was used for a boolean argument without any apparent
reason. These are the type of unintended coercions I am trying to bring
to light with the RFC.

Using any string as true is also already a bit dangerous: "0" is a
special case string that results to false, which adds a big wrinkle to
the assumption "non-empty string is true".

My main arguments why I think this will not lead to too much unnecessary
pain:

 * Each individual case is easy to fix, the easiest (but also least
   useful) would be to loosly compare a value to true ($value == true)
   instead of directly giving the value to a typed bool
 * bool arguments for internal functions are usually optional, less
   numerous and are much more likely to be set by a constant expression
   than a variable
 * deprecation notices are easy to ignore, and the "disadvantage" of
   the high number of deprecation notices with 8.0 and 8.1 should be
   that most tooling and codebases have gotten more used to dealing
   with them without too much panic

I also added these points to the RFC, because I think there is some
resentment built up for deprecation notices by now, which I can understand.


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

2022-05-16 Thread Andreas Leathley

On 16.05.22 18:24, Guilliam Xavier wrote:

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)?

Yes, that is correct and I just added a note about that in the RFC -
thanks for the suggestion! I also added a part about how to avoid the
deprecation notice, which should also make it clearer / add some context.

--
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 Andreas Leathley

Hello Kamil,

I suspect this is very different depending on the codebase. My main
reason for introducing this deprecation notice is to start highlighting
possible problems in codebases where nobody even suspected them before.
In one application recently I actually had the string "false" (coming
from a form transmission) being passed to a boolean argument and leading
to true, which definitely was unintended.

I have tried coming up with reasons why these deprecation notices could
be harmful or unnecessary, but I think anytime they occur there is a
legitimate reason to check the code (and make it more explicit). If an
integer 5 is passed to a boolean type, how is that not suspicious? Yet I
do think this is a deprecation notice that will be far less common than
some in recent history (like "non-integer-compatible float to int
conversions" or "passing null to non-nullable parameters of built-in
functions"), because there are far less boolean parameters in the
built-in functions of PHP compared to string/int, and I'd wager bool is
also less used in codebases compared to string/int/float.

If you or anybody else has a recommendation on how to measure how this
would affect codebases and what information in that regard would be
useful, I am open to look into that more. The impact should be rather
low in general because it is only a deprecation notice, and I think a
lot of codebases are getting used to dealing with deprecations more with
the last two PHP versions.

Best regards,

Andreas

On 16.05.22 17:19, Kamil Tekiela wrote:

Hi Andreas,

Has any case study been done already about how it will affect existing
codebases?

Regards,
Kamil



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

2022-05-16 Thread Andreas Leathley

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


[PHP-DEV] Request for wiki karma

2022-05-16 Thread Andreas Leathley

Hello Internals,

I would like to request wiki edit privileges to prepare an RFC for
Stricter implicit boolean coercions, where I started a discussion
recently and am currently finalizing an preliminary implementation.

Username: iquito

Thanks!

Best regards,

Andreas Leathley


Re: [PHP-DEV] The future of objects and operators

2022-05-08 Thread Andreas Leathley

On 07.05.22 22:59, Jordan LeDoux wrote:

I like the way you organized the different levels of support within the
feature, it's a good organizational structure for thinking about the
feature-set. Given the feedback though, I found myself a little concerned
that if I created a Level 1 proposal, it's very possible that the people in
groups 1 and 3 above might vote for it. However, in doing so it's also very
possible that all the use-cases those voters care about would then be
covered, and many would then block anything which helps use-cases they do
not commonly use. In essence, the particular feedback I received made me
concerned that passing a Level 1 RFC would basically guarantee that Level
2+ would never happen until the voter base itself was significantly changed.

Creating "smaller steps" (within a certain feature set) seems to have
been the more successful route for PHP RFCs and not necessarily slowed
down further enhancements, in my estimation. The more one single RFC is
about, the more there is to possibly dislike. It is also easier to
reason about less changes at any one point in time and make a more
compelling case for the changes. So I think your overall goal of more
feature-complete operator overloading remains viable even if you start
"small" with a level 1 proposal.

--
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 Andreas Leathley

On 02.05.22 13:56, Alexandru Pătrănescu wrote:

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".

As I dealt with several PHP upgrades, and I'm still going to deal with them
in the future, I proposed an idea at some point on the mailing list:
To find a way to "flag" a behavior change.
The problem is that it should be something outside E_ALL, or to be able to
handle it in a totally different way than setting an error handler for it.
Something that can be used when preparing for an PHP upgrade, something
like:
register_version_change_handler(callable $callback, $toPhpVersion)
While preparing for a future runtime version, it would be deployed to
production and would record behavioral changes in a logging system.
These changes need to be manually reviewed, of course, as a change can be
to return false instead of null and if that value would be used further in
an if.
When using in a library maybe there could be some token like @@@ to not
trigger the handler.


To me, adding another error/change handler system seems like a bad way
of dealing with this, not to mention that you need to introduce this
behavior in a PHP version first before anyone can then use it, so it
would be years before this could be useful, and even more years until
there would be established patterns and enough knowledge around it.
Using the existing way of notices, warnings and errors seems just as
good to me, and people have been handling those for many years. Any new
way of dealing with this should have a very high bar to clear and would
need to prove a huge gain in value.

To me this does fit the definition of a deprecation - behavior for the
given code will change intentionally in a future version, and you are
warning about that future change. But one could also emit a notice, or a
warning. The advantage of deprecation notices is that many tools ignore
those specifically, as they are something to look at, but not
necessarily right at this moment. Being more lenient in certain
situations with deprecation notices is therefore a good pattern for
easier adoption of new versions. I have included that behavior in my own
applications, by logging deprecations separately - I will check them out
once in a while, but they do not need immediate attention. Any other PHP
notice or warning would warrant immediate attention, as it would be
unexpected.

--
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 Andreas Leathley

On 26.04.22 16:36, Rowan Tommins wrote:

On 26/04/2022 14:53, Andreas Leathley wrote:

'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".

Interesting, I didn't know the default value of a checkbox is "on" if no
value is specified. That might make it another sensible value to accept
for implicit bool conversion, even though I am not sure how many
checkboxes are used without setting an explicit value, but it could be
considered an established value, especially with how commonplace HTML
forms and checkboxes are in PHP applications.

--
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-26 Thread Andreas Leathley

On 26.04.22 15:27, Rowan Tommins wrote:


I was actually thinking about this the other day, in the context of
adding new cast functions which reject more values than our current
explicit casts.


This is also something I am interested in - having functions which do
the same as implicit type casts, so something like
"coerce_to_int('hello')" would lead to a TypeError like it would when
passing it to an int parameter, and maybe
"is_coerceable_to_int('hello')" which would return false, so it would be
possible to check values the same way as PHP does internally. The
current explicit cast functions are quite heavy-handed and not great for
every situation - when parsing a CSV or getting data from a database I
would rather coerce values where an error could occur if it doesn't make
sense than to explicitely cast and not even notice if the value made no
sense at all.


When I started thinking about booleans, it was much harder to define
what makes sense. I've certainly seen new programmers confused that
(bool)'false' is true, and having it error would usually be more
helpful; but (bool)'on' being true is useful when dealing with HTML
forms, for instance.


'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. One
of the big reasons of starting this discussion is because of HTML forms,
as that is where people might add values and not know what that leads to
in PHP. At these application boundaries it would be helpful to get a
clear message what value was converted to true (but might have lost
information by doing that) and what other value to use which is
considered more clear.

--
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-26 Thread Andreas Leathley

On 26.04.22 14:47, Christian Schneider wrote:

There are two big reasons:
- BC: Checking for the truthiness of a value is very common and would require a 
lot of code changes.
- Some of us like the conciseness of "if ($foo) ...", see below


That would not be my target - in an if expression a lot more values are
allowed anyway (arrays, objects, etc.), so this is not about determining
truthiness, but actual conversions to a bool type, like a bool
parameter, a bool return type or a bool property type. The inspiration
for this is the "Deprecate implicit non-integer compatible float to int
conversions" (https://wiki.php.net/rfc/implicit-float-int-deprecate),
minus the mathematical expressions that were considered there. It is
about avoiding probably-unintended values being coerced to boolean and
therefore losing information / adding unnoticed bugs to a codebase.


I'm definitely against adding more special cases like 'false'.
Side-note: Removing something like '0' => false is also a BC break, not just 
adding 'false'.


I am not suggesting removing the coercion from the string '0' to false
or changing anything about that.


One of the big issues I have with this (as well as undefined variables
not being allowed in if ($foo)) is that the replacement constructs are
clunky:
if ($foo)  =>. if (!empty($foo))

For me this is quite a regression in readability but then again that's a matter 
of taste.
And would !empty($foo) even work in your world or how would empty() be defined?

empty is also not something I would consider covering, as there you also
do not need a conversion to a bool type.

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



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

2022-04-26 Thread Andreas Leathley

On 26.04.22 12:02, Mark Randall wrote:

On 26/04/2022 10:54, Andreas Leathley wrote:

Any non-empty string (except "0") is converted to true and any non-zero
integer or float is converted to true.


If we could get rid of "0" being false, that alone would be a huge
benefit for the language in the long run.

I know why it exists, but I don't think it should. In fact it never
should have existed in the first place.


For me, highlighting all the places where a possibly unintended
conversion to true is happening would make "0" a lot less bad. "0.0"
being silently true while "0" and 0.0 is false seems a bit awkward.

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



[PHP-DEV] Stricter implicit boolean coercions

2022-04-26 Thread Andreas Leathley

Hello Internals,

Implicit type coercions (when not using strict_types) have become
increasingly less lossy/surprising in PHP, especially coercions to
integer and float, where you get a TypeError if you pass a non-numeric
string to an integer parameter, and a deprecation notice if you pass a
float(-string) with a fractional part to an integer parameter. The big
exception so far is coercions to boolean, where you can provide any
scalar value and never get an error or a notice.

Any non-empty string (except "0") is converted to true and any non-zero
integer or float is converted to true. From my perspective this can
easily lead to hidden bugs, for example when passing the wrong variable
to a boolean argument or boolean property. Passing a string like "hello"
as a boolean is probably a bug, just like passing the number 854 or the
float 0.1 . "on" and "off" and "true" and "false" all lead to a boolean
true, as examples of strings that could be used in applications and
might not all be meant as a value of true.

I have not found any past proposals or discussions to change boolean
coercions, so I would like to find out how the thoughts on internals are
to change this, or if there are any reasons not to change this that I
have not thought of. 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

I can also see a case for allowing the strings 'true' and 'false', and
changing 'false' to be coerced to false, but that would be a BC break. I
am not sure if that is worthwhile.

Anything else would emit either a notice or a warning as a first step
(to be determined). My main goal would be to make these
probably-not-boolean usages more visible in codebases. Depending on the
feedback here I would create an RFC and try to do an implementation (to
then discuss it in more detail), so as of now this is mostly about
getting some basic feedback on such a change, and if someone else has
had any similar thoughts/plans.

Thanks for any feedback!

Andreas Leathley


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

2022-04-21 Thread Andreas Hennings
On Thu, 21 Apr 2022 at 11:18, Rowan Tommins  wrote:
>
> On Wed, 20 Apr 2022 at 19:16, Claude Pache  wrote:
>
> > > You make a very important claim in your bug report:
> > >
> > > > However, in real world, is_callable() is almost never given totally
> > arbitrary stuff
> > >
> > > My concern is that we have no way of knowing whether this is true, and
> > whether there will always be a clear action for users who see the
> > deprecation notice.
> >
> > In this case, there is always the possibility for them to use the error
> > suppression operator. That remains easy, and looks like a reasonable use
> > case of that operator.
> >
>
>
> The error suppression operator is a big blunt tool, and using it to squash
> a deprecation notice would be an absolute last resort. Note that in
> contrast to the strpos() case where both behaviours can be achieved with
> *permanent* changes, the error suppression would only be a temporary
> workaround for error logging, with no value in itself.
>
>
>
> > If we have to balance between addressing the verified issue of not
> > emitting deprecation notice for well-known and fairly frequent code
> > patterns, and addressing the potential and non-fatal issue of emitting too
> > much notices for totally unknown use cases, the choice should be
> > straightforward.
> >
>
>
> Again, this is true IF you are correct that one set of patterns is common
> and the other is not, but so far I've not seen any attempt to find out
> whether that's true. The idea of ignoring "unknown" use cases seems really
> dangerous - like closing your eyes so you can't see the bad effects of what
> you do. What we need to know is whether such use cases are *rare*, or
> whether the people using them are just not subscribed to this list.
>
> One starting point would be to find usages in the top 100 or 1000 packages
> on Packagist using https://github.com/nikic/popular-package-analysis -
> perhaps Juliette has already done that when testing their PHPCompatibility
> sniff?

As a package author, you might not really know where the value is coming from.
A parameter will be declared as `@param mixed $callback_or_not`, if it
internally calls the`is_callable()` method.
And a static analysis tool will only see `mixed`, not "mixed, but if
it is a string, it does not start with 'static::', or if i's an array,
the first value is not 'static'.".

On the other hand, the value probably won't be completely arbitrary.
It might be coming from a discovery process that reads yml files or
annotations, or that calls some kind of hook in php. Or it is
generated with string concatenation.
Whatever it is, it is probably explicitly or implicitly hard-coded somewhere.

Here is a starting point for a search. But only for explicit calls.
https://sourcegraph.com/search?q=context:global+is_callable%5C%28%28%5C%5B%27%28static%7Cself%29%27%7C%27%28static%7Cself%29::.*%27%29%2C+lang:php=regexp

>
> Regards,
> --
> Rowan Tommins
> [IMSoP]

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



Re: [PHP-DEV] NULL Coercion Consistency

2022-04-21 Thread Andreas Leathley




There is another 3.5 years until PHP 9 is likely to come out, which is a

lot of time for people to adjust their codebase. I could even see an
argument for not promoting it to a fatal error in 9.0 if so many people
need more time.



If it's deprecated, that is an intent to break... and if no other solutions
present themselves, and the vote for this RFC fails... why would it be
delayed? It will then be clear the Internals developers want this (they
would have made an informed choice, and put their name to it).


A deprecation notice is fairly harmless. If in two years many projects
and many developers say that they need more time to fix these
deprecations and promoting them to errors would cause a lot of problems,
then it would be easy to prolong the period where it is only a
deprecation with a small RFC. By then more people will know if they are
impacted, many frameworks will have updated, and there will be a clearer
picture if this is such a big deal or not. Right now this is not clear -
I doubt most projects are using PHP 8.1, not even all
frameworks/libraries are compatible to PHP 8.1.



Are you going to suggest any improvements? what have I missed? I'm trying
to keep it short, because I know long RFC's can be a problem.


An RFC should cover the discussions held on this mailing list. From the
RFC howto:

"Update your RFC to document all the issues and discussions. Cover both
the positive and negative arguments."

Do you honestly believe you have done that? I have tried to discuss some
counterpoints and alternatives to your proposal, but none are mentioned
in the RFC. I also don't see the discussion points of other people in
the RFC. None of the alternatives to your proposal are mentioned in the
RFC - like changing the internal functions to accept null instead. There
have been quite a few suggestions and arguments made so far, and I don't
see them in the RFC.

I have discussed RFCs with a few people on this mailing list, sometimes
with very different opinions about a topic, and not always was there a
resolution to the topic at hand. Yet the discussions with you have been
the most frustrating so far, because you say you are open to arguments
and proposals, yet you do not seem to consider them at all - yet you
really seem to believe you are totally open-minded. I have been
impressed by a few people on this mailing list who I disagreed with
wholeheartedly, because I noticed with how much care they tried to relay
disagreeing arguments and other proposals in the RFC and how balanced
the RFCs were at the end. Your RFC seems totally incomplete to me and
mainly based on your made-up opinion. But at this point I don't think I
will get through to you in any way, which is why I will step out of this
conversation. If the RFC comes to a vote in the current conditions
though I will raise an objection that it does not represent the
discussions held on this mailing list and should be disregarded because
of that.

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



Re: [PHP-DEV] NULL Coercion Consistency

2022-04-20 Thread Andreas Leathley

On 14.04.22 14:14, Craig Francis wrote:

Yep, I agree with everything you have said there, and it's what George
seems to be working towards (which I also agree with):

https://github.com/Girgias/unify-typing-modes-rfc


Yet your RFC goes exactly against the quoted document by making the
differences between strict_types larger.


I also cannot explain why NULL should be rejected, other than for those
developers who see NULL as an invalid value and also use
`strict_types=1`... as in, when a team of developers spends a few hundred
hours adding strval() everywhere, what does that actually achieve? what do
they tell the client? does it make the code easier to read? does it avoid
any bugs? or is it only for 8.1 compatibility?

I don't get why you would add strval everywhere. Why are you getting
null everywhere? In most of the examples in your RFC "null" is
specifically chosen as a default value and could easily be an empty
string (why do something like "$_POST['value'] ?? null" if you actually
want an empty string?). For the framework examples, the second argument
of these functions is the default value - it does not have to be null.
And "filter_input" I have not seen in a codebase yet, probably because
of its weird double function as retrieving an input variable and also
filtering it, with both null, false and the result as a possible return
value.

The few cases where I encountered the deprecation notice it was always a
mistake and easy to fix, and I was glad that was pointed out to me.
There is another 3.5 years until PHP 9 is likely to come out, which is a
lot of time for people to adjust their codebase. I could even see an
argument for not promoting it to a fatal error in 9.0 if so many people
need more time. Removing the deprecation and changing fundamental
aspects about the type system in PHP by auto-coercing null just so
people do not need to update their codebase seems like the worst
possible way forward.

So far, your RFC does not mention the arguments made against your
proposed changes in an understandable way. George Peter Banyard wrote
some extensive arguments and you have only included one sentence without
any of his arguments and try to refute it in the very next sentence as
not really an argument, and it was mentioned by him that coercing null
in other languages like Java has lead to problems. Comparisons to other
languages could be helpful, as NULL is not just a value in PHP - NULL in
MySQL for example also cannot be coerced and is its own distinct value
(it even has its own syntax for comparisons).

I am still bothered by the language of the RFC in general where you
often write things like ".. it hasn't been the case for everyone else",
"most developers are not in a position" and so on. Assuming you know
what everyone is doing and how everyone is doing it in an RFC does not
seem constructive. All the numbers you cite are also circumstantial and
not about the supposed problem discussed in the RFC - for example, you
assume people not using static analysis are in favor of your RFC, even
though this is pure speculation. Compared to all the other RFCs in the
last 3 years I read through I don't only disagree with this RFC, I also
think it is not very well reasoned about and does not convey the
discussions that were held about the topic on this mailing list. It
mainly contains your opinion, which seems insufficient for an RFC.

--
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() throwa deprecation notice ?

2022-04-19 Thread Andreas Hennings
A deprecation warning on is_callable() would imply that in a future
version of PHP that call will be illegal.
But this is not the case.
is_callable() is meant to accept any value, and return true or false.
is_callable('static::method') will still be a valid call in future
versions, only the result will be different.
This change simply cannot be covered with a deprecation warning.
Developers have to update their code when they upgrade to PHP 9.x, or
they need a PHP_VERSION_ID check, as sad as that is.

One solution could be to accept an additional parameter to enable the
forward behavior for is_callable().
But then this parameter would have to be removed again later.
Also, is_callable() already has two extra parameters, so it would get crowded.

-- Andreas

On Tue, 19 Apr 2022 at 17:18, Claude Pache  wrote:
>
>
>
> > Le 18 mars 2022 à 18:03, Juliette Reinders Folmer 
> >  a écrit :
> >
> > On 18-3-2022 14:37, Christoph M. Becker wrote:
> >> On 16.03.2022 at 06:52, Juliette Reinders Folmer wrote:
> >>> 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.
> >>>> The |is_callable()| function and |callable| type remain side-effect
> >>>> free and do not throw a deprecation warning. They will continue to
> >>>> accept these callables until support is removed entirely.
> >>> While I can fully support this for the `callable` type, I wonder if the
> >>> decision to not throw a deprecation on use in `is_callable()` is the
> >>> right one (though I understand the desire to keep it side-effect free).
> >>> Consider these code samples:
> >>>   function foo(callable $callback) {}
> >>>   foo('static::method');
> >>> This function call not throwing a deprecation is not problematic as in
> >>> PHP 9.0 the function will start throwing a TypeError.
> >>>   if (is_callable('static::method')) {
> >>>   static::method();
> >>>   }
> >>> The second code sample, however, is problematic, as 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.
> >>> Would anyone care to enlighten me as to whether this was given due
> >>> consideration ?
> >> Frankly, I don't know.  Apparently, there was almost no discussion about
> >> that RFC.  Part of the reasoning to not raise E_DEPRECATED when calling
> >> is_callable() was likely the typical use case
> >>   $callable = …;
> >>   if (is_callable($callable)) {
> >>   call_user_func($callable);
> >>   }
> >> what would report the deprecation when actually calling the callable.
> >> Not sure what to do regarding your given use case(s).
> >> --
> >> Christoph M. Becker
> >
> > Unfortunately, those aren't the only places I see this happening and my 
> > example is not a stand-alone case either.
> >
> > I came across the above code sample ( is_callable('static::method') / 
> > is_callable(['parent', __FUNCTION__]) with variable method calls) in a 
> > number of different packages when testing a (PHPCompatibility) sniff I am 
> > writing to detect the deprecation, so this code pattern looks to be 
> > relatively common.
> >
> > Some examples:
> > * 
> > https://github.com/symfony/service-contracts/blob/bc0a2247c72d29241b5a06fb60dc1c9d9acf2a3a/ServiceSubscriberTrait.php#L39
> > * 
> > https://github.com/mockery/mockery/blob/c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac/library/Mockery/Mock.php#L960
> > * 
> > https://github.com/simplepie/simplepie/blob/dacf0ed495d2e8fb306e526ca3f2a846af78a7c9/tests/oldtests/absolutize/RFC3986.5.4/base.php#L13
> >
>
> As I think that it is a serious oversight of the RFC, I have open:
>
> https://github.com/php/php-src/issues/8401 
> <https://github.com/php/php-src/issues/8401>
>
> —Claude
>
>

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



Re: [PHP-DEV] NULL Coercion Consistency

2022-04-14 Thread Andreas Leathley

On 14.04.22 10:10, Craig Francis wrote:


My intro says "Roughly 85% scripts do not use strict_types=1", and "Roughly
33% of developers use static analysis" (source of numbers noted in my
RFC)... while that does not guarantee anything, it's a fairly good
indication that most developers do not care about types (in regards to
coercion), or specifically, how you "see null as a real type".

As an aside, I would like to include more stats (maybe WordPress install
numbers?), but I couldn't think of any which were easy to source (ref
reliability), or be that useful to the discussion.


I have never used strict_types in any code I have ever written, and I
care about types and type coercions. Yet I do not like the strict_types
distinction and I am glad that I do not need to use it, and I think we
are not that far away from even reconciling these two systems. I do not
mind that the string "5" can be passed to an int parameter, while
passing the string "hello" will throw a type exception no matter what
mode you use. With some adjustments to certain coercions the advantage
of strict_types would be even more neglible - as you can pass "hello" to
a boolean parameter without problems currently, and I don't like that.

Looking at usage numbers and assuming that supports your point seems
like a big leap to me. You are assuming these developers are making a
choice while it seems quite possible that a lot of code has been written
without thinking about all the implications, which is where so many bugs
are coming from. In the last months reviewing code I noticed quite a few
developers are copy-pasting code like crazy, or using generated code
from other tools - both of which are often not well reasoned about. So
this has little to do with developers not caring about methods of type
coercions and more about the language permitting such code, leading to
many follow-up problems.

Also, this "problem" only affects the internal functions, yet you want
to change it for all functions. If you use a framework and pass a value
to a method of that framework, it would already have created a type
error with null and a non-nullable argument for quite some time. I think
you are making this out to be a bigger problem than it is. Sure, in a
codebase with lots of custom code where no incoming variable is checked
if it even exists there will be problems, but even then it is easily
fixable. In a codebase based on a common framework it is much less of a
problem, as you will probably be using lots of framework components and
not mainly internal functions, and there you already have the
"limitation" of not being able to pass null to a non-nullable method.

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



Re: [PHP-DEV] NULL Coercion Consistency

2022-04-13 Thread Andreas Leathley

On 13.04.22 15:36, Craig Francis wrote:

On Mon, 11 Apr 2022 at 20:08, Andreas Leathley  wrote:

You are taking parts of the documentation out of context, and omitting
the start of the whole "Converting to string" section:

"A value can be converted to a string using the (string) cast or the
strval() function. String conversion is automatically done in the
scope
of an expression where a string is needed. This happens when using the
echo or print functions, or when a variable is compared to a
string. The
sections on Types and Type Juggling will make the following clearer."



I'm sorry, I've read this several times now, and I'm not sure what
this adds. My RFC simply quotes the paragraphs that explain how null
is coerced (other than the small abbreviation for booleans, those
paragraphs are included in their entirety), I don't think it needs any
more context than that, it's not like I'm mis-representing how
coercion works (and is used) in PHP.


Mentioning the documentation as a reason to be "consistent" (which comes
up again and again in your arguments with this RFC) just seems like a
bogus reason to me. It is nitpicking about specific sentences in the
documentation without refering to the surrounding context. It would be
nicer to argue according to real technical arguments instead of
arguments about sentences taken out of context in the documentation.



You can see NULL however you like, but most developers do not share
that view. NULL has been passed to these functions, since, well,
forever; and changing code to manually convert NULL to the relevant
type is incredibly time consuming, and of questionable value (e.g.
when developers simply add strval() everywhere).


"Most developers do not share that view". I find statements such as
these as a tall order - did you interview the majority of developers
around the world? Are you suggesting you are talking as a representative
of a large population of PHP developers? How do you think you got such a
role? I would prefer some humility and not assume you are an elected
leader of an underrepresented group of developers and even knowing the
intention behind their code.

"NULL has been passed to these functions, since, well, forever" - this
also goes for wrong values being passed to functions since forever
leading to security issues and bugs. That is the whole point of
developing a language: Reducing the surface for bugs, improving parts of
it where a lot of bugs have happened historically and not making the
same mistakes as other languages (and learning from the good parts of
other languages). More people writing code in a certain way does not
make that code better or safer.


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

2022-04-11 Thread Andreas Hennings
> sketch out a more complete picture for the type
system.  We can implement it in pieces and parts, but we should have a goal
in mind for where we want to land.

I think the type system in psalm is pretty cool. It does have fixed
literal values, but also deeply structured array types.
But:
- I don't think we'll arrive there in one leap
- I am not sure we _want_ to arrive there, ever. Perhaps it is just
too much for native support, especially if we want repeated runtime
checks.
- Runtime checks on array types seem like a nightmare.
- I am pretty confident that adding `true` won't close any doors fur
future type systems, if we already have `false`.

Alternatively we could look at compile-time type systems like in C++
(or Java?), where we don't have to waste time on runtime checks.
The default implicit variable type could be "variant", but variables
with a declared type would behave as in C++, with a faster and slimmer
storage model.
Of course any union type that allows values other than object or null
would have to use the storage model of "variant".
Sounds like a lot of work, but if we want to dream big, it is
something to consider.

(There might be better examples than C++, I only mention it because I
spent some time with it long ago. Perhaps even Java?)

-- Andreas

On Mon, 11 Apr 2022 at 18:18, Sara Golemon  wrote:
>
> On Mon, Apr 11, 2022 at 8:59 AM Tim Düsterhus  wrote:
> > For `true` the story is different, as this type is an entirely new type
> > available to userland and by the same argument one could have literal
> > strings or literal integers as distinct types as well. I wouldn't object
> > to that per se (and there's precedent in TypeScript), but there could be
> > a clearer plan for the type system as a whole, instead of adding types
> > piecemeal.
> >
>
> ^This. The bit about making a plan, I mean.  A slow erosion of what it
> means to be a type might be the easier pill to swallow, but it results in
> more chaos overall in the type system.  I'd like to see someone (literally
> anyone) take the time to sketch out a more complete picture for the type
> system.  We can implement it in pieces and parts, but we should have a goal
> in mind for where we want to land.
>
> Using this RFC as an example, it naturally leads into the question of value
> types (which is what `true` really is, a bool with a value of true), so why
> can't we say this method must return the number 42 or a string containing
> 'pamplemousse' ?  A roadmap would help us understand what those kinds of
> value types (in an unbounded type like string or a large bounded type like
> int) compared to the tight bounded type of bool.
>
> And yes.  Generics.   We can't talk about the type system without the
> subject of generics being extremely relevant.  Ignoring them because it's
> complicated is just kicking the can down the road.
>
> All that having been said, sure. I don't mind adding true for completeness,
> because it's fairly obvious and the scope of bool is fairly small, but I
> would really encourage anyone to step up and plan out a wider reaching goal
> for the type system.
>
> -Sara

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



Re: [PHP-DEV] NULL Coercion Consistency

2022-04-11 Thread Andreas Leathley

On 11.04.22 20:22, Craig Francis wrote:

Just take NULL to String coercion as an example, the documentation
clearly
and simply says “null is always converted to an empty string”, this needs
to be updated to end with "... except when being passed to a function, in
which case NULL will result in a Type Error" (I think that's "broken and
inconsistent").


You are taking parts of the documentation out of context, and omitting
the start of the whole "Converting to string" section:

"A value can be converted to a string using the (string) cast or the
strval() function. String conversion is automatically done in the scope
of an expression where a string is needed. This happens when using the
echo or print functions, or when a variable is compared to a string. The
sections on Types and Type Juggling will make the following clearer."

In the same section it is also defined how resources and arrays get
converted to strings. Following your argument, you should be able to
pass arrays and resources to a string parameter because there is a clear
definition in the documentation of what then happens.

I unfortunately really don't like the direction of your RFC, because I
see null as a real type and because it increases the divide between
strict_types and not using strict_types. I have never used strict_types
- in modern PHP code I find it unnecessary, if you use parameter,
property and return types. I am glad PHP has decreased the difference
between using strict_types or not, so your direction of trying to
increase the difference seems like the wrong way to go. Ideally I would
rather want to see a future where strict_types can be removed/reconciled.

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



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

2022-03-25 Thread Andreas Heigl

Hey Ilija.

On 25.03.22 15:38, Arnaud Le Blanc wrote:

Hi Ilija

I find that sprintf() is easier to read in most cases. One reason for this is
that the text is separated from the code. It's also easier to review for
humans and linters.

The strtoupper example would look like this with sprintf:

 $world = 'world';
 echo sprintf('Hello %s!', strtoupper($world));

Longer examples can be nicely split in multiple lines:

 echo sprintf(
 'Received HTTP status code %d (reason phrase: %s)',
 $response->getStatusCode(),
 $response->getReasonPhrase(),
 );


This technique also allows me to use the original string in translation 
while still keeping the replacements out of that.


So something like

echo sprintf(
gettext('Hello %s!'),
strtoupper($world)
);

would easily work and provide the translator only with the string `Hello 
%s` which is much less to break than `Hello {strtoupper($world)}!`


So for internationalized applications I'd rather keep the sprintf 
approach than a new string-syntax.


A way to use sprintf in a more out-of-the-box way like in ruby would be 
awesome! Something like


echo 'Hello %s' % [strtoupper($world)];

or

echo 'Hello %{world}' % ['world' => strtoupper($world)];

But I'm absolutely happy with the current sprintf functionality.

Just my 0.02€

Cheers

Andreas

--
  ,,,
 (o o)
+-ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


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

2022-03-12 Thread Andreas Heigl

Hey Ilija.

On 11.03.22 18:13, Ilija Tovilo wrote:

Hi everyone

It's been a while. Hope you are doing well.

Last year I sent an e-mail to the mailing about the current state of
string interpolation in PHP. I have now created an RFC to better
explain the current behavior and why it would make sense to
deprecate/remove some of it.

https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation

Previous thread:
https://externals.io/message/111519

Let me know what you think.


As I already stated on twitter[1] for me there are multiple things missing:

First of all it would make it much easier for me to see what impact this 
RFC has if there were any numbers in it of how many large-scale 
repositories on for example github are affected by this.


But on the other hand, and that's much more important to me, I am 
missing the part where you explain the concrete benefits of that 
deprecation for the evolution of the language.


In evolution everything is fine as it is unless it directly hinders the 
forthcoming and development of new essential features. IN PHP that means 
- at least for me - as long as something is not in the way of a new 
feature or a strategy we leave it as it is.


Deprecating something in terms of raising a deprecation message in the 
error log, means that something is going to go away in one of the next 
versions. We are going to remove a feature because we have a strategy to 
improve something in that part. Be it complexity in the source code or 
replacing a functionality or speeding up the language.


But so far I can see none of these things to apply here. The only 
argument that you are giving in the RFC are that they are "rarely 
useful" (reminds me a bit of Jack Sparrows "Ah! But you have heard of 
me") and that they are easily confused.


While the later argument would also speak for unifying the 
needle/haystack parameter order it is also making an assumption. Which 
is not backed by any statistics. How many bug reports do we have in the 
bug tracker due to this "confusion"?


Also what is "useful" is always a rather subjective matter. Just because 
I don't find feature X useful doesn't mean that others can't find it useful.


But what worries me the most is that your proposal to deprecate and 
essentially remove some string features that have been in the language 
for quite some time and have once been considered relevant is not giving 
me an idea of how that will benefit the language itself. How that will 
immediately allow us to improve the language. By either removing 20% of 
code that we suddenly don't need to maintain any more or because it will 
allow us to immediately implement feature X in PHP9.


And just removing something to allow a different RFC that "might" allow 
proposing other stuff is premature optimization. We might be able to 
need this feature, so let's tweak our code for that possibility right 
now. Without knowing whether that might actually be happening. And we 
should not remove features *now* just because someone at one point in a 
future might want to do something.


So while I appreciate the idea of a cleaner API I will for sure vote 
"no" on this RFC in it's current form.


My 0.02€

Cheers

Andreas


[1] https://twitter.com/heiglandreas/status/1502338172210065409

--
  ,,,
 (o o)
+-----ooO-(_)-Ooo-+
| Andreas Heigl   |
| mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
| https://andreas.heigl.org   |
+-+
| https://hei.gl/appointmentwithandreas   |
+-+


OpenPGP_0xA8D5437ECE724FE5.asc
Description: OpenPGP public key


OpenPGP_signature
Description: OpenPGP digital signature


  1   2   3   4   5   6   >