Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> Secondary votes are generally discouraged.  I can see the argument for 
> wanting a short-short version of set, given how common the validation use 
> case is, but => is almost universally the "evaluates to" symbol, so using 
> that for a set operation rather than get just feels weirdly inconsistent.  If 
> there were a set-only shorthand, it should be something else.
>
> That said, the ideal for validation would probably be guard clauses, like 
> this, but that would be a completely different RFC for another time.
> ```
> function foo(string $name where strlen($name) < 10) { ... }
>
> class Foo {
>   public function __construct(
> public string $name where strlen($name) < 10;
>   ) {}
> }
> ```
```guard``` seems a subset feature of ```hook```, although you want to
expand its use case in parameter. Property and parameter are variable.
If ```guard``` can be implemented in both case as you write above,
theoretically  ```hook``` can be either. I will choose ```hook```
rather than ```guard``` to anticipate future expansion. Isn't it
better to choose one broad concept than many?

I found a contradiction here. Previously you said that:
> ... the problem with omitting the {} is that it creates yet another syntax 
> variant. That makes it harder for the parser, for static analyzers, for 
> user-space parsing tools like php-parser, etc. That's more work for everyone 
> for fairly little gain.

And here, you introduce a syntax variant. Is it really significant if
we introduce a new ```where``` keyword ```compared to the already used
```get``` keyword? I will clarify here in case there is
misunderstanding:
* If we have more than one hook per property, then the syntax will be
the same as proposed by RFC.
* If we have only one hook per property, than the syntax are:
```
public function __construct(
  public string $prop1 get => strtoupper($this->_prop1),
){}

public function __construct(
  public string $prop2 set => $field = strtolower($value),
){}

public function __construct(
  public string $prop3 get {
$temp = strtoupper($this->_prop1);
return substr($temp, 0, 10) . '...';
  },
){}

public function __construct(
  public string $prop4 set {
$temp = strtolower($value);
$field = substr($temp, 0, 10);
  },
){}
```
Note: Please ignore any error. The ending comma is actually part of
the parameter list, not a hook. So it becomes optional if the param is
only one or it is the last param.

All the examples are constructor property promotion, because that is
my only concern. Because the space is limited, the more consistent the
code, the better. If I have to write hooks outside CPP, I don't mind
using the other syntax. There's plenty of room to fill, and
consistency is tolerable.

Should we postpone the implementation of the shortest version?
Hopefully we have enough time to decide which one will be implemented
next.

>
> ... Ilija also noted to me off-list that you could also have a set hook that 
> throws an exception rather than just being null, which would also work to 
> prevent writes.

Such a coincidence. I was going to revise my code:
```
// cache once and freeze,
// and without additional hidden property
// in case asymmetric visibility in not implemented yet
public string $prop1 {
  get => $field ??= $this->heavyTask($this->propx, $prop->y);
  set => throw new Exception("prop1 is read only");
}
```

> I think an unset hook is a fine addition in the future.  The way the code is 
> implemented it should be straightforward to add.  However, it feels like 
> scope creep to include it right now, especially when there are workarounds 
> available.  If there's a clear consensus from voters to include it, though, 
> we can consider that.  (Meaning, anyone that would favor including an unset 
> hook now, speak up or we'll assume it's better to stick with just get/set for 
> now.)

+1 for including ```unset``` as part of this RFC.

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



Re: [PHP-DEV] [RFC] Define proper semantics for range() function

2023-05-15 Thread Jorg Sowa
Hello!

I have one concern about the part:

> Emit an E_WARNING when $start or $end is cast to an integer because the
other boundary input is a number or numeric string. (e.g. range
('5', 'z'); or range (5,
'z');)

Doesn't it limit the functionality of the function for the numbers as
characters? Currently when we call range('/','z') we get full range of
characters. https://onlinephp.io/c/9cb12

But when we change argument $start to next character which is zero ('0')
then we get array with only one element. https://onlinephp.io/c/a0cda

Casting numerical string in this function may be confusing.

Sorry for making fuss just before voting, but didn't see this topic before
and wanted to share my insights with you thinking it may be relevant.

Kind regards,
Jorg

On Mon, May 15, 2023 at 4:42 PM G. P. B.  wrote:

> Hello Internals,
>
> I plan to put the RFC to a vote tomorrow in its current state, which has
> not been changed since the 30th of March:
> https://wiki.php.net/rfc/proper-range-semantics
>
> Any final comments or complaints should be raised now.
>
> Best regards,
>
> George P. Banyard
>


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
On Mon, May 15, 2023, at 8:12 PM, Hendra Gunawan wrote:

>> For the second, the problem with omitting the {} is that it creates yet 
>> another syntax variant.  That makes it harder for the parser, for static 
>> analyzers, for user-space parsing tools like php-parser, etc.  That's more 
>> work for everyone for fairly little gain.
>
> Sad to read that. Making one of them as the shortest shorthand feels
> like a picky decision. Some people agree with ```get```. Some people
> will argue that ```set``` deserves more than ```get```. Personally, I
> choose ```set``` to be the shortest shorthand as it is more relevant
> with constructor property promotion and value object. Do we need a 2nd
> vote for this one?

Secondary votes are generally discouraged.  I can see the argument for wanting 
a short-short version of set, given how common the validation use case is, but 
=> is almost universally the "evaluates to" symbol, so using that for a set 
operation rather than get just feels weirdly inconsistent.  If there were a 
set-only shorthand, it should be something else.

That said, the ideal for validation would probably be guard clauses, like this, 
but that would be a completely different RFC for another time.

function foo(string $name where strlen($name) < 10) { ... }

class Foo {
  public function __construct(
public string $name where strlen($name) < 10;
  ) {}
}

>> What we really would need here is asymmetric visibility.  No set hook, but 
>> make the property private(set) so that trying to write to it gives an error, 
>> as it should.
>
> So if asymmetric visibility is implemented, will my code be this simple?
> ```
> // cache once and freeze,
> // and without additional hidden property
> public private(set) string $prop1 {
>   get => $field ??= $this->heavyTask($this->propx, $prop->y);
> }
> ```

If you don't want cache clearing, yes.  Ilija also noted to me off-list that 
you could also have a set hook that throws an exception rather than just being 
null, which would also work to prevent writes.

For clearing that cached value, I think an unset hook is probably the best way, 
with either approach.

>>  For cache clearing, the best way to do that is probably with an unset hook. 
>>  That's been omitted from the RFC for now for simplicity, but that sounds 
>> like it would be an argument to introduce it later.
>
> I was going to write about this one. IMO, why do we need to provide
> additional hidden properties, when we are able to store the cache
> directly into it? Obviously we need a ```unset``` hook.

I think an unset hook is a fine addition in the future.  The way the code is 
implemented it should be straightforward to add.  However, it feels like scope 
creep to include it right now, especially when there are workarounds available. 
 If there's a clear consensus from voters to include it, though, we can 
consider that.  (Meaning, anyone that would favor including an unset hook now, 
speak up or we'll assume it's better to stick with just get/set for now.)

--Larry Garfield

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> (Also, when replying, please please remove duplicate names from the to/cc 
> line.  I just got double copies of everything in this thread this morning.  
> I'm on the list, I don't need to be CCed.)

Sorry about that. Not my habit before.

> For the second, the problem with omitting the {} is that it creates yet 
> another syntax variant.  That makes it harder for the parser, for static 
> analyzers, for user-space parsing tools like php-parser, etc.  That's more 
> work for everyone for fairly little gain.

Sad to read that. Making one of them as the shortest shorthand feels
like a picky decision. Some people agree with ```get```. Some people
will argue that ```set``` deserves more than ```get```. Personally, I
choose ```set``` to be the shortest shorthand as it is more relevant
with constructor property promotion and value object. Do we need a 2nd
vote for this one?

> Removing the {} entirely from all forms makes it harder to denote where the 
> list of hooks begins and ends.  They would probably have to be 
> comma-separated, like this:
>
> public string $foo
>   get { return $this->bar; },
>   set { $this->bar = $value; };
>
> Which I'd argue is harder to read anyway, because you have to be careful of 
> the very small , and ; marks.  The {} is just easier for humans to parse as 
> well as the machine.

Looks like it's not more simple compared to the other one.

> What we really would need here is asymmetric visibility.  No set hook, but 
> make the property private(set) so that trying to write to it gives an error, 
> as it should.

So if asymmetric visibility is implemented, will my code be this simple?
```
// cache once and freeze,
// and without additional hidden property
public private(set) string $prop1 {
  get => $field ??= $this->heavyTask($this->propx, $prop->y);
}
```

>  For cache clearing, the best way to do that is probably with an unset hook.  
> That's been omitted from the RFC for now for simplicity, but that sounds like 
> it would be an argument to introduce it later.

I was going to write about this one. IMO, why do we need to provide
additional hidden properties, when we are able to store the cache
directly into it? Obviously we need a ```unset``` hook.

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



Re: [PHP-DEV] [RFC] [Discussion] Deprecate functions with overloaded signatures

2023-05-15 Thread Matthew Sewell


> On 15 May 2023, at 19:51, Rowan Tommins  wrote:
> 
> On 15 May 2023 19:38:56 BST, Larry Garfield  wrote:
> 
>> I agree entirely.  Setting reasonable expectations for users to plan around, 
>> such as a known 5-years-per-major cycle, helps end users far more than 
>> "whelp, we did something big, version number time!"
> 
>> Tangent: If I were to put together an RFC that set out such a 5 year cycle 
>> expectation with reasonable guidelines around when things could be 
>> deprecated, would anyone actually support it?
> 
> A big yes from me, but I've not had the most promising responses when banging 
> that drum in the past.
> 

Hi,

As an end user this would be very useful and address a lot of queries when 
planning and budgeting for PHP developments, especially if major breaking 
changes were also in .0 versions as I saw suggested elsewhere in a recent 
thread (also from Larry I think).

I've been spending a lot of time reading around and thinking after the "Future 
Stability of PHP Thread" last month and think that this level of predictability 
would do a lot to mitigate issues (though appreciate it would have other 
consequences).

Best wishes,

Matt 



Re: [PHP-DEV] [RFC] [Discussion] nameof

2023-05-15 Thread Robert Landers
> 3v4l.org is great for verifying things like this, because you can see at a 
> glance if there's been a change in behaviour in previous versions, or indeed 
> versions newer than you have installed. If you've got an up to date PhpStorm, 
> you can actually use it directly from a scratch file. (Huge shout-out to Sjön 
> Hortensius for making and maintaining such a useful tool!)

I've never used a scratch file in PhpStorm until just now and it is
quite magical, thanks for the tip.

Robert Landers
Software Engineer
Utrecht NL

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



Re: [PHP-DEV] [RFC] [Discussion] Deprecate functions with overloaded signatures

2023-05-15 Thread Rowan Tommins
On 15 May 2023 19:38:56 BST, Larry Garfield  wrote:

>Tangent: If I were to put together an RFC that set out such a 5 year cycle 
>expectation with reasonable guidelines around when things could be deprecated, 
>would anyone actually support it?

A big yes from me, but I've not had the most promising responses when banging 
that drum in the past.

Regards,

-- 
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
On Mon, May 15, 2023, at 8:32 AM, Lynn wrote:

> It's starting to get crowded in object constructors. The following example
> is so much more readable and maintainable imo. Would it be possible to
> still add the quick assignment as a language feature? I'm personally not
> happy having property definitions in both the class body _and_ the
> constructor signature.
>
> ```php
> class User {
> private string $first;
> private string $last;
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
>
> public function __construct($this->fullName) {}
> }
>
> // vs
>
> class User {
> private string $first;
> private string $last;
>
> public function __construct(
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
> ) {}
> }
>
> // or
>
> class User {
> private string $first;
> private string $last;
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
>
> public function __construct(string $fullName)
> {
> $this->fullName = $fullName;
> }
> }

The last version skips constructor promotion entirely, so will absolutely work. 
 For this case, that's frankly the best approach, since you're right, the 
constructor gets rather messy otherwise.

Changing the syntax and semantics for CPP itself (as in the first code block 
above) is considerably out of scope for this RFC.  I recall someone pointing 
out why double-declaring the property would cause problems, but I forget the 
reason.  In any case, another promotion syntax would be a topic for another 
RFC.  I don't recall off hand the reasons Nikita had for choosing the syntax 
that ended up being used.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] [Discussion] nameof

2023-05-15 Thread Rowan Tommins
On 15 May 2023 19:26:09 BST, Robert Landers  wrote:

>php -a
>Interactive shell
>
>php > use \NoExists\Channel;
>php > echo Channel::class;
>Channel
>
>Turns out, it's a CLI specific thing

Ah, probably each line in the interactive shell is considered a separate 
compilation context, like a separate file, so the use statement is no longer in 
effect on the next line.

3v4l.org is great for verifying things like this, because you can see at a 
glance if there's been a change in behaviour in previous versions, or indeed 
versions newer than you have installed. If you've got an up to date PhpStorm, 
you can actually use it directly from a scratch file. (Huge shout-out to Sjön 
Hortensius for making and maintaining such a useful tool!)

Regards,

-- 
Rowan Tommins
[IMSoP]

Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
Missed one...

On Mon, May 15, 2023, at 8:14 AM, Hendra Gunawan wrote:

> Can the engine detect these logical errors?
> ```
> public string $fullName = "hendra gunawan" => $this->first . " " . 
> $this->last;
>
> // or with my proposal:
> public string $fullName = "hendra gunawan" get => $this->first . " " .
> $this->last;
>
> // or even this one:
> public string $fullName = "hendra gunawan" {
>   get => $this->first . " " . $this->last;
>   set => [$this->first, $this->last] = explode(" ", $value);
> ```
>
> Explanation:
> There is no automatic backing store value created to store the default value.
>
> Terima Kasih.

Those would be compile-time syntax errors, yes.  (Or possibly link time, if 
inheritance is involved, but still before execution time.)

--Larry Garfield

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



Re: [PHP-DEV] [RFC] [Discussion] Deprecate functions with overloaded signatures

2023-05-15 Thread Larry Garfield
On Mon, May 15, 2023, at 6:36 PM, Rowan Tommins wrote:
> On 15 May 2023 09:54:41 BST, "G. P. B."  wrote:
>
>>Why are we assuming that PHP 9.0 is going to come after PHP 8.4?
>
> Historically, PHP has had a major release roughly every five years. The 
> main exception is PHP 6, which was never released - but whose major 
> features became PHP 5.3, five years after 5.0, and six before 7.0
>
> I think planning a rough timeline is more useful to users and 
> contributors than waiting until there's some exciting headline feature. 
> Otherwise, it becomes tempting to sneak in breaking changes in 8.x 
> because "we don't know how soon 9.0 is", or to have a rush of changes 
> because "we've only just decided 9.0 is soon".
>
> It also helps avoid putting a release number on an experimental feature 
> that might never arrive, as with Unicode strings in 6.0; or that might 
> turn out to be less important to most users than other changes, like 
> the JIT in 8.0.

I agree entirely.  Setting reasonable expectations for users to plan around, 
such as a known 5-years-per-major cycle, helps end users far more than "whelp, 
we did something big, version number time!"

Tangent: If I were to put together an RFC that set out such a 5 year cycle 
expectation with reasonable guidelines around when things could be deprecated, 
would anyone actually support it?

--Larry Garfield

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



Re: [PHP-DEV] [RFC] [Discussion] Deprecate functions with overloaded signatures

2023-05-15 Thread Rowan Tommins
On 15 May 2023 09:54:41 BST, "G. P. B."  wrote:

>Why are we assuming that PHP 9.0 is going to come after PHP 8.4?

Historically, PHP has had a major release roughly every five years. The main 
exception is PHP 6, which was never released - but whose major features became 
PHP 5.3, five years after 5.0, and six before 7.0

I think planning a rough timeline is more useful to users and contributors than 
waiting until there's some exciting headline feature. Otherwise, it becomes 
tempting to sneak in breaking changes in 8.x because "we don't know how soon 
9.0 is", or to have a rush of changes because "we've only just decided 9.0 is 
soon".

It also helps avoid putting a release number on an experimental feature that 
might never arrive, as with Unicode strings in 6.0; or that might turn out to 
be less important to most users than other changes, like the JIT in 8.0.

Regards,

-- 
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Larry Garfield
Consolidating all replies into a single message.  Please try to keep them 
together so it's easier to respond to.

(Also, when replying, please please remove duplicate names from the to/cc line. 
 I just got double copies of everything in this thread this morning.  I'm on 
the list, I don't need to be CCed.)

On Sun, May 14, 2023, at 11:41 PM, Hendra Gunawan wrote:

> Hi Larry.
>
> ```
> public string $fullName => $this->first . " " . $this->last;
> ```
> 1. Suppose that I forgot to declare ```$this->first```. Based on the
> "deprecate dynamic properties" proposal, will I get an error/warning?

Correct, it will behave the same as if you had a fullName() method that 
accessed an undefined $first property.  

> 2. The shorthand notations supported (the shortest one) creates
> impaired syntax, and not pretty to look at for constructor property
> promotion.
>
> ```
> public function __construct(
>   public string $prop1 => strtoupper($this->_prop1),
>   public string $prop2 {set => $field = strtolower($value);},
> ){}
> ```

Well, the first is not really valid anyway.  That creates a virtual property 
with no set hook, which when you pass a value to it in the constructor call 
will give an error that you are trying to write to a virtual property.  So 
that's already a non-issue.

For the second, the problem with omitting the {} is that it creates yet another 
syntax variant.  That makes it harder for the parser, for static analyzers, for 
user-space parsing tools like php-parser, etc.  That's more work for everyone 
for fairly little gain.

Removing the {} entirely from all forms makes it harder to denote where the 
list of hooks begins and ends.  They would probably have to be comma-separated, 
like this:

public string $foo 
  get { return $this->bar; }, 
  set { $this->bar = $value; };

Which I'd argue is harder to read anyway, because you have to be careful of the 
very small , and ; marks.  The {} is just easier for humans to parse as well as 
the machine.

> Suppose that I just want to cache once and freeze, and I don't want to
> create additional hidden property. Please make a judgement on the
> validity of this syntax:
> ```
> public string $prop1 {
>   get => $field ??= $this->heavyTask($this->propx, $prop->y);
>   set => null;
> }
> ```
>
> Explanation:
> * Since the ```get``` hook uses ```$field```, the engine will create a
> backing store value with name ```$prop1```, and will be filled at the
> first call only. The later call will use the already stored value.
> * Since no new value is assigned to ```$field``` in the ```set```
> hook, the value stored in ```$prop1``` is still the same as before.
> * Since any return statement will be discharged in ```set``` hook, the
> assignment chaining is safe to use and the value which is transferred
> is alway the rightmost value (not the value returned by the ```set```
> hook).
> ```
> $varx = $obj->prop1 = "hello";  // $varx value is "hello", and
> $obj->prop1 value is unchanged
> ```

An interesting approach.  It should work as you describe, but there's two 
reasons I would discourage it:

1. A "set that doesn't set" creates unexpected behavior for callers.  If I call 
set, I expect something to happen.  It would be rather confusing to call set 
and not set things.
2. It doesn't actually allow a cache clearing option.

What we really would need here is asymmetric visibility.  No set hook, but make 
the property private(set) so that trying to write to it gives an error, as it 
should.  For cache clearing, the best way to do that is probably with an unset 
hook.  That's been omitted from the RFC for now for simplicity, but that sounds 
like it would be an argument to introduce it later.  Asymmetric visibility 
would be the higher priority, though.

> But, this statement below is NOT ALWAYS correct for "cache once and freeze":
> ```
> public string $prop1 {
>   set => $field ??= $this->heavyTask($this->propx, $prop->y);
> }
> ```
> Explanation:
> * Since default ```get``` hook can be called before ```set``` hook,
> backing store value with name ```$prop1``` will still be empty.
> * Otherwise, I have to duplicate the body of the ```set``` hook into
> ```get``` hook to prevent an emptiness backing store.
>
> Please give a comment.
> Thanks.

Correct; while this syntax would compile, it would result in the value assigned 
to the property being ignored, and then the other heavyTask() value assigned to 
it, but that still wouldn't ensure it was available the first time you called 
`get`.  That's probably not what anyone wants.

It looks like you answered your own question on the interface point, so I'll 
leave that be.

--Larry Garfield

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



Re: [PHP-DEV] [RFC] [Discussion] nameof

2023-05-15 Thread Robert Landers
On Mon, May 15, 2023 at 8:18 PM Rowan Tommins  wrote:
>
> On 15 May 2023 18:44:47 BST, Robert Landers  wrote:
> >use const \NoExist\TEST;
> >use \NoExist\Channel;
> >echo TEST;
> >echo Channel::class;
> >
> >the output is:
> >
> >Undefined constant "TEST" in ...
> >Channel
>
> I'm not sure how you got that; according to https://3v4l.org/gltKN only PHP 
> 5.6 has a message with the unqualified name:
>
> > Notice: Use of undefined constant TEST - assumed 'TEST' in /in/gltKN on 
> > line 5
>
> Before that, there was no "use const", and in every version after that, it's 
> a fatal error with the fully qualified name:
>
> > Fatal error: Uncaught Error: Undefined constant "NoExist\TEST" in 
> > /in/gltKN:5
>
> Take the constant part away so that the next line runs, and 
> https://3v4l.org/q0XQO shows the fully qualified name right back up PHP 5.5, 
> because expanding the name is actually the *only* thing that ::class does in 
> that context.
>
> Regards,
>
> --
> Rowan Tommins
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

php --version
PHP 8.2.6 (cli) (built: May 12 2023 06:24:00) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.6, Copyright (c) Zend Technologies
with Zend OPcache v8.2.6, Copyright (c), by Zend Technologies
with Xdebug v3.2.0, Copyright (c) 2002-2022, by Derick Rethans

php -a
Interactive shell

php > use \NoExists\Channel;
php > echo Channel::class;
Channel

Turns out, it's a CLI specific thing, when running in a file, it does
indeed output the full name. I stand corrected; I tend to use the CLI
for testing out stuff.

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



Re: [PHP-DEV] [RFC] [Discussion] nameof

2023-05-15 Thread Rowan Tommins
On 15 May 2023 18:44:47 BST, Robert Landers  wrote:
>use const \NoExist\TEST;
>use \NoExist\Channel;
>echo TEST;
>echo Channel::class;
>
>the output is:
>
>Undefined constant "TEST" in ...
>Channel

I'm not sure how you got that; according to https://3v4l.org/gltKN only PHP 5.6 
has a message with the unqualified name:

> Notice: Use of undefined constant TEST - assumed 'TEST' in /in/gltKN on line 5

Before that, there was no "use const", and in every version after that, it's a 
fatal error with the fully qualified name:

> Fatal error: Uncaught Error: Undefined constant "NoExist\TEST" in /in/gltKN:5

Take the constant part away so that the next line runs, and 
https://3v4l.org/q0XQO shows the fully qualified name right back up PHP 5.5, 
because expanding the name is actually the *only* thing that ::class does in 
that context.

Regards,

-- 
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] [Discussion] nameof

2023-05-15 Thread Rowan Tommins
On 15 May 2023 14:07:31 BST, Lydia de Jongh  wrote:
>> ...
>> #[SomeAttribute(callback: nameof(\Acme\bar(...))]
>> ...
>
>This callback to nameof(). is really terrible  

Just to be clear, the "callback:" in that example is existing syntax for named 
parameters, not part of the nameof() syntax. A positional parameter would just 
look like this:

#[SomeAttribute(nameof(\Acme\bar(...))]

That's the same number of characters as this:

#[SomeAttribute(\Acme\bar(...)::nameof]

The main difference is the the function-ish syntax makes it a bit clearer what 
you're asking for the name of, because the whole thing is in parentheses. There 
might even be cases where the function-ish syntax needs additional parentheses 
anyway, like are needed in (new Something)->doSomething()

Changing "nameof" to "function", "method", etc depending on type doesn't really 
add anything, since the output is always a string anyway, not some 
type-specific thing.

Regards,

-- 
Rowan Tommins
[IMSoP]

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



Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> If there is no forward compatibility consideration, can we simplify
> interface definition to this one?
> ```
> interface IFace
> {
>   public string $readable;
>   public string $writeable;
>   public string $both;
> }
> ```

After carefully reading the proposal again, I think I know the answer
for my own question.

Short answer: no, we still need ```{ get; }``` to enforce the implemented class.

There are two different things here:
1. enforcing the implemented class
2. enforcing the caller site

If there are only ordinary properties, then ```{ get; }``` is truly
useless at the moment. On the other hand, virtual properties need
rules to be enforced, since there is no default hook given to it.

Since PHP lacks method definition enforcement at the caller site, I
assume that property would suffer the same.

Since we don't know what type of property is in the caller site,
static analysis tools can benefit from ```{ get; }``` to produce a
warning that we should not assign value to the property. A more
complex check should be performed to the implemented class because the
property type can be determined directly (if i am not wrong).
```
interface IFace
{
  public string $readable1 { get; }
  public string $readable2 { get; }
}

class CX implements IFace {
  private string $_propx;

  public string $readable1;
  public string $readable2 {
get => $this->_propx;
set => $this->_propx = $value;
  }

  public function consumeIt(IFace $par) {
// these statements should trigger warning by SA tools
$par->readable1 = "hello";
$par->readable2 = "world";

// OK
$this->readable1 = "hello";

// this statement should trigger error by SA tools
$this->readable2 = "hello";
  }
}
```

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



Re: [PHP-DEV] [RFC] [Discussion] nameof

2023-05-15 Thread Robert Landers
> I totally agree with Rowan. In many (most?) cases you need the fully
> qualified name.
> Even or especially for error handling! Of course mostly the error is
> somewhere else. But you want to know the starting point. An
> unqualified name gets you nowhere. Although backtrace can help you
> out.
>
> And this is also consistent with how  ::class or get_class() work
> it gives fully qualified names.

> On the other hand you could argue that 'nameof()' in itself means:
> 'just looking for the direct/unqualified name of something' and is an
> addition to ::class and get_class()

This is exactly what I was thinking when I wrote it out, however, you
can pass the full name to get the full name (an escape hatch of
sorts).

> Then we still need something to get the fully qualified name/path of a
> variable or php-item.
> For a class we have: ::class, get_class() and class_exists().
> And inside these function you can use:
> get_class(MyClass::class);

Variables don't get stored in a namespace or they exist only in the
local scope (they can't have a 'qualified' name, in my experience):

namespace A { $b = 'c'; }
echo $b; // outputs: 'c'

For callables, you can already get the fully qualified name:

echo (new ReflectionFunction(strstr(...)))->getName();

You, however, cannot get the name of a constant, except through
get_defined_constants() and comparing values (searching in the
namespace you care about) and doesn't help you if it isn't defined.

There's further evidence that an unqualified name is the right way to go:

use const \NoExist\TEST;
use \NoExist\Channel;
echo TEST;
echo Channel::class;

the output is:

Undefined constant "TEST" in ...
Channel

note that it does NOT say "\MyNamespace\TEST" is undefined nor does it
output "\NoExist\Channel", so if the user wants to write:

use function \AppPlugins\Config;

if(!function_exists(nameof(Config(...
 throw new Exception(nameof(Config(...)) . ' does not exist, please
define it.');

It's going to output the unqualified name anyway, simply due to how
PHP resolves names. Using the "escape hatch", however, we can "force"
PHP to do what we expect:

if(!function_exists(nameof(\AppPlugins\Config(...)))
  throw new Exception(nameof(Config(...)) . ' does not exist, please
define it.');

I'll update the RFC to reflect this.

> The downside is that we get many new 'magic constants'...

There are no magic constants in this RFC.

Robert Landers
Software Engineer
Utrecht NL

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



Re: [PHP-DEV] [VOTE] Use exceptions by default in SQLite3 extension

2023-05-15 Thread someniatko
Got it, thank you for explaining.

Regards,
Illia / someniatko

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



Re: [PHP-DEV] [VOTE] Use exceptions by default in SQLite3 extension

2023-05-15 Thread G. P. B.
On Mon, 15 May 2023 at 15:41, someniatko  wrote:

> The `PDOException` class is actually extending the `RuntimeException`,
> not just `Exception`.
>

Yes, and this is, IMHO, a mistake.
Outside SPL, there are only 4 extensions which extend from RuntimeException:
 - PDO
 - MySQLi
 - SNMP
 - Phar

See:
https://heap.space/search?project=php-src===spl_ce_RuntimeException===

The vast majority of extensions that define their own custom exceptions
extend Exceptions.
The reason being that depending on a separate extension (here SPL) instead
of core API is less than ideal.

Moreover, SPL exceptions are meant for userland.
And I personally find it extremely strange that if I attempt to catch a
RuntimeException I might as well catch a PDO failure.

Best regards,

George P. Banyard


Re: [PHP-DEV] [VOTE] Use exceptions by default in SQLite3 extension

2023-05-15 Thread BohwaZ
Hi Illia,

thank you for your feedback.

This is actually what I did, first, but I changed after feedback from
@Girgias:

https://github.com/php/php-src/pull/11058#discussion_r1162723112

> You are likely to get push back not just from myself if you propose
> it as such in an RFC

I don't have a strong opinion one way or another. I just felt it was
more coherent (with PDO) to use RuntimeException.

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



Re: [PHP-DEV] [RFC] Define proper semantics for range() function

2023-05-15 Thread G. P. B.
Hello Internals,

I plan to put the RFC to a vote tomorrow in its current state, which has
not been changed since the 30th of March:
https://wiki.php.net/rfc/proper-range-semantics

Any final comments or complaints should be raised now.

Best regards,

George P. Banyard


Re: [PHP-DEV] [VOTE] Use exceptions by default in SQLite3 extension

2023-05-15 Thread someniatko
Hi!

It says in the RFC:

> PDO is using exceptions, like everyone else.

and

> Create a new exception class SQLite3Exception, which extends the Exception 
> class

The `PDOException` class is actually extending the `RuntimeException`,
not just `Exception`. I am sure it is better to do this for
`SQLite3Exception` as well.

Regards,
Illia / someniatko

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



Re: [PHP-DEV] [RFC] [Discussion] nameof

2023-05-15 Thread Lydia de Jongh
(I hope it is ok that I take parts from several mails)

Op za 13 mei 2023 om 12:37 schreef Rowan Tommins :
> On 13 May 2023 10:04:39 BST, Lydia de Jongh  wrote:
>
> >I prefer a magic constant like `::name` instead of a function call as it
> >can be used in a wider scope; for example as a parameter in an Attribute.
>
> Don't confuse the syntax with the implementation: "::class" isn't actually a 
> constant, and the proposed "nameof()" isn't actually a function; both are 
> just syntaxes understood by the compiler to generate strings according to 
> certain rules. The RFC explicitly mentions use in attributes:

Just got that from the php manual  : as it is listed under the
'magic constants'
(https://www.php.net/manual/en/language.constants.magic.php)
But I understand your point.

> > The one part of the RFC that surprised me was this:
> >
> > > When getting the name of constants and functions, the name will NOT be 
> > > the full name, but the lexical name. This means that if the name is 
> > > use'd, it will be that name. However, if the full name is used in the 
> > > nameof(), the full name is returned.
> >
> > No reason is given *why* it works this way, and expanding the namespaces on 
> > a name is one of the most useful features of "::class". Importantly, it 
> > means that the string created can be passed to other contexts, and still 
> > refer to the same thing.

Op zo 14 mei 2023 om 14:55 schreef Rowan Tommins :
>
> On 14 May 2023 11:59:13 BST, Robert Landers  wrote:
> >use function \Path\To\Function\Serializer\to_json as json_serializer;
> >
> >// a bunch of code using json_serializer()
> >throw new Exception('json_serializer returned invalid json');
> >// or
> >throw new Exception('\Path\To\Function\Serializer\to_json returned
> >invalid json');
>
> I can see your reasoning now, but I can think of arguments both ways round: 
> if you're trying to find out *why* the function returned invalid JSON, you 
> need to know where the source code for that function is, so need its fully 
> qualified name.
>
> My gut feel is still that it's more often useful to have the expansion done 
> for you, but maybe others have different perspectives.
>

Op zo 14 mei 2023 om 17:45 schreef Robert Landers :
>
> > Conversely, namespace imports are entirely local to the current file (or 
> > even a namespace{} block), and it's almost impossible for running code to 
> > see anything other than the expanded name.
> >
> > That doesn't mean that there aren't good reasons to have nameof() handle 
> > both things in the way proposed, I just think those reasons are probably 
> > different for the two cases.
>
> That's a fair point. Maybe it is worth putting it up for a secondary
> vote? I do have a strong preference, but I'd rather have full names
> than no names, and doesn't change the RFC that much. If I'm
> understanding correctly, it would only affect first-class callables
> and constants.
>

I totally agree with Rowan. In many (most?) cases you need the fully
qualified name.
Even or especially for error handling! Of course mostly the error is
somewhere else. But you want to know the starting point. An
unqualified name gets you nowhere. Although backtrace can help you
out.

And this is also consistent with how  ::class or get_class() work
it gives fully qualified names.

On the other hand you could argue that 'nameof()' in itself means:
'just looking for the direct/unqualified name of something' and is an
addition to ::class and get_class()

Then we still need something to get the fully qualified name/path of a
variable or php-item.
For a class we have: ::class, get_class() and class_exists().
And inside these function you can use:
get_class(MyClass::class);

For a method we only have: method_exists and it needs 2 parameters,
for the methodname: only string is possible 
Would be nice to have, and consistent to have:
- MyClass::method::method
- method_exists($object->method::method)
- get_method(MyClass::method::method)

And the same for properties:
- MyClass::property::property
- method_exists($object-> property::property)
- get_method(MyClass:: property::property)

The downside is that we get many new 'magic constants'...

What about:
- for unqualified names:
-- nameof(any-php-item)
-- any_php_item::nameof

- for fully qualified names:
-- pathof(any-php-item) or fullnameof()
-- any_php_item::pathof or ::fullnameof


> > To put things into a more productive context, then, I think a useful 
> > improvement to the RFC would be some examples of how you would use it with 
> > the different supported types, showing why the proposed semantics are 
> > useful for those scenarios.
>
> I can do that for sure.

Aside for error handling, I think it would give attributes a boost as
they handle configuration and metadata, without having a proper way to
address variables and other php items, except classes.

#[MyAttribute(property: MyClass::myProperty::fullnameof)]

Which IMHO is much better then:
#[MyAttribute(property: 

Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
> ```php
> class User {
> private string $first;
> private string $last;
> public string $fullName {
> get => $this->first . ' ' . $this->last;
> set => [$this->first, $this->last] = explode(' ', $value, 2);
> }
>
> public function __construct($this->fullName) {}
> }
> ```

Not entirely true, you created redundancy code for ```$fullName```.
This is why we created constructor property promotion: to eliminate
redundancy.

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



Re: [PHP-DEV] [RFC] [Discussion] Deprecate functions with overloaded signatures

2023-05-15 Thread G. P. B.
On Sat, 13 May 2023 at 00:08, Larry Garfield  wrote:

> That means it's impossible to write code that works from 8.2 to 9.0
> without version checks.  The overlap period is only 2 releases (8.3 and
> 8.4).  That's too short of a window.
>

Why are we assuming that PHP 9.0 is going to come after PHP 8.4?
There has been no decision as to when the new major is going to be released.
And as far as I'm concerned, the only good reason to move from 8.x to 9.0
is when we convert streams from resources to objects, which is going to be
a large enough BC that those sorts of minor BC breaks should frankly be a
non-issue.
So could we not speculate on an arbitrary timeline of the new major version
being tagged and go on the merit of this proposal in isolation?

I don't see much of an issue of, introduce the new functions/methods in PHP
8.3, deprecate them in PHP 8.3+x (for x > 0) and remove in PHP 9.0.

Best regards,

George P. Banyard


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Lynn
On Mon, May 15, 2023 at 1:41 AM Hendra Gunawan 
wrote:

> 2. The shorthand notations supported (the shortest one) creates
> impaired syntax, and not pretty to look at for constructor property
> promotion.
>

It's starting to get crowded in object constructors. The following example
is so much more readable and maintainable imo. Would it be possible to
still add the quick assignment as a language feature? I'm personally not
happy having property definitions in both the class body _and_ the
constructor signature.

```php
class User {
private string $first;
private string $last;
public string $fullName {
get => $this->first . ' ' . $this->last;
set => [$this->first, $this->last] = explode(' ', $value, 2);
}

public function __construct($this->fullName) {}
}

// vs

class User {
private string $first;
private string $last;

public function __construct(
public string $fullName {
get => $this->first . ' ' . $this->last;
set => [$this->first, $this->last] = explode(' ', $value, 2);
}
) {}
}

// or

class User {
private string $first;
private string $last;
public string $fullName {
get => $this->first . ' ' . $this->last;
set => [$this->first, $this->last] = explode(' ', $value, 2);
}

public function __construct(string $fullName)
{
$this->fullName = $fullName;
}
}

```


Re: [PHP-DEV] [RFC] Property hooks, nee accessors

2023-05-15 Thread Hendra Gunawan
On Tue, May 9, 2023 at 4:38 AM Larry Garfield  wrote:
>
> Ilija Tovilo and I would like to offer another RFC for your consideration.  
> It's been a while in coming, and we've evolved the design quite a bit just in 
> the last week so if you saw an earlier draft of it in the past few months, I 
> would encourage you to read it over again to make sure we're all on the same 
> page.  I'm actually pretty happy with where it ended up, even if it's not the 
> original design.  This approach eliminates several hard-to-implement edge 
> cases while still providing a lot of functionality in one package.
>
> https://wiki.php.net/rfc/property-hooks
>
> --
>   Larry Garfield
>   la...@garfieldtech.com

Hi Larry

Can the engine detect these logical errors?
```
public string $fullName = "hendra gunawan" => $this->first . " " . $this->last;

// or with my proposal:
public string $fullName = "hendra gunawan" get => $this->first . " " .
$this->last;

// or even this one:
public string $fullName = "hendra gunawan" {
  get => $this->first . " " . $this->last;
  set => [$this->first, $this->last] = explode(" ", $value);
```

Explanation:
There is no automatic backing store value created to store the default value.

Terima Kasih.

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