Re: [PHP-DEV][RFC][DISCUSSION] Add grapheme_levenshtein function

2025-03-24 Thread Tim Düsterhus

Hi Yuya

Am 2025-03-16 02:12, schrieb youkidearitai:

I created the RFC page for grapheme_levenshtein.
https://wiki.php.net/rfc/grapheme_levenshtein
I would like go to voting at two weeks if any comment is nothing.

If any comment, feel free to comment.


My only comment would be that you forgot to adjust the RFC status to 
“Under Discussion” and to move it into the correct section on the 
overview page.


Other than that your RFC seems like a useful addition for the folks that 
need it, thanks for taking the feedback into account after the 
mb_levenshtein RFC failed!


Best regards
Tim Düsterhus


Re: [PHP-DEV] Re: RFC: short and inner classes

2025-03-24 Thread Rowan Tommins [IMSoP]



On 24 March 2025 09:20:03 GMT, "Alexandru Pătrănescu"  
wrote:
>On Sun, Mar 23, 2025 at 5:20 PM Larry Garfield 
>wrote:
>
>>
>> So, how would nested classes compare to fileprivate, in terms of ability
>> to solve the problem space?  As I understand it, the goal is:
>>
>> 1. Classes that can be instantiated only by the class that uses them.
>> 2. But can be returned from that class to a caller and reused as
>> appropriate.
>>
>
>
>I think the one other difference is that nested classes can access private
>variables or their outer classes.

You can achieve the same with "file private" access: in your example mark the 
constructor as "file private", and put the Builder in the same file

fileprivate function __construct(private array $points) {}


If you'll excuse a brief philosophical detour, I noticed something interesting 
in the Swift documentation: the description of nested classes doesn't describe 
any special scope access. Instead, the description of "access levels" defines 
"private" in a way that naturally includes them:

> Private access restricts the use of an entity to the enclosing declaration, 
> and to extensions of that declaration that are in the same file.

It's a subtly different framing - nested types aren't breaking into the private 
entity, the "private" keyword is explicitly letting nested types in.

A language could, if it chose, have different keywords for "private to exactly 
this type" and "private to this type and any nested types":

strict_private function __construct(private array $points) {}
private_or_nested function __construct(private array $points) {}

Just as there are many combinations like "this class, subclasses, or other 
classes in this module".


The point being that there's nothing fundamental about nested types that gives 
them access to private properties. What they do is give us a new dimension to 
define access levels of our choice - { contains, contained by, neither }.

File scope gives us instead the dimension { same file, different file }; and 
module scope gives us { same module, different module, no module }, and maybe 
some additional relationships between modules.


Rowan Tommins
[IMSoP]


Re: [PHP-DEV] RFC: short and inner classes

2025-03-24 Thread Larry Garfield
On Mon, Mar 24, 2025, at 3:47 AM, Rob Landers wrote:

> On Sun, Mar 23, 2025, at 16:17, Larry Garfield wrote:

>> I've been following this thread with interest, and at the moment I'm 
>> honestly undecided.  I certainly see the use cases for this functionality 
>> (whatever it gets named), but as a practical matter it sounds like it 
>> introduces a lot of extra clunk and complexity.  And it seems like the use 
>> cases could be addressed as well with either fileprivate or module-private.  
>> (The former being considerably less work.)
>> 
>> So, how would nested classes compare to fileprivate, in terms of ability to 
>> solve the problem space?  As I understand it, the goal is:
>> 
>> 1. Classes that can be instantiated only by the class that uses them.
>> 2. But can be returned from that class to a caller and reused as appropriate.
>> 
>> The autoloading question (loading a whole file for just an implementation 
>> detail value object) is not one that carries much weight for me, as that's a 
>> user-space question, not an engine question.  (Nothing in PHP itself says 
>> you cannot put 20 3 line classes or enums together in one file.  It's just 
>> PSR-4 that says not go. Even composer would allow it if configured properly) 
>>  So how would the less-complicated alternative compare?
>> 
>> --Larry Garfield
>
> Hey Larry,
>
> I think file-private would/could be useful, but that only limits you to 
> a "private" scope, which severely hampers what you can do with it. If 
> we went with "module-private" (rhetorical question: what is a module?), 
> but then you wouldn't be able to have "private" scope.

When I say module scope, I'm referring to something along the lines that Arnaud 
and I were exploring a while back.  tldr, "cluster of files with a common 
namespace root, which can get loaded together."  It was mostly about 
performance, but did offer module-private as well, with some nice potential.  
At the moment it's stalled out on "there's nasty hard edge cases and we're not 
sure if it's worth it" concerns.

Concept brain dump here: 
https://github.com/Crell/php-rfcs/blob/master/modules/spec-brainstorm.md
Code exploration from Arnaud here: https://github.com/arnaud-lb/php-src/pull/10

Still well short of RFC state, of course, but provided for context.

> With nested/inner classes, for example, you can put a protected class 
> on a class or interface and access it only from those that use it, 
> regardless of what file or "module" (namespace?) they are in; the logic 
> can be encapsulated to where it is used, not where it is defined.
>
> interface Shipment {
>   protected class Items {}
>   public readonly class Destination {}
>   function deliver(self:>Destination $destination);
> }
>
> class InternationalShipment implements Shipment {
>   private function handle(Shipment:>Items $items) {}
>
>   public function deliver(Shipment:>Destination $destination) {}
> }

In this case, I am not seeing what the nesting gets you.  Making Destination a 
normal class doesn't hurt anything here, does it?

> However, you can use private nested/inner classes to encapsulate the 
> logic to where it is defined instead, like file-private would give you.
>
> The goal here isn't to only to reduce "namespace pollution" but also to 
> encapsulate related logic integrally connected to the outer class's 
> behavior. Since you've referenced Kotlin a number of times, I assume 
> you are familiar with the concept of nested classes there? This is 
> extremely similar.

My short foray into Kotlin did not include nested classes, so I cannot speak to 
them other than knowing they exist.

--Larry Garfield


Re: [PHP-DEV] Re: Constructor property promotion for final properties

2025-03-24 Thread Daniel Scherzer
On Mon, Mar 24, 2025 at 11:22 AM Larry Garfield 
wrote:

>
> To answer the original question: I'm not against this change, but as it is
> a syntax change, I think it does warrant an RFC, even if it's a small/easy
> one.  That's a good way to flesh out the edge cases like that.
>
> --Larry Garfield
>

Okay, I've created https://wiki.php.net/rfc/final_promotion - I'll send an
official notification email separately, but just wanted to include a link
in the original thread.

--Daniel


Re: [PHP-DEV][RFC][DISCUSSION] Add grapheme_levenshtein function

2025-03-24 Thread youkidearitai
2025年3月25日(火) 3:21 Tim Düsterhus :

> Hi Yuya
>
> Am 2025-03-16 02:12, schrieb youkidearitai:
> > I created the RFC page for grapheme_levenshtein.
> > https://wiki.php.net/rfc/grapheme_levenshtein
> > I would like go to voting at two weeks if any comment is nothing.
> >
> > If any comment, feel free to comment.
>
> My only comment would be that you forgot to adjust the RFC status to
> “Under Discussion” and to move it into the correct section on the
> overview page.
>
> Other than that your RFC seems like a useful addition for the folks that
> need it, thanks for taking the feedback into account after the
> mb_levenshtein RFC failed!
>
> Best regards
> Tim Düsterhus
>


Hi Tim

I moved "Under Duscussion" section for RFC page.
Thank you very much asking.
(I writing this email to moving, I'm sorry if wrong English)

Regards
Yuya

>


[PHP-DEV] [RFC] [Discussion] Final promoted properties

2025-03-24 Thread Daniel Scherzer
Hi internals,

I'd like to start the discussion for a new RFC about allowing final
promoted properties. You can see some preliminary discussion at <
https://externals.io/message/126475>, but this is now an official RFC.

* RFC: https://wiki.php.net/rfc/final_promotion
* Implementation: https://github.com/php/php-src/pull/17861

--Daniel


Re: [PHP-DEV] Feedback for nullc Idea

2025-03-24 Thread Robert Chapin

On 3/23/2025 11:10 AM, Larry Garfield wrote:

I'm not sure it justifies a new pseudo-function language construct.


Fair enough.  Thank you for the feedback.

On 3/23/2025 2:37 PM, Rowan Tommins [IMSoP] wrote:
It's telling that all your examples with ?? put a value other than 
null on the right-hand side.


I may have over-simplified the examples.  Comparing $input === 'yes' 
will have the same result whether $input is null or 'none' or an empty 
string.  So not implying a result type, just want to compare a literal 
or other variable to $input even when not declared.


A different example could be if (coalesce($_POST['tick']) > 10) return;

In my experience, a lot of people struggle to follow logic like this, 
and it can easily lead to subtle bugs. Compare the same logic with 
explicit defaults:


if (nullc($test, 'off') === 'on')
if (nullc($test, 'on') !== 'off')


Having optional defaults seems fine.  Meanwhile...

if ($test ?? 'on' !== 'on') will evaluate to true when $test is set to 'on'.

There is a small risk that some people might have an existing function 
with different behaviour, e.g. a test on "emptiness" with `$arg != 
false`, and need to rename it when upgrading PHP.


This is a good point.  I assume that risk exists for all new functions 
and needs to be considered.


I'm still only lukewarm on including it, because it's mostly just 
reminding you to include a pair of parentheses:


Think of it as a quick way to use an undeclared variable without having 
to explain operator precedence to other developers.


In any case, thank you for the feedback.


Re: [PHP-DEV] PHP True Async RFC - Stage 2

2025-03-24 Thread Edmond Dantes
>
> You're cheating again - you've put an extra pair of brackets around one
> expression and not the other, and assumed they'll work differently, but
that's
> not the grammar you proposed.
>

Why am I cheating?
> spawn (getClosure());
This is an honest statement, provided that the second parentheses are
optional. The full notation would be:
> spawn (getClosure())();

> Instead you'd have to write this:
> spawn (function() use(): string { return "string"; });

Exactly right, that's how it should be according to PHP syntax.
Therefore, if we want to get rid of double parentheses, we need a separate
rule for closures.

I would name these two cases as follows:
* spawn callable – the general usage case
* spawn closure – the special case for closures

I don't think these two rules make the language inconsistent because the
`function` keyword allows separating the first expression from the second
one.

`spawn function` means that a `Closure` definition follows.
Accordingly, there should be no additional parentheses `()` at the end.

The reverse meaning is that if `spawn` is not followed by the `function`
keyword, then it must be a valid expression that can be enclosed in
parentheses.
There are some doubts about whether all situations are correct, but so far,
this is how it works for me:

- call a standard PHP function

```php
spawn file_get_contents('file1.txt');
```

- call a user-defined function

```php
function example(string $name): void {
echo "Hello, $name!";
}

spawn example('World');
```

- call a static method

```php
spawn Mailer::send($message);
```

- call a method of an object

```php
$object = new Mailer();
spawn $object->send($message);
```

- self, static or parent keyword:

```php
spawn self::send($message);
spawn static::send($message);
spawn parent::send($message);
```

- call `$class` method

```php
$className = 'Mailer';
spawn $className::send($message);
```

- expression

```php
// Use result of foo()
spawn (foo())();
// Use foo as a closure
spawn (foo(...))();
// Use ternary operator
spawn ($option ? foo() : bar())();
```

- call array dereference

```php
$array = [fn() => sleep(1)];
spawn $array[0]();
```

- new dereference

```php
class Test {
public function wait(): void {
sleep(1);
}
}

spawn new Test->wait();
```

- call dereferenceable scalar:

```php
spawn "sleep"(5);
```

- call short closure

```php
spawn (fn() => sleep(1))();
```

> Sorry, what is exactly what we'd like to avoid?

Syntax ambiguities.
But it seems that avoiding them completely is impossible anyway because
I've already found an old case where a property and a method are used in
the same expression.


Re: [PHP-DEV] Re: RFC: short and inner classes

2025-03-24 Thread Alexandru Pătrănescu
On Sun, Mar 23, 2025 at 5:20 PM Larry Garfield 
wrote:

>
> So, how would nested classes compare to fileprivate, in terms of ability
> to solve the problem space?  As I understand it, the goal is:
>
> 1. Classes that can be instantiated only by the class that uses them.
> 2. But can be returned from that class to a caller and reused as
> appropriate.
>


I think the one other difference is that nested classes can access private
variables or their outer classes.
Example:
```
class Polygon {
private function __construct(private array $points) {}
public function getPoints(): array {
return $this->points;
}
public class Builder {
private array $points = [];
public function addPoint(Points $point): self {
$this->points[] = $point;
return $this;
}
public function build(): Polygon {
if (count($this->points) < 3) {
throw new InvalidArgumentException('A polygon must have at
least 3 points');
}
return new Polygon($this->points);
}
}
}
```
And it would be used like this:
```
$polygon = new Polygon::Builder()
->addPoint($point1)
->addPoint($point1)
->addPoint($point1)
->build();
```
With no way to create a Polygon otherwise, due to the private constructor.

-- Alex


Re: [PHP-DEV] Feedback for nullc Idea

2025-03-24 Thread Aimeos | Norbert Sendetzky

On 23.03.25 19:37, Rowan Tommins [IMSoP] wrote:
I'm sympathetic to the problem you're trying to solve - the precedence 
of ?? isn't always helpful - but I'm not sure I like the proposed 
solution, for 3 reasons.


1) The name "nullc" is over-shortened and cryptic. The "c" looks almost 
like an accident, and it doesn't actually do anything if given a null.


To me, a wider approach might be more helpful, i.e. using "get" with an 
optional default value:


if(get($a['val']))
// equals if($a['val] ?? null)

if(get($a['val'], true))
// equals if($a['val] ?? true)

if(get($a['val], 'yes'))
// equals if($a['val] ?? 'yes')

Best,

--
Norbert Sendetzky

Aimeos GmbH
Rennbahnstr. 32
DE-22111 Hamburg

E-Mail: norb...@aimeos.com
Phone:  +49 40 8668 4492
Web: aimeos.com

Trade register: District court Hamburg HRB 143090
Managing director: Norbert Sendetzky
VAT ID: DE302287839