Re: [PHP-DEV] RFC: Support Closures in constant expressions

2024-11-05 Thread Larry Garfield
On Mon, Nov 4, 2024, at 6:57 PM, Gina P. Banyard wrote:
> On Monday, 4 November 2024 at 20:32, Larry Garfield 
>  wrote:
>
>> On Mon, Nov 4, 2024, at 6:06 AM, Tim Düsterhus wrote:
>> > 
>> > Here's another brainteaser:
>> > 
>> > function foo(
>> > string $bar,
>> > Closure $baz = static fn () => $bar,
>> > ) {
>> > var_dump($baz());
>> > }
>> > 
>> > foo('captured');
>> > 
>> > What would you expect the semantics of that script to be?
>> 
>> 
>> My expectation is that it's confusing, and therefore we should simply 
>> disallow it. Which roughly translates to detecting if a closure tries to use 
>> an unbound variable statically. Which is probably more difficult than I make 
>> it sound. :-)
>
> Which is why short closures are being disallowed.
> The value of it *is* limited, and the semantics of it are confusing.
> I am struggling to see why this is such a big deal.

I suspect, since several people have asked about it, it's because most of the 
use cases for having a default Closure value are going to be short; the sort of 
short cases that short-closures and FCC are designed for.  If it's long, then 
you're probably better off moving it to a private method and making a FCC 
reference to that private method the default value instead.

So if most of the use cases align with where one would use short-closures and 
FCC, not being able to is disappointing, even if the reasons for it are valid.

>> > > If it cannot reasonably be done now, but is possible, that should be
>> > > listed in future scope with roughly what it would take for a follow-up
>> > > to do. (And then we can argue if it should just be done now, with more
>> > > information as to how much work that is.)
>> > 
>> > I have added an entry to the “Future Scope” section. See also my reply
>> > to Alex.
>
>> Thanks. Can you include what the implementation challenges are for the 
>> future-scope items, to explain why they're being punted to later rather than 
>> addressed now? (As there seems clear interest in having all of them.)
>> 
>
> I have never seen a future scope section which describes these 
> challenges, and this feels just giving more work to people for no 
> benefit?

I'm not asking for a detailed description of the engine nuances of detecting 
unbound variables.  Just something along the lines of "this would require 
detecting unbound variables, that's hard, so we'll save that for later."  Which 
is a level of detail I frequently do provide in my RFC future-scopes.

--Larry Garfield


Re: [PHP-DEV] [RFC] PHP.net analytics

2024-11-05 Thread Larry Garfield
On Fri, Nov 1, 2024, at 6:10 PM, Bob Weinand wrote:
> On 1.11.2024 22:41:29, Larry Garfield wrote:
>> In a similar vein to approving the use of software, Roman Pronskiy asked for 
>> my help putting together an RFC on collecting analytics for PHP.net.
>>
>> https://wiki.php.net/rfc/phpnet-analytics
>>
>> Of particular note:
>>
>> * This is self-hosted, first-party only.  No third parties get data, so no 
>> third parties can do evil things with it.
>> * There is no plan to collect any PII.
>> * The goal is to figure how how to most efficiently spend Foundation money 
>> improving php.net, something that is sorely needed.
>>
>> Ideally we'd have this in place by the 8.4 release or shortly thereafter, 
>> though I realize that's a little tight on the timeline.
>
> Hey Larry,
>
> I have a couple concerns and questions:
>
> Is there a way to track analytics with only transient data? As in, data 
> actually stored is always already anonymized enough that it would be 
> unproblematic to share it with everyone?
> Or possibly, is there a retention period for the raw data after which 
> only anonymized data remains?

The plan is to configure Matomo to not collect anything non-anonymous to begin 
with, to the extent possible.  We're absolutely not talking about user-stalking 
like ad companies do, or anything even remotely close to that.

I'm not convinced that publishing raw, even anonymized data, is valuable or 
responsible.  I don't know of any other sites off hand that publish their raw 
analytics, and I don't know what purpose that would serve other than just a 
principled "radical transparency" stance, which I generally don't agree with.

However, having an automated aggregate dashboard similar to 
https://analytics.bookstackapp.com/bookstackapp.com (made by a different tool, 
but same idea) that we could make public is the goal, but we don't want to do 
that until it's been running a while and we're sure that nothing personally 
identifiable could leak through that way.

> Do you actually have a plan what to use that data for? The RFC mostly 
> talks about "high traffic". But does that mean anything? I do look at a 
> documentation page, because I need to look something specific up (what 
> was the order of arguments of strpos again?). I may only look shortly at 
> it. Maybe even often. But it has absolutely zero signal on whether the 
> documentation page is good enough. In that case I don't look at the 
> comments either. Comments are something you rarely look at, mostly the 
> first time you want to even use a function.

Right now, the key problem is that there's a lot of "we don't know what we 
don't know."  We want to improve the site and docs, the Foundation wants to 
spend money on doing so, but other than "fill in the empty pages" we have no 
definition of "improve" to work from.  The intent is that better data will give 
us a better sense of what "improve" even means.  

It would also be useful for marketing campaigns, even on-site.  Eg, if we spend 
the time to write a "How to convince your boss to use PHP" page... how useful 
is it?  From logs, all we could get is page count.  That's it.  Or the 
PHP-new-release landing page that we've put up for the last several releases.  
Do people actually get value of that?  Do they bother to scroll down through 
each section or do they just look at the first one or two and leave, meaning 
the time we spent on any other items is wasted?  Right now, we have no idea if 
the time spent on those is even useful.  

Another example off the top of my head: Right now, the enum documentation is 
spread across a dozen sub-pages.  I don't know why I did that exactly in the 
first place rather than one huge page, other than "huge pages bad."  But are 
they bad?  Would it be better to combine enums back into fewer pages, or to 
split the visibility long-page up into smaller ones?  I have no idea.  We need 
data to answer that.

It's also absolutely true that analytics are not the end of data collection.  
User surveys, usability tests, etc. are also highly valuable, and can get you a 
different kind of data.  We should likely do those at some point, but that 
doesn't make automated analytics not useful.


Another concern with just using raw logs is that it would be more work to 
setup, and have more moving parts to break.  Let's be honest, PHP has an 
absolutely terrible track record when it comes to keeping our moving parts 
working, and the Infra Team right now is tiny.  The bus factor there is a 
concern.  Using a client-side tracker is the more-supported and 
fewer-custom-scripts approach, which makes it easier for someone new to pick it 
up w

Re: [PHP-DEV] RFC: Support Closures in constant expressions

2024-11-04 Thread Larry Garfield
On Mon, Nov 4, 2024, at 6:06 AM, Tim Düsterhus wrote:
> Hi
>
> Am 2024-10-31 07:16, schrieb Larry Garfield:
>> Hm.  It would never occur to me to use a function for a non-class 
>> constant in the first place, so I don't know. :-)  Frankly I can't 
>> recall the last time I used a non-class constant period. :-)
>> 
>> That said, PHP consts are already a bit squishy, and auto-capture is 
>> always by value.  That wouldn't give us a loophole?
>
> Here's another brainteaser:
>
>  function foo(
>  string $bar,
>  Closure $baz = static fn () => $bar,
>  ) {
>  var_dump($baz());
>  }
>
>  foo('captured');
>
> What would you expect the semantics of that script to be?

My expectation is that it's confusing, and therefore we should simply disallow 
it.  Which roughly translates to detecting if a closure tries to use an unbound 
variable statically.  Which is probably more difficult than I make it sound. :-)

>> If it cannot reasonably be done now, but is possible, that should be 
>> listed in future scope with roughly what it would take for a follow-up 
>> to do.  (And then we can argue if it should just be done now, with more 
>> information as to how much work that is.)
>
> I have added an entry to the “Future Scope” section. See also my reply 
> to Alex.
>
> Best regards
> Tim Düsterhus

Thanks.  Can you include what the implementation challenges are for the 
future-scope items, to explain why they're being punted to later rather than 
addressed now?  (As there seems clear interest in having all of them.)

--Larry Garfield


[PHP-DEV] [RFC] PHP.net analytics

2024-11-01 Thread Larry Garfield
In a similar vein to approving the use of software, Roman Pronskiy asked for my 
help putting together an RFC on collecting analytics for PHP.net.

https://wiki.php.net/rfc/phpnet-analytics

Of particular note:

* This is self-hosted, first-party only.  No third parties get data, so no 
third parties can do evil things with it.
* There is no plan to collect any PII.
* The goal is to figure how how to most efficiently spend Foundation money 
improving php.net, something that is sorely needed.

Ideally we'd have this in place by the 8.4 release or shortly thereafter, 
though I realize that's a little tight on the timeline.

-- 
  Larry Garfield
  la...@garfieldtech.com


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-31 Thread Larry Garfield
On Sat, Oct 26, 2024, at 3:24 PM, Jim Winstead wrote:

> There were more existing 3rd-party dependencies that should probably be 
> added to the policy text:
>
> https://news-web.php.net/php.internals/125769
>
> Two I missed were JpGraph and Parsedown which are used by web-doc. 
> (Currently by side-loading JpGraph and having an old copy of Parsedown 
> committed to web-doc, I would hope to move those out as Composer 
> dependencies if we decide to allow that.)
>
> Jim

I have updated the pre-approved list to include everything we're currently 
using for PHP Tooling, and added a few of them to the other lists as well.  
(List both Psalm and PHPStan, list both CS-Fixer and CodeSniffer, etc.)  For 
JPGraph, it looks like the original is abandoned and there's a zillion forks, 
so I listed the one that is by far most popular on Packagist.

Since folks may have opinions on these lists, I'll give it a few more days 
before calling the vote in case someone wants to weigh in.

The link again is: https://github.com/php/policies/pull/10

--Larry Garfield


Re: [PHP-DEV] RFC: Support Closures in constant expressions

2024-10-30 Thread Larry Garfield
On Wed, Oct 30, 2024, at 3:01 AM, Tim Düsterhus wrote:
> Hi
>
> Am 2024-10-30 05:25, schrieb Larry Garfield:
>> This seems like a good idea to me.  My only real question is why we 
>> need to forbid short-closures.  I fully agree that capturing variables 
>> for such functions doesn't work.  What I don't understand is why that 
>> precludes short-closures.  Is it not possible to "just" say "there's 
>> nothing to even capture in this context, don't try"?  (There may be 
>> technical reasons for that, but I do not know what they are and the RFC 
>> doesn't say.)
>
> It would indeed require some special handling to disable the 
> auto-capturing in the code. This would be solvable of course, but 
> there's also semantic ambiguity, because users reasonably expect short 
> closures to perform auto-capturing:
>
>  
>  $foo = 'foo';
>
>  const Closure = static fn (array $bar): array => [$foo, $bar];
>
>  var_dump((Closure)('bar'));
>
> If this would be legal syntax: What would you expect to be printed?
>
> Best regards
> Tim Düsterhus

Hm.  It would never occur to me to use a function for a non-class constant in 
the first place, so I don't know. :-)  Frankly I can't recall the last time I 
used a non-class constant period. :-)

That said, PHP consts are already a bit squishy, and auto-capture is always by 
value.  That wouldn't give us a loophole?

If it cannot reasonably be done now, but is possible, that should be listed in 
future scope with roughly what it would take for a follow-up to do.  (And then 
we can argue if it should just be done now, with more information as to how 
much work that is.)

--Larry Garfield


Re: [PHP-DEV] RFC: Support Closures in constant expressions

2024-10-29 Thread Larry Garfield
On Tue, Oct 29, 2024, at 10:11 AM, Tim Düsterhus wrote:
> Hi
>
> Volker and I would like to start discussion on our RFC to "Support 
> Closures in constant expressions".
>
> Please find the following resources for your reference:
>
> - RFC: https://wiki.php.net/rfc/closures_in_const_expr
> - Implementation: https://github.com/php/php-src/pull/16458
>
> Best regards
> Tim Düsterhus

This seems like a good idea to me.  My only real question is why we need to 
forbid short-closures.  I fully agree that capturing variables for such 
functions doesn't work.  What I don't understand is why that precludes 
short-closures.  Is it not possible to "just" say "there's nothing to even 
capture in this context, don't try"?  (There may be technical reasons for that, 
but I do not know what they are and the RFC doesn't say.)

--Larry Garfield


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-24 Thread Larry Garfield
On Wed, Oct 2, 2024, at 1:36 PM, Larry Garfield wrote:
> Since Jim's RFC proposal was criticized for being too vague, I hereby 
> offer a somewhat more prescriptive policy proposal on using 3rd party 
> code.  (With JIm's blessing.)  It's still more heuristics than rules, 
> but I think that's the right approach generally.  It also includes a 
> voting mechanism to resolve edge cases when they come up.
>
> I'm sure we'll bikeshed it to death, but please keep an open mind about 
> the concept in the first place.  PHP is more than just php-src, and 
> that's a good thing.  We need to catch up with that reality, while at 
> the same time maintaining a reasonable neutrality about projects 
> Internals doesn't manage directly.
>
> https://wiki.php.net/rfc/third-party-code
>
> *Puts on trusty flame-retardant suit*

An update here.  I have converted the RFC into a PR against the policies repo.  
(Thanks to Derick for his help in dealing with RST format.)

https://github.com/php/policies/pull/10

It's essentially the same as the last RFC text, though I split up the approved 
lists to make it easier to add to in the future.  I also added an exceptions 
mechanism for Dokuwiki.

The RFC itself has been updated to be basically just a placeholder stub for the 
PR.  The vote will be basically "merge this PR?  Y/N."

Absent any more feedback, I will call a vote on it in a week or so.

--Larry Garfield


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-24 Thread Larry Garfield
On Wed, Oct 23, 2024, at 6:57 PM, fennic log wrote:

> I remember a while ago a discussion about bundling composer with PHP by 
> default (and possibly dropping pear).
> What ever happened with that?
> As the first thing any dev does after setting up PHP, is install 
> composer. As this RFC points out, almost every project modern uses 
> composer to manage dependencies, and every Library, SDK and framework 
> requires composer.
> So i'd change this line in the RFC
>>  We should use it, we should document it, we should promote it.
> To
>> We should use it, we should document it, we should promote it, we should 
>> bundle it! 
>  
> As I mentioned, it is basically a requirement nowadays to work in PHP 
> unless you are doing something custom that doesnt require any 
> dependencies, but then, is that person planning to release it to the 
> public?
> I am of no opinion of weather php devs internally should use composer, 
> i have no skin in that game. But Documentation - Yes, Promotion - Yes, 
> but does it really need it? Bundle it - Yes!

Bundling Composer with PHP is an entirely different question with a host of 
additional concerns to consider, like whether the Composer maintainers would 
even want that.  Let's please stay focused on the topic at hand.

--Larry Garfield


Re: [PHP-DEV] Asymmetric visibility is a BC break

2024-10-23 Thread Larry Garfield
On Wed, Oct 23, 2024, at 11:04 AM, ericm...@php.net wrote:
> On 10/22/24 22:39, Calvin Buckley wrote: 
>> After discussing it and thinking about it for a few days, I agree it's
>> not a BC break. Existing code should be fine, and larger frameworks
>> that tend to rely on reflection trickery and such also tend to need
>> updates for newer PHP. The expectations don't really change.
>> 
>> I don't think we need to rush a solution in for 8.4 as long as we can
>> implement one with the existing APIs in userland. As Larry mentioned,
>> readonly (and hooks) already made the previous assumptions invalid by
>> 8.1. As long as we can provide a polyfill and documentation (which
>> should also cover the readonly case in 8.1 too), I'm OK with deferring
>> isReadable/isWritable to 8.5. 

> Chiming in briefly to second Calvin's statement above.
>
> ~Eric

Thanks for the confirmation.

We'll work on a small RFC to propose for 8.5.  No rush on it.

--Larry Garfield


Re: [PHP-DEV] [RFC] Change behaviour of array sort functions to return a copy of the sorted array

2024-10-20 Thread Larry Garfield
On Sun, Oct 20, 2024, at 4:39 PM, Bob Weinand wrote:
> On 20.10.2024 23:23:21, Ilija Tovilo wrote:
>> Hi Bilge
>>
>> On Sun, Oct 20, 2024 at 10:30 PM Bilge  wrote:
>>> I fail to see the logic of present tense = mutate, past tense = copy. At 
>>> least there is a pattern to it, but I would have to look it up several 
>>> times before it sunk in since it is not intuitive at all.
>> It's sorted, the adjective. As in, "give me a _sorted_ array",
>> compared to "_sort_ this array". It's a common convention and I always
>> found it intuitive.
>>
>> Ilija
>
> Hey Ilija,
>
> yes, I agree it's intuitive.
>
> However, I consider it bad to add extra functions for this behaviour. 
> There's very little gain in extra functions, sort(), sorted(), 
> shuffle(), shuffled(), etc..
>
> So yeah, I'd agree on the naming *if* these were the only variation of 
> sorting/shuffling etc. functions. But that's not the case here.
>
>
> I, for my part, very much like the RFC, for that it gives functionality, 
> which I've been missing quite some times already and is minimally invasive.
>
> Bob

I am confused by this statement.  How is "adding more functions that do exactly 
what they say on the tin and act in a predictable fashion" bad?  It's not like 
we're running out of space for functions.  Small, purpose-built, 
highly-predictable APIs that fully address a problem space are the ideal goal; 
the number of them is largely irrelevant.

I wouldn't mind array_sorted() instead of sorted(), since it wouldn't work on 
iterables.  But array_sort() vs sort() is just horribly confusing for no good 
reason, and the API itself does nothing to tell you which is which.

--Larry Garfield


Re: [PHP-DEV] [RFC] Change behaviour of array sort functions to return a copy of the sorted array

2024-10-20 Thread Larry Garfield
On Sun, Oct 20, 2024, at 12:42 PM, Gina P. Banyard wrote:
> Hello internals,
>
> I would like to propose a short RFC to make the return value of the 
> sort() and similar functions more useful:
> https://wiki.php.net/rfc/array-sort-return-array
>
> I intend for the discussion to last 2 weeks and then open the vote.
>
> Best regards,
>
> Gina P. Banyard

Like others, I'm skeptical of the behavior here not being all that clear.

What several other languages do, and what I have in the plan for collections 
if/when they ever happen, is sort() sorts in place, while sorted() returns a 
new value.  There's similarly reverse() (in place) and reversed() (new value 
returned).  

*sorted($arr) seems like it would be a lot less confusing, and consistent with 
what other languages (and hopefully future PHP) do.  (I don't know what that 
means for array_walk(), but I don't know what that would even return anyway.)

--Larry Garfield


Re: [PHP-DEV] Asymmetric visibility is a BC break

2024-10-15 Thread Larry Garfield
On Mon, Oct 14, 2024, at 10:27 PM, Pierre Joye wrote:
> Hello,
>
> On Mon, Oct 14, 2024, 8:07 AM Bilge  wrote:
>> On 14/10/2024 01:02, Valentin Udaltsov wrote:
>> > The problem is that in practice most of the PHP libraries consider
>> > themselves to be compatible with newer PHP versions.
>> >
>> > For instance, Symfony PropertyInfo uses `"php": ">=8.2"` constraint in
>> > its `composer.json`.
>> 
>> That seems like a problem they have created for themselves. It seems an 
>> error to me to declare software forward-compatible with PHP versions 
>> that do not yet exist and thus have clearly not been tested against. 
>> Being as it is an error, we shouldn't consider it impinges on PHP's 
>> definition of a BC break.
>
>
> As much as I like this new feature and I am more than thankful for the 
> work behind it, if a test in codes using a x.y version of php works but 
> fails in x.y+1, it is a BC break, no matter how we look at it. A php 
> dependency targeting x.* is very common. While it tends to be used less 
> frequently as the amount of issues increase, that's not necessarly a 
> good thing.
>
> In some cases it is a necessary evil (extension deprecated adding 
> warnings, security fix requiring a bc break, f.e.).
>
> However, I am very doubtful here. And I do not know if it can be 
> avoided while keeping the new behaviors. 
>
> All in all, it would be great to at least agree that there is a BC 
> break issue, so it can be addressed according, whatever the final 
> decision is.
>
> best,
> Pierre


I think folks are operating with different definitions of "BC Break".

Consider:

// Foreign.php

class Foreign {
  public function __construct(public string $name) {}
}

// My code:

$f = new Foreign('beep');
$rProp = (new ReflectionObject($f))->getProperty('name');
if ($rProp->isPublic()) {
  $f->name = 'boop';
}

Under PHP 8.0, this code works.
Upgrading to PHP 8.1, this code *still works* exactly the same.  Therefore, 
there is no BC break.
Upgrading to PHP 8.4, this code *still works* exactly the same.  Therefore, 
there is no BC break.

Now, someone edits Foreign.php in 8.1 to read:

class Foreign {
  public function __construct(public readonly string $name) {}
}

Now, my code will fail, because isPublic() does not guarantee "is writeable" 
anymore.  

Is this a BC break in PHP?

I can see the argument either way, personally, but I tend toward no.  One PHP 
version to the next should always be safe to upgrade an *existing* code base.  
Just swap out the PHP binary and it should still work the same.  We want that.  
However, once you start modifying any part of the code (including 
dependencies), all bets are off.

Suppose some library switched from using annotations to using attributes.  Any 
other code that was looking for those annotations is now broken, but it would 
be ridiculous to accuse attributes of having broken BC in PHP.  Or ancient PHP 
4 code that just assumed all properties were public (which they were in PHP 4), 
now confronted with PHP 5 code that has private properties.  Is that a PHP BC 
break?  Not at all.

And again, the relevant change here happened in PHP 8.1.  This is only 
tangentially related to 8.4 at all, because isPublic() has not implicitly meant 
is-writeable anymore for three years.

--Larry Garfield


Re: [PHP-DEV] Asymmetric visibility is a BC break

2024-10-13 Thread Larry Garfield
On Sun, Oct 13, 2024, at 9:37 PM, Valentin Udaltsov wrote:


> First of all, I have already agreed above that PHP does not have a BC
> break here. Now we are discussing the potential problems in the PHP
> ecosystem and how they could be mitigated.

Ilija and I have discussed this issue a bit.

The first issue is that isPublic() technically means "does this property have 
the public flag set," and nothing more. Prior to 8.1, that implicitly also 
meant "can the property be read and written to from public scope," because of 
how properties worked. (And same for isProtected().) That implicit assumption 
became invalid in 8.1 with readonly, which stealth introduced limited and not 
fully designed asymmetric visibility as well as properties that could not be 
set multiple times from any scope. Full aviz in 8.4 doesn't change that. It 
just makes the previous assumption change more apparent. The fact that no one 
seems to have reported it as an issue until now suggests it's not a 
particularly widespread problem.  In practice, if someone is using reflection 
to determine the visibility of a property, they'll be writing to it through 
reflection as well if at all.

The best solution here is probably to just clarify the docs, which I will do as 
part of the aviz docs that I have already been working on.  cf: 
https://github.com/php/doc-en/pull/3828

The second issue is that the behavior of isProtectedSet() / isPrivateSet() was 
not as clearly defined in the RFC as it should have been. That's on us for not 
being clearer, as we apologize for the oversight.

Those methods follow the low level pattern of isPublic() , that is, they just 
report of a given flag is set, not what the implications of that flag in 
various contexts are. That is consistent with the rest of the reflection API, 
so we feel that is best left as-is.

That still means the "so can I  read/write this property or not?" question has 
no simple operation for it. Again: it never did, we just kinda sorta had it 
indirectly and implicitly. For that we feel the best answer, as well as least 
disruptive given we're in RCs, is dedicated methods as Ilija has already 
described that take all property behavior and context into account. (isReadable 
and isWriteable.)

As a reminder, the concept is:

$rProp->isReadable($obj); // Can this property on $obj be read from the calling 
scope?
$rProp->isReadable($obj, 'static'); // Same as previous.
$rProp->isReadable($obj, null); // Can this property on $obj be read from 
global scope?
$rProp->isReadable($obj, Foo::class); // Can this property on $obj be read from 
code inside class Foo?

$rProp->isWriteable($obj); // Can this property on object $obj be written from 
the calling scope?
$rProp->isWriteable($obj, 'static'); // Same as previous.
$rProp->isWriteable($obj, null); // Can this property on object $obj be written 
from global scope?
$rProp->isWriteable($obj, Foo::class); // Can this property on object $obj be 
written from code inside class Foo?

cf: https://github.com/php/php-src/pull/16209

(The use of null to indicate global scope is borrowed from Closure::bind(), 
which does the same.)

These methods do runtime analysis to see if a property should be 
readable/writeable.  Specifically:

isReadable()
* Checks that the property is readable from the passed scope
* Checks that the property is initialized (i.e. not typed and never written to)
* Checks that the property is not virtual or has a get hook
isWritable()
* Checks that the property is writable (respecting symmetric and asymmetric 
properties) from the passed scope
* Checks that the property is not readonly, is not yet initialized, or is 
reinitializable (__clone)
* Checks that the property is not virtual or has a set hook

Of note, this does not absolutely guarantee that a read/write will succeed.  
There's at least two exceptions: One, some PHP built-in classes have 
effectively immutable properties but do not use `readonly` or `private(set)`.  
Those would not be detected here, until and unless they are updated to use the 
now-available mechanisms.  (See, eg: 
https://github.com/php/php-src/issues/15309)  The other is that a get or set 
hook may throw an exception under various circumstances.  There is no way to 
evaluate that via reflection, so it's a gap that will necessarily always be 
there.

Whether those methods are OK to add in the RC phase or if they should be left 
to early 8.5, and if they would need a formal RFC, is up to the RMs to decide. 
RMs, what is your preference?

--Larry Garfield


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-09 Thread Larry Garfield
On Tue, Oct 8, 2024, at 8:48 PM, Mike Schinkel wrote:
>> On Oct 7, 2024, at 7:31 PM, Jim Winstead  wrote:
>> 
>> What is currently blocking content that at least one unpaid volunteer* wants 
>> to contribute in a way that leverages the existing technical infrastructure 
>> is that there is vague, unwritten policy that we don't mention third-party 
>> tools in the PHP documentation, except for all of the third-party tools that 
>> we already mention in the PHP documentation.
>
> I am totally with you on this, and I apologize on my part if anything 
> about what I said made people view it as an either-or proposition. 
>
> Instead, I intended comments were intended to be viewed as "Yes, and..."

*snip*

At this time, we're not looking for yes-ands in this thread.  Please stop 
dragging it off topic into your own pet ideas.  If you really want to push 
them, start new threads for them and leave this one alone.

--Larry Garfield


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-06 Thread Larry Garfield
On Sun, Oct 6, 2024, at 2:33 PM, Mike Schinkel wrote:

>> On Oct 5, 2024, at 10:25 PM, Larry Garfield  wrote:
>> 
>> A number of people are concerned that if we use any of the "Big Names", it 
>> would be interpreted as an endorsement of that project.  Eg, if we rebuilt 
>> the main website using Laravel, the Symfony folks would feel slighted.  If 
>> we used Symfony, the Laravel folks would get rather cross.  If we used Yii, 
>> the Slim folks would get upset.  If we used Drupal, we'd get constant "well 
>> why not Wordpress?" questions.  Etc.
>
> OR, we could change the current model and consider and another approach.
>
> Instead of maintaining a website based on 1980s[1] technology which can 
> give newer developers who are interested in modern developer tools the 
> opinion that PHP is not for them, PHP could move to a model for its 
> website where it embraces "Big names" and does so on merit.

*snip*

While I am sympathetic to the idea of "if you want professional work done, just 
hire a professional," that is also vastly off topic for what we're discussing 
right now.  The scope at the moment is much more "can we *please* tell people 
to use Composer?  Can we *please* use PHPUnit for writing PhD and not feel 
guilty about it?"  It's much more pedestrian and practical for the time being.

--Larry Garfield


Re: [PHP-DEV] [RFC] [Discussion] Add get_declared_enums() function

2024-10-06 Thread Larry Garfield
On Sun, Oct 6, 2024, at 2:25 AM, Juliette Reinders Folmer wrote:

> I can imagine combining the alternative approach via 
> get_declared_symbols() with a new symbol_exists() function like you 
> suggest above (with a similar slow path to deprecate and remove the old 
> functions).
>
> On the plus side, the alternative approach makes for much more 
> versatile functionality. In a number of the cases I looked at, the 
> results from various get_declared_*() functions are combined before 
> further processing, so having a `get-declared_symbols()` function would 
> allow for simplifying that code. The same can be said for the 
> *_exists() functions.

FWIW, I'd love to have get_declared_symbols() and symbol_exists() functions, 
regardless of what we do with enums in particular.  That's arguably a topic for 
another RFC, though.  (And debatable if functions would count as symbols, but 
again, topic for another time.)

--Larry Garfield


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-06 Thread Larry Garfield
On Sat, Oct 5, 2024, at 11:27 PM, Stephen Reay wrote:

>> A number of people are concerned that if we use any of the "Big Names", it 
>> would be interpreted as an endorsement of that project.  Eg, if we rebuilt 
>> the main website using Laravel, the Symfony folks would feel slighted.  If 
>> we used Symfony, the Laravel folks would get rather cross.  If we used Yii, 
>> the Slim folks would get upset.  If we used Drupal, we'd get constant "well 
>> why not Wordpress?" questions.  Etc.
>> 
>> While I feel that concern is sometimes over-blown, I do believe it is valid. 
>>  Notably, the "big name communities" tend to also be complete, integrated 
>> solutions, and those also tend to be where there's more active competition.  
>> Eg, there's only one meaningful Yaml implementation the market, and two UUID 
>> libraries worth mentioning.  But there's literally dozens of "frameworks" or 
>> "CMSes" to get mad at us.
>> 
>> So banning "full" frameworks is my attempt at steering clear of the 
>> appearance of that kind of favoritism.  Showing favoritism for Composer or 
>> Xdebug is, well, there's no competition to complain.  PHPUnit is technically 
>> not the only testing framework on the market, but it has north of 90% share 
>> (and is used internally by some of the few others).  But showing favoritism 
>> between Drupal, Wordpress, TYPO3, Concrete5, and Joomla gets a lot dicier.
>> 
>> A full framework also makes maintenance potentially more challenging, as we 
>> it's a much larger external moving target than a UUID library that we could 
>> easily fork in a worst case scenario.
>> 
>> So... I don't really have a solid, clear definition of what constitutes a 
>> "full framework", because in the market, there isn't one.  I'm sure someone 
>> could make a compelling argument that Slim isn't a full framework, for 
>> instance, although I don't think I'd agree with it.
>> 
>> It is inherently squishy, which is why these are intended as heuristics, not 
>> strict rules, and when it's unclear we can bring it to a vote via RFC, case 
>> by case.
>> 
>> I'm open to better ways to define what "full" means here if anyone has 
>> suggestions.
>> 
>> --Larry Garfield
>> 
>
> Hi Larry,
>
> Right I understand the motivation, it's just the phrasing that I think 
> needs to be clarified.
>
> From what you've said (which is kind of what I imagined you probably 
> meant) I think it just needs to be clarified that the "full 
> application" exclusion is about *web* applications, and doesn't 
> applying to command line tooling/utilities.
>
> Cheers
>
> Stephen

Valid point.  I've added another definition, and used it throughout:

 Libraries refers to existing third party code packages or tools, either C 
extensions or PHP code, maintained by someone other than the PHP Internals 
team. It also includes command line utilities used primarily by a developer. It 
may also refer to non-profit PHP ecosystem organizations, such as the PHP 
Foundation or PHP-FIG.

Web Application refers to a “full” web framework that provides end-to-end web 
application capabilities, or an installable complete application. It does not 
refer to command line utilities used primarily by developers building 
applications. 

(Libraries are OK, Web Applications are mostly not, except in marketing where 
we can mention them as long as we don't play favorites.)

--Larry Garfield


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-05 Thread Larry Garfield
On Sat, Oct 5, 2024, at 12:30 PM, Stephen Reay wrote:
>> On 3 Oct 2024, at 01:48, Larry Garfield  wrote:
>> 
>> Since Jim's RFC proposal was criticized for being too vague, I hereby offer 
>> a somewhat more prescriptive policy proposal on using 3rd party code.  (With 
>> JIm's blessing.)  It's still more heuristics than rules, but I think that's 
>> the right approach generally.  It also includes a voting mechanism to 
>> resolve edge cases when they come up.
>> 
>> I'm sure we'll bikeshed it to death, but please keep an open mind about the 
>> concept in the first place.  PHP is more than just php-src, and that's a 
>> good thing.  We need to catch up with that reality, while at the same time 
>> maintaining a reasonable neutrality about projects Internals doesn't manage 
>> directly.
>> 
>> https://wiki.php.net/rfc/third-party-code
>> 
>> *Puts on trusty flame-retardant suit*
>> 
>> -- 
>>  Larry Garfield
>>  la...@garfieldtech.com
>> 
>
> Hi Larry,
>
> Can you expand a bit more on this item from the exclusion list?
>
>> The library is a “full” application or framework.
> To me that would mean anything that can be executed itself (be it a web 
> app, a command like tool or daemon, etc.
>
> But then you specifically say Composer and PHPUnit and Psalm and 
> PHPstan are explicitly allowed... aren't all of them "full" 
> applications, because  they can be executed in and of themselves.
>
> So, can you perhaps define what you mean by "full application" a little 
> more clearly?
>
> Cheers
>
> Stephen

A number of people are concerned that if we use any of the "Big Names", it 
would be interpreted as an endorsement of that project.  Eg, if we rebuilt the 
main website using Laravel, the Symfony folks would feel slighted.  If we used 
Symfony, the Laravel folks would get rather cross.  If we used Yii, the Slim 
folks would get upset.  If we used Drupal, we'd get constant "well why not 
Wordpress?" questions.  Etc.

While I feel that concern is sometimes over-blown, I do believe it is valid.  
Notably, the "big name communities" tend to also be complete, integrated 
solutions, and those also tend to be where there's more active competition.  
Eg, there's only one meaningful Yaml implementation the market, and two UUID 
libraries worth mentioning.  But there's literally dozens of "frameworks" or 
"CMSes" to get mad at us.

So banning "full" frameworks is my attempt at steering clear of the appearance 
of that kind of favoritism.  Showing favoritism for Composer or Xdebug is, 
well, there's no competition to complain.  PHPUnit is technically not the only 
testing framework on the market, but it has north of 90% share (and is used 
internally by some of the few others).  But showing favoritism between Drupal, 
Wordpress, TYPO3, Concrete5, and Joomla gets a lot dicier.

A full framework also makes maintenance potentially more challenging, as we 
it's a much larger external moving target than a UUID library that we could 
easily fork in a worst case scenario.

So... I don't really have a solid, clear definition of what constitutes a "full 
framework", because in the market, there isn't one.  I'm sure someone could 
make a compelling argument that Slim isn't a full framework, for instance, 
although I don't think I'd agree with it.

It is inherently squishy, which is why these are intended as heuristics, not 
strict rules, and when it's unclear we can bring it to a vote via RFC, case by 
case.

I'm open to better ways to define what "full" means here if anyone has 
suggestions.

--Larry Garfield


Re: [PHP-DEV] [RFC] Policy on 3rd party code

2024-10-04 Thread Larry Garfield
On Fri, Oct 4, 2024, at 6:22 AM, Derick Rethans wrote:
> On Wed, 2 Oct 2024, Larry Garfield wrote:
>
>> Since Jim's RFC proposal was criticized for being too vague, I hereby 
>> offer a somewhat more prescriptive policy proposal on using 3rd party 
>> code.  (With JIm's blessing.)  It's still more heuristics than rules, 
>> but I think that's the right approach generally.  It also includes a 
>> voting mechanism to resolve edge cases when they come up.
>> 
>> I'm sure we'll bikeshed it to death, but please keep an open mind 
>> about the concept in the first place.  PHP is more than just php-src, 
>> and that's a good thing.  We need to catch up with that reality, while 
>> at the same time maintaining a reasonable neutrality about projects 
>> Internals doesn't manage directly.
>> 
>> https://wiki.php.net/rfc/third-party-code
>> 
>> *Puts on trusty flame-retardant suit*
>
> | The following packages are explicitly approved for use by this RFC, as 
> | they meet all of the criteria above.
> | 
> | - Xdebug
>
> That's not strictly true, as it doesn't have an "Approved License". It's 
> a nitpick, but Xdebug has "The Xdebug License" 
> (https://github.com/xdebug/xdebug/blob/master/LICENSE), which is the PHP 
> License 3.01, but with s/PHP/Xdebug.
>
> I've been wanting to change that for ages, but it requires approval from 
> all contributors, and that's not going to happen easily.
>
> cheers,
> Derick

Drat.

I suppose we could list that as an exception, like Docuwiki?  The design is 
"RFC wins over heuristic", so if people vote to approve its mention, subtleties 
in the license don't matter.

--Larry Garfield


[PHP-DEV] [RFC] Policy on 3rd party code

2024-10-02 Thread Larry Garfield
Since Jim's RFC proposal was criticized for being too vague, I hereby offer a 
somewhat more prescriptive policy proposal on using 3rd party code.  (With 
JIm's blessing.)  It's still more heuristics than rules, but I think that's the 
right approach generally.  It also includes a voting mechanism to resolve edge 
cases when they come up.

I'm sure we'll bikeshed it to death, but please keep an open mind about the 
concept in the first place.  PHP is more than just php-src, and that's a good 
thing.  We need to catch up with that reality, while at the same time 
maintaining a reasonable neutrality about projects Internals doesn't manage 
directly.

https://wiki.php.net/rfc/third-party-code

*Puts on trusty flame-retardant suit*

-- 
  Larry Garfield
  la...@garfieldtech.com


Re: [PHP-DEV] [RFC] [Discussion] Add get_declared_enums() function

2024-10-02 Thread Larry Garfield
On Wed, Oct 2, 2024, at 7:27 AM, Alexandru Pătrănescu wrote:

> I think my view comes from when I initially dug (15+ years ago) into 
> what an enum in Java is, and learned that it is just a syntactic sugar, 
> and a final class would be generated implementing `Comparable` and 
> extending an abstract class `Enum`.
> 
> And I think in PHP that could be a similar view. And most of the 
> limitations we have are not impossible to create with a standard class.

That is roughly the way enums are implemented in several languages, including 
PHP.  

> I think in time we might get to remove some limitations.
> I, personally, don't agree with the `Stringable` related limitation.

This has been discussed numerous times already. Please don't bring it up here, 
it's not relevant to this thread.

> And also with the limitation on no state. In Java this is the simple 
> way to create a singleton: an enum with one case; and we can't have 
> this in PHP.

That is what we mean by ADTs or Tagged Unions (various names for the same 
thing), and it's something Ilija and I have on the roadmap.  It's been on the 
roadmap since the first enum release, but we deliberately punted it for later 
to keep the initial RFC manageable.  It's also dependent on the pattern 
matching RFC, which hopefully we'll be able to bring up for discussion for 8.5.

> If we remove the limitations, should we reclassify at that point enums 
> as classes?

Enums already are classes.  I don't know what reclassification you're talking 
about.  The RFC is about adding a "get me a list of only those classes that are 
enums" function to PHP.  Changing how Enums behave or are implemented is wildly 
out of scope.

--Larry Garfield


Re: [PHP-DEV] Protected destructors

2024-10-01 Thread Larry Garfield
On Tue, Oct 1, 2024, at 2:06 PM, Rowan Tommins [IMSoP] wrote:
> On Tue, 1 Oct 2024, at 19:29, Larry Garfield wrote:
>> I would have said with() would be neat in PHP. :-)
>
> I have been considering for a while proposing Context Managers 
> [Python's with(), not to be confused with VisualBasic & JavaScript 
> unrelated feature with the same keyword].
>
> My primary example use case is safe database transactions, which I've 
> seen implemented in PHP in two ways:
>
> 1) Callback style, where the code to run in a transaction has to be 
> wrapped in a function, usually an anonymous closure. This is often 
> cited as a use case for implicit capture in closures, but even with 
> that it adds a layer of indirection, and changes the meaning of 
> "return" and "yield" inside the wrapped block.
>
> 2) "Resource Acquisition Is Initialization" style, where the destructor 
> rolls back the transaction if it hasn't been committed or rolled back 
> manually. This requires fewer changes to the wrapped code, but as 
> Arnaud points out, it's not 100% reliable / predictable in PHP, due to 
> details of the GC.
>
> Context Managers present a third option, where the code in the 
> transaction remains a normal sequence of statements, but there is a 
> more explicit guarantee about what will happen when the with{} block is 
> exited. The Python design document has interesting background on what 
> they included and excluded: https://peps.python.org/pep-0343/
>
> C#'s "using statement" is similar, but explicitly designed for ensuring 
> the correct "disposal" of an object rather than hooking entry to and 
> exit from a "context": 
> https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/statements/using
>
> Regards,
> -- 
> Rowan Tommins
> [IMSoP]

I would support having Python-esque context managers in PHP, and would be happy 
to help make it happen (if research and English writing would be useful to 
whoever is doing the implementation).

--Larry Garfield


Re: [PHP-DEV] [RFC] Change Directory class to behave like an opaque object

2024-10-01 Thread Larry Garfield
On Tue, Oct 1, 2024, at 4:02 PM, Nick Lockheart wrote:
>> 
>> Hey Nick,
>> 
>> Is this actually an issue though? \Directory would be a weird thing
>> to autoload. Most people tend to autoload specific namespaces. I
>> think it would be weird to autoload into the global namespace.
>> 
>> Maybe I am wrong, and that is why I ask.
>> 
>> — Rob
>
>
> In a situation where people aren't using namespaces at all, it would be
> normal to create your own class with a conflicting name, not knowing
> there was a built-in.

Which is why anyone creating a global namespace class, especially with a 
generic name like that, in 2024 is Doing PHP Wrong(tm).  The top-level 
namespace has been considered "reserved" (at least de facto, if perhaps not 
sung from the rooftops) for... 15 years?  Maybe not as long as there have been 
namespaces, but close to.

I have no strong opinions on this RFC as I've not paid close attention to it, 
but "we can't introduce an unnamespaced class, that's a BC break" is simply not 
true, and not consistent with how Internals and the stdlib are and have been 
developed.

--Larry Garfield


Re: [PHP-DEV] Protected destructors

2024-10-01 Thread Larry Garfield
On Tue, Oct 1, 2024, at 10:39 AM, K Sandvik wrote:
>> On Oct 1, 2024, at 5:12 AM, Arnaud Le Blanc  wrote:
>> 
>> Some use-cases of destructors could be replaced with patterns like
>> Python's with() [3], Java's try-with [4], or Go's defer [5].
>
> defer would be neat in PHP. --Kent

I would have said with() would be neat in PHP. :-)

--Larry Garfield


Re: [PHP-DEV] Zephir, and other tangents

2024-09-23 Thread Larry Garfield
On Mon, Sep 23, 2024, at 1:14 AM, Mike Schinkel wrote:

> I absolutely love that Larry called the question if it were technically 
> possible.  Maybe Larry will read this and can answer the question — 
> since he was heavily involved with Drupal — "Would Drupal be willing to 
> require or at least recommend a 3rd party WASM extension vs. a bundled 
> one here? 
> https://www.drupal.org/docs/getting-started/system-requirements/php-requirements#extensions";

To clarify since I was called out by name: I have had no involvement in Drupal 
in 7 years, have no interest in being involved in Drupal, would be perfectly 
happy to see the Drupal project fail and its leadership go bankrupt (for 
reasons that are entirely personal/social, not technical), and thus have no 
insight into what Drupal would or would not be willing to require.

--Larry Garfield


Re: [PHP-DEV] Zephir, and other tangents

2024-09-20 Thread Larry Garfield
On Fri, Sep 20, 2024, at 12:28 PM, Dennis Snell wrote:

> I’m not sure why you’re singling out Automattic, since nobody from 
> Automattic started this thread or requested other people provide 
> unfunded volunteer work, or why you’re expecting a single corporate 
> entity to fully fund long-term planned features in the language. Is 
> that how PHP normally grows? I’m not familiar with the process.
>
> My goal in sharing here is to help better represent my own perspective 
> of WordPress’ needs based on what I’ve seen. It’s long been on my list 
> to propose a WASM RFC, but because I personally haven’t had the 
> priority available to get an implementation working I haven’t done so. 
> It’s my impression from the documentation that the purpose of these 
> email threads w.r.t. RFCs is to gather interest and input before any 
> RFC would be put together, to hold these discussions before anyone 
> commits any major time to it.

FWIW, I feel that an embedded Wasm bridge, with a good API, would be an 
excellent addition and way more useful than the crappy experience of FFI.

Logistical question, for those with more stdlib expertise: Since we have other 
extensions in php-src that only work if you install some other library as well 
(eg, curl), which distros pretty much take care of for us, would a small 
in-php-src extension that is just a thin wrapper for Wasmtime or similar be 
viable?  Not embedding Wasmtime into the php-src code, just the extension, and 
it's up to the user/distro to install both so that they work.  

(Note: I'm not asking if you think it's a good idea, just if it's physically 
possible/worth discussing.)

--Larry Garfield


Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again)

2024-09-17 Thread Larry Garfield
 return $new;
  }

  public function __invoke(mixed $arg): mixed {
foreach ($this->steps as $step) {
  $arg = $step($arg);
}
return $arg;
  }

  operator +(\Closure $other, OperandPosition $pos): self {
return match ($pos) {
  OperandPosition::LeftSide => self::fromArray([...$this->steps, $other]),
  OperandPosition::RightSide => self::fromArray([$other, ...$this->steps]),
};
  }
}

$fun = new Composed() 
  + someFunc(...) 
  + $obj->someMethod(...) 
  + fn(string $a) => $a . ' (archived)' 
  + strlen(...);

$fun($input);  // Calls each closure in turn.

Note that there are a half-dozen libraries in the wild that do something akin 
to this, just much more clumsily, including in Laravel.  The code above would 
be vastly simpler and easier to maintain and debug.

## Units

Others have mentioned this before, but to make clear what it could look like:

abstract readonly class MetricDistance implements MetricDistance {
  protected int $factor = 1;

  public function __construct(private int $length) {}

  public function +(MetricDistance $other, OperandPos $pos): self {
return new self(floor(($this->length * $this->factor + $other->length * 
$other->factor)/$this->factor));
  }

  public function -(MetricDistance $other, OperandPos $pos): self {
return match ($pos) {
  OperandPosition::LeftSide => new self(floor(($this->length * 
$this->factor - $other->length * $other->factor)/$this->factor)),
  OperandPosition::RightSide => new self(floor($other->length * 
$other->factor - $this->length * $this->factor)/$this->factor)),
};
  }

  public function __toString(): string {
return $this->length;
  }
}

readonly class Meters extends MetricDistance {
  protected int $factor = 1;
}

readonly class Kilometers extends MetricDistance {
  protected int $factor = 1000;
}

$m1 = new Meters(500);
$k1 = new Kilometers(3);
$m1 += $k1;
print $m1; // prints 3500

$m1 + 12; // Error.  12 what?

There's likely a bug in the above somewhere, but it's late and it still gets 
the point across for now.

(Side note: The previous RFC supported abstract operator declarations, but not 
declarations on interfaces.  That seems necessary for completeness.)

## Date and time

DateTimeImmutable and DateInterval already do this, and they're not "fancy 
math."



I consider all of the above to be reasonable, viable, and useful applications 
of operator overloading, none of which are fancy or esoteric math cases.  
Others may dislike them, stylistically.  That's a subjective question, so 
opinions can differ.  But the viability of the above cases is not disputable, 
so the claim that operator overloading is too niche to be worth it is, I would 
argue, demonstrably false.

--Larry Garfield


Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again)

2024-09-17 Thread Larry Garfield
On Tue, Sep 17, 2024, at 3:14 PM, Jordan LeDoux wrote:

>> I think it's absolutely possible - and desirable - to choose a philosophical 
>> position on that spectrum, and use it to drive design decisions. The choice 
>> of "__add" vs "operator+" is one such decision.
>> 
>
> Ah, I see. I suppose I never really entertained an idea like this 
> because in my mind it can't even handle non-trivial math, let alone the 
> sorts of things that people might want to use overloads for. Once you 
> get past arithmetic with real numbers into almost any other kind of 
> math, which operators are meaningful, and what they mean exactly, 
> begins to depend a lot on context. This is why I felt like even if we 
> were limiting the use cases to math projects, things like commutativity 
> should not necessarily be enforced.
>
> The line `$a + $b` and `$b + $a` are SUPPOSED to give different results 
> for certain types of math objects, for instance. The line `$a - $b` and 
> `$b - $a` more obviously give different results to most people, because 
> subtraction is not commutative even for real numbers.
>
> My personal opinion is that the RFC should not assume the overloads are 
> used in a particular domain (like real number arithmetic), and thus 
> should not attempt to enforce these kinds of behaviors. But, opinions 
> like this are actually what I was hoping to receive from this thread. 
> This could be the way forward that voters are more interested in, even 
> if it wouldn't be my own first preference as it will be highly limiting 
> to the applicable domains.

I'm not sure where exactly in this thread to put this, so I'm putting it here...

Rowan makes an interesting point regarding operators vs operations.  In 
particular, the way the <=> logic is defined, it is defining an operation: 
comparison.  Using it for anything other than ordering comparison is simply not 
viable, nor useful.  It's defining a custom implementation if a specific 
pre-existing action.

For all the other operators, the logic seems to be defined for an operator, the 
behavior of which is "whatever makes sense in your use case, idk."  That is, to 
use Rowan's distinction, a philosophically different approach.  Not a bad one, 
necessarily.  In fact, I think it's a very good one.

But, as they are different, perhaps that suggests that comparison should 
instead not be implemented as an operator overload per se, but as a named magic 
method.  The existing logic for it is, I think, fine, but it's a fair criticism 
that you're not defining "what happens for a method-ish named <=>", you're 
defining "how do objects compare."  So I think it would make sense to replace 
the <=> override with a `__compare(mixed $other): int`, which any class could 
implement to opt-in to ordering comparisons, and thus work with <, >, ==, <=>, 
etc.  (And, importantly, still keep the "specify the type(s) you want to be 
able to compare against" logic, already defined.)

A similar argument could probably be made for ==, though I've not fully thought 
through if I agree or not.  Again, I think the previously defined logic is 
fine.  It would be just changing the spelling from `operator ==(mixed $other): 
bool` to `public function __equals(mixed $other): bool`.  But that again better 
communicates that it is a core language behavior that is being overridden, 
rather than an arbitrarily defined symbol-function-thing with domain-specific 
meaning.

There was an RFC for a Comparable interface back in the stone age (2010), but 
it looks like it never went to a vote: https://wiki.php.net/rfc/comparable

Arguably, this would then make more sense as a stand-alone RFC that happens to 
reuse a lot of the existing code and logic defined for operator overloads, 
which are all still just as valid.

That does not apply to the arithmetic, bitwise, or logic operators.  Overriding 
+ or / for a specific domain is not the same, as you're not hooking into engine 
behavior the way <=> or == are.  For those, I'd prefer to stick to the 
current/previous implementation, with the `operator` keyword, for reasons I 
explained before.

Jordan, does that distinction make sense to you?

--Larry Garfield


Re: [PHP-DEV] Re: Which IDE do you recommend for php-src development?

2024-09-16 Thread Larry Garfield
On Mon, Sep 16, 2024, at 7:06 PM, Hans Henrik Bergan wrote:
> +1 for VSCode, I use it practically everywhere these days,
> HTML/Javascript/TypeScript/PHP/C/C++/Python/Lua, all on VSCode.
>
> On Mon, 16 Sept 2024 at 13:07, Barel  wrote:
>>
>> On Sat, 14 Sept 2024 at 23:44, Barel  wrote:
>>>
>>> Hi
>>>
>>> For C/C++ development I usually use CLion from Jetbrains but I tried to use 
>>> it with php-src and was unable to get it to work properly. CLion really 
>>> insists on using CMake and has only quite limited support for makefiles. 
>>> After trying to get it to work unsuccessfully I am ready to try something 
>>> else.
>>>
>>> So which IDE would you recommend for php-src development? I understand that 
>>> people probably have many different preferences but I wondered if there was 
>>> something that most php internals developers used. One important feature 
>>> would be to easily work with the project running on a docker container
>>>
>>> Thanks in advance!
>>>
>>> Carlos
>>
>>
>> Answering myself in case someone finds this useful in the future.
>>
>> Several people recommended VSCode so decided to give it a try. I found this 
>> guide which describes very well what you need to do to get VSCode working 
>> for a php-src project hosted in a docker container. Works brilliantly, I am 
>> able to work with the code in the container using all VSCode features, 
>> including debugging with GDB. Nice!
>>
>> https://bogomolov.tech/php-extension-development/


Please please someone capture the details of this thread somewhere on the wiki 
or php.net, or maybe even in the php-src repo itself.  We really need to have 
good "how to get from git clone to a working C debugger" instructions.

--Larry Garfield


Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again)

2024-09-16 Thread Larry Garfield
On Mon, Sep 16, 2024, at 2:47 AM, Jordan LeDoux wrote:
> On Sun, Sep 15, 2024 at 9:12 PM Larry Garfield  wrote:
>> 
>> The "multiply by -1 for <=>" bit I don't fully understand the point of.  The 
>> RFC tries to explain, but I don't quite grok it.
>> 
>
> I will perhaps respond with more detail to the rest of your message 
> later, but I wanted to address this specifically, because I also feel 
> that the original RFC I wrote didn't explain that well. The situation 
> this bit was referring to is as follows:
>
> You have an object Foo that implements an overload for the `<=>` 
> operator. The proposed signature for `<=>` was simply: 
>
> `operator <=>($other): int`
>
> This operator did not have an `OperandPosition` argument. The reason 
> for this was to prevent developers from creating situations where `5 > 
> $foo` is true and `5 < $foo` is true. Instead, internally it did the 
> same sort of reordering that the engine currently does. It calls the 
> implementation the developer defined, and then checks if the object 
> that the implementation was called from was on the right side of the 
> operator. If it was, then it multiplies the result of the user defined 
> overload by -1. Multiplying the result of the overload ONLY when the 
> overload is called for the right side is equivalent to flipping the 
> order. So `5 > $foo` is multiplied by -1 and then evaluated as if it 
> were `$foo < 5`. This is an edge case, but it was an important one in 
> my mind.
>
> It would be entirely unnecessary if we allowed the `<=>` overload to 
> know what position it was in, but that would enable lots of developer 
> mistakes in my mind for no real gain. Instead, developers should just 
> implement the overload as if the object assumes it will always be 
> called from the left side of the comparison.
>
> Jordan

OK, that makes a lot more sense.  Reading through the text of the RFC, I didn't 
catch that it only multiplied by -1 if the comparing object was on the right.  
The implementation is fine, but if you do for a second round, making that a bit 
clearer would be helpful.

--Larry Garfield


Re: [PHP-DEV] [Pre-RFC Discussion] User Defined Operator Overloads (again)

2024-09-15 Thread Larry Garfield
feel that there is ANY design, version, or implementation of 
> operator overloads possible that you would support and be in favor of, 
> regardless of whether it matches the approach taken previously? If so, 
> can you describe any of the core ideas you feel are most important?

I was fairly happy with the previous version, so proposing that as-is would 
have my vote.  I would probably oppose including arbitrary symbol overloading 
at this time.

To me, the most important factors are:

1. It's type-safe, and leverages the type system to "make invalid states 
unrepresentable" as much as possible.  (I'd put the rules around <=> into this 
category.)

2. It allows me to opt-in piecemeal to just those operators that make sense.

3. The performance overhead compared to using a method is minimal.

4. It is future-compatible with further language evolution, to the extent 
possible.  (The `operator` keyword helps here.)

I'd love to see this brought up again, and hope there is sufficient interest to 
do so.

--Larry Garfield


Re: [PHP-DEV] bikeshed: Typed Aliases

2024-09-13 Thread Larry Garfield
On Mon, Sep 9, 2024, at 4:35 PM, Rowan Tommins [IMSoP] wrote:
> On 09/09/2024 19:41, Mike Schinkel wrote:
>
>> Referencing prior art (e.g. Go) PHP could allow int literals — e.g. `1`, 
>> `47`, etc. — to be passed to typedefs derived from ints but require int 
>> variables to be typecast to the required type. Same for string literals. 
>
> That's an interesting compromise, worth considering.

I have concerns about this.  Mainly, it depends on what we would want a typeef 
to *do*.  Eg, if it's just an alternate name, then maybe.  If, however, 
typedefs allow other functionality -- such as validation, additional methods, 
etc. -- then primitive -> typeef is not a guaranteed total function.  Eg;

typedef UserId: string is /\s{3}-\s{4}/ {
  public function groupId(): string {
return substr($this, 3);
  }
}

Maybe that particular functionality makes sense to do, maybe not, that's a 
separate discussion.  My point for now is just that there are typedef 
approaches where auto-up-casting would be frequently invalid, and probably also 
designs where auto-down-casting would be invalid (or possibly valid).  For now, 
we should keep all options on the table until we decide which options we want 
to make impossible.

>> In Go you cannot add or subtract on a typedef without casting to the 
>> underlying type.  I would definitely prefer that to be relaxed, but only
>>  if it is relaxed via an explicit opt-in, e.g. something maybe like 
>> this:
>> 
>> typedef UserId: int operations: +, -, *, /;
>> typedef UserName: string operations: .; 

Not to go further down this rabbit hole than is necessary, but I would much 
rather see operator overloads adopted, along the lines of Jordan's previous 
RFC, and let typedefs implement that if them if sensible.

There's probably yet another research project to do here.  I'd volunteer, but I 
now have a newborn taking up most of my time. :-)

--Larry Garfield


Re: [PHP-DEV] bikeshed: Typed Aliases

2024-09-07 Thread Larry Garfield
On Sat, Sep 7, 2024, at 12:07 PM, Rowan Tommins [IMSoP] wrote:
> On 7 September 2024 17:23:13 BST, Davey Shafik  wrote:
>>
>>My point is that if you talk about type DEFs, you now have this feature where 
>>you can input one type and get something that encapsulates it, and it seems 
>>weird that enums would LOOK similar In type hint usage and function 
>>differently.
>
> Personally, I would prefer to go the other way: make typedefs, like 
> enums, something you explicitly construct / cast to, rather than 
> something that implicitly coerces any compatible value. 
>
> Like enums, I would want to use typedefs to prevent accidental mixing 
> of values (e.g. a name where a reference number was expected, or a size 
> in pixels where a size in centimetres was expected). That use is 
> compromised if every scalar value is silently accepted for any matching 
> typedef.
>
> Regards,
> Rowan Tommins
> [IMSoP]

There's a couple of different use cases floating around close to each other 
here.

One is a type *alias*, which is just "a way to type less."

The other is a type *def*, which creates a new for-reals type that you can 
check at runtime.

They are closely related, but serve different purposes.  While an alias could 
make sense file-local or app-wide, in practice a def only makes sense app-wide.

Whether we want to have one or the other or both is a subjective question.  
Personally I'd be fine with both, as I see them serving different purposes.

eg:

typealias Foo: Bar|Baz;

Foo is now a compile time copy-paste for Bar|Baz, meaning this is totally valid:

class A {
  public Foo $a;
}

class B {
  public Bar|Baz $a;
}

The other direction is:

typedef UserId: int;

UserID is now an object that consists of just an int, but can be type checked 
against.  What's unclear is if you can do other int-y things to them (add, 
subtract, etc.), or if it's really just a shorthand for

readonly class UserId {
  public function __construct(public int $value) {}
}

I could see an argument for either.  If we had operator overloads, I would 
absolutely go for the latter; make all of those other int-y things opt-in.  
Once we get pattern matching, as noted a few months ago, it could be quite 
powerful to allow patterns as a validation on a typedef of that sort.

typedef UserId: int is >0;

Though that opens up all kinds of interesting questions about a typedef based 
on another typedef, if that's a form of inheritance or not, etc.  Again, I'm 
not sure if Rob wants to go there or not, but it's a place my brain has gone 
before. :-)

We may want to focus just on aliases for now, but design them in such a way 
that they do not cause an issue for typedefs in the future.  (Eg, using the 
`typealias` keyword instead of just `type`.)

--Larry Garfield


Re: [PHP-DEV] bikeshed: Typed Aliases

2024-09-07 Thread Larry Garfield
On Fri, Sep 6, 2024, at 7:46 PM, Davey Shafik wrote:

> My main struggle with this is readability. As much as I want custom 
> types (and type aliases is a good chunk of the way there), the main 
> issue I have is understanding what the valid inputs are:
>
> function foo(Status $string): void { }
>
> How do I know that Status is a) not a class, b) that I can fulfill the 
> requirement with a string, and/or maybe any object with __toString(), 
> or maybe it’s ints? Or objects or enums?
>
> Even with file-local aliases (which I would definitely prefer to avoid) 
> we will most likely rely on developer tooling (e.g. IDEs and static 
> analyzers) to inform the developer what the right input types are.
>
> I would very much prefer to either go all in with an Enum-like (which 
> means that we can hang methods on to the value) or we need to 
> distinguish between type hints for class-likes and type hints for 
> not-class-likes (*Bar anyone?).
>
> Expanding on type-class-likes: within the type methods, $this->value 
> would refer to the original value, any operators would follow the 
> _same_ rules as either the original values type (e.g. $int = 4; $string 
>  = “foo”; $int . $string == “4foo", or call __toString() in all the 
> normal places for strings if defined).
>
>
> type Stringable: string|int {
>  public function __toString(): string
>  {
>   return (string) $this->value; // original value
>  }
>
>  // Add Stringable methods here
> }.

Methods on typedefs was the sort of "other stuff classes do" that I was trying 
to avoid getting into right now. :-)  Mainly because I can totally see how it's 
tempting, but also have no idea what it would mean from a type-theoretic 
perspective.  It would only make sense if we're talking type DEFs, not type 
ALIASes.  I'm not against that, and it could be fun to try and think through 
the type theoretical implications, but I don't think that's what Rob was going 
for so I didn't want to take that side quest just yet.  (Though if he's OK with 
it, I'm OK with it.)

> So, with that in mind… I’d also like to open up the ability for Enums 
> to be fulfilled by the backed value, that is:

This is

1. Off topic for type aliases.
2. Has been discussed numerous times before.  Enums are not equivalent to their 
backing value.  The backing value is a standardized-serialization value.  
Nothing more.  A string-backed enum is not a string, and a string is not a 
string-backed enum.  Trying to use an enum as transparently equivalent to its 
backing value is a categorical error and belies a misunderstanding of what 
Enums are.

cf: https://peakd.com/hive-168588/@crell/on-the-use-of-enums

--Larry Garfield


Re: [PHP-DEV] bikeshed: Typed Aliases

2024-09-07 Thread Larry Garfield
On Sat, Sep 7, 2024, at 7:42 AM, Mike Schinkel wrote:
>> On Sep 6, 2024, at 4:45 PM, Larry Garfield  wrote:
>> Aliases can then be used only in parameter, return, property, and instanceof 
>> types.  Extends and implements are out of scope entirely.
>
> Is there a strong technical reason why extends and implements should be 
> out of scope? 
>
> There is definite utility for this, to create a local alias in a 
> namespace that can be used throughout the namespace rather than having 
> to refer to the external namespace in many different places.

Because it quickly can produce nonsensical syntax.

class A {}
class B {}

typealias AB: A|B;

// This is logically nonsensical.
class C extends AB {}

While there are edge cases where that might be logical (if A and B are 
interfaces and &-ed together, then it's kinda sorta the same as C implements A, 
B), separating those out and allowing just that subset sounds like a lot of 
work for dubious gain, and introducing surprise inconsistency.  Better to just 
avoid that entirely.

--Larry Garfield


Re: [PHP-DEV] bikeshed: Typed Aliases

2024-09-06 Thread Larry Garfield
On Fri, Sep 6, 2024, at 6:27 PM, Rob Landers wrote:

>> I suspect there's also other edge case bits to worry about, particularly if 
>> trying to combine a complex alias with a complex type, which could lead to 
>> violating the DNF rule.  For example:
>
> Oh, DNF is the bane of my existence with this RFC—I don't want to mess 
> this up. I'll see you at the end of the example, though.
>
>> 
>> typealias Foo: (Bar&Baz)|Beep;
>> 
>> use (Bar&Baz)|Beep as Foo;
>> 
>> function narf(Foo&Stringable $s) {}
>> 
>> With the compile time approach, that would expand to 
>> `(Bar&Baz)|Beep&Stringable`, which is not a valid type def.
>
> I can see how you arrived at this, but I think you may have missed a 
> step, since the entirety of Foo will be &'d with Stringable.
>
> Foo = (Bar & Baz) | Beep
>
> want: (Foo) & Stringable
>
> expand Foo: ((Bar & Baz) | Beep) & Stringable
>
> Which can be reduced to the following in proper DNF (at least, it 
> compiles—https://3v4l.org/0bMlP):
>
> (Beep & Stringable) | (Bar & Baz & Stringable)
>
> It's probably a good idea to update the RFC explaining how expansion works.

Woof.  We're not "fixingup" anyone's DNF elsewhere.  I cannot speak for 
everyone, but I'd be perfectly fine not doing any magic fixing for now, and 
then debating separately if we should do it more generally.  Just doing it for 
aliases doesn't seem like the best plan.

--Larry Garfield


Re: [PHP-DEV] bikeshed: Typed Aliases

2024-09-06 Thread Larry Garfield
s have all sorts of other things they 
do, but that is probably too complex scope creepy to get into here so I will 
not go further than that mention.

I suspect there's also other edge case bits to worry about, particularly if 
trying to combine a complex alias with a complex type, which could lead to 
violating the DNF rule.  For example:

typealias Foo: (Bar&Baz)|Beep;

use (Bar&Baz)|Beep as Foo;

function narf(Foo&Stringable $s) {}

With the compile time approach, that would expand to 
`(Bar&Baz)|Beep&Stringable`, which is not a valid type def.

With the runtime approach, I don't know if that could be handled gracefully or 
if it would still cause an error.

I'm not sure what the right solution is on this one, just pointing it out as a 
thing to resolve.

--Larry Garfield


Re: [PHP-DEV] [RFC] [Discussion] Add WHATWG compliant URL parsing API

2024-08-30 Thread Larry Garfield
On Mon, Aug 26, 2024, at 2:40 AM, Máté Kocsis wrote:
> Hi Ignace, Niels,
>
> Sorry for being silent for so long, I was working hard on the 
> implementation besides some summer activities :) I can say that I had
> really good progress in the last month and now I think (hope) that I 
> managed to address most of the concerns/suggestions people mentioned
> in this thread. To summarize the most important changes:

I'm not fluent enough in the different parsing styles to comment on the 
difference there.

I do have concerns about the class design, though.  Given the improvements to 
the language, the accessor methods offer zero benefit at all.  Public-read 
properties (readonly or otherwise) would be faster and offer no less of a 
guarantee.  If you want to allow someone to extend the class and provide some 
custom logic, use aviz instead of readonly and extenders can use hooks instead 
of the methods.  The getters don't offer any value anymore.

It took me a while to realize that, I think, the fromWhatWg() method is using 
an in/out parameter for error handling.  That is an insta-no on my part.  
in/out reference parameters make sense in C, maybe C++, and basically nowhere 
else.  I view them as a code smell everywhere they're used in PHP.  Better 
alternatives include exceptions or union returns.

It looks like you've removed the with*() methods.  Why?  That means it cannot 
be used as a builder mechanism, which is plenty valuable.  (Though could be an 
issue with query as a string vs array.)

The WhatWgError looks to me like it's begging to be an Enum.

I am confused by the new ini value.   It's for use in cases where you're NOT 
parsing the URL yourself, but relying on some other extension that does URL 
parsing internally as a side effect?  

As usual, I am not a fan of an ini setting, but I cannot think of a different 
alternative off hand.

--Larry Garfield


Re: [PHP-DEV] [Discussion] Implementing interfaces via traits

2024-08-30 Thread Larry Garfield
experience, it also introduces 
> complexity in how interfaces are used. To alleviate this, the `default` 
> keyword could be explicitly used to mark default methods, making it 
> easier for developers to understand and manage. For example:
>
> interface I1 {  
> `default public function foo(): int {  
> return \PHP_INT_MAX;  
> }  
> }
> `
> This explicit marking not only clarifies the intention behind the 
> method but also aids in distinguishing between regular and default 
> methods, simplifying the mental model required to work with interfaces.

How?  All I see here is another keyword I have to use.  It doesn't do anything 
extra for me as a consumer of that interface.  It doesn't add disambiguation to 
the language, either for the engine or human readers (as the presence of the 
body does that already).  It just gives me 8 more characters to type.  



> Just thinking out loud here - looking forward to hearing some thoughts.

My thought is we should just pass Default Interface Methods and be done with 
it. :-)

--Larry Garfield


Re: [PHP-DEV] [RFC] [Discussion] Using and Mentioning Third-party Packages in PHP Documentation and Web Projects

2024-08-28 Thread Larry Garfield
On Wed, Aug 28, 2024, at 2:51 AM, John Coggeshall wrote:
>> And that is how you will find that the "new" languages will "win". If we
>> don't promote how modern PHP Development works, then there will be more
>> "PHP, a fractal of bad design" articles to come for decades.
>> 
>> We *must* do better than this. It probably doesn't all need to be in the
>> documentation (doc-en), but it absolutely belongs on our website.
>> 
>
> Hear Hear Derick!! 
>
> I am not advocating that php.net put its finger on the scale in favor 
> of Laravel over others with this comment, but why php.net does not have 
> a documentation analog similar to how Laravel's documentation is set up 
> is beyond me. Useful installation instructions, sections on "How do I 
> do database stuff", "Security", "Filtering Data", "Installing third 
> party packages" etc... there are too many people who have embedded in 
> their brains that PHP is a badly designed language because we don't 
> teach or even advertise to people how to write good PHP code... as 
> others have mentioned as an example, the lack of even a mention of 
> composer on php.net is mind-blowing.
>
> As Derick said, back 20+ years ago PHP had amazing documentation for 
> the times -- miles ahead IMO than most open source projects. But the 
> world has moved on, developers want and need higher level documentation 
> that is more opinionated on not just the dry APIs available you might 
> use to connect to a database (for example), but how to properly connect 
> to a database. Back 20 years ago we had companies like Zend around who 
> devoted considerable resources to filling that gap for the community 
> (along with O'Reilly, etc.) but those entities are gone now and it is 
> up to the project to pick up the slack.
>
> I also think it's a mistake to get too caught up with the concept of 
> "endorsements" and people worrying that "oh gosh if php.net talks about 
> Laravel and Zend Framework then that means something bad for XYZ 
> framework" (pick your favoriate techs here). It's easily solved by 
> having a section on "Popular PHP Frameworks" that explains the concept 
> that PHP as a language doesn't embrace any particular framework, the 
> importance that you do generally want to embrace a framework to do 
> anything serious, and provide a list of popular ones that people 
> commonly turn to when building their apps. As for using a framework or 
> any other PHP-related tech in the project's codebases... I think we're 
> grossly overestimating how much weight that decision would carry with 
> the PHP community at large. Short of the PHP Project stating "X is the 
> official framework of PHP" (and especially if we say "We don't have an 
> official framework but here are good options that are very popular" 
> instead), the concern over the appearance of endorsements at this point 
> is really an invented issue rooted at least in part by historic 
> concerns that simply don't exist anymore.
>
> Coogle

What a couple of people have touched on is that that all we have right now is a 
Reference, which is only one kind of documentation.  The common zeitgeist these 
days says there's 4: https://diataxis.fr/

* Tutorials
* How-to guides
* Explanation
* Reference

We have a reference with gaps, and that's about it.  In practice, it will be 
functionally impossible to write a meaningful tutorial or how-to guide that 
never mentions anything but php-src-provided code.  Or at least the result 
would be sub-standard and doing the reader a disservice.

I don't think I'd support a list of "popular" frameworks, but mentioning 
Composer, Xdebug, and PHPUnit seems a requirement for a useful modern tutorial.

Admittedly, the docs team is very under-resourced right now and even the 
reference section has not-small holes, making maintaining even more types of 
documentation a potential challenge.  That's something the Foundation could 
possibly help with.  But that's not the topic at hand: The topic at hand is 
just "look, we should be able to mention Composer, Xdebug, and PHPUnit, OK?"  
On which I very much am in agreement.

--Larry Garfield


Re: [PHP-DEV] [RFC] [Discussion] Using and Mentioning Third-party Packages in PHP Documentation and Web Projects

2024-08-26 Thread Larry Garfield
On Mon, Aug 26, 2024, at 1:06 PM, Bob Weinand wrote:
> Hey Jim,
>
> On 26.8.2024 19:44:18, Jim Winstead wrote:
>> Hi,
>> 
>> Another RFC around process: 
>> https://wiki.php.net/rfc/web-and-doc-use-not-endorsement
>> 
>> Feedback would be appreciated. My intention is to start voting on September 
>> 9th unless there is still ongoing discussion.
>> 
>> Thanks.
>> 
>> Jim
>
>
> Thanks for bringing this up - I also suggest that we make this a binary 
> choice - either we adopt the proposed language or its opposite.
>
> I.e. a rejection of this should codify that statement in the negative.
>
>
>
> I do in particular reject the notion that we should document 
> third-party projects (usage for our infra is fine).
>
> The point of the PHP documentation is to describe the PHP runtime and 
> PECL extensions, which are both officially distributed through php.net.
>
> Anything not related to these does not belong into the manual, much 
> less into core documentation (like language/oop5 autoload.xml, to take 
> the example from https://github.com/php/doc-en/pull/3677/files).
>
>
>
> Changing this current unwritten rule is an invitation to implicitly 
> promote specific projects. The question is really where does it end? 
> Would we for example also mention PSRs as "widely followed guidelines 
> for interoperability" or something? It's a strong invitation for some 
> scope creep.
>
> As such I strongly condemn the idea of inclusion of this guideline.
>
>
>
> There are, ultimately, enough ways for people to learn about the PHP 
> ecosystem, the php.net documentation is none of them. If I go to 
> php.net, it's because I want to learn about the runtime, not its 
> ecosystem.

There's two separate questions here, I think, which should probably be 
addressed separately.

One is whether PHP.net code can *use* third party libraries (and be open about 
it).  Eg, would it be OK if Phd (the documentation compiler) used Composer for 
autoloading?  Used symfony/serializer or crell/serde in some way?  Used 
ramsey/uuid as an internal implementation detail?  Right now, the answer is de 
facto no, with some unclear exceptions.  I very firmly believe the answer 
should be a strong YES, or at least a "mostly", because doing otherwise 
hamstrings our ability to actually do the much-needed work of keeping the infra 
going.

The other is whether the documentation should recognize the rest of the 
ecosystem, or be "just" "things in the php org on Github."  I can definitely 
see the potential for scope creep here, and we should be mindful of that, but 
at the same time, having an official first-party "where to start with the 
ecosystem" place is extremely valuable!  Sending someone into PHP without 
recognizing the existence of Composer, which has basically no competition, is 
doing them a gross disservice.  Telling them about PHPUnit, which is 
overwhelmingly the most popular testing system but there are others (mostly 
built on top of it), I would lean yes but I can see the argument against.  
Recommending a template engine and listing just Twig and Blade but not Latte, 
for example, I can totally see where that becomes an issue and why we wouldn't 
want to do that.

My recommendation on the GitHub thread was, and still is, to make it a one-off 
vote in each case.  We had a one-off vote to recognize the Foundation on 
php.net and direct people to it.  I'd favor a one-off vote to allow talking 
about Composer/Packagist in the docs, and I would vote yes on it.  I'd probably 
vote no for a one-off vote to mention Twig.

PHP.net is the starting point for people in the PHP ecosystem, good or bad.  We 
don't need to take ownership of the whole ecosystem or documentation therein, 
but at least providing jumping off points to obvious sources 
(Composer/Packagist, phptherightway.com, etc.) would be doing a good service 
for our users.

--Larry Garfield


Re: [PHP-DEV] [RFC] Default expression

2024-08-26 Thread Larry Garfield
On Mon, Aug 26, 2024, at 6:36 AM, Jakob Givoni wrote:
> On Mon, Aug 26, 2024 at 12:49 PM Rowan Tommins [IMSoP] 
>  wrote:
>> On Mon, 26 Aug 2024, at 10:14, Bilge wrote:
>> > You're absolutely right, I would be interested to see any viable patch 
>> > that effectively implements a set of restrictions on how `default` may 
>> > be used. Requesting it be done at the parser level was not meant as a 
>> > gotcha, that's just how I (with my lack of experience) would have 
>> > approached it, but certainly trapping cases in the compiler is equally, 
>> > if not more valid and/or practical.
>> 
>> Another approach that occurred to me was in the executor: rather than 
>> evaluating to the default value immediately, "default" could resolve to a 
>> special value, essentially wrapping the reflection parameter info. Then when 
>> the function is actually called, it would be "unboxed" and the actual value 
>> fetched, but use in any other context would be a type error.
>> 
>> That would allow arbitrarily complex expressions to resolve to "default", 
>> but not perform any operations on it - a bit like propagating sqrt(-1) 
>> through an engineering formula where you know it will be cancelled out 
>> eventually.
>> 
>
> I 100% agree with this.
> "default" should not evaluate to a value before sending it as an 
> argument to the function or method.
> I understand from what the RFC author wrote a while ago that doing so 
> (evaluating to the actual default value using reflection) was the 
> easier and perhaps only viable way at the moment, but if that's the 
> case, I don't think the value of this RFC justifies doing something 
> like that, which to me seems like a hack.
>
> For those already expressing interest in being able to modify a binary 
> flag default parameter using this "trick", I still don't think it 
> justifies this RFC. In my opinion, functions that accept multiple 
> arbitrary options by compressing them into a binary flag have a badly 
> designed interface to begin with.
>
> So, my 10c: Make "default" a pure keyword / immutable value if 
> possible, or reconsider whether this feature is really worth the fuss.

The problem here is that `foo(default | ADDITIONAL_FLAG)` is so far the most 
compelling use case I've seen for this feature.  It's really one of only two I 
see myself possibly using, frankly.  So a limitation that would disallow that 
pattern would render the RFC almost useless.

The other compelling case would be the rare occasions where today you'd do 
something like this:

if ($user_provided_value) {
  foo($beep, $user_provided_value);
} else {
  foo($beep);
}

Which this RFC would allow to be collapsed into 

foo($beep, $user_provided_value ?: default);

So far those are the two use cases I can realistically see being helpful, and I 
acknowledge both are.  I recognize that "limiting the allowed expression 
structures arbitrarily is way harder than it sounds" is a valid argument as 
well.  At the same time, John C has offered some valid examples of cases where 
it would open up additional footguns, and we want to minimize those in general. 
 Those shouldn't be ignored, either.

At the moment I'm on the fence on this RFC.  I could go either way right now, 
so I'm watching to see how it develops.

--Larry Garfield


Re: [PHP-DEV] State of Generics and Collections

2024-08-25 Thread Larry Garfield
On Mon, Aug 19, 2024, at 12:08 PM, Derick Rethans wrote:
> Hi!
>
> Arnaud, Larry, and I have been working on an article describing the 
> state of generics and collections, and related "experiments".
>
> You can find this article on the PHP Foundation's Blog:
> https://thephp.foundation/blog/2024/08/19/state-of-generics-and-collections/
>
> cheers,
> Derick

To offer my own answers to the questions posed:

* I am against erased generics in the language, on the grounds that we already 
have them via docblocks and user-space tooling.  Pushing the entire ecosystem 
to move that existing syntax into another existing syntax that doesn't really 
offer the user anything new is not worth the effort or disruption it would 
cause.  Reified, enforced generics would be worth the hassle.

* Even if I could be convinced of erased generics as a stop-gap, I would want 
to see a official, supported, first-party support for validating them in the 
PHP linter command, or similar.  If that is surprisingly hard (it may be), then 
that would preclude erased generics for me.

* I am open to punting on type inference, or having only limited type inference 
for now (eg, leaving out union types).  Primarily, doing so would be 
forward-compatible.  Saying for now that you must type `foo(new A())` even 
if it's redundant doesn't preclude the language in the future allowing `foo(new 
A())` that figures out the generic type for you, and the explicit code would 
still continue to work indefinitely.  So this seems like an area that is safe 
to allow to grow in the future.

* I am also OK if there is a (small) performance hit for generic code, or for 
especially esoteric generic code.  Eg, if `new Foo` has a 1% performance hit 
vs `new Foo`, and `new Foo` has a 5% performance hit, I can live with 
that.  `new Foo` is a zany edge case anyway, so if that costs a bit more, 
I'm fine.  It would not be fine if adding generics made `new Foo` 30% slower, 
or if `new Foo` was 30% slower than the non-generic version.

* My sense at the moment is that in/out markers for variance would not be a 
blocker, so I'd prefer to include those from the start.  That's caveated on 
them not being a blocker; mainly I want to make sure we ensure they can be done 
without breaking things in the future, and I suspect the difference between 
"make sure we can do it" and "just do it" is small.  (I could be wrong on that, 
of course.)

* I feel the same about `class Foo` (Foo is generic over 
A, but A must implement the Something interface): We should make sure it's 
doable, and I suspect verifying that is the same as just doing it, so let's 
just do it.  But if we can verify but it will be a lot more work to do, then we 
could postpone that.

* I could deal with the custom collection syntax, but I'd much rather have real 
reified generics and then build on top of that.  That would be better for 
everyone.  I'm willing to wait for it.  (That gives me more time to design 
collections anyway. :-) )

--Larry Garfield


Re: [PHP-DEV] [RFC] Default expression

2024-08-25 Thread Larry Garfield
On Sun, Aug 25, 2024, at 10:29 AM, Bilge wrote:
> On 25/08/2024 14:35, Larry Garfield wrote: 
>> The approach here seems reasonable overall.  The mental model I have from 
>> the RFC is "yoink the default value out of the function, drop it into this 
>> expression embedded in the function call, and let the chips fall where they 
>> may."  Is that about accurate? Yes, as it happens. That is the approach we 
>> took, because the alternative would have been changing how values are sent 
>> to functions, which would have required a lot more changes to the engine 
>> with no clear benefit. Internally it literally calls the reflection API, but 
>> a low-level call, that elides the class instantiation and unnecessary hoops 
>> of the public interface that would just slow it down. My main holdup is the 
>> need.  I... can't recall ever having a situation where this is something I 
>> needed.  Some of the examples show valid use cases (eg, the "default plus 
>> this binary flag" example), but again, I've never actually run into that 
>> myself in practice. That's fine. Not everyone will have such a need, and of 
>> those that do, I'm willing to bet it will be rare or uncommon at best. But 
>> for those times it is needed, the frequency by which it is needed in no way 
>> diminishes its usefulness. I rarely use `goto` but that doesn't mean we 
>> shouldn't have the feature. My other concern is the list of supported 
>> expression types.  I understand how the implementation would naturally make 
>> all of those syntactically valid, but it seems many of them, if not most, 
>> are semantically nonsensical.  Eg, `default > 1` would take a presumably 
>> numeric default value and output a boolean, which should really never be 
>> type compatible with the function being called.  (A param type of int|bool 
>> is a code smell at best, and a fatal waiting to happen at worst.)  In 
>> practice, I think a majority of those expressions would be logically 
>> nonsensical, so I wonder if it would be better to only allow a few 
>> reasonable ones and block the others, to keep people from thinking 
>> nonsensical code would do something useful.


> Since you're not the only one raising this, I will address it, but just 
> to say there is no good reason, in my mind, to ever prohibit the 
> expressiveness. To quote Rob
>
>>I'm reasonably certain you can write nonsensical PHP without this feature. I 
>>don't think we should be the nanny of developers.

See, I approach it from an entirely different philosophical perspective:

To the extent possible, the language and compiler should prevent you from doing 
stupid things, or at least make doing stupid things harder.

This is the design philosophy behind, well, most good user interfaces.  It's 
why it's good that US and EU power outlets are different, because they run 
different voltages, and blindly plugging one into the other can cause damage or 
death.

This is the design philosophy behind all type systems: Make illogical or 
dangerous or "we know it can't work" code paths a compile error, or even 
impossible to express at all.

This is the design philosophy behind password_hash() and friends: The easy 
behavior is, 99% of the time, the right one, so doing the "right thing" is 
easy.  Doing something dumb (like explicitly setting password_hash() to use md5 
or something) may be possible, but it requires extra work to be dumb.

Good design makes the easy path the safe path.

Now, certainly, the definition of "stupid things" is subjective and squishy, 
and reasonable people can disagree on where that threshold is.  That's what a 
robust discussion is for, to figure out what qualifies as a "stupid thing" in 
this case.

Rob has shown some possible, hypothetical uses for some of the seemingly silly 
possible combinations, which may or may not carry weight with people.  But 
there are others that are still unjustified, so for now, I would still put 
"default != 5" into the "stupid things" category, for example.

As you've noted, this is already applicable only in some edge cases to begin 
with, so enabling edge cases of edge cases that only maybe make sense if you 
squint is very likely in the "stupid things" territory.

> I fully agree with that sentiment. It seems to be biting me that I went 
> to the trouble of listing out every permutation of what *expression* 
> means where perhaps this criticism would not have been levied at all 
> had I chosen not to do so. 

>From one RFC author to another, it's better to make that list explicitly and 
>let us collectively think through the logic of it than to be light on details 
>and not realize what will break until later.  We've had RFCs that did that, 
>and it caused problems.  The discussion can absolutely be frustrating (boy do 
>I know), but the language is better for it.  So I'm glad you did call it out 
>so we could have this discussion.

--Larry Garfield


Re: [PHP-DEV] [RFC] Default expression

2024-08-25 Thread Larry Garfield
On Sat, Aug 24, 2024, at 11:49 AM, Bilge wrote:
> Hi gang,
>
> New RFC just dropped: https://wiki.php.net/rfc/default_expression. I 
> think some of you might enjoy this one. Hit me with any feedback.
>
> This one already comes complete with working implementation that I've 
> been cooking for a little while. Considering I don't know C or PHP 
> internals, one might think implementing this feature would be 
> prohibitively difficult, but considering the amount of help and guidance 
> I received from Ilija, Bob and others, it would be truer to say it would 
> have been more difficult to fail! Huge thanks to them.
>
> Cheers,
> Bilge

I am still not fully sold on this, but I like it a lot better than the previous 
attempt at a default keyword.  It's good that you mention named arguments, as 
those do replace like 95% of the use cases for "put default here" in potential 
function calls, and the ones it doesn't, you call out explicitly as the 
justification for this RFC.

The approach here seems reasonable overall.  The mental model I have from the 
RFC is "yoink the default value out of the function, drop it into this 
expression embedded in the function call, and let the chips fall where they 
may."  Is that about accurate?

My main holdup is the need.  I... can't recall ever having a situation where 
this is something I needed.  Some of the examples show valid use cases (eg, the 
"default plus this binary flag" example), but again, I've never actually run 
into that myself in practice.

My other concern is the list of supported expression types.  I understand how 
the implementation would naturally make all of those syntactically valid, but 
it seems many of them, if not most, are semantically nonsensical.  Eg, `default 
> 1` would take a presumably numeric default value and output a boolean, which 
should really never be type compatible with the function being called.  (A 
param type of int|bool is a code smell at best, and a fatal waiting to happen 
at worst.)  In practice, I think a majority of those expressions would be 
logically nonsensical, so I wonder if it would be better to only allow a few 
reasonable ones and block the others, to keep people from thinking nonsensical 
code would do something useful.

--Larry Garfield


Re: [PHP-DEV] State of Generics and Collections

2024-08-23 Thread Larry Garfield
On Fri, Aug 23, 2024, at 1:38 PM, Rob Landers wrote:
> On Fri, Aug 23, 2024, at 20:27, Bruce Weirdan wrote:
>> On Fri, Aug 23, 2024 at 4:27 PM Larry Garfield  
>> wrote:
>>> Moving those definitions to attributes is certainly possible, though AFAIK 
>>> both the PHPStan and Psalm devs have expressed zero interest in it.
>>> Part of the challenge is that such an approach will either still involve 
>>> string parsing,
>> 
>> That's not really a challenge and would help somewhat with the current 
>> status quo where we have to guess where the type ends and the textual part 
>> of the comment begins. But it gets ugly for any type that has to include 
>> quotes (literal strings, array keys, etc). Technically one can use nowdocs, 
>> but it's not much better:  https://3v4l.org/4hpte
>>  
>>> or will involve a lot of deeply nested attribute classes. 
>> 
>> Yeah, that would look like Lisp's S-exprs, but much worse - which, in my 
>> opinion, would harm adoption.
>> 
>> All in all, in my opinion attribute-based solutions are less ergonomic than 
>> what we already have now in docblocks.
>> 
>> --
>>   Best regards,
>>   Bruce Weirdan 
>> mailto:weir...@gmail.com
>
> Thank you Larry for expressing some of the problems. Is there any 
> reason nesting has to be supported out of the gate? Think about type 
> hints. It started with some basic functionality and then grew over 
> time. There is no reason we have to have a new kitchen sink, oven, 
> dishwasher and stove when all we want is a new refrigerator. 
>
> — Rob

While I understand the temptation to "just do part of it", which comes up very 
often, I must reiterate once again that can backfire badly.  That is only 
sensible when:

1. There's a very clear picture to get from A->Z.
2. The implementation of C and D cannot interfere with the design or 
implementation of J or K.
3. The steps along the way offer clear self-contained benefits, such that if 
nothing else happens, it's still a "complete" system and a win.
4. The part being put off to later isn't just putting off the "hard part".

In practice, the level at which you get all four is quite coarse, much coarser 
than it seems most people on this list think.

Examples of where we have done that:

* Enums.  The initial Enum RFC is part one of at least 3 steps.  Step 2 is 
pattern matching, Step 3 is ADTs/tagged unions.  Those are still coming, but 
all three were spec'ed out in advance (1), we're fairly confident that the enum 
design will play nice with tagged unions (2), and enums step 1 has very clearly 
been hugely positive for the language (3, 4).

* Property hooks and aviz.  These were designed together.  They were originally 
a single planning document, way back in Nikita's original RFC.  After 
effectively doing all the design work of both together, we split up the 
implementations to make them easier.  Hooks was still a large RFC, but that was 
after we split things up.  That meant we had a clear picture of how the two 
would fit together (1, 2), either RFC on its own would have been beneficial to 
the language even if they're better together (2, 3), and both were substantial 
tasks in themselves (4).

* Gina's ongoing campaign to make PHP's type juggling have some passing 
resemblance to logic.

With generics, the syntax isn't the hard part.  The hard part is type 
inference, or accepting that generic-using code will just be extraordinarily 
verbose and clumsy.  There is (as I understand from Arnaud, who again can 
correct me if I'm wrong) not a huge amount of difference in effort between 
supporting only Foo and supporting Foo>.  The nesting isn't the 
hard part.  The hard part is not having to type Foo 4 times across 2 files 
every time you do something with generics.  If that can be resolved 
satisfactorily (and performantly), then the road map to reified generics is 
reasonably visible.

So for any intermediate generics implementation, it would need to have a very 
clear picture to get from that initial state to the final state (without the 
landmines that something like readonly gave us), we'd need to be confident 
we're not adding any landmines, each step would need to be useful in its own 
right, and it would have to be breaking up the "hard work" into reasonable 
chunks, not just punting the hard work for later.

Leaving out nested generics doesn't achieve those.

This is also why the dedicated collections work that Derick and I were looking 
into has been on pause, because adding a dedicated collections syntax, and then 
getting full reified generics later, would lead to a very ugly mess of 
inconsistency.  Better to wait and tr

Re: [PHP-DEV] State of Generics and Collections

2024-08-23 Thread Larry Garfield
On Fri, Aug 23, 2024, at 6:48 AM, Roman Pronskiy wrote:
> On Mon, Aug 19, 2024 at 7:11 PM Derick Rethans  wrote:
>>
>> Arnaud, Larry, and I have been working on an article describing the
>> state of generics and collections, and related "experiments".
>>
>> You can find this article on the PHP Foundation's Blog:
>> https://thephp.foundation/blog/2024/08/19/state-of-generics-and-collections/
>
> Thank you Arnaud, Derick, Larry for the article.
>
> Do you consider the path of not adding generics to the core at all? In
> fact, this path is implicitly taken during the last years. So maybe it
> makes sense to enforce that status quo?
>
> Potential steps:
> - Make the current status quo official by recognizing generics PHPDoc
> syntax as The Generics for PHP. Just adding a php.net manual page will
> do.
> - Recognize Composer as the official PHP tool. It's currently not
> mentioned on php.net at all.
> - Suggest using PHPStan or Psalm for generics and type checks.
> - Add an official specification for generics in the PHP manual to
> eliminate semantic variances between tools.
>
> This will keep the core simple and reduce the maintenance burden, not
> increase it.
>
> Moreover, it does not contradict with any other implementation
> mentioned in the article, should they happen. In fact, it could be a
> first baby-step for any of them.
>
> There is also an attempt to do generics via attributes –
> https://github.com/php-static-analysis/attributes – it could
> potentially be a better alternative of recognising “official” syntax,
> because unlike PHPDocs, attributes can be available in core and the
> syntax is checked.
>
> What do you folks think?
>
> -Roman

The null option is always an option, yes.  The thing to understand is that 
today, *we already have erased generics*, via PHPStan/Psalm.  That's one reason 
I am, personally, against erased generics in the language proper.  They don't 
really offer anything we don't have already.

Moving those definitions to attributes is certainly possible, though AFAIK both 
the PHPStan and Psalm devs have expressed zero interest in it.  Part of the 
challenge is that such an approach will either still involve string parsing, or 
will involve a lot of deeply nested attribute classes.  For instance, if today 
you'd write:

/**
 * @var array>
 */
protected array $foos;

(An entirely reasonable lookup table for some circumstances).  What would that 
be in attributes?

This would still need string parsing:

#[GenericType('string', 'Dict>')]

And a form that doesn't need string parsing:

#[DictType('string', new Dict('string', Foo::class))]

Which is getting kinda ugly fast.

All else equal, if we have to keep generics to implicit/erased, I'd favor going 
all the way to the latter (no-string-parsing attributes), and revising the 
syntax along the way.  (The current syntax used by SA tools is decidedly weird 
compared to most generic languages, making it hard to follow.)

If instead we used attributes for reified generics, then we have all the same 
challenges that make reified generics hard, just with a different syntax.  As I 
understand it (again, Arnaud is free to correct me), these two syntaxes would 
be equally straightforward to parse, but also equally complex to implement the 
runtime logic for:

#[DictType('string', new Dict('string', Foo::class))]
protected array $foo;

protected Dict> $foo;

The latter is more compact and typical of our sibling languages, but once the 
parser is done, all of the other challenges are the same.

As for making docblock generics "official", one, as I noted I hate the current 
syntax. :-)  Two, that seems unwise as long as PHP still has an option to 
remove comments/docblocks at compile time.  Even if it's not used much anymore, 
the option is still there, AFAIK.

And that's before we even run into the long-standing Internals aversion to even 
recognizing the existence of 3rd party tools for fear of "endorsing" anything.  
(With the inexplicable exception of Docuwiki.)

--Larry Garfield


Re: [PHP-DEV] State of Generics and Collections

2024-08-23 Thread Larry Garfield
On Fri, Aug 23, 2024, at 4:58 AM, Kévin Dunglas wrote:
> Thanks for sharing this research work.
>
> Instead of having to choose between fully reified generics and erased 
> type declarations, couldn't we have both? A new option in php.ini could 
> allow to enable the “erased” mode as a performance, production-oriented 
> optimization.
> In development, and on projects where performance isn't critical, types 
> (including generics) will be enforced at runtime, but users will have 
> the option of opting to disable these checks for production 
> environments.

Strictly speaking, yes, a disabled-types mode could be made regardless of what 
happens with generics.  But the downsides of that approach remain the same.  
I'm personally against type erasure generally, in large part because I don't 
know what it would break in terms of reflection, and in part because I *know* 
people will turn it off for dev, too, and then end up writing buggier code.

> If this is not possible, the inline caches presented in the article, 
> combined with “worker” runtimes such as FrankenPHP, Swoole, RoadRunner, 
> etc., could make the cost of enforcing generics negligible: 
> technically, types will be computed once and reused for many HTTP 
> requests (because they are handled by the same long-running PHP script 
> under the hood). As working runtimes already provide a significant 
> performance improvement over FPM, we could say that even if 
> non-performance-critical applications (most applications) will be a bit 
> slower because of the new checks,  people working on 
> performance-sensitive applications will have the opportunity to reduce 
> the cost of checks to virtually nothing by switching to a 
> performance-oriented runtime.

>From talking to Arnaud, the main issue here is the file-at-a-time compilation. 
> I'm not entirely clear if a persistent process would side-step that, with the 
>delayed resolution bits, or if those would have to be re-resolved each time.  
>(That's an Arnaud question.)  Another possibility that's been floated a bit, 
>tangentially, is allowing some kind of multi-file loading, which would allow 
>for a larger scope to be included at once as an opcache segment, and thus the 
>optimizer could do more.

That said, I suspect the benefits of the JIT when using a worker-mode runner 
would be larger anyway.

Also, speaking for me personally and no one else, I am still very much in favor 
of official steps to improve worker-mode options in php-src directly.  What 
form that takes I'm not sure, but I would very much favor making worker-mode a 
first-class citizen, or at least a one-and-a-half class citizen, rather than 
its current second-class status.

--Larry Garfield


Re: [PHP-DEV] State of Generics and Collections

2024-08-19 Thread Larry Garfield
On Mon, Aug 19, 2024, at 5:16 PM, Bob Weinand wrote:

> Regarding the Collections PR, I personally really don't like it:
>
>  • It implements something which would be trivial if we had reified 
> generics. If this ever gets merged, and generics happen later, it would 
> be probably outdated and quirkiness the language has to carry around.
>  • It's not powerful. But rather a quite limited implementation. No 
> overrides of the built-in methods possible. No custom operations ("I 
> want a dict where a specific property on the key is the actual unique 
> key", "I want a custom callback be executed for each modification"). 
> It's okay as a PoC, but far from a complete enough implementation.

I think we weren't that clear on that section, then.  The intent is that 
dedicated collection classes are, well, classes.  They can contain additional 
methods, and probably can override the parent methods; though the latter may 
have some trickiness if trying to access the internal data structure, which may 
or may not look array-ish.  (That's why it's just a PoC and we're asking for 
feedback if it's worth trying to investigate further.)

>  • It's a very specialized structure/syntax, not extensible for 
> userland at all. Some functionality like generic traits, where you'd 
> actually monomorphize the contained methods would be much more 
> flexible. E.g. class Articles { use Sequence; }. Much less 
> specialized syntax, much more extensible. And generic traits would be 
> doable, regardless of the rest of the generics investigation.
> In fact, generic traits (essentially statically replacing the generic 
> arguments at link-time) would be an useful feature which would remain 
> useful even if we had fully reified generics.
> I recognize that some functionality will need support of internal 
> zend_object_handlers. But that's not a blocker, we might provide some 
> default internal traits with PHP, enabling the internal class handlers.
> So to summarize, I would not continue on that path, but really invest 
> into monomorphizable generic traits instead.

Interesting.  I have no idea why Arnaud has mainly been investigating reified 
generics rather than monomorphized, but a monomorphized trait has potential, I 
suppose.  That naturally leads to the question of whether monomorphized 
interfaces would be possible, and I have no idea there.  (I still hold out hope 
that Levi will take another swing at interface-default-methods.)

Though this still wouldn't be a path to full generics, as you couldn't declare 
the inner type of an object at creation time, only code time.  Still, it sounds 
like an area worth considering.

--Larry Garfield


Re: [PHP-DEV] Should there be a `get_declared_enums()` function ?

2024-08-17 Thread Larry Garfield
On Fri, Aug 16, 2024, at 7:53 PM, Juliette Reinders Folmer wrote:
> On 16-8-2024 17:01, Ayesh Karunaratne wrote:
>> I went ahead and created PR https://github.com/php/php-src/pull/15443 along 
>> with tests, UPGRADE notice, etc. I think having a `get_declared_enums` 
>> function will be helpful. The implementation is simple and straightforward 
>> too. 
> Thanks for creating the PR Ayesh!
>
> I'm presuming it's too late for PHP 8.4, what with feature freeze 
> having come & gone this week.
>
> Based on the mostly supportive responses on the list, I wonder whether 
> an RFC is needed. If so, I'd be happy to create an initial draft (for 
> PHP 8.5).
>
> Smile,
> Juliette

I would prefer to have an RFC for this, even if it's short.  I'm not against 
it, I just think there's enough non-trivial questions (eg, impact on 
get_declared_classes()) that it warrants an RFC process/discussion.

--Larry Garfield


Re: [PHP-DEV] String enums & __toString()

2024-08-16 Thread Larry Garfield
On Fri, Aug 16, 2024, at 5:01 PM, Bilge wrote:
> On 16/08/2024 22:51, Gina P. Banyard wrote:
>> On Friday, 16 August 2024 at 22:01, Bilge  wrote:
>>> 
>>> 
>>> On Fri, 16 Aug 2024, 20:57 John Coggeshall,  wrote:
>>>> 
>>>> I'm not seeing an obvious upside to forbidding straight out `__toString()` 
>>> 
>>> I tend to agree, but Crell will drive by in a minute to drop some 
>>> philosophical nonsense about why we're all wrong :^)
>> 
>> If you could avoid disrespecting a contributor to the project, this would be 
>> appreciated.
> To be clear, I have nothing but love and respect for Larry.
>
> Cheers,
> Bilge

I appreciate that. :-)

To the original question, there's two reasons that __toString() was 
deliberately omitted from enums:

1. To discourage their use as "fancy strings".  Enums are their own type, 
independent of any other.  Making them usable as 95% strings partially defeats 
their purpose.

2. We still intend to add associated values to enums at some point (aka ADTs, 
aka tagged unions), and... we're not really sure yet if that will impact 
__toString() at all.  It may, it may not, we don't know.  So for now we're 
keeping our options open by disallowing __toString(), in case it ends up being 
needed for some ADT-related behavior in the future.

Point 2 will, hopefully, resolve itself in time once we can get ADT support in. 
 Point 1 will remain, however.

--Larry Garfield


Re: [PHP-DEV] [DISCUSSION] Class Constant Enums?

2024-08-16 Thread Larry Garfield
On Fri, Aug 16, 2024, at 1:31 PM, Arvids Godjuks wrote:

> Hello Larry,
> I feel obliged to remind about the 80/20 rule where the last 20% of 
> progress ends up being 80% of all the work. And from the discussion 
> it's already looking like there are some major questions and caveats 
> and engine problems that are gonna rear their ugly heads. I'm more in 
> favour starting with somewhat self-contained features and steadily work 
> to expand on them as people put the effort into it. The same as was 
> done with the type system. You can lay the proper foundation now, so 
> it's not blocking future expansion, but I really do not think full 
> embedded classes are gonna be a short endeavor - probably multiple 
> years if not half a decade going by prior record on features of this 
> size.
> -- 
>
> Arvīds Godjuks
> +371 26 851 664
> arvids.godj...@gmail.com
> Telegram: @psihius https://t.me/psihius

To go off on this tangent for a bit...

There's a difficult balancing act to be had here.  On the one hand, yes, design 
small and grow as you get feedback makes sense.  On the other hand, if you 
don't think through the whole plan, those early steps could end up being 
blockers for expansion, not a benefit.  The most obvious example, readonly was 
billed as a building block toward aviz.  It ended up making aviz harder, and it 
not passing the first time around.  It remains to be seen if first-class 
callables end up getting in the way of full PFA in the future.  The piecemeal 
way in which anonymous functions have been added over time has led to a lot of 
rough edges, and made discussions about smoothing them over harder (eg, the 
auto-closure-long-callable RFC).

When those first steps are effectively set in stone forever, rather than 
something you can adjust based on future feedback, "YAGNI" becomes an actively 
harmful approach to system design.

--Larry Garfield


Re: [PHP-DEV] [DISCUSSION] Class Constant Enums?

2024-08-16 Thread Larry Garfield
On Fri, Aug 16, 2024, at 6:35 AM, Alexandru Pătrănescu wrote:
> Hi Nick,
>> 
>> Is there any interest in having enums as class constants?
>> 
>> I'm often finding cases where I would like to have an enum inside of a
>> class, but don't want a free-floating enum that's basically like
>> another class.
>> 
> 
> .. 
> 
>> 
>> class SSHClient {
>> 
>>public const enum CommandResult
>>{
>>case Success;
>>case Failure;
>>case Unknown;
>>case Timeout;
>>}
>> 
>>// ...
>> }
>> 
>> 
>> // Usage:
>> 
>> SSHClient::CommandResult::Success
>
>
> I feel this topic could be maybe more broad and be called "nested 
> classes" that are already supported in multiple languages: Java, Swift, 
> Python, C#, C++, JavaScript, etc.
>
> The syntax you showed is usually identical with what other languages 
> use, except that probably the const is unnecessary.
> The nested class can have visibility as sometimes having it private 
> makes sense.
> Accessing it through `::` is probably fine, but a deeper look at the 
> grammar might be necessary.
> The nested class would have access to parent class private properties 
> and methods.
>
> I also mentioned this topic on the subject of defining a type in an 
> autoloader compatible way.
> And indeed, a type could also be defined nested in a class if we want 
> to support that as well.
>
> Now, this feature is not simple, and I think it needs proper 
> sponsorship from someone experienced with internals.
>
> Regards,
> Alex

I agree with Alexandru.  Since enums are 90% syntactic sugar over classes, 
"inner enums" would be 80% of the way to "inner classes".  And I would be in 
favor of inner classes. :-)  There's a lot of potential benefits there, but 
also a lot of edge cases to sort out regarding visibility, what is allowed to 
extend from what, etc.  But that would support inner enums as well.

Based on our sibling languages (Java, Kotlin, C#, etc.), the syntax would 
likely be something like:

class Outer
{
  private string $foo;

  public function __construct(protected Sort $order) {}

  enum Sort
  {
case Asc;
case Desc;
  }

  class Inner
  {
public function __construct(private string $baz) {}
  }

  private class HIdden
  {
public function __construct(private string $baz) {}
  }
}

Which enables:

$case = Outer::Sort::Asc;
$o = new Outer($case);

$i = new Outer::Inner('beep');

$h = new Outer::Hidden('beep'); // Visibility error

I would have to research to see if other languages did this, but one option 
would be to allow an inner class to extend an outer class even if it's final, 
which would essentially give us sealed classes for free:

final class Outer
{
  class InnerA extends Outer {}

  class InnerB extends Outer {}

  class InnerC extends Outer {}
}

// But this is still not OK:
class Sibling extends Outer {}

Note: I have no idea how difficult/complicated this would be, but I would be in 
favor of exploring it.

--Larry Garfield


Re: [PHP-DEV] Should there be a `get_declared_enums()` function ?

2024-08-15 Thread Larry Garfield
On Wed, Aug 14, 2024, at 8:51 PM, Juliette Reinders Folmer wrote:
> L.S.,
>
> I just noticed the following, which struck me as weird/inconsistent:
>
> There are four different OO structures in PHP:
> 1. Classes
> 2. Interfaces
> 3. Traits
> 4. Enums
>
> For all four, an `*_exists()` function is available, i.e. 
> `class_exists()`, `interface_exists()`, `trait_exists()` and 
> `enum_exists()` [2].
>
> But only for three out of the four, a `get_declared_*()` function 
> exists.
> There is `get_declared_classes()`, `get_declared_interfaces()`, 
> `get_declared_traits()`, but no `get_declared_enums()` [2].
>
> I'm aware that enums are internally considered classes and that 
> `get_declared_classes()` will retrieve them [1], but the same could be 
> said about interfaces and traits, yet they do have their own 
> `get_declared_*()` function.
>
> Should a `get_declared_enums()` function be added ?
> And should the `get_declared_classes()` function be adjusted to exclude enums 
> ?
>
> I did check the enum RFC [3], but I couldn't find any mention or 
> discussion about this in the RFC.
>
> Smile,
> Juliette
>
>
> 1: https://3v4l.org/0ub6I
> 2: https://www.php.net/manual/en/ref.classobj.php
> 3: https://wiki.php.net/rfc/enumerations

Conext: I can't remember the last time I used get_declared_classes() (thanks to 
autoloading and class_exists() it's a kinda pointless function), so when we 
were working on enums it never occurred to us to think about it.  It wasn't a 
deliberate decision to omit, as far as I recall.

I think I'd be open to adding it; my concern would be the overlap with 
get_declared_classes(), which as you note currently would include enums, and 
changing that is a BC break (even if a tiny one that I doubt would impact 
anyone).

--Larry Garfield


Re: [PHP-DEV][Discussion] Should All String Functions Become Multi-Byte Safe?

2024-08-11 Thread Larry Garfield
On Sun, Aug 11, 2024, at 10:50 AM, Nick Lockheart wrote:
> HTML 5 was adopted in 2014, over ten years ago. HTML 5 only supports
> the UTF-8 multi-byte character encoding.
>
> It seems like there's still a lot of string functions that assume that
> a character is a single byte, and these may actually work as expected
> when dealing with Latin characters, but may fail unexpectedly if a
> sequence is more than one byte.
>
> Are there any use cases for PHP where **single-byte** characters are
> the norm?
>
> It seems that if everything on the Internet is multi-byte encoded now,
> then all of the PHP string functions should be multi-byte safe.
>
>
> The WHATWG Encoding Standard:
>
> https://encoding.spec.whatwg.org/
>
> Also, according to Mozilla, "[The meta charset] attribute declares the
> document's character encoding. If the attribute is present, its value
> must be an ASCII case-insensitive match for the string "utf-8", because
> UTF-8 is the only valid encoding for HTML5 documents."
>
> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta#charset

Some background and history, for those not familiar...

After PHP 5.2, there was a huge effort to move PHP to using Unicode internally. 
 It was to be released as PHP 6.  Unfortunately, it ran into a whole host of 
problems, among them:

1. It tried to use UTF-16 internally, as there were good libraries for it but 
it was much much slower than was acceptable.
2. It required rewriting basically everything.
3. Trying to support two string variants at the same time (because binary 
strings are still very useful) in almost the same syntax turned out be, um, 
kinda hard.

After a number of years of work, it was eventually concluded that it was a dead 
end.  So the non-Unicode-related bits of what would have been PHP 6 got renamed 
to PHP 5.3 and released to much fanfare, kicking off the PHP Renaissance Era.

When PHP 5.6+1 was released, there was a vote to decide if it should be called 
6 or 7.  7 won, mainly on the grounds that a number of very stupid book 
publishers had released "PHP 6" books in anticipation of PHP 6's release that 
were now completely useless and misleading.  So we skipped 6 entirely, and PHP 
6-compatibility is a running joke among those who have been around a while.

Fortunately, the vast majority of single-byte strings are ASCII, and ASCII is, 
by design, a strict subset of UTF-8, so in practice the lack of native UTF-8 
strings rarely causes an issue.

Trying to introduce Unicode strings to the language now as a native type 
would... probably break just as much if not more.  If anything it's probably 
harder today than it was in 2008, because the engine and existing code to 
not-break has grown considerably.

A much better approach would be something like this RFC from Derick a few years 
ago:

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

If you need something today, then Symfony has a user-space approximation of it: 

https://symfony.com/doc/current/string.html

--Larry Garfield


Re: [PHP-DEV] [Vote] Asymmetric visibility v2

2024-08-10 Thread Larry Garfield
On Fri, Jul 26, 2024, at 1:25 PM, Larry Garfield wrote:
> Voting for Asymmetric Visibility is now open.
>
> https://wiki.php.net/rfc/asymmetric-visibility-v2
>
> The vote will end on 9 February, probably afternoonish in my timezone.

I have now closed the vote on this RFC.

The final result is 24 Yes, 7 No, for a total of 77.4% in favor.

The RFC has passed.  Thanks everyone for your participation and input.  Ilija 
will get the PR merged soonish.

--Larry Garfield


Re: [PHP-DEV] [RFC] [VOTE] Transform exit() from a language construct into a standard function

2024-08-09 Thread Larry Garfield
On Thu, Aug 8, 2024, at 9:10 AM, Andreas Heigl wrote:
> Hey Gina, hey all
>
> Am 08.08.24 um 15:44 schrieb Gina P. Banyard:
>> On Wednesday, 7 August 2024 at 17:07, Andreas Heigl  
>> wrote:
>>> Stupid question maybe, but are we voting on the RFC or on the patch?
>>>
>>> If the patch does not match what.the RFC proposes, then the patch has 
>>> a problem. That should IMO though not affect voting on an RFC.
>>>
>>> Or am I.missimg something?
>> 
>> In theory, it is the RFC idea.
>> In practice, a lot of the times it is the patch for complex features.
>> 
>> However, it is still within the purview of core developers to veto the 
>> implementation of an RFC.
>> Which could be the case here rather than voting against the RFC outright.
>
> I have no problem that core developers veto a certain implementation of 
> an RFC. I actually expect them to do so.
>
> But the vote should IMO *always and exclusively* be based on the RFC. 
> Not on the implementation. If the voting happens based on the 
> implementation due to the complexity of the features that means that the 
> RFC is not wel written and needs to be improved. Or the implementation 
> is problematic and needs to be vetoed by the core developers.

How exactly would voters veto an implementation if not through the RFC?  That's 
literally the only formal input mechanism they have, and previous attempts to 
add others have been soundly rejected.

As a historical note, the partial function application RFC was declined despite 
there being general consensus that the proposal was quite good and quite 
desireable.  The issue was that Nikita felt the implementation proposed with it 
was too fragile, and wasn't sure how to make it less fragile, so he voted No 
and several others followed suit.  I am fairly confident that if a less-fragile 
implementation could be found, it would pass handily.

So yes, RFCs have been rejected in the past on "implementation only."

--Larry Garfield


Re: [PHP-DEV] [RFC] [VOTE] Transform exit() from a language construct into a standard function

2024-08-05 Thread Larry Garfield
On Mon, Aug 5, 2024, at 6:04 AM, Derick Rethans wrote:
> On Tue, 30 Jul 2024, Christoph M. Becker wrote:
>
>> On 30.07.2024 at 11:49, Gina P. Banyard wrote:
>> 
>> > I have just opened the vote for the "Transform exit() from a 
>> > language construct into a standard function" RFC: 
>> > https://wiki.php.net/rfc/exit-as-function
>> >
>> > The vote will last for two weeks until the 13th of August 2024.
>> 
>> As userland PHP developer, I always regarded `exit` as a control flow 
>> instruction (quite similar to `break`), and as such I'm not really in 
>> favor of converting it to a proper function (especially since it is 
>> not, because the parantheses could be omitted).
>
> Xdebug uses exit for exactly that too. For control flow analysis. And I 
> also always have considered it to be a control flow instruction.
>
> I see no benefit in changing it to a function, especially because 
> there will never be a function "exit" from it, just only an "entry". 
> This breaks function execution symmetry (and causes issues with Xdebug 
> when I last tried to make it work with a development branch for this 
> RFC).
>
> As the RFC is scarce on mitigations for this, I am currently voting "no" 
> as I am unsure how certain features in Xdebug could remain working. I 
> have written to the list on other reasons before 
> (https://externals.io/message/123277#123450) without a conclusion.
>
> I'll consider changing it to yes if there is a commitment for addressing 
> these feature-maintaining-requirements to keep Xdebug working, either 
> through new APIs (think observer) or other mitigations.
>
> cheers,
> Derick

While I support language and engine cleanup, if this change causes issues for 
Xdebug that is a fairly significant problem.  For that reason I have shifted my 
Yes to a No for now.  Like Derick, I will switch it back to a Yes should the 
Xdebug issue be resolved to his satisfaction.  But "keep Xdebug working" is a 
rather mission-critical requirement for any RFC, as a practical matter.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-08-05 Thread Larry Garfield
On Mon, Aug 5, 2024, at 7:27 AM, Vincent de Lau wrote:
> From: Rob Landers  
> Sent: Sunday, July 21, 2024 11:21 AM
>
>> On Sat, Jul 20, 2024, at 23:51, Larry Garfield wrote:
>> > On Sat, Jul 20, 2024, at 7:22 AM, Rodrigo Vieira wrote:
>> > > Will the alternative syntax on hook not even be put to a vote?
>
>> > It was, a year and a half ago when Aviz was first proposed.  The 
>> > preference was split, but leaned toward the prefix-style syntax.  So we 
>> > went with that.  I don't think we'll ever get everyone to want the same 
>> > syntax, but we're using the one that was both somewhat more popular, and 
>> > (as discussed in the RFC) arguably superior.
>
>> > As the "comments in yield from" thread has shown, *any* even slight change 
>> > to PHP's syntax will require work from static analysis tools.  That's the 
>> > nature of the problem space, regardless of the syntax specifics.
>
>> Just to play devil’s advocate, it was also before we had property hooks who 
>> advertised itself as a way to “wrap and guard access to object properties” 
>> but we are simply ignoring their existence here.
>
> I'm very disappointed that this discussion was not concluded before the 
> vote was started. One of the main arguments for picking this syntax is 
> the research from two years ago, when hooks where not a thing. In my 
> opinion that makes that whole research obsolete in this new context. 
> I've asked to redo the research, but that was not acknowledged
>
> For the 'split visibility' concern, there has been some mentioning of 
> reviving the `var` keyword, allowing you to place all visibility in the 
> hook block.
>
> While I don't have the 'perfect' syntax in mind, I strongly believe 
> that this subject required a bit more investigation and discussion. My 
> only hope now is that the people voting take this into consideration, 
> especially as this is now being rushed into 8.4.

While hooks were not a feature when Aviz was first proposed, it was very clear 
at the time that they were coming, and the syntax was mostly already figured 
out, at least in broad strokes.  It's not like no one knew we'd be having {} 
after the property if hooks pass.  I would not call the results obsolete.  
Rather, I think what it shows is that there's no syntax that will satisfy 
everyone, so trying to find a syntax favored by everyone would just waste time 
and end in failure anyway.

I would hardly call this rushed; it was open for multiple months, and built on 
the previous discussion in 2023.  Lazy Objects, for instance, was first 
proposed a month after aviz, and started its vote on the same day.  (No shade 
on Lazy Objects; I'm happy to see that passing.)

--Larry Garfield


Re: [PHP-DEV] [Vote] Asymmetric visibility v2

2024-08-05 Thread Larry Garfield
On Mon, Aug 5, 2024, at 8:49 AM, Theodore Brown wrote:
> On Fri, July 26, 2024 at 12:25 Larry Garfield wrote:
>
>> Voting for Asymmetric Visibility is now open.
>>
>> https://wiki.php.net/rfc/asymmetric-visibility-v2
>
> Hi Larry and Ilija,
>
> Thank you for all your work on this RFC!
>
> One part that doesn't make sense to me is this sentence near the end in 
> the "Readonly is incompatible with inheritance" section:
>
>> With asymmetric visibility, the `readonly` usage here can be replaced with 
>> `protected protected(set)` or `readonly protected protected(set)`, avoiding 
>> the need to double-declare properties.
>
> `protected protected(set)` just removes readonly, and is the same as 
> `protected`, right? So couldn't such a change be done now without 
> asymmetric visibility?
>
> And the change to `protected protected(set) readonly` as shown in the 
> example also seems unnecessary, since earlier in the RFC it says that 
> readonly will be changed to imply `protected(set)` rather than 
> `private(set)`. So it seems that no change is needed to the abstract 
> class here - the properties can remain `protected readonly`, and the 
> implementation can be simplified since readonly properties will now 
> imply `protected(set)`.
>
> Or have I misunderstood something here?

I believe in this case you're correct.  That example was written early on, 
before we decided to expand readonly to protected(set) by default.  I didn't 
realize that needed to be updated as well.  Yes, in this case, the widening of 
readonly would also resolve that issue.  `protected protected(set)` would now 
be redundant, but not hurt anything, whereas `protected private(set)` would 
have an effect.  `public public(set) readonly` would also be legal (though I 
don't personally know why you'd do that, there's no inherent reason to make it 
illegal).

--Larry Garfield


Re: [PHP-DEV] [Vote] Property Hook performance improvements

2024-07-30 Thread Larry Garfield
On Mon, Jul 15, 2024, at 2:05 PM, Larry Garfield wrote:
> Hi all.  I have just opened the voting on the property hook 
> (performance) improvement RFC.
>
> https://wiki.php.net/rfc/hook_improvements
>
> With the readonly bits pushed out to later, this is probably the 
> shortest RFC I have ever written. :-)  Vote opens now, and will close 
> in 2 weeks on 29 July.

A day late but not a dollar short, I have closed the voting for the hook 
improvements RFC.  The final vote is 33 in favor, 0 against.  The RFC has 
passed.

Thanks everyone!

--Larry Garfield


Re: [PHP-DEV] [Vote] Asymmetric visibility v2

2024-07-26 Thread Larry Garfield
On Fri, Jul 26, 2024, at 6:54 PM, Bilge wrote:
>> Presumably the proposed PHP version is wrong?

No, this is still within the window to target 8.4.

--Larry Garfield


Re: [PHP-DEV] [Vote] Asymmetric visibility v2

2024-07-26 Thread Larry Garfield
On Fri, Jul 26, 2024, at 6:25 PM, Larry Garfield wrote:
> Voting for Asymmetric Visibility is now open.
>
> https://wiki.php.net/rfc/asymmetric-visibility-v2
>
> The vote will end on 9 February, probably afternoonish in my timezone.
>
> -- 
>   Larry Garfield
>   la...@garfieldtech.com

Sigh.  And of course I meant the voting will end on 9 AUGUST, aka, two weeks 
from today.  (No idea where that came from.)

--Larry Garfield


[PHP-DEV] [Vote] Asymmetric visibility v2

2024-07-26 Thread Larry Garfield
Voting for Asymmetric Visibility is now open.

https://wiki.php.net/rfc/asymmetric-visibility-v2

The vote will end on 9 February, probably afternoonish in my timezone.

-- 
  Larry Garfield
  la...@garfieldtech.com


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-07-26 Thread Larry Garfield
On Fri, Jul 26, 2024, at 12:58 PM, Rob Landers wrote:

>> And now that I see it spelled out more, I do agree that while it appears a 
>> bit more verbose, and this "(set)" looks odd at first, having all the 
>> visibility upfront is a lot clearer than having to read through the hooks to 
>> see what visibility applies.
>
> On a large property hook that potentially span hundreds of lines, I'd 
> rather only need to scroll up to the "set =>" to see how it is set vs. 
> going all the way back up to the property itself.

If someone has a property hook that is hundreds of lines long, their code is 
already crap and there's no hope for them.

--Larry Garfield


Re: [PHP-DEV] [RFC] [VOTE] Deprecations for PHP 8.4

2024-07-26 Thread Larry Garfield
On Fri, Jul 26, 2024, at 11:11 AM, Christoph M. Becker wrote:
> On 26.07.2024 at 12:03, Gina P. Banyard wrote:
>
>> Stephen Rees-Carter, a security expert that has performed countless security 
>> audits on Wordpress and Laravel websites, would like to disagree with the 
>> fact that it is not enough of a good reason. [1]
>> A warning on a documentation page is useless, as nobody is forced to read it.
>
> Right, but even a deprecation notice is likely to be ignored by those
> (either use the shut-up operator, or use hash("md5), or maybe a polyfill
> to support old PHP versions), so the deprecation wouldn't help in such
> cases.
>
> (I've recently seen a new release of a software which still uses
> <https://www.openwall.com/phpass/>.  Apparently, the notice to prefer
> the password_*() API has been ignored or overlooked.)
>
> On the other hand, I'm quite confident that a deprecation could be
> useful for some developers, who would at least reconsider the use of
> md5/sha1 hashes, but just have overlooked this; although some static
> analysis should report respective issues.  However, there is certainly
> code without any static analysis, where at least this discussion appears
> to be helpful, e.g. our php-sdk-binary-tools might reconsider their use
> of md5() and md5(uniqid())[2].
>
> Note that I'm not against these deprecations, but I'm also not strongly
> in favor.  I see valid arguments from both proponents and opponents.
>
>> [1] https://x.com/valorin/status/1816593881791860963
>
> [2] <https://github.com/php/php-sdk-binary-tools/issues/21>
>
> Cheers,
> Christoph

One thing to remind people about, the deprecations for md5(), sha1(), and 
uniqid() explicitly say they cannot be outright removed before PHP 10.  That's 
at least 6 years away.  That gives a loong time for documentation, 
tutorials, instructions, and code to be updated.

That long deprecation period is the reason why I was comfortable voting yes.  
This isn't something that would happen tomorrow.  It would be in at least two 
presidential elections from now.

--Larry Garfield


Re: [PHP-DEV] [RFC] Lazy Objects

2024-07-24 Thread Larry Garfield
On Thu, Jul 18, 2024, at 7:12 AM, Nicolas Grekas wrote:

>> Otherwise, I'm quite looking forward to this.
>
> 🤞

Another thought that occurred to me.  Given how lightweight it *looks* to be 
(may not actually be, but looks it), how much overhead would there be to having 
a compiled DI container that is lazy by default?  Just make everything lazy 
with a fairly standard initializer or factory, unless a specific case says you 
shouldn't.  That way you can use optional dependencies in a constructor pretty 
much at will with no overhead of needing to create a chain of dependencies as a 
result.

Would that be a bad idea for some reason, or would it actually work?

(This doesn't really affect my vote, more just a thought that came up.)

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-07-23 Thread Larry Garfield
On Mon, Jul 22, 2024, at 7:07 PM, Tim Düsterhus wrote:
> Hi
>
> On 7/20/24 03:14, Larry Garfield wrote:
>> Baring any new developments, we plan to start the vote early next week.
>
> I've went through the RFC once more. I have the following remarks:
>
>> For that reason, a private(set) property is automatically final and may not 
>> be redeclared at all.
>> 
>
> I assume that explicitly marking it as final is still allowed (just 
> redundant)?

Correct.  I have added a comment to that effect.

>> There is one caveat regarding virtual properties that have no set operation. 
>> If there is no set operation defined on a property, then it is nonsensical 
>> to specify a visibility for it. That case will trigger a compile error. For 
>> example:
>> 
>
> How does this interact with inheritance? Consider the following example:
>
>  class P {
>  public $answer { get => 42; }
>  }
>
>  class C extends P {
>  public protected(set) $answer { get => 42; set => 'dummy'; }
>  }
>
> This could be considered to be both narrowing the `set` visibility from 
> `public` to `protected` (which is unsound), but also widening it from 
> “never” to `protected` (which would be sound).

I checked with Ilija, and confirmed that it's the second.  I have updated the 
RFC accordingly to make that explicit.

>> as it's possible now for a property to be visible but not writeable. For the 
>> time being,
>
> I dislike the “for the time being” phrasing, because changing that would 
> effectively result in a breaking change, because the __set() may be 
> called in situations that were not anticipated. I would have preferred a 
> stronger phrasing that makes it clear that the RFC authors know what 
> they are talking about.
>
> Best regards
> Tim Düsterhus

I wordsmithed this a bit further.  We're not trying to be wishy-washy.  Rather, 
there are a couple of knock-on implications that are worth discussing that we 
consider off topic, but the approach we're taking does not preclude them.  
We're deliberately taking the conservative approach.  Adding a __set fallback 
in the future would not be a BC break, as it would be changing a hard error 
condition to a legal condition, which is something nearly all new features do.  
We don't think it's wise to do that, but if someone wanted to advocate for that 
in the future we're not precluding it.  If none of those further discussions 
happen, we still consider this behavior complete and acceptable.

--Larry Garfield


Re: [PHP-DEV] [RFC] [VOTE] Deprecations for PHP 8.4

2024-07-23 Thread Larry Garfield
On Tue, Jul 23, 2024, at 4:00 PM, Matthew Weier O'Phinney wrote:

>> However, a few people indicated a desire to have an explicit wildcard _ 
>> anyway, even if it's redundant, as it's a more common and standard approach 
>> in other languages.  We've indicated that we are open to making that an 
>> optional secondary vote in the pattern matching RFC if there's enough 
>> interest (it would be trivial), though I haven't bothered to add it to the 
>> RFC text yet.
>> 
>> Having _ available could also be used in other "wildcard" or "ignore this" 
>> cases, like exploding into a list assignment or similar, though I don't 
>> believe that has been fully explored.
>
> Can you provide examples of what that usage would look like? And the 
> question I have really is, does this actually _require_ using "_", or 
> could another token be used for such matches?

Hypothetical pattern matching example:

$foo is ['a' => int, 'b' => $b, 'c' => mixed];

That would assert that there's 3 keys.  "a" may be any integer (but only an 
integer), "b" can be anything and will be captured to a variable, and "c" must 
be defined but we don't care what it is.

The suggestion is to basically alias _ to "mixed" for pattern purposes:

$foo is ['a' => int, 'b' => $b, 'c' => _];

As "there's a var here but I don't care what it is, ignore it" is a common 
meaning of _ in other languages.  But that would need to be disambiguated from 
a pattern saying "c must be an instance of the class _".  Technically any 
symbol/set of symbols could be used there (as it's just an alias to mixed, 
which has the exact same effect), but _ is a common choice in other languages.

In theory, that could be expanded in the future to something like (note: this 
hasn't been seriously discussed that I know of, I'm just spitballing randomly):

[$a, $b, _] = explode(':', 'foo:bar:baz');

To assign $a = "foo", $b  to "bar", and just ignore "baz".  Which might cause 
parser issues if _ is a legal class name, I'm not sure.  There's probably other 
"ignore this" cases we could come up with, but I haven't actually thought about 
it.

Again, whether any of the above is a compelling argument or not I leave as an 
exercise for the reader.

--Larry Garfield


Re: [PHP-DEV] [RFC] [VOTE] Deprecations for PHP 8.4

2024-07-23 Thread Larry Garfield
On Tue, Jul 23, 2024, at 2:41 PM, Christoph M. Becker wrote:
> On 23.07.2024 at 16:04, Larry Garfield wrote:
>
>> On Tue, Jul 23, 2024, at 1:42 PM, Matthew Weier O'Phinney wrote:
>>
>>> On Fri, Jul 19, 2024 at 12:41 PM Gina P. Banyard  wrote:
>>>
>>>> I have opened the vote for the mega deprecation RFC:
>>>> https://wiki.php.net/rfc/deprecations_php_8_4
>>>
>>> The section "Deprecate using a single underscore ''_'' as a class name"
>>> indicates that probably the primary reason to deprecate it is a
>>> potential future conflict in the pattern matching RFC, where it can be
>>> used as a wildcard.
>>>
>>> However, I see no mention of this character as a wildcard anywhere in that 
>>> RFC.
>>>
>>> Can somebody clarify?
>>
>> The pattern matching RFC previously listed _ as a wildcard character.
>>
>> In the discussion a month ago, someone pointed out that `mixed` already 
>> serves that exact purpose, so having an extra wildcard was removed.
>>
>> However, a few people indicated a desire to have an explicit wildcard _ 
>> anyway, even if it's redundant, as it's a more common and standard approach 
>> in other languages.  We've indicated that we are open to making that an 
>> optional secondary vote in the pattern matching RFC if there's enough 
>> interest (it would be trivial), though I haven't bothered to add it to the 
>> RFC text yet.
>>
>> Having _ available could also be used in other "wildcard" or "ignore this" 
>> cases, like exploding into a list assignment or similar, though I don't 
>> believe that has been fully explored.
>>
>> That's the context/background here.  Whether that encourages you to vote for 
>> or against that section I leave as an exercise for the reader.
>
> Well, I wonder how that is supposed to work.  Assuming the underscore
> would be used as wildcard in a class name context, that could only be
> done after using that character as class name is no longer allowed.  So
> that would have to wait for the next major PHP version (at least).
>
> Note that I'm not worried about no longer being able to use an
> underscore as class name, but rather that this introduces another
> inconsistency to our indentifiers.  Disallowing an underscore as
> function name is obviously off the table, thanks to gettext.
>
> Christoph

I think someone checked and found no examples of someone using _ as a class 
name, so the impact of removing it and/or using it for something else would be 
nearly nil.  That may still push _ as a wildcard out to a future version, but I 
leave that up to others.  As I said, I don't have strong feelings either way.

--Larry Garfield


Re: [PHP-DEV] [RFC] [VOTE] Deprecations for PHP 8.4

2024-07-23 Thread Larry Garfield
On Tue, Jul 23, 2024, at 1:42 PM, Matthew Weier O'Phinney wrote:
> On Fri, Jul 19, 2024 at 12:41 PM Gina P. Banyard  wrote:
>> Hello internals,
>> 
>> I have opened the vote for the mega deprecation RFC:
>> https://wiki.php.net/rfc/deprecations_php_8_4
>> 
>> Reminder, each vote must be submitted individually.
>> 
>> 
>> Best regards,
>> 
>> 
>> Gina P. Banyard
>
>
> The section "Deprecate using a single underscore ''_'' as a class name" 
> indicates that probably the primary reason to deprecate it is a 
> potential future conflict in the pattern matching RFC, where it can be 
> used as a wildcard.
>
> However, I see no mention of this character as a wildcard anywhere in that 
> RFC.
>
> Can somebody clarify?

The pattern matching RFC previously listed _ as a wildcard character.

In the discussion a month ago, someone pointed out that `mixed` already serves 
that exact purpose, so having an extra wildcard was removed.

However, a few people indicated a desire to have an explicit wildcard _ anyway, 
even if it's redundant, as it's a more common and standard approach in other 
languages.  We've indicated that we are open to making that an optional 
secondary vote in the pattern matching RFC if there's enough interest (it would 
be trivial), though I haven't bothered to add it to the RFC text yet.

Having _ available could also be used in other "wildcard" or "ignore this" 
cases, like exploding into a list assignment or similar, though I don't believe 
that has been fully explored.

That's the context/background here.  Whether that encourages you to vote for or 
against that section I leave as an exercise for the reader.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-07-22 Thread Larry Garfield
On Sun, Jul 21, 2024, at 2:45 PM, Tim Düsterhus wrote:
> Hi
>
> On 7/20/24 03:14, Larry Garfield wrote:
>> We've made one change since we last discussed it:  Specifically, Ilija 
>> realized that __set's behavior is already inconsistent, so supporting it for 
>> aviz properties with invisible set would make it even more inconsistent, not 
>> less.  For that reason, we've changed the __set behavior such that a 
>> non-readonly aviz property will not trigger __set.  Further details are in 
>> the RFC, but in short, all of the use cases for that behavior now have 
>> better alternatives, such as property types, hooks, and aviz itself.  So 
>> there's really no point to falling back to __set in edge cases.
>> 
>> https://wiki.php.net/rfc/asymmetric-visibility-v2#interaction_with_set_and_unset
>> 
>> Baring any new developments, we plan to start the vote early next week.
>
> I find it unfortunate that this RFC received a non-trivial change on a 
> Saturday after the discussion has been idle for more than a month 
> together with the announcement that the vote will begin shortly after 
> the weekend. Folks should be given sufficient time to react to the 
> newest developments. Personally I plan to give this RFC another read, 
> because I already forgot the details after a month of not looking at it, 
> but I'm not sure if I'll manage today.
>
> For now:
>
> Is there any implementation of this RFC? The RFC text only references 
> the https://github.com/php/php-src/pull/9257 PR hasn't been updated 
> since December 2022.
>
> Best regards
> Tim Düsterhus

Oof, sorry, I thought Ilija had updated the link already.  It is now updated, 
and the PR is here:

https://github.com/php/php-src/pull/15063

Since the PR wasn't easily available until now, we're going to push the vote 
start back to this coming Friday.

--Larry Garfield


Re: [PHP-DEV] Request for opinions: bug vs feature - change intokenization of yield from

2024-07-20 Thread Larry Garfield
On Sat, Jul 20, 2024, at 11:51 AM, Tim Düsterhus wrote:
> Hi
>
> On 7/20/24 18:40, Juliette Reinders Folmer wrote:
>> Tim, you're making my point for me. This is *exactly* why the current
>> change should be reverted.
>
> I am not sure how you read "PHP users have no idea what a token is" as 
> an argument in favor of reverting the change, because reverting the 
> change means that completely reasonable code suddenly stops working with 
> a parser error in a patch version and PHP users will rightfully come to 
> PHP's issue tracker to complain.
>
>> And not, like it is now, an undocumented, random change creating an
>> inconsistency in the Tokenizer.
>
> The tokenizer is doing the right thing: It tokenizes the PHP source 
> code. It is absolutely normal that PHP first and second-digit updates 
> make changes to the token stream. New tokens are added, old tokens are 
> removed, tokens may appear in places where they previously could not 
> appear for well-formed PHP programs. Tools working on the token stream 
> need to adapt and this change is no different from any other change to 
> PHP's syntax in that regard (except that documenting the change was 
> forgotten).
>
> Best regards
> Tim Düsterhus

Yes, any syntax change means tools need to adapt, but that doesn't mean 
tokenization can change randomly and accidentally.  Syntax changes require an 
RFC.  If an RFC passes that necessitates SA tools update, so be it.  (That 
happens almost every version.)  But that's still an RFC change.

I would agree with reverting this change for now.  The odds of it breaking 
something for someone are vanishingly small, and it's a bug, not a feature.  If 
we want it to be a feature, we can make an RFC for it.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-07-20 Thread Larry Garfield
On Sat, Jul 20, 2024, at 7:22 AM, Rodrigo Vieira wrote:
> Will the alternative syntax on hook not even be put to a vote?

It was, a year and a half ago when Aviz was first proposed.  The preference was 
split, but leaned toward the prefix-style syntax.  So we went with that.  I 
don't think we'll ever get everyone to want the same syntax, but we're using 
the one that was both somewhat more popular, and (as discussed in the RFC) 
arguably superior.

As the "comments in yield from" thread has shown, *any* even slight change to 
PHP's syntax will require work from static analysis tools.  That's the nature 
of the problem space, regardless of the syntax specifics.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-07-20 Thread Larry Garfield
On Sat, Jul 20, 2024, at 10:47 AM, Ilija Tovilo wrote:
> Hi Rob
>
> On Sat, Jul 20, 2024 at 3:47 PM Rob Landers  wrote:
>>
>> On Sat, Jul 20, 2024, at 03:14, Larry Garfield wrote:
>>
>> On Wed, May 29, 2024, at 2:15 PM, Larry Garfield wrote:
>> >
>> > https://wiki.php.net/rfc/asymmetric-visibility-v2
>>
>> Hi folks.  After a side quest to polish off hooks, we're nearly ready to 
>> bring aviz to a vote.
>>
>> We've made one change since we last discussed it:  Specifically, Ilija 
>> realized that __set's behavior is already inconsistent, so supporting it for 
>> aviz properties with invisible set would make it even more inconsistent, not 
>> less.  For that reason, we've changed the __set behavior such that a 
>> non-readonly aviz property will not trigger __set.  Further details are in 
>> the RFC, but in short, all of the use cases for that behavior now have 
>> better alternatives, such as property types, hooks, and aviz itself.  So 
>> there's really no point to falling back to __set in edge cases.
>>
>> https://wiki.php.net/rfc/asymmetric-visibility-v2#interaction_with_set_and_unset

>> This is a pretty massive breaking change.
>
> There was a miscommunication between Larry and me. The change is not
> to any existing behavior. __get/__set are currently called under two
> circumstances:
>
> * The properties _full_ visibility is not met.
> * The property was explicitly unset.
>
> We're not changing this behavior. Instead, we decided not calling
> __set for asymmetric visibility, when only the set visibility isn't
> met. Before making this decision, implicitly implying protected(set)
> for a readonly property would have led to __set being called (because
> the scope protection now comes from asymmetric visibility, rather than
> readonly itself), which would have been a change to the current
> behavior.
>
> So, in short: If only the set visibility isn't met, we're now throwing
> an error. This is consistent with readonly today, and with get-only
> hooks. If somebody wants to change this in the future, they can do so
> without any BC breaks, and most likely should make the behavior
> consistent across all of these three cases.
>
> Ilija

After discussing with Ilija further, I've rewritten the __set section (again).  
As Ilija said, the long and short of it is "we change nothing", but leave the 
door open to clean up __set's behavior in the future, once we decide what 
cleanup is warranted.

--Larry Garfield


Re: [PHP-DEV] [RFC] Asymmetric Visibility, v2

2024-07-19 Thread Larry Garfield
On Wed, May 29, 2024, at 2:15 PM, Larry Garfield wrote:
> As promised, Ilija and I offer this revised version of asymmetric visibility. 
>  
>
> https://wiki.php.net/rfc/asymmetric-visibility-v2
>
> It's still essentially the same as last year's version, but with a few 
> adjustments and changes:
>
> * readonly properties are now supported in a logical fashion.
> * We've brought back the abbreviated form, as public-read, something 
> else set is the most common use case.
> * The section on magic methods has been greatly simplified.  The 
> implementation itself hasn't changed, but the explanation is a lot less 
> confusing now.
> * We've explained how aviz interacts with hooks (they don't, really) 
> and with interface properties (in the obvious way), which didn't exist 
> at the time of the last draft.
> * We've added a section with examples of how aviz is a concrete 
> improvement, even in a world with readonly and hooks.
> * We've added a section discussing why the prefix-style syntax was 
> chosen.

Hi folks.  After a side quest to polish off hooks, we're nearly ready to bring 
aviz to a vote.

We've made one change since we last discussed it:  Specifically, Ilija realized 
that __set's behavior is already inconsistent, so supporting it for aviz 
properties with invisible set would make it even more inconsistent, not less.  
For that reason, we've changed the __set behavior such that a non-readonly aviz 
property will not trigger __set.  Further details are in the RFC, but in short, 
all of the use cases for that behavior now have better alternatives, such as 
property types, hooks, and aviz itself.  So there's really no point to falling 
back to __set in edge cases.

https://wiki.php.net/rfc/asymmetric-visibility-v2#interaction_with_set_and_unset

Baring any new developments, we plan to start the vote early next week.

Cheers.

--Larry Garfield


Re: [PHP-DEV] Optional constructor body

2024-07-18 Thread Larry Garfield
On Thu, Jul 18, 2024, at 2:03 PM, Lily Bergonzat wrote:
> I would love to see those improvements as well, however I am surprised
> we seem to be more inclined to push a more substantial change than a
> minor one.
>
> I feel like the more substantial one would be more likely to break
> stuff, compared to the minor one, and so I don't see why the minor one
> would be refused?
>
> That said, I am new here, and I do not yet know how things work, so it
> probably is because I lack experience.

As you're new, I'll just note, please don't top post. :-)

The optimal size of an RFC is a very squishy topic.  There are some that argue 
for "the smallest possible and no smaller," on the theory that bite-sized 
changes are easier to discuss.  However, they also attract more bikeshedding, 
and often a feature is not actually useful except in conjunction with other 
parts of it.  On the flipside, a tiny RFC has a hard time justifying its 
existence, since whatever intended follow-ups that would make it actually 
useful are never guaranteed to happen (either the authors lose interest or they 
get voted down later, etc.).  Going through an RFC also has a lot of process 
overhead, and breaking one small RFC into many tiny RFCs can actually take far 
longer than the one larger RFC.

Conversely, an RFC can be too big to really comprehend, and then no one really 
understands what it's doing without hours of reading and research, and there's 
so many moving parts even the authors cannot keep track of them.  On the 
flipside, some parts just don't make any sense on their own unless combined 
with other aspects of a proposal.

So there's really no "natural" size for RFCs generally.  It will vary with the 
topic.  Also, the impact of an RFC often has very little to do with its length 
or number of features.  The RFC text for "don't require ; to end a statement 
anymore" would likely be pretty short, but would also break, er, everything. :-)

Conversely, offering a new syntax for abbreviated constructors (as being 
discussed here) would be longer than that, but the impact on existing code 
would be zero (unless it's done badly).

Also, "minor work" can end up causing problems for future work.  See also: 
readonly, which was intended as a "junior stepping stone" to more complex 
features, but as we've found, actually makes those future features *more* 
complex because it wasn't designed with those future expansions in mind.

My own stance (which I do not claim to be universal) is that an RFC is 
"right-sized" when it offers notable, meaningful benefit on its own, without 
"holes" in the functionality, but can and should have natural "extension 
points" where it will dovetail nicely with other, future features, which can be 
planned or not.  Sometimes that means a very short RFC, other times it means 
something the size of property hooks. :-)  It's really a case-by-case situation.

--Larry Garfield


Re: [PHP-DEV] Optional constructor body

2024-07-18 Thread Larry Garfield
On Thu, Jul 18, 2024, at 10:11 AM, Oliver Nybroe wrote:
> Thanks for sharing previous discussions, I will definitely take a look 
> at those before writing up the RFC. 
>
>
>> If you do with to go with an RFC, I'd like to see if your proposal
> addresses whether this syntax should implicitly call
> `parent::__construct()`, and if a semi colon is expected or not
> (`public function __construct(public int $foo);` vs `public function
> __construct(public int $foo)`).
> Thank you, these are very valuable points to address in the RFC. 
>
> I can definitely feel that there will be some mixed opinions about 
> semicolon vs no semi colon.
>
>
> Best regards
> Oliver Nybroe (he/him)

Please don't top-post.

Since the last time this came up, PSR-12 has been replaced with PER-CS, which 
as of 2.0 now says: 

> If a function or method contains no statements or comments (such as an empty 
> no-op implementation or when using constructor property promotion), then the 
> body SHOULD be abbreviated as {} and placed on the same line as the previous 
> symbol, separated by a space.

cf: https://www.php-fig.org/per/coding-style/#44-methods-and-functions

(I... suppose technically it doesn't mention classes, but I've been doing it 
for empty classes too.)

So the "coding style" part of the previous issue has been resolved.  Whether 
that changes anyone's mind about whether this should be done or not is up to 
them to decide.

Personally, I'd probably vote for it if it came up, but I agree it's a pretty 
minor improvement and unlikely to pass.  It would probably only be worth doing 
if there were other common-pattern-optimizations around the constructor that 
came with it.  Things like auto-forwarding to the parent, or a more compact 
syntax than a full constructor method, or other things that make writing a 
"pure data" product type easier rather than just s/{}/;/

I don't know what those could look like.  As a data point, in Kotlin (which is 
what my day job is now), constructor properties are always promoted, 
essentially.  

class Foo(val a: String, val b: String) { // This is the equivalent of PHP's 
promoted properties.

  val c: Int = 5 // A non-constructor-initialized property. These can have 
hooks, constructor ones I think cannot.

  init {
// This is the non-promoted part of a constructor body, and runs after the 
properties are assigned.
  }
}

In case of inheritance, there's dedicated required syntax for forwarding to the 
parent:


class Foo(val a: String, val b: String) : Bar(b) { // equivalent to 
parent::__construct($b)

}

You can also make the constructor private (etc.) with more explicitness:

class Foo private constructor(val a: String, val b: String) {}

Of note, if there's no constructor then the parens are omitted, and if there's 
no body then the {} body is omitted.  That means a great many "value 
objects"/DTOs, etc just look like this:

class Foo(
  val a: String,
  val b: String,
)

Which would be equivalent to PHP's

class Foo {
  public function __construct(
public readonly string $a,
public readonly string $b.
  ) {}
}

cf: https://kotlinlang.org/docs/classes.html

To be clear, I'm not suggesting PHP just copy Kotlin directly.  I'm saying that 
if we want to improve the constructor syntax for common cases, which I am open 
to, we should be looking to do something more substantial and ergonomic than 
just replacing {} with ;, and we could probably get some good inspiration from 
other languages in our family.  (Java, Kotlin, C#, Swift, etc.)

--Larry Garfield


Re: [PHP-DEV] [RFC] Lazy Objects

2024-07-17 Thread Larry Garfield
On Wed, Jul 17, 2024, at 6:31 PM, Nicolas Grekas wrote:

> A bit unrelated to the above topic: we've further clarified the RFC by 
> addition restrictions to what can be done with lazy proxies. Namely, 
> when the factory returns an object from a parent class, we describe 
> that adding more on the proxy class would throw, and we also explain 
> why. We also added a restriction to prevent a proxy from having an 
> overridden __clone or __destruct when the factory returns a parent, and 
> explained why again.
>
> This should simplify the overall behavior by preventing edge case that 
> wouldn't have easy answers. If those limitations prove too restrictive 
> in practice (my experience tells me they should be fine), they could be 
> leveraged in the future.
>
> On our side, this should close the last topics we wanted to address 
> before opening the vote.
>
> Please let us know if anyone has other concerns.
>
> Cheers,
> Nicolas

Minor point: Why is the $initializer return type null, instead of void?  I 
don't see a purpose to allowing an explicit null return and nothing else.

Otherwise, I'm quite looking forward to this.

--Larry Garfield


Re: [PHP-DEV] array_reduce callback key

2024-07-17 Thread Larry Garfield
On Wed, Jul 17, 2024, at 9:01 AM, Bilge wrote:
> On 17/07/2024 01:41, Levi Morrison wrote:
>> Adding arguments to a function can mess up internal callbacks, btw, so I 
>> don't like modifying the
>> existing function.
> Which internal callbacks can be messed up by this change? They clearly 
> aren't tested, as the build is passing.
>
> Cheers,
> Bilge

There's a number of issues here.

PHP-defined functions ignore excess arguments.

C-defined functions error on excess arguments.

A function with an optional second argument... may break if it gets passed an 
optional argument that isn't aligned with its expectation.  intval() is the 
usual example (https://www.php.net/intval), but it would also impact something 
like trim().  If someone is using a function with one param and one optional 
param as a callback right now, suddenly passing the key as the second argument 
could cause all sorts of weirdness.

Similarly, if someone is using a single-param C-defined function as a callback 
right now, and array_reduce() starts passing a second argument, it will fatal.

I ran into this issue while building Crell/fp, and my only solution (after 
swearing a lot) was to just make two separate versions of every operation: One 
that passes the key and one that doesn't.  (cf: 
https://github.com/Crell/fp/blob/master/src/array.php)  The user has to pick 
the right one.  That is, sadly, the only reliable solution, even if done in the 
stdlib.

(Of course, the real solution is to introduce a separate map/dict type that has 
its own dedicated API for map/filter/reduce, but now we're well out of scope... 
 Using the same structure for lists and maps is PHP's original sin.)

--Larry Garfield


[PHP-DEV] [Vote] Property Hook performance improvements

2024-07-15 Thread Larry Garfield
Hi all.  I have just opened the voting on the property hook (performance) 
improvement RFC.

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

With the readonly bits pushed out to later, this is probably the shortest RFC I 
have ever written. :-)  Vote opens now, and will close in 2 weeks on 29 July.

-- 
  Larry Garfield
  la...@garfieldtech.com


Re: [PHP-DEV] [RFC] [Discussion] Add WHATWG compliant URL parsing API

2024-07-15 Thread Larry Garfield
On Mon, Jul 15, 2024, at 9:20 AM, Máté Kocsis wrote:
> Hey Ignace, Nicolas,
>
> Based on your request for adding support for RFC 3986 spec compatible 
> parsing,
> I evaluated another library (https://github.com/uriparser/uriparser/) 
> in the recent days
> in order to add support for the requested functionality. As far as I 
> can tell, the results
> were very promising, so I'm ok to include this into my proposal (I 
> haven't pushed my
> changes yet and haven't updated the RFC yet).
>
> Regarding the reference resolution 
> (https://uriparser.github.io/doc/api/latest/#resolution)
> feature which has also already been asked for, I'm genuinely wondering 
> what the use-case is?
> But in any case, I'm fine with incorporating this as well into the RFC, 
> since apparently
> both Lexbor and uriparser support this (naturally).
>
> What I became puzzled about is the correct object structure and naming. 
> Now that uriparser
> which can deal with URIs came into the picture, while Lexbor can parse 
> URLs, I don't
> know if it's a good idea to have a dedicated URI and a URL class 
> extending the former one...
> If it is, then in my opinion, the logical behavior would be that Lexbor 
> always instantiates URL
> classes, while uriparser would have to decide if the passed-in URI is 
> actually an URL, and
> choose the instantiated class based on this factor... But in this case 
> the differences between
> the RFC 3986 and WHATWG specifications couldn't be spelled out, since 
> URL objects
> could hold URLs parsed based on both specs (and therefore having a 
> unified interface is required).
>
> Or rather we should have a separate URI and a WhatwgUrl class so that 
> the former one would
> always be created by uriparser, while the latter one by Lexbor? This 
> way we could have a dedicated
> object interface for both standards (e.g. the RFC 3986 related one 
> could have a getUserInfo() method,
> while the WHATWG related one could have both getUser() and 
> getPassword() methods). But then
> the question is how interchangeable these classes should be? I.e. 
> should we be able to convert them
> back and forth, or should there be an interface that is implemented by 
> the two classes?
>
> I'd appreciate any suggestions regarding these questions.
>
> P.S. due to its bad receptance, I got rid of the UrlParser class as 
> well as the UrlComponent enum from my
> implementation in the meantime.
>
> Regards,
> Máté

I apologize if I missed this up-thread somewhere, but what precisely are the 
differences between URI and URL?  My understanding was that URL is a subset of 
URI (all URLs are URIs, but not all URIs are URLs).  You're saying they're 
slightly disjoint sets?  Can you give some concrete examples of where the 
parsing rules would produce different results?  That may give us a better sense 
of what the logic should be.

--Larry Garfield


Re: [PHP-DEV] [PHP-Dev] Versioned Packagers (Iteration IV)

2024-07-10 Thread Larry Garfield
On Wed, Jul 10, 2024, at 1:38 AM, Mike Schinkel wrote:

>> In fact, if you use an optimized/dumped autoloader, then Composer simply 
>> builds an internal giant lookup table of what class maps to what file.  
>> PSR-4 is then *completely irrelevant* at runtime.  It's already one giant 
>> O(1) lookup map.  That can be done *today*.  That *is* done today.
>
> Yes, it can be done today. It *is* done today.  By. Developer. Managed. Apps.


> Already done.  I explained how an `spl_autoload_map()` would do exactly 
> that above.
>
>> When you have a proven that it's even possible to have multiple local symbol 
>> tables, we can talk.  Until then, please spare us.
>
> My one useful takeaway from your email — except that I already knew 
> that — was the need to figure out how PHP can handle multiple symbol 
> tables.  Beyond that, your take your own advice and spare us (me) from 
> your contempt and condescension as they are not good looks on anyone.

I find it amusing that several of your responses to me saying "you could do 
this stupid thing but no one does that" is "WordPress does that thing."  I make 
no comment other than to observe it.

But let me understand: In a thread started by Michael Morris where he 
explicitly said the most important thing for him is multi-version loading, 
you're going to insist you're talking only about moving Composer's classmap 
logic into core, and nothing about multi-version loading.

If that's the case, then please be polite to Michael Morris and get out of his 
thread.

Also, be aware that classmap-in-core was already discussed 3 years ago and went 
nowhere.

https://wiki.php.net/rfc/autoload_classmap
https://externals.io/message/113545

Largely because, as Sara said then, and Rowan just said on this thread, it can 
be done better in user-space and is already done better in user-space... by 
Composer.

https://externals.io/message/113569

You even commented in that thread:

https://externals.io/message/113554

So it's not a new idea, it's an idea that's already been greeted with a general 
"meh".

Yes, most "developer managed apps" use Composer today to side-step the 
"bajillion autoloaders" problem.  It's a solved problem.

Nothing precludes Wordpress from doing the same.  I admittedly have not looked 
at WP's core in a very long time, but I would be absolutely shocked if it 
wasn't pretty straightforward to build code into WP core that looks at the 
source directories of all plugins, finds the classes there, and builds a big 
index (stored in a cache directory or the database) that it can use in one 
single autoloader registered by WP itself.  I know that can be done, because 
that's exactly how Drupal 7's autoloader worked.  I know, because I wrote it.  
In 2008.  (It was later modified by others, but the initial version was mine.)

That would work even with WP's "download code and drop it on disk" model.  That 
has been possible since PHP 5.2 at least, when I wrote exactly that for Drupal. 
 It wasn't even that hard.  Literally any "user managed app" could do the same.

Why hasn't WP core done that in order to make life easier for plugin developers 
and avoid registering 50 separate autoloaders?  I dunno, you should ask Matt 
Mullenweg.  We have nothing to do with it.

--Larry Garfield


Re: [PHP-DEV] [RFC] Property Hook improvements

2024-07-10 Thread Larry Garfield
On Mon, Jul 1, 2024, at 12:02 PM, Larry Garfield wrote:
> Hi folks.  As Ilija's been polishing off hooks to get the PR merged, 
> we've run into two small revisions that should make life better for all 
> involved.  One is a performance improvement that requires a very slight 
> error handling behavior change, and the other is enabling readonly in 
> selected (but probably all of the relevant) circumstances.
>
> I'd say we expect these to be uncontroversial, but this is PHP. :-)  So 
> I will instead just note that it's a short RFC and open the discussion 
> accordingly.
>
> https://wiki.php.net/rfc/hook_improvements

Based on discussion here and off-list, and after confirming with Nicolas that 
lazy objects would be compatible with readonly properties already (which have 
very similar use cases in practice), we're going to hold off on the readonly 
hooks part of this RFC.  I've split it off to its own RFC for later:

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

The other half of this RFC, removing the recursion guard in return for 
performance, has had no objections.  Its discussion period ends Friday, so I 
will open the vote on that Monday-ish.

--Larry Garfield


Re: [PHP-DEV] [RFC] Improve language coherence for the behaviour of offsets and containers

2024-07-10 Thread Larry Garfield
On Tue, Jul 9, 2024, at 7:52 PM, Levi Morrison wrote:
>> Moreover, I know the traffic on the list has been pretty high, but I do 
>> intend to have this RFC up for voting for inclusion in PHP 8.4, and I'm not 
>> exactly sure how I am meant to interpret the lack of responses.
>
> I am personally strongly in favor of the direction. As mentioned in
> the PR, my main concern is honestly quite a small one: I think
> `Appendable::append` ought to be renamed. Maybe `Appendable` and
> `FetchAppendable` too.
>
> The reason is that `append` is a common operation on a container type,
> which is likely to want to implement these interfaces. I easily
> identified a few such things with a quick GitHub search:
>  1. 
> https://github.com/pmjones/php-styler/blob/5c7603f420e3a75a5750b3e54cc95dfdbef7d6e2/src/Line.php#L166
>  2. 
> https://github.com/ParvulaCMS/parvula/blob/dcb1876bef70caa14d09e212838a35cb29e23411/core/Models/Config.php#L46
>
> Given that I anticipate these methods to largely be called by
> handlers, and not by names, I think an easy solution is to just name
> this `offsetAppend` to match the other offset operations. For example,
> I don't anticipate code doing:
>
> $container->append($item);
>
> I expect largely they will do:
>
> $container[] = $item;
>
> So it doesn't really matter if the name is `append` or `offsetAppend`
> for the main use-case, and thereby we avoid some road bumps on
> adoption. Any SPL containers with `append`, such as ArrayObject, can
> make it an alias of `offsetAppend`, I think?
>
> Anyway, this is a minor thing, and I will vote yes regardless of
> whether it (and maybe the *Appendable interface names) are changed.
> But I do think it would be prudent to change it. It would also match
> the `offset*` convention of the other interfaces.

Based on my research into collections with Derick, I agree that "append" is not 
a good name to claim for this interface; it would make it incompatible with 
standard collection method naming.  offsetAppend() would neatly side-step that 
issue.  +1 to what Levi said.

As to my limited response so far, it's mostly because I read through the 
proposal in detail a few months ago when it was first informally put forward 
and liked it then, and it seems there haven't been any serious changes since 
for me to comment on.  I am very much in favor, though.

--Larry Garfield


Re: [PHP-DEV] [PHP-Dev] Versioned Packagers (Iteration IV)

2024-07-09 Thread Larry Garfield
oes Wordpress.  Or TYPO3.  Or any other project.  Because that's 
a core PHP limitation.  

In Python, every module is really just an object with a big dictionary of the 
functions/classes it has.  When you "import" a symbol from another module, the 
engine is doing little more than `$this['foo'] &= $that['foo']`.  That's a core 
part of how the language works.  (I'm not sure of Javascript's details, but I 
suspect from using it that it's similar.)

PHP works very very differently.  PHP has a single global list of symbols.  
(Well, two, for classes and functions.)  Namespaces are just syntax sugar over 
very-long-names, nothing more.  There is no "local symbol table," so having 
different local symbol tables point to different code blocks using the same 
name is not even conceivable.

If you want to change that, and give PHP multiple local symbol tables, then 
autoloading... is utterly irrelevant.  The question there is "how can we 
introduce local symbol tables in the engine without requiring 10 million 
developers to rewrite the file header of 1 billion PHP files across the world?" 
 Honestly, I'm not convinced its even possible. Someone with more engine 
knowledge than I could be able to find away, maybe, but I am skeptical.  If 
it's even possible, I suspect it would be an absurdly large amount of work and 
necessarily include many hard BC breaks.

If you'd like to prove me wrong, go for it.  But that's the problem to address. 
 Debating file paths is about four steps down the line before it's even 
relevant.  And even then... if you can't make a PSR-4-organized package (of 
which there are several hundred thousand) slot into that new model comfortably 
with zero effort on the part of the package author, it's doomed.

So please, spare us the ill-informed descriptions of how you think autoloaders 
work, when you have demonstrated you do not know how they work.  

Spare us the litany of complaints about PSR-4 when you have demonstrated you 
don't know what PSR-4 says.  

Spare us the gnashing of teeth about how hard it is to use a Wordpress plugin 
that hasn't been updated in 10 years with a modern plugin because the former is 
still using a 10 year old abandoned version of some library, when that's not 
PHP's problem, that's a Wordpress maintenance problem.

If you want to move this effort forward, here's your todo list:

1. Do some research in the engine to determine if local symbol tables are even 
possible without rewriting the engine.
2. Work through the highly complex logic of handling three layer overlapping 
transitive dependencies in a diamond pattern with conflicting version 
requirements.
3. Investigate the performance impact of maintaining multiple versions of the 
same code in memory at once, when the order they get loaded will vary by 
request.
4. Think through how you'd support *both* composer-based and "user managed" 
applications with such a model, especially projects that are already 
architecturally a decade out of date (like Wordpress).

When you have a proven that it's even possible to have multiple local symbol 
tables, we can talk.  Until then, please spare us.

--Larry Garfield


Re: [PHP-DEV] [RFC] Improve language coherence for the behaviour of offsets and containers

2024-07-07 Thread Larry Garfield
On Thu, Jul 4, 2024, at 8:52 AM, Gina P. Banyard wrote:
> Hello internals,
>
> I would like to formally open the discussion on an RFC I've been 
> working on for the past year:
> https://wiki.php.net/rfc/container-offset-behaviour
>
> As DokuWiki is a bit of a faff at times, the Markdown sources are 
> available on GitHub:
> https://github.com/Girgias/php-rfcs/blob/master/container-offset-behaviour.md
>
> The implementation is basically done, other than some mysterious JIT 
> issues that I haven't been able to pinpoint yet.
>
>
> Best regards,
>
> Gina P. Banyard

I want to find time to go through some of the bits in finer detail to be sure, 
but you've gone through enough finer bits that I doubt I'd find much to object 
to. :-)  Strongly supportive here.

--Larry Garfield


Re: [PHP-DEV] Iteration III: Packages (was Re: [PHP-DEV] [Initial Feedback] PHP User Modules - An Adaptation of ES6 from JavaScript)

2024-07-04 Thread Larry Garfield
On Thu, Jul 4, 2024, at 5:48 AM, Rob Landers wrote:

> If I could have one to be a PER first, it would be the container 
> interface (PSR-11). When it was originally worked on, there was 
> basically one lifecycle of an object: a request. For almost all 
> possible SAPIs, after the request ended, everything was gone. Today, we 
> basically have multiple ones if you are using modern runtimes:
>  1. Environment Scope: configuration that survives execution of the 
> program
>  2. Global Scope: services/entities that can exist beyond the lifetime 
> of a request, but may or may not (depending on runtime)
>  3. Request Scope: services/entities that should be unique for every 
> request.
>  4. Volatile Scope: services/entities that should be created every time 
> they are injected.
> Right now, these are all mixed into one giant container, that may or 
> may not be shared between requests, because that is the interface we 
> have to work with. It isn't great :| but it works, barely.
>
> — Rob

There's been on and off discussion this year about container registration, not 
just retrieval.  That could be done as an add-on PSR, most likely.  The 
challenge is that there's fundamentally different ways to go about 
registration, and little consensus on it.  (And the people most interested in 
talking about it haven't wanted to go to the effort of organizing a Working 
Group.)  I suspect scoping would have similar challenges.  But if someone can 
get a working group together around a particular direction, we'd be open to 
that discussion.

That would be entirely off topic for this list, though, so let's not go further 
down that rabbit hole.

--Larry Garfield


Re: [PHP-DEV] [RFC] Property Hook improvements

2024-07-01 Thread Larry Garfield
On Mon, Jul 1, 2024, at 8:32 PM, Tim Düsterhus wrote:
> Hi
>
> On 7/1/24 19:02, Larry Garfield wrote:
>> I'd say we expect these to be uncontroversial, but this is PHP. :-)  So I 
>> will instead just note that it's a short RFC and open the discussion 
>> accordingly.
>
> Big fan of the performance improvement, given that I convinced Ilija to 
> look into that once more. Really happy with what he found there.
>
> For the second part about supporting readonly: I don't want to rush this 
> in the last few weeks before feature freeze, especially since the word 
> 'investigating' appears in the RFC text. Given that readonly is 
> currently entirely unsupported, this could very well be added with PHP 
> 8.5, allowing folks to really think about the implications and how it 
> interacts with stuff. That's a "no" from my side.

"Investigating" here is a small term, honestly.  Ilija just hadn't had a chance 
to poke at it to see where is more feasible.  I expect it would be a day or so 
at most to sort that part out; we just wanted to get the discussion going given 
the timing, and he didn't have time over the weekend. :-)

Are there specific concerns you have about implications, or just a general 
"dude, it's July" sense?

> Best regards
> Tim Düsterhus
>
> PS: Small typo: '$this-dbApi->loadCategory($this->categoryId);', '>' 
> missing there after 'this-'.

Fixed, thanks.

--Larry Garfield


Re: [PHP-DEV] [RFC] Property Hook improvements

2024-07-01 Thread Larry Garfield
On Mon, Jul 1, 2024, at 5:28 PM, Lynn wrote:

> "A side effect of that optimization, however, is that we cannot 
> proactively detect the bug above. Instead, it would result in an 
> infinite loop, which would eventually trigger a a stack overflow."
>
> This got a small typo ("a a" at the end). 

Fixed, thanks.

> This reads no different to me 
> than infinite recursion between 2 methods. It honestly does not bother 
> me, and any static analysis tool will be able to pick this anyway. 
> Sounds like a free performance gain to me!

Yep, it would be exactly 2 method recursion, and the engine would naturally 
treat it as such.

--Larry Garfield


[PHP-DEV] [RFC] Property Hook improvements

2024-07-01 Thread Larry Garfield
Hi folks.  As Ilija's been polishing off hooks to get the PR merged, we've run 
into two small revisions that should make life better for all involved.  One is 
a performance improvement that requires a very slight error handling behavior 
change, and the other is enabling readonly in selected (but probably all of the 
relevant) circumstances.

I'd say we expect these to be uncontroversial, but this is PHP. :-)  So I will 
instead just note that it's a short RFC and open the discussion accordingly.

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

-- 
  Larry Garfield
  la...@garfieldtech.com


Re: [PHP-DEV] Re: [Discussion] Add date_test_set_now() function

2024-07-01 Thread Larry Garfield
On Mon, Jul 1, 2024, at 3:56 PM, Go Kudo wrote:

> I apologize, the main point of my explanation was off.
>
> To put it simply, I'm suggesting that it might be good to implement 
> convenient and commonly used features from Carbon at the ext-date level.
>
> I'm proposing the date_test_set_now() function for the following reasons:
>
> User-land libraries like Carbon / Chronos have a setTestNow method, 
> indicating a potential demand for this feature.
> It's impossible to determine whether a value is relative or absolute 
> time from either user-land or Extension.
> While this is convenient for maintaining legacy systems, that's not the 
> essence of this proposal.
>
> As you pointed out, this is an issue that should ideally be solved in 
> user-land. I deeply understand that.
>
> However, in reality, PHP's time-related processing is diverse, and to 
> comprehensively handle all of these, it seems necessary to address this 
> at the ext-date level.
>
> https://www.php.net/manual/en/ref.datetime.php
>
> For example, you might want to use the date() function to display the 
> current time on a whim. However, doing this ruins everything.
>
> Even if other parts of your code use Carbon or comply with PSR-20, 
> using the date() function is problematic because the current time it 
> references cannot be modified.
>
> `date_test_now(\DateInterval $shiftInterval)` can solve this problem.
>
> Of course, there might be various side effects. However, seeing 
> `Carbon::setTestNow()` being used in various places, I think this 
> feature might be necessary.
>
> I would appreciate your thoughts on this.
>
> Best Regards,
> Go Kudo

They are unchanged.  

> For example, you might want to use the date() function to display the 
> current time on a whim.

So don't do that.  Relying on global mutable state is a bug.  That older parts 
of the stdlib made that mistake doesn't mean we should continue it.  (See also 
the Random extension, which also works to avoid global mutable state.)

> Of course, there might be various side effects.

Exactly.  This is not something to just brush aside with a comment.  

The way Carbon does it is wrong, for the same reason: It just sets a global 
state.  The correct answer is to use PSR-20 and inject a fixed-time instance of 
the Clock.

--Larry Garfield


Re: [PHP-DEV] [Discussion] Add date_test_set_now() function

2024-07-01 Thread Larry Garfield
On Mon, Jul 1, 2024, at 1:07 PM, Go Kudo wrote:
> Hi, Internals.
>
> I've been absent for a long time due to poor health. I'm finally back.
>
> I maintain a legacy application written in PHP, and occasionally need 
> to fake the current time for testing purposes. However, PHP doesn't 
> provide a standard way to fake the current time, so I've been changing 
> the OS's current time to do this, which is quite painful.
>
> This can be avoided by using third-party libraries (such as 
> Carbon::setTestNow()). However, it's almost impossible to modify all 
> parts of a legacy application that depend on the current time.
>
> Another option is to use libfaketime 
> (https://github.com/wolfcw/libfaketime), but this is also quite painful 
> to use.
>
> Since this was absolutely necessary for my work, I implemented this 
> functionality as a PHP Extension. (Please ignore the dirty 
> implementation related to PDO. I'm not planning to propose it this 
> time.)
>
> https://github.com/colopl/php-colopl_timeshifter
>
> However, this Extension has some problems.
>
> The first is that there's no way to determine whether the format passed 
> to the ext-date parser is relative or absolute time, resulting in a 
> dirty hack using usleep. The second is that it depends on timelib, so 
> it breaks when upstream changes related to timelib are made.
>
> So, how about adding a `date_set_test_now(\DateInterval 
> $shiftInterval)` function to ext-date?
>
> This function would treat the current time as shifted by the passed 
> DateInterval. Since it's implemented on the ext-date side, there's no 
> need for dirty hacks using usleep.
>
> I'd like to hear your opinions. Thank you.
>
> Best Regards,
> Go Kudo

We don't generally add features just to support very-old legacy code.  These 
days, the correct answer would be to use PSR-20.  (Implementations are 
trivially easy, many available, and it's dead easy to write your own.)  That 
doesn't much help legacy code, but adding global features just to support 
legacy code that should get refactored anyway doesn't seem like a great idea.

--Larry Garfield


Re: [PHP-DEV] [Initial Feedback] Typed Arrays

2024-07-01 Thread Larry Garfield
On Mon, Jul 1, 2024, at 12:21 PM, Richard Miles wrote:
> Howdy Rob,
>
>>> I appreciate your feedback, and I think it’s valid. I try to compare my 
>>> expectations to what is possible in typescript.
>> 
>> I feel like Typescript is the wrong model to follow. The type system in 
>> Typescript is Turing Complete 
>> (https://github.com/microsoft/TypeScript/issues/14833) and php barely has a 
>> type system. It doesn’t even have consistent type checking, for that matter 
>> (properties are checked differently than arguments which are checked 
>> differently than constructor arguments — and the fact they agree with each 
>> other at all, is interesting, because they don’t arrive at the same 
>> conclusions in the same way. I’ve been dealing with subtle bugs here for 
>> weeks on an unannounced RFC implementation) and this is why generics is a 
>> can of worms: implementing it would essentially force a rewrite of the type 
>> system into a proper type system.
>> 
>> In my honest opinion, before we can even have this type of conversation, we 
>> need to have an RFC about the syntax (there may already be one, I haven’t 
>> checked — and internet is spotty where I currently am). The pattern matching 
>> RFC was proposed as though it would be written one way, people have thrown 
>> out ideas of different syntax, but I don’t think there is an “official” 
>> syntax. A good starting point may be to simply propose an RFC about syntax 
>> so future RFCs can be consistent. 
>> 
>> — Rob
>
> I actually did not know it was turning complete, very interesting! 
> While it is easy for anyone to say, ‘we're not even close to 
> typescript,’ 
> that’s precisely what brings me to the table. I would be happy with us 
> just voting on syntax. It seems like past RFC’s only 
> ever got hung up on generics (wrongfully?). I want to work on 
> implementing generics, too, after this. I feel this is probably a good 
> stepping stone. 
>
> A vote would solidify the following:
>
>
> interface iArrayA ['a' => string ]
> interface iArrayB extends iArrayA ['b' => string, 'c' => ?string, ‘d’ 
> =>  SomeClass, ‘e’=>  iArrayA, ‘f’ => mixed ]
> $array = (iArrayA &| iArrayB) [ ‘a’ => ‘hello’ ];
>
>
> That would allow us to move into an implementation discussion, which is 
> also absolutely needed. 
>
> Best, 
> Richard Miles

As Stephen already said, we have this already.  It's spelled like this:

class A {
  public function __construct(public string $a) {}
}

class B extends A {
  public function __construct(
public string $a, 
public string $b, 
public ?string $c,
public SomeClass $d,
public A $e,
mixed $f,
  ) {}
}

If you know the keys at code time, use a class, not an array.  Full stop, 
period, end of story.  Using an array as a record object in PHP >= 7 *is 
wrong*.  It's slower, more memory-intensive, less ergonomic, harder to debug, 
harder to statically analyze, harder to learn, harder to use.  If you're still 
doing that, it's past time to stop.  If your legacy application from the PHP 3 
days is still doing that, it's past time to upgrade it.

So new language features to make "misuse arrays as objects" easier are actively 
counter-productive.

A Dict / Hashmap is appropriate when you do *not* know the keys in advance, and 
thus cannot use a pre-defined object for it.  There are plenty of use cases for 
that, but in that case, all you need type-wise is the key type and value type, 
because all entries should be of the same type (give or take inheritance).  
Mixing in random other types... is wrong.  That's the whole reason why people 
keep talking about collections/typed arrays/generics.

So the "array interface" syntax you keep posting is actively counter-productive.

--Larry Garfield


Re: [PHP-DEV] Iteration III: Packages (was Re: [PHP-DEV] [Initial Feedback] PHP User Modules - An Adaptation of ES6 from JavaScript)

2024-07-01 Thread Larry Garfield
On Sun, Jun 30, 2024, at 8:28 PM, Michael Morris wrote:
> So let's take another crack at this based on all the points raised in 
> the thread. This should also underline why I don't consider this an RFC 
> - I am iterating until we arrive at something that may be refinable 
> into an RFC. And I say we because without the aid of those in this 
> conversation I would not have arrived at what will follow.
>
> Before I continue I would like to apologize for being somewhat 
> irritable. We're all here because we enjoy using this language and want 
> to see it improved and prevent bad changes. Opinions will differ on 
> this and in the heat of the moment of arguing a point things can get 
> borderline.
>
>
> Returning to a point I made earlier, Composer isn't used on Wordpress.  
> I went over to the Wordpress discussion list and read over why, because 
> that discussion provides clues to what kind of package management may 
> be adoptable. I think the largest point is that Wordpress should be 
> usable without ever resorting to using the command line. Yes, it does 
> have a command line tool - wp-cli - and it is powerful, but using it as 
> an administrator of a Wordpress site is not required.
>
> The largest block to composer's inclusion in Wordpress is the inability 
> to run multiple versions of a module. Yes, it's a mess when this 
> happens, but if you're an end user, you just want your plugins to work. 
>  If one plugin that no one has updated in a year that you're using is 
> consuming version 2 of a package, you're gonna be annoyed at best if 
> the module stops working when you install a new plugin that is using 
> version 3 of the same package and has a BC break in it.  Composer can't 
> resolve this easily.

There's still a few key, fatal issues in this version of the proposal.

1. It appears like it expects PHP to be able to write to disk itself as part of 
normal operation.  This is an immediate fatal flaw.  Most security best 
practices these days recommend that the disk where code is be read-only.  Some 
hosting companies mandate it.  Any language feature that precludes that is dead 
in the water.

2. Supporting multiple versions of the same class is *wy* out of scope.  
You seem to imply Composer is the reason we cannot do that.  That's incorrect.  
PHP has a single global symbol table for classes.  (And a separate one for 
functions for not-great historical reasons.)  Trying to define the same class 
twice will fatal the engine.  While there are some screwy conditional-include 
games you can play, they're fragile and still would not allow WP Plugin A to 
use v1 of a library and WP Plugin B to use v2 of a library.  I am not versed in 
that part of the engine, but I would be shocked if splitting up the global 
symbol table was possible, let alone feasible.

3. Using URLs as the package naming system is the dumbest thing Go ever did.  
Let's not replicate that. :-)

I think the core problem here is that this thread keeps trying to graft 
Python/Go/JS/Rust style packages onto PHP.  PHP, however, is structurally 
closer to Java/C#, so following that package logic (which is built off of 
namespaces) would be far more natural, and thus far easier to migrate to.

Really, the only targets we should be looking at, IMO, are:

1. Package-level visibility.
2. Giving the compiler/optimizer/JIT a larger "scope" of code to 
compile/optimize at once, so it can do smarter things.

I think everything else is a distraction.

I have some thoughts on how we can far more easily accomplish 1, and maybe 2, 
but I will probably hold off on that for now as it would just get lost in the 
noise of this thread, plus the list is too busy as is these days with everyone 
trying to get their in-flight RFCs finalized before the feature freeze 
deadline. :-)  (Really, this is a poor time to be having this kind of 
discussion.  Fall is generally the better time, just logistically.)

--Larry Garfield


Re: [PHP-DEV] [Initial Feedback] Typed Arrays

2024-07-01 Thread Larry Garfield
On Mon, Jul 1, 2024, at 4:48 AM, Michał Marcin Brzuchalski wrote:
> pon., 1 lip 2024 o 03:01 Larry Garfield  napisał(a):

>> Contextual point: Nearly every other major language at this point that has a 
>> meaningful standard library has gone with a three-separate-object approach 
>> (Seq, Set, Dict, called various things).  At least Python, Javascript, Rust, 
>> Kotlin, and Swift, in my research.  (Go doesn't, but Go avoids having 
>> features by design.)  And AFAIK *every* language except PHP and Lua 
>> separates sequences from dictionaries.  Typed arrays will not full resolve 
>> the seq vs dict problem, which is arguably PHP's original sin.  And there's 
>> a lot of weird issues to resolve around what the syntax could even be, since 
>> PHP has untyped variables.
>> 
>> The custom collection syntax Derick has been working on is a second-best 
>> alternative to generics, essentially.  It is less ergonomic, no question, 
>> but can also be implemented without generics, and so is about 5x easier to 
>> do.  If we could get native generics, then I think everyone involved agrees 
>> building collections off of that -- in essentially the same way as every 
>> language I mentioned above --- would be preferable to a custom one-off 
>> syntax.
>> 
>> --Larry Garfield
>
> Considering other languages it is worth mentioning that Java and C# 
> have generics AND typed arrays that act as a typed list/seq so sure it 
> doesn't solve all problems otherwise these languages wouldn't have both 
> of them.

I believe in those languages Array came first, and then the collections were 
added later when they determined that Array was insufficient and too low-level. 
 (I'm not an expert on the history of either language, but that's my 
understanding from reading their documentation.)  Using the collections is the 
preferred approach now for most applications.

> From my personal experience, a typed list/seq solves most cases where I 
> need the elements of an array to be strictly instances of a specific 
> type.
> What I see typed list/seq like `string[]` has more ergonomics, it can 
> be used to interact between libraries and application code without 
> creating intermediate objects, while collection proposal always 
> requires declaring type - this simply multiplies the number of declared 
> types and create more coupling where it is not needed! Also, most cases 
> I work with are just fine with using just foreach or array_ family 
> functions.

Yes, the need to create the monomorphized object yourself is a downside of the 
dedicated collections syntax.  No question.  The trade-off is that it's vastly 
easier to implement than either full generics or typed arrays.  We haven't 
fully developed it yet as there's still experimentation going on (by people 
with far more engine knowledge than me) to see if we can have our cake and eat 
it too.

> This doesn't have to collide with generics in any way, as mentioned 
> before in the thread these features may exist simultaneously, typed 
> list/seq can translate in the future to a generic type.
> I believe it'd make people's lives easier if we could have this in 
> place soon.
> Don't you agree?
>
> Cheers,
> Michał Marcin Brzuchalski

1. I think you are vastly under-estimating the level of effort for making typed 
arrays, and making them performant.  Arnaud has been exploring that, and it's 
far from trivial.  "Have this in place soon" hand-waves over an awful lot of 
complexity.

2. You're correct that typed arrays and generics could coexist in the language, 
if both could be implemented.  But that is also a lot of work, with overlapping 
problem spaces.

3. The core failing of typed arrays is that they still don't guarantee a 
sequence; everything is still a string|int key dictionary with no support for 
object keys, and PHP's screwy array-specific type casting.  Frankly, people who 
don't see the challenges here have not tried to write array-handling libraries. 
:-)  (Crell/fp taught me all kinds of things about how broken arrays are, due 
to their fundamental unpredictability.)

--Larry Garfield


Re: [PHP-DEV] [Initial Feedback] Typed Arrays

2024-06-30 Thread Larry Garfield
On Sun, Jun 30, 2024, at 11:13 AM, Michał Marcin Brzuchalski wrote:
> Hi Richard,
>
> czw., 27 cze 2024, 22:33 użytkownik Richard Miles 
>  napisał:
>> 
>> > I worked with Joe Watkins to do a proof-of-concept for generic traits.
>> > It's a bit old since it's from 2017, but could be a useful starting
>> > point if you are serious about pursuing this idea:
>> > 
>> > https://github.com/php/php-src/compare/master...morrisonlevi:php-src:parameterized_traits
>> 
>> 
>> I’m also interested in this; it will help see branches like these.
>> Did you ever get the POC working? What did you feel like was the biggest 
>> hurdle?
>
> There even was an RFC in voting which Joe implemented and it addresses 
> nearly what is discussed it this thread https://wiki.php.net/rfc/arrayof
>
> I must admit that the collection proposal is bit too complex to 
> address such tiny but powerfully in my opinion functionality which is 
> typed array. What Derick showed looks more like generic collection and 
> such require declaring it's type. In my opinion this is way too mush 
> hassle to declare as many collection types as many usages in 
> application. Also two collection types with the same collection item 
> type will not be compatible from type perspective. While typed array 
> seems much more clear and compatible in all places where typed array is 
> needed without declaring separate type for each usage.
>
> If I were to choose between typed-array and collection like Derick 
> showed a little bit I'd choose typed arrays definitely as a first 
> feature to be merged into PHP.
>
> Cheers,
> Michał Marcin Brzuchalski

Contextual point: Nearly every other major language at this point that has a 
meaningful standard library has gone with a three-separate-object approach 
(Seq, Set, Dict, called various things).  At least Python, Javascript, Rust, 
Kotlin, and Swift, in my research.  (Go doesn't, but Go avoids having features 
by design.)  And AFAIK *every* language except PHP and Lua separates sequences 
from dictionaries.  Typed arrays will not full resolve the seq vs dict problem, 
which is arguably PHP's original sin.  And there's a lot of weird issues to 
resolve around what the syntax could even be, since PHP has untyped variables.

The custom collection syntax Derick has been working on is a second-best 
alternative to generics, essentially.  It is less ergonomic, no question, but 
can also be implemented without generics, and so is about 5x easier to do.  If 
we could get native generics, then I think everyone involved agrees building 
collections off of that -- in essentially the same way as every language I 
mentioned above --- would be preferable to a custom one-off syntax.

--Larry Garfield


Re: [PHP-DEV] [RFC] [Discussion] Add bcdivmod to BCMath

2024-06-30 Thread Larry Garfield
On Sun, Jun 30, 2024, at 10:11 AM, Saki Takamachi wrote:
> Hi,
>
>>> Just a suggestion: what about making the returned array an associative
>>> array ? Like so:
>>> ```
>>> array(
>>>  'quotient' => 61,
>>>  'remainder' => 1,
>>> );
>>> ```
>>> This would remove the need for devs to remember the order of the return
>>> values and would make the return value self-documenting.
>> 
>> An associative array would combine the worst of an array (no IDE 
>> autocompletion, no strong typing, increased memory usage) with the worst of 
>> an object (no easy way to extract the values into local variables with array 
>> destructuring).
>> 
>> The example in the RFC doesn't show it, but the following makes the proposed 
>> API really convenient to use:
>> 
>>$slicesOfPizza = new BcMath\Number(8);
>>$mouthsToFeed = new BcMath\Number(3);
>>[$perMouth, $slicesLeft] = $slicesOfPizza->divmod($mouthsToFeed);
>> 
>> Note how the order of values matches the words in the method name. First the 
>> result of 'div', then the result of 'mod’.
>
>
> Thanks, I have added this example to the RFC (Please let me know if you 
> have any problems).
>
>
>> I came here to say the same thing. The best solution would be not having to 
>> refer to documentation or experiment with values, and this hits the nail on 
>> the head.
>> 
>> The only thing that makes it weird is having to write it out, which at that 
>> point, it is probably faster to type out bcdiv and bcmod separately.
>> 
>> Have you considered simply using references passed to the function? I feel 
>> like that is more idiomatically php.
>
> Of course, that idea was proposed, but it was pointed out that current 
> PHP tends to avoid such implementations, so we didn't adopt it. The 
> reason why passing by reference was not adopted was added to the RFC.
>
> Regards,
>
> Saki

I agree an associative array is the second-worst option.  An inout by-ref 
argument is the absolute worst.

Normally my default position is that when in doubt, make it a structured object 
with properly defined properties, and screw whatever micro-performance hit it 
is, you won't notice.  99% of the time I believe that is the correct approach.

I can see the argument that this is the other 1%, since it's just two values, 
which will basically always be wanted separately but both wanted (meaning 
divmod(...)->divsor is kinda pointless), and their order should be fairly 
self-evident.

However, in that case I would urge that both the RFC and the resulting 
documentation *always* use examples that return into a `[$foo, $bar]` 
destructured list.  Don't even suggest that people should use 0 and 1 indexes.  
It's a tuple for deconstruction, that's it, if you're using it some other way 
you're probably wrong.  Politely ignore that it's even possible, lest we lead 
people down the dark path.

(Which means removing the current index-using example and just keeping the 
pizza example.)

--Larry Garfield  


Re: [PHP-DEV] [RFC] [Discussion] Add WHATWG compliant URL parsing API

2024-06-30 Thread Larry Garfield
On Sun, Jun 30, 2024, at 1:00 AM, Máté Kocsis wrote:
>> It mirrors the interface, but it can’t be swapped out for a UriInterface 
>> instance, especially since it can’t be extended, so I wouldn’t consider it 
>> compatible. I would still need to write a compatibility layer that composes 
>> Url\Url and implements UriInterface.
>
> I guess my words were slightly misleading: what I should have written 
> is that the methods themselves are compatible.
> 
>> Since PSRs are concerned with shared interfaces and this class is final and 
>> does not implement any interfaces, I’m not sure how you envision “a next 
>> iteration” of PSR-7 to use this directly, unless what you mean is that 
>> UriInterface would be deprecated and applications would type directly 
>> against Url\Url.
>
> Yes, I meant the latter exactly. If we had a well-usable URL object 
> representation in the standard library, then there would be no need to 
> have an userland interface as well (unless they have different behavior 
> or purpose). Analogically, we have DateTimeImmutable, and there is no 
> PSR for a date time interface. (I know there is Carbon and other 
> libraries, but they are for convenience, not for interoperability).

I cannot speak on behalf of FIG here, but as a long-time member of FIG and a 
member of the Core Committee, I would urge you to *not* try to make a core Url 
object compatible with UriInterface.  It's solving a slightly different 
problem, using a language that is very different (PHP 8.4 vs 5.5 or so), with 
somewhat different constraints.

Instead, let's make sure that any new Url object is *composable* by PSR-7 
UriInterface.  A UriInterface implementation that is backed by a Url object 
internally should be an easy task to do if anyone wants, and we should make 
sure we don't do anything that makes that unnecessarily hard, but right now the 
language is simply not capable of making core Url a drop-in replacement for 
UriInterface, so let's not even try.

Whether that means Url should be readonly or not, have getters/setters/withers, 
split authority into user:pass, etc. are things we should discuss on their own 
merits, not based on "well PSR-7 did it this way over 10 years ago, so we'll 
just do that."

--Larry Garfield


  1   2   3   4   5   6   7   8   9   10   >