Re: [PHP-DEV] [RFC] [Discussion] #[\Deprecated] attribute again v1.3

2024-04-26 Thread Stephen Reay


Sent from my iPhone

> On 26 Apr 2024, at 22:06, Rowan Tommins [IMSoP]  wrote:
> 
> 
> 
>> On 26 April 2024 09:40:57 BST, Mike Schinkel  wrote:
>> 
>> Given a lack of agreed definition for 'since' it appears you are using 
>> narrow assumptions about the meaning of 'since' that led you to view 'since' 
>> as useless.
> 
> I can't see any ambiguity in the definition: "This function has been 
> deprecated since version 7.2" seems a straightforward English sentence, 
> meaning that before 7.2 it wasn't deprecated, and from that version onward it 
> is.
> 
> If there's some alternative reading of it, it's not that I'm assuming it 
> doesn't apply, it's that I'm completely unaware of what it might be.
> 
> Regards,
> Rowan Tommins
> [IMSoP]
> 

I'd even go so far as to suggest that "since" is so commonly understood that we 
don't need the "This function has been " and "version " parts, and could simply 
write: `#[Deprecated(since: '7.2')]` and have it be understood by humans and 
tooling alike. 

Re: [PHP-DEV] [RFC] [Discussion] #[\Deprecated] attribute again v1.3

2024-04-25 Thread Stephen Reay

Sent from my iPhone

> On 25 Apr 2024, at 16:26, Rowan Tommins [IMSoP]  wrote:
> 
> On 24 April 2024 18:18:28 BST, Jorg Sowa  wrote:
>> What about setting this parameter vaguely as the boolean we can pass?
>> ...
>> #[Deprecated(since: $packageVersion > 5.5)]
>> #[Deprecated(since: PHP_VERSION_ID > 80100)]
>> #[Deprecated(since: date("Y-m-d") > "2024-01-21")]
> 
> 
> Even if these expressions were legal, as far as I know, standard reflection 
> doesn't give any access to the source code or AST of how the attribute was 
> written, so this would just end up with a meaningless "$since = true", and 
> some source code that might as well be a comment.
> 
> To be honest, I'm not really sure what I'd do with the information in a 
> "since" field even if it was there. If you were running PHP 7.4, what 
> difference would it make to know that create_function was deprecated in 7.2, 
> rather than in 7.1 or 7.3? The two relevant facts are when the suggested 
> replacement was introduced (in case you need to support multiple versions); 
> and what is the soonest that the deprecated feature will be removed. The 
> second in particular is something I would like every deprecation message to 
> include, rather than the vague "may be removed in a future version".
> 
> I found this discussion of "since" in Rust's implementation, but don't find 
> the arguments in favour particularly compelling: 
> https://github.com/rust-lang/rfcs/pull/1270#issuecomment-138043714
> 
> 
> Of interest, that discussion also linked to a related feature in Java, which 
> could perhaps be added to a list in the RFC alongside the Rust and JetBrains 
> ones already mentioned: https://openjdk.org/jeps/277
> 
> It's interesting to note, for instance, that both Java and Rust designers 
> considered a specific "replacement" field, but decided that it was unlikely 
> to be useful in practice. The Java proposal states this nicely:
> 
>> In practice, there is never a drop-in replacement API for
>> any deprecated API; there are always tradeoffs and
>> design considerations, or choices to be made among
>> several possible replacements. All of these topics require
>> discussion and are thus better suited for textual
>> documentation.
> 
> The JetBrains attribute *does* include a "replacement" argument, but it's 
> heavily tied into a specific use case: it contains a template used for code 
> transformation in the IDE. Both it and "since" are explicitly marked 
> "applicable only for PhpStorm stubs".
> 
> Regards,
> Rowan Tommins
> [IMSoP]
> 

I think it's worth pointing out that phpdoc has had a @deprecated [version] 
[description] attribute for a long time - since is, IMO a different name for 
"version" and indicates the version that element was deprecated. If you're on 
X.y and it says it was deprecated in X.w you know you don't need to worry about 
it being removed until at least Y.a.

Also, phpdoc *also* has a separate @since attribute, which documents the 
*introduction or modification* of an element.

I think suggestions of a "Since" attribute "beside" the deprecated attribute 
defeat the purpose of it being an attribute, on top of being confusing when 
compared to existing phpdoc attributes.

#[Deprecated, Since(1.9)] to me, means "currently deprecated; introduced (or 
significantly changed) in 1.9"

To mean what you're suggesting it would need to be 
#[Deprecated, Since(1.9, 'Deprecated in favour of foo...')] which is just 
needless duplication. 


For those who don't see the point of `since`, I think the obvious answer is: 
documentation. Rather than needing a separate docblock to detail the 
deprecation, it can be all in one, just as parameter types and return types 
are. This reduces duplication, and reduces possibility of mismatched values.

If you wanted it to be clearer I'd suggest maybe rename "since" to "version", 
but that's more to give a hint at intended use than anything. 



Re: [PHP-DEV] PDO subclass names

2024-04-23 Thread Stephen Reay

Sent from my iPhone

> On 23 Apr 2024, at 22:35, Bilge  wrote:
> On 23/04/2024 10:25, Stephen Reay wrote:
>> The argument that "Client" is meaningless becomes pretty moot when you 
>> realise that you can import a *namespace* and use it relatively, if you so 
>> wish:
>> ```
>> import MyLib\HTTP;
>> $a = new HTTP\Client(...);
>> ```
> 
> Hi Stephen,
> 
> Granted, but I also believe the user can and should have the reasonable 
> expectation that they can work comfortably (without conflicts or aliases) 
> using leaf (class) names exclusively.
> 
> Kind regards,
> Bilge

I'm sorry but I think you've missed the entire point of namespaces if you want 
class names to all be universally unique without their namespace component.

The referenced RFC gives clear examples of how a class with a prefix would be 
converted to a namespace and class.


Re: [PHP-DEV] PDO subclass names

2024-04-23 Thread Stephen Reay


Sent from my iPhone

> On 23 Apr 2024, at 22:35, Bilge  wrote:
> On 23/04/2024 10:25, Stephen Reay wrote:
>> The argument that "Client" is meaningless becomes pretty moot when you 
>> realise that you can import a *namespace* and use it relatively, if you so 
>> wish:
>> 
>> ```
>> import MyLib\HTTP;
>> 
>> $a = new HTTP\Client(...);
>> ```
> 
> Hi Stephen,
> 
> Granted, but I also believe the user can and should have the reasonable 
> expectation that they can work comfortably (without conflicts or aliases) 
> using leaf (class) names exclusively.
> 
> Kind regards,
> Bilge

I'm sorry but I think you've missed the entire point of namespaces if you want 
class names to all be universally unique without their namespace component.

The referenced RFC gives clear examples of how a class with a prefix would be 
converted to a namespace and class. 


Re: [PHP-DEV] PDO subclass names

2024-04-23 Thread Stephen Reay
Sent from my iPhoneOn 23 Apr 2024, at 19:26, Lynn  wrote:On Tue, Apr 23, 2024 at 11:26 AM Stephen Reay <php-li...@koalephant.com> wrote:Sent from my iPhoneOn 23 Apr 2024, at 18:21, Lynn <kja...@gmail.com> wrote:On Tue, Apr 23, 2024 at 10:21 AM Bilge <bi...@scriptfusion.com> wrote:On 21/04/2024 14:00, Saki Takamachi wrote:
> Hi internals,
>
> Recently I've been working on an RFC regarding object support for BCMath. While working on that, I learned of the following RFC:
> https://wiki.php.net/rfc/namespaces_in_bundled_extensions
>
> If we follow this RFC, is it reasonable to place subclasses of PDO under the namespace "PDO”?
>
> e.g.
> ```
> PdoMysql => PDO\Mysql
> PdoPgsql => PDO\Pgsql
> PdoSqlite => PDO\Sqlite
> PdoOdbc => PDO\Odbc
> PdoDblib => PDO\Dblib
> PdoFirebird => PDO\Firebird
> ```
>
> We'll probably get a BC Break if try to fix this after 8.4 is released, so before it's released is last chance to fix this safely.
>
> If Tim's RFC under discussion is passed, the namespace will be "Pdo" instead of "PDO”.
> https://wiki.php.net/rfc/class-naming-acronyms
>
> I would appreciate hearing your opinions.
>
> Regards,
>
> Saki

Hi Saki,

Consider that adding a namespace does not/should not change the class 
name. That is, `MyClass` once namespaced becomes `MyNamespace\MyClass`. 
Ergo, `PdoMysql` becomes `Pdo\PdoMysql`. The class name should still 
make sense and be a "strong name" (without conflict) once imported.

To state it more concretely, I believe it is normal and correct to 
include 1-3 namespace components within the class name itself, in order 
to create such a "strong name". As a more concrete example of this, 
consider `HttpClient`, `FtpClient` and `SoapClient`. Far too often, we 
see user libraries (incorrectly) namespace these as `Http\Client`, 
`Ftp\Client` and `Soap\Client` (or similar) where the leaf name just 
becomes `Client`. "Client", by itself is a meaningless moniker, but that 
is all we see once the name is imported, notwithstanding importing 
multiple of these clients in one file causes conflicts that now need to 
be resolved with local aliases. In general, I believe aliasing to be an 
anti-pattern that points to a failure to create strong names and thus 
should be avoided by including some of the namespace portion in the 
class name to make the class name more meaningful. Once imported, we do 
not see the namespace portion within the body of the file any more; 
`HttpClient` and `FtpClient` make much more sense by themselves, whether 
or not they would otherwise conflict.

Kind regards,
BilgeThe code base I work in has 25 classes that are called "Line". They have namespaces like `App\Model\Invoice\Line`, this is cumbersome to work with so I would also prefer something like `Pdo\PdoMysql`, even if it's not likely to conflict with a name such as Mysql.
I don't think it's appropriate to claim that a namespace like MyLib\HTTP\Client is categorically "wrong".The argument that "Client" is meaningless becomes pretty moot when you realise that you can import a *namespace* and use it relatively, if you so wish: ```import MyLib\HTTP;$a = new HTTP\Client(...);```I'm not claiming that any particular import pattern is more "correct" (and I think it's a bad idea to suggest that other usage patterns are "incorrect") but adding repetitive prefixes kind of defeats the purpose of namespaces.You may as well just go back to MyLib_HTTP_Client, and ignore that namespaces exist. In your own codebase you should do what works best for you. When it comes to vendor classes I don't want to have to scroll through a list of 20 identical classes to find the one in the right namespace. It requires extra development and review effort to figure out if the right class called "Client" or "Factory" is used. For reference, I have 12 "Response", 12 "Client", 20 "Factory", and 20 "TestCase" classes in this project, of which most are vendors. If the proposal was to have `PDO\MySQL\Client`, I would be sympathetic to your view. I wouldn't agree with you that it's somehow wrong or hard to use, but I'd be sympathetic.That isn't what's being suggested. I also don't really see how vendor use is relevant here. What third party userland libraries do is largely just on a whim of whatever new shiny thing PHP-FIG pumps out to feel important. This seems like the wrong place to complain about namespacing practices of vendor libraries.  The PHP RFC referenced applies to bundled php extensions, like... PDO and the various drivers for it. Using partially imported namespaces and aliases causes inconsistencies that makes it harder to find things.I honestly don't know what you're talking about here.  Nobody here is advocating for MyLibHttpClient class names either.The person you replied to literally said:On 23 Apr 2024, at 17:46, Bilge  wrote:I believe it is normal and correct to include 1-3 namespace components within the class name itselfMyLibHttpClient easily falls within that description.

Re: [PHP-DEV] PDO subclass names

2024-04-23 Thread Stephen Reay
Sent from my iPhoneOn 23 Apr 2024, at 18:21, Lynn  wrote:On Tue, Apr 23, 2024 at 10:21 AM Bilge  wrote:On 21/04/2024 14:00, Saki Takamachi wrote:
> Hi internals,
>
> Recently I've been working on an RFC regarding object support for BCMath. While working on that, I learned of the following RFC:
> https://wiki.php.net/rfc/namespaces_in_bundled_extensions
>
> If we follow this RFC, is it reasonable to place subclasses of PDO under the namespace "PDO”?
>
> e.g.
> ```
> PdoMysql => PDO\Mysql
> PdoPgsql => PDO\Pgsql
> PdoSqlite => PDO\Sqlite
> PdoOdbc => PDO\Odbc
> PdoDblib => PDO\Dblib
> PdoFirebird => PDO\Firebird
> ```
>
> We'll probably get a BC Break if try to fix this after 8.4 is released, so before it's released is last chance to fix this safely.
>
> If Tim's RFC under discussion is passed, the namespace will be "Pdo" instead of "PDO”.
> https://wiki.php.net/rfc/class-naming-acronyms
>
> I would appreciate hearing your opinions.
>
> Regards,
>
> Saki

Hi Saki,

Consider that adding a namespace does not/should not change the class 
name. That is, `MyClass` once namespaced becomes `MyNamespace\MyClass`. 
Ergo, `PdoMysql` becomes `Pdo\PdoMysql`. The class name should still 
make sense and be a "strong name" (without conflict) once imported.

To state it more concretely, I believe it is normal and correct to 
include 1-3 namespace components within the class name itself, in order 
to create such a "strong name". As a more concrete example of this, 
consider `HttpClient`, `FtpClient` and `SoapClient`. Far too often, we 
see user libraries (incorrectly) namespace these as `Http\Client`, 
`Ftp\Client` and `Soap\Client` (or similar) where the leaf name just 
becomes `Client`. "Client", by itself is a meaningless moniker, but that 
is all we see once the name is imported, notwithstanding importing 
multiple of these clients in one file causes conflicts that now need to 
be resolved with local aliases. In general, I believe aliasing to be an 
anti-pattern that points to a failure to create strong names and thus 
should be avoided by including some of the namespace portion in the 
class name to make the class name more meaningful. Once imported, we do 
not see the namespace portion within the body of the file any more; 
`HttpClient` and `FtpClient` make much more sense by themselves, whether 
or not they would otherwise conflict.

Kind regards,
BilgeThe code base I work in has 25 classes that are called "Line". They have namespaces like `App\Model\Invoice\Line`, this is cumbersome to work with so I would also prefer something like `Pdo\PdoMysql`, even if it's not likely to conflict with a name such as Mysql.
I don't think it's appropriate to claim that a namespace like MyLib\HTTP\Client is categorically "wrong".The argument that "Client" is meaningless becomes pretty moot when you realise that you can import a *namespace* and use it relatively, if you so wish: ```import MyLib\HTTP;$a = new HTTP\Client(...);```I'm not claiming that any particular import pattern is more "correct" (and I think it's a bad idea to suggest that other usage patterns are "incorrect") but adding repetitive prefixes kind of defeats the purpose of namespaces.You may as well just go back to MyLib_HTTP_Client, and ignore that namespaces exist. 

Re: [PHP-DEV] [RFC[ Property accessor hooks, take 2

2024-03-12 Thread Stephen Reay



> On 8 Mar 2024, at 22:53, Larry Garfield  wrote:
> 
> Hi folks.  Based on earlier discussions, we've made a number of changes to 
> the RFC that should address some of the concerns people raised.  We also had 
> some very fruitful discussions off-list with several developers from the 
> Foundation, which led to what we feel are some solid improvements.
> 
> https://wiki.php.net/rfc/property-hooks
> 
> Smaller changes:
> 
> 1. We've added a PropertyHookType enum for use in reflection, which lets us 
> get rid of a possible exception.
> 2. get_mangled_object_vars()'s behavior is now defined to be the same as an 
> array, ie, skip hooks.
> 3. A final property with a final hook is no longer an error. It's just 
> silently redundant, like for methods.
> 5. Made explict what happens with recursive hook calls and method calls from 
> a hook.  The behavior here is the same as for __get/__set.
> 6. Made support for #[\Override] explicit.
> 7. Added an FAQ regarding the property-centric approach rather than 
> method-centric approach.
> 8. Clarified that the parent::$foo::get() syntax works on a parent property 
> regardless of whether it has hooks.
> 9. Clarified that untyped properties are supported.  (Though, it's 2024, 
> please don't use untyped properties.)
> 10. Clarified that interface properties cannot specify a wider write-type, 
> for simplicity.  That could be considered as a future add-on with no BC 
> breaks.
> 11. Provided an explanation of how to interpret the parent-hook access syntax.
> 12. Added an FAQ item explaining why a 'virtual' keyword is not feasible.
> 
> Larger changes:
> 
> 0. As noted a while ago, $field has been removed.
> 
> 1. I've added an FAQ question regarding the parent::$foo::get() syntax, and 
> why it is.
> 
> 2. The $foo => expression shorthand has been removed.  The legal shorthands 
> are now:
> 
> public string $foo {
>  get => evaluates to a value;
>  set => assigns this value;
> }
> 
> 3. The set shorthand (with => ) now means "write this value instead".  The 
> non-shorthand version (set { } ) is always return void, so you have to assign 
> the value yourself but you get more flexibility.  Having updated the examples 
> accordingly, I think this is actually a really nice and intuitive trade-off, 
> as it makes the common transformation and validation cases (eg, in 
> constructor promotion) even easier to follow with no redundancy.
> 
> 4. On a set hook, the user may specify both a type and name, or neither.  
> (That is, set {} or set (Foo $newFoo).  If not specified, it defaults to the 
> type of the property and $value, as before.
> 
> 5. I restructured how the content in 2, 3, 4 is presented and moved some 
> stuff around so that it flows more logically (I think).
> 
> 6. The restrictions around references have been softened.  Specifically, 
> references are only disallowed if a backed property has a set hook.  If it 
> has only a get, or if it's a virtual property, references are allowed.  We 
> also added a future-scope section on a possible way to support assigning by 
> reference in the future, if there is sufficient need.
> 
> 7. Interfaces may now require a  hook, or just 'get'.  A class may use a 
>  hook on a 'get' interface declaration.  This is the same logic as 
> already exists for methods; we're just copying it.
> 
> Hopefully the above changes should resolve most outstanding concerns.  I do 
> think the updated shorthand handling is better overall, so I'm happy with it.
> 
> There also seems to be little consensus so far on naming this thing hooks vs 
> accessors.  Absent a consensus, we'll probably stick with hooks to avoid the 
> effort of renaming all the things.
> 
> Thank you everyone for the feedback so far, and if you still have some, 
> please say so.  (Even if it's just to say that you're happy with the RFC now 
> so we feel more comfortable bringing it to a vote.)
> 
> --Larry Garfield
> 

Hi Larry

Thanks again for both of your work on this, I'm really hopeful this passes. 

Was there ever any further discussion/resolution/decision about the use an 
explicit `virtual` keyword, and the related flag for creation of a backing 
store? I thought it was discussed by several people but I don't recall seeing 
any eventual consensus, and it looks to my eye that it hasn't changed from the 
original proposal: i.e. it's 'magic' and `$this->{__PROPERTY__}` won't work? 

Is that correct?


Cheers

Stephen 

Re: [PHP-DEV] Idea: Implicit inheriting function argument & return type-hint

2024-03-09 Thread Stephen Reay



> On 9 Mar 2024, at 21:27, Christian Schneider  wrote:
> Am 09.03.2024 um 08:18 schrieb Marc :
>> As the pseudo type `mixed` exists since PHP 8.0, which is already 
>> out-of-date, I have the feeling it would be better to force people to 
>> explicitly write `mixed` to widen the type of an overwritten function and 
>> let "no type" inherit the argument and return type of the parent.
>> 
>> Example:
>> 
>> class A {
>>public function typed(int $var): int { return $var; }
>>public function untyped($var) { return $var; } // implicit mixed as no 
>> overwrite
>> }
>> class B extends A {
>>public function typed($var) { return $var; } // implicit int as inherited 
>> from overwritten function
>> }
> 
> This sounds like a bad idea to me as I cannot look at the function definition 
> in class B and determine what the type of $var is.
> On top of that: If the type of $var in A is changed then it would 
> automatically also change in B. While this seems convenient it could also 
> break B in subtle ways as the function suddenly gets different types than 
> expected.
> 
> Regards,
> - Chris

I guess my discussion with Larry was at least part of what you're referring to.

The proposal here would introduce the same problem as we discussed on the other 
RFC: inconsistency with what people are used to elsewhere in the language (eg 
untyped properties).

It also means that existing code would have the complete opposite effect to 
previously, making it a huge BC break. You'd likely have to have two stages: 
deprecate and then remove use of untyped parameters, and then reintroduce 
untyped to mean "inherited" type, which still suffers from the issues Christian 
pointed out.

I could get behind the "first half" of that process:  making a type required 
(ie deprecating type-less parameters/properties) but I doubt there's enough 
support for that to pass a vote. 

Cheers

Stephen 

Re: [PHP-DEV] [RFC[ Property accessor hooks, take 2

2024-03-01 Thread Stephen Reay



> On 28 Feb 2024, at 21:25, Larry Garfield  wrote:
> 
> On Wed, Feb 28, 2024, at 7:49 AM, Stephen Reay wrote:
> 
> *snip*
> 
>>> == Re virtual properties:
>>> 
>>> Ilija and I talked this through, and there's pros and cons to a `virtual` 
>>> keyword.  Ilija also suggested a `backed` keyword, which forces a backed 
>>> property to exist even if it's not used in the hook itself.
>>> 
>>> * Adding `virtual` adds more work for the developer, but more clarity.  It 
>>> would also mean $this->$propName or $this->{__PROPERTY__} would work "as 
>>> expected", since there's no auto-detection for virtual-ness.  On the 
>>> downside, if you have a could-be-virtual property but never actually use 
>>> the backing value, you have an extra backing value hanging around in memory 
>>> that is inaccessible normally, but will still show up in some serialization 
>>> formats, which could be unexpected.  If you omit one of the hooks and 
>>> forget to mark it virtual, you'll still get the default of the other 
>>> operation, which could be unexpected.  (Mostly this would be for a 
>>> virtual-get that accidentally has a default setter because you forgot to 
>>> mark it `virtual`.)
>>> * Doing autodetection as now, but with an added "make a backing value 
>>> anyway" flag would resolve the use case of "My set hook just calls a 
>>> method, and that method sets the property, but since the hook doesn't 
>>> mention the property it doesn't get created" problem.  It would also allow 
>>> for $this->$propName to work if a property is explicitly backed.  On the 
>>> flipside, it's one more thing to think about, and the above example it 
>>> solves would be trivially solved by having the method just return the value 
>>> to set and letting the set hook do the actual write, which is arguably 
>>> better and more reliable code anyway.
>>> * The status quo (auto-detection based on the presence of $this->propName). 
>>>  This has the advantage it "just works" in the 95% case, without having to 
>>> think about anything extra.  The downside is it does have some odd edge 
>>> cases, like needing $this->propName to be explicitly used.  
>>> 
>>> I don't think any is an obvious winner.  My personal preference would be 
>>> for status quo (auto-detect) or explicit-virtual always.  I could probably 
>>> live with either, though I think I'd personally favor status quo.  Thoughts 
>>> from others?
>>> 
>> 
>> I agree that a flag to make the field *virtual* (thus disabling the 
>> backing store) makes more sense than a flag to make it backed; It's 
>> also easier to understand when comparing hooked properties with regular 
>> properties (essentially, backed is the default, you have to opt-in to 
>> it being virtual). I don't think the edge cases of "auto" make it 
>> worthwhile just to not need "virtual".
> 
> Uh, I can't tell if you're saying "use status quo" or "use the virtual 
> keyword."  Please clarify. :-)

I'm saying I think an explicit `virtual` keyword is the better option of the 
three (because the benefits of the 'auto' mode don't outweigh the edge cases it 
introduces).
> 
>>> == Re reference-get
>>> 
>>> Allowing backed properties to have a reference return creates a situation 
>>> where any writes would then bypass the set hook, and thus any validation 
>>> implemented there.  That is, it makes the validation unreliable.  A major 
>>> footgun.  The question is, do we favor caveat-emptor flexibility or 
>>> correct-by-construction safety?  Personally I always lead toward the 
>>> latter, though PHP in general is... schizophrenic about it, I'd say. :-)
>>> 
>>> At this point, we'd much rather leave it blocked to avoid the issue; it's 
>>> easier to enable that loophole in the future if we really want it than to 
>>> get rid of it if it turns out to have been a bad idea.
>>> 
>>> There is one edge case that *might* make sense: If there is no set hook 
>>> defined, then there's no set hook to worry about bypassing.  So it may be 
>>> safe to allow  on backed properties IFF there is no set hook.  I worry 
>>> that is "one more quirky edge case", though, so as above it may be better 
>>> to skip for now as it's easier to add later than remove.  But if the 
>>> consensus is to do that, we're open to it.  (Question for everyone.)
>>> 
>> 
>> I don't ha

Re: [PHP-DEV] [RFC[ Property accessor hooks, take 2

2024-02-28 Thread Stephen Reay



> On 28 Feb 2024, at 06:17, Larry Garfield  wrote:
> 
> On Sun, Feb 25, 2024, at 10:16 PM, Rowan Tommins [IMSoP] wrote:
>> [Including my full previous reply, since the list and gmail currently 
>> aren't being friends. Apologies that this leads to rather a lot of 
>> reading in one go...]
> 
> Eh, I'd prefer a few big emails that come in slowly to lots of little emails 
> that come in fast. :-)
> 
>>> On 21/02/2024 18:55, Larry Garfield wrote:
 Hello again, fine Internalians.
 
 After much on-again/off-again work, Ilija and I are back with a more 
 polished property access hooks/interface properties RFC.
>>> 
>>> 
>>> Hello, and a huge thanks to both you and Ilija for the continued work 
>>> on this. I'd really like to see this feature make it into PHP, and 
>>> agree with a lot of the RFC.
>>> 
>>> 
>>> My main concern is the proliferation of things that look the same but 
>>> act differently, and things that look different but act the same:
> 
> *snip*
> 
>>> - a and b are both what we might call "traditional" properties, and 
>>> equivalent to each other; a uses legacy syntax which we haven't 
>>> removed for some reason
> 
> I don't know why we haven't removed `var` either.  I can't recall the last 
> time I saw it in real code.  But that's out of scope here.
> 
> *snip*
> 
>> I think there's some really great functionality in the RFC, and would 
>> love for it to succeed in some form, but I think it would benefit from 
>> removing some of the "magic".
>> 
>> 
>> Regards,
>> 
>> -- 
>> Rowan Tommins
>> [IMSoP]
> 
> 
> I'm going to try and respond to a couple of different points together here, 
> including from later in the thread, as it's just easier.
> 
> == Re, design philosophy:
> 
>> In C#, all "properties" are virtual - as soon as you have any 
>> non-default "get", "set" or "init" definition, it's up to you to declare 
>> a separate "field" to store the value in. Swift's "computed properties" 
>> are similar: if you have a custom getter or setter, there is no backing 
>> store; to add behaviour to a "stored property", you use the separate 
>> "property observer" hooks.
>> 
>> Kotlin's approach is philosophically the opposite: there are no fields, 
>> only properties, but properties can access a hidden "backing field" via 
>> the special keyword "field". Importantly, omitting the setter doesn't 
>> make the property read-only, it implies set(value) { field = value }
> 
> A little history here to help clarify how we ended up where we are: The 
> original RFC as we designed it modeled very closely on Swift, with 4 hooks.  
> Using get/set at all would create a virtual property and you were on your 
> own, while the beforeSet/afterSet hooks would not.  We ran that design by 
> some PHP Foundation sponsors a year ago (I don't actually know who, Roman did 
> it for us), and the general feedback was "we like the idea, but woof this is 
> complicated with all these hooks and having to make my own backing property 
> for all these little things.  Couldn't this be simplified?"  We thought a bit 
> more, and I off-handedly suggested to Ilija "I mean, would it be possible to 
> just detect if a get/set hook is using a backing store and make it 
> automatically?  Then we could get rid of the before/after hooks."  He gave it 
> a quick try and found that was straightforward, so we pivoted to that 
> simplified version.  We then realized that we had... mostly just recreated 
> Kotlin's design, so shrugged happily and went on with life.
> 
> As noted in an earlier email, C#, Kotlin, and Swift all have different 
> stances on the variable name for the incoming value.  We originally modeled 
> on Swift so had that model (optional newVal name), and also because we liked 
> how compact it was.  When we switched to the simplified, incidentally 
> Kotlin-esque approach, we just kept the optional variable as it works.
> 
> I think where that ended up is pretty nice, personally, even if it is not a 
> direct map of any particular other language.
> 
> == Re asymmetric typing:
> 
> This is capability already present today if using a setter method.  
> 
> class Person {
>private $name;
> 
>public function setName(UnicodeString|string $name)
>{
>$this->name  =  $value  instanceof UnicodeString ? $value : new  
> UnicodeString($value); 
>}
> }
> 
> And widening the parameter type in a child class is also entirely legal.  As 
> the goal of the RFC is, essentially, "make most common getter/setter patterns 
> easy to add to a property without making an API-breaking method, so people 
> don't have to add redundant just-in-case getters and setters all the time," 
> covering an easy-to-cover use case seems like a good thing to do.  
> 
> It also ties into the question of the explict/implicit name, for the reason 
> you mentioned earlier (unspecified means mixed), not by intent.  More on that 
> in another section.
> 
> == Re virtual properties:
> 
> Ilija and I talked this 

Re: [PHP-DEV] [RFC[ Property accessor hooks, take 2

2024-02-23 Thread Stephen Reay

> On 23 Feb 2024, at 22:58, Larry Garfield  wrote:
> 
> On Fri, Feb 23, 2024, at 8:33 AM, Stephen Reay wrote:
>>> On 23 Feb 2024, at 06:56, Larry Garfield  wrote:
> 
>> Hi Larry,
>> It's good to see this idea still progressing.
>> I have to agree with the other comment(s) that the implicit
>> `$field`/`$value` variables seem odd to me. I understand the desire for
>> brevity and the potential future scope of reused hooks, but this
>> concept seems to fly in the face of many years of PHP reducing "magic"
>> like this.
> 
> The "magic" that PHP has been removing is mostly weird and illogical type 
> casting.  As noted, neither of these variables are any more "magic" than 
> $this.
> 
> However, since it seems no one likes $field, we have removed it from the RFC. 
>  Of note, to respond to your comment further down, $this->{__PROPERTY__} will 
> not work.  The virtual-property detection looks for the AST representation of 
> $this->propName, and only that.  Dynamic versions that turn into that at 
> runtime cannot work, as it needs to be known at compile time.

I guess it's mostly irrelevant on single-use hooks anyway, but that sounds like 
a potential gotcha with reusable hooks, and I think it's worth making it very 
clear *now* in the RFC/docs that dynamic access like this won't work as 
expected (and why). Perhaps some other indicator on reusablele hooks can be 
used at that point, to signify if it's virtual or not.


> For $value, however, we feel strongly that having the default there is a 
> necessary part of the ergonomic picture.  In particular, given your comments 
> here:
> 
>> To give one answer to your question about ambiguity if the `$value`
>> parameter is required - I don't believe this is actually ambiguous, in
>> the context of PHP:
>> - method parameters in child classes don't implicitly 'inherit' the
>> parent method parameter's type if they don't define one (they widen to
>> mixed);
>> - method return types have no implicit inheritance, they must declare a
>> compatible return type;
>> - typed class properties don't implicitly inherit the parent type when
>> the type left off a child property - they must declare the same type.
>> AFAIK there is no existing behaviour in PHP where omitting a type would
>> mean "the type is implicitly inherited from X", it either means the
>> same as mixed, or it's an error.
> 
> That to me suggests that IF a custom variable name is provided, we should 
> require also specifying the type.  In which case, in the 95% case, if we 
> require the full argument signature then the 95% case would need to 
> double-specify the type, which is a hard-no from an ergonomic standpoint.
> 
> Especially combined with the suggestion yesterday to allow return-to-set in 
> the short-set version, that would mean comparing this:
> 
> public string $phone {
>   set(string $phone) => $this->phone = $this->sanitizePhone($phone);
> }
> 
> To this:
> 
> public string $phone {
>   set => $this->sanitizePhone($value);
> }
> 
> And to me, there's absolutely no contest.  The latter has about 1/3 as many 
> places for me to make a typo repeating the same information over again.  Now 
> imagine comparing the above in a property that's used with constructor 
> promotion.
> 
> 
> public function __construct(
>   public string $phone { set(string $phone) => $this->phone = 
> $this->sanitizePhone($phone); }
>   public string $phone { set => $this->sanitizePhone($value); }
> ) {}
> 
> Again, it's absolutely no contest for me.  I would detest writing the longer 
> version every time.

I think you're making slightly misleading comparisons there, by picking the two 
extremes (and ignoring the possibly for shorter explicit names) - the explicit 
parameter name surely doesn't preclude the use of return-to-set functionality? 
So the comparison could equally be:

```
public function __construct(
   public string $phone { set => $this->sanitizePhone($value); }
   public string $phone { set(string $v) => $this->sanitizePhone($v); }
){}

```


> If PHP has been moving away from weird and inexplicable magic, it's also been 
> moving away from needless boilerplate.  (Constructor promotion being the best 
> example, but not the only; types themselves are a factor here, as are arrow 
> functions.)  As the whole point of this RFC is to make writing common code 
> easier, requiring redundant boilerplate for it to work is actively 
> counter-productive.
> 
> So what I'd suggest instead is "specify the full signature if you want a 
> custom name OR wider type; or omit the param list entirely to get a same-type 
> 

Re: [PHP-DEV] [RFC[ Property accessor hooks, take 2

2024-02-23 Thread Stephen Reay


> On 23 Feb 2024, at 06:56, Larry Garfield  wrote:
> 
> On Wed, Feb 21, 2024, at 11:02 PM, Matthew Weier O'Phinney wrote:
>> On Wed, Feb 21, 2024 at 12:57 PM Larry Garfield  
>> wrote:
>>> After much on-again/off-again work, Ilija and I are back with a more 
>>> polished property access hooks/interface properties RFC.  It’s 99% 
>>> unchanged from last summer; the PR is now essentially complete and more 
>>> robust, and we were able to squish the last remaining edge cases.
>>> 
>>> Baring any major changes, we plan to bring this to a vote in mid-March.
>>> 
>>> https://wiki.php.net/rfc/property-hooks
>>> 
>>> It’s long, but that’s because we’re handling every edge case we could think 
>>> of.  Properties involve dealing with both references and inheritance, both 
>>> of which have complex implications.  We believe we’ve identified the most 
>>> logical handling for all cases, though.
>> 
>> Once again in reading the proposal, the first thing I'm struck by are 
>> the magic "$field" and "$value" variables inside accessors. The first 
>> time they are used, they're used without explanation, and they're 
>> jarring.
>> 
>> Additionally, once you start defining the behavior of accessors... you 
>> don't start with the basics, but instead jump into some of the more 
>> esoteric usage, which does nothing to help with the questions I have.
>> 
>> So, first:
>> 
>> - Start with the most basic, most expected usage for each of reading 
>> and writing properties.
>> - I need a better argument for why the $field and $value variables 
>> exist. Saying they're macros doesn't help those not deep into 
>> internals. As a user, why do they exist?
> 
> For $field, it's not a requirement.  It's mostly for copy-paste convenience.  
> A number of people have struggled on this point so if the consensus is to 
> leave out $field and just use $this->propName directly, we can accept that.  
> They can be re-added if reusable hook packages are added in the future (as 
> noted in Future Scope).
> 
> For $value, it's to avoid boilerplate.  For the majority case, you'll be just 
> operating on an individual value trivially.  Checking it's range, or 
> uppercasing it, or whatever.  Requiring the developer to provide a name 
> explicitly is just extra work; it's much the same as how PHP doesn't require 
> you to pass $this as the first argument to a method explicitly, the way 
> Python and Rust do.  It's just understood that $this exists, and once you 
> learn that it's obvious.
> 
> On the occasions where you do want to specify an alternate name for some 
> reason, or more likely you're providing a wider type, you can.  But in the 
> typical case it would just be one more thing for the dev to have to type out. 
>  This is especially true in what I expect to be a common case, which is 
> promoted constructor arguments with an extra validator set hook on them.
> 
> It also introduces some ambiguity.  If I specify only the name, does that 
> mean I'm widening the type to mixed?  Or just that I'm omitting the name?  If 
> specifying the name is rare, that's not really a big deal.  If it's required 
> in every case, it's a confusion point  in every case.
> 
> In the interest of transparency. for comparison:
> 
> * Kotlin appears to require an argument name, but by convention recommends 
> using "value".
> * Swift makes it optional, with a default name of "newValue".  (Same logic as 
> in the RFC.)
> * C# ... as far as I can tell, doesn't support a custom name at all; it's 
> always called "value", implicitly.
> 
>> Second: you don't have examples of defining BOTH get and set OTHER than 
>> when using expressions for both accessors or a mix. I'm actually 
>> unclear what the syntax is when both are defined. Is there supposed to 
>> be a `;` terminating each? Or  a `,`? Or just an empty line? Again, 
>> this is one of the more common scenarios. It needs to be covered early, 
>> and clearly.
> 
> ... huh.  I thought we had one in there somewhere.  I will add one, thanks.  
> Though to clarify, there's no separator character.
> 
> public string $foo {
>get {
>// ...
>}
>set {
>// ...
>}
> }
> 
>> Third: the caveats around usage with arrays... give me pause. While I'm 
>> personally trying to not use arrays as much as possible, a lot of code 
>> I see or contribute to still does, and the fact that an array property 
>> that uses a write accessor doesn't allow the same level of access as a 
>> normal array property is something I see leading to a lot of confusion 
>> and errors. I don't have a solution, but I worry that this one thing 
>> alone could be enough to prevent the passage of the RFC.
> 
> We completely agree that it's a suboptimal situation.  But as explained, it 
> is the way it is because it's not possible (as far as we can tell) to fully 
> support hooks on array properties.  If you can think of one, please share, 
> because we'd love to make this part better.  I don't like it either, but we 
> 

Re: [PHP-DEV] Proposal: Arbitrary precision native scalar type

2023-12-13 Thread Stephen Reay


> On 7 Dec 2023, at 13:36, Alex Pravdin  wrote:
> 
> Hello internals,
> 
> 
> This is the second round of the discussion regarding arbitrary precision 
> scalar type integration into PHP. The previous part: 
> https://marc.info/?l=php-internals=168250492216838=2 was initiated by me 
> before deep diving into the work with decimals in PHP. After 6 months of 
> working, I would like to update my proposal taking into account my experience 
> and the previous discussion.
> 
> Today's alternatives and their problems are the following.
> 
> bcmath:
> - Workaround: using string type.
> - Unintuitive function calls instead of regular math operations.
> - Unintuitive strings instead of numbers. People want to work with numbers.
> - Can not use proper type-hinting.
> - Can use PHP's basic type coercions.
> 
> Ext-decimal:
> - Third-party extension.
> - Workaround: implements the Decimal class that allows basic regular math 
> operations.
> - Requires using class methods for the rest of math operations.
> - The latest release was in 2019 and there's a danger that it will be 
> unmaintained and not compatible with the future PHP releases.
> - The php-decimal documentation website is currently down.
> - Since objects are always casted to true when not null, "(bool) Decimal(0)" 
> will equal to true which is not intuitive.
> - IDEs are often confused when you use math operations on objects while the 
> code works fine.
> 
> GMP:
> - Workaround: implements the GMP class that allows basic math operations.
> - Requires using separate functions for the rest of operations.
> 
> - Objects are always casted to true, GMP(0) will equal to true.
> 
> 
> Accounting for all of the above, I suggest adding a native numeric scalar 
> arbitrary precision type called "decimal". Below are the preliminary 
> requirements for implementation.
> 
> 
> Decimal values can be created from literals by specifying a modifier or using 
> the (decimal) typecast:
> 
> $v = 0.2d;
> $v = (decimal) 0.2; // Creates a decimal value without intermediary float
> 
> It uses the precision and scale defined in php.ini.
> 
> The "decimal" typehint allows to define custom precision and scale: 
> decimal(20,5). It accepts regular expressions returning ints in the execution 
> context. It accepts int constants and literals in class field and function 
> argument definitions.
> 
> New functions added: get_scale and get_precision to return corresponding 
> values about a decimal value.
> 
> If decimal value with different scale and precision is going to be assigned 
> to a variable or parameter with smaller scale or precision, it first tries to 
> convert the value. If it's not possible, then an exception is thrown like 
> "Can not convert decimal (a, b) x. to decimal(c, d)". If possible, it 
> performs the conversion and generates a warning like "Assigning decimal(a, b) 
> to decimal(c, d) may be not possible with some values".
> 
> It works the same as "float" in terms of its usage and type casting except 
> for one thing. Float value can be passed to a decimal argument or typecasted 
> with a warning like "Float to decimal conversion may incur unexpected 
> results".
> 
> Decimal to float conversion is allowed and smooth:
> 
> function f (float $value) {}
> 
> f(0.2);
> 
> f(0.2d); // allowed with no warnings
> 
> 
> Function "str_to_decimal" added to convert string representation of numbers 
> to decimals.
> 
> 
> Typecast from string to decimal works the same as the "str_to_decimal" 
> function.
> 
> Function "float_to_decimal" added to explicitly convert floats to decimals. 
> It performs float to string conversions using php.ini settings as defaults 
> but also accepts parameters to configure the conversion. Then, it converts 
> string to decimal. Since the main problem of float to decimal conversion is 
> that we don't know the exact result until we use some rounding when 
> transforming it to a human-readable format, it looks like the step of the 
> conversion to a string is inevitable. Any more optimized algorithms are 
> welcome.
> 
> Explicit typecast from float to decimal works the same as "float_to_decimal" 
> function with all default values but also throws a warning. This is to 
> encourage users to use explicit conversion with the "float_to_decimal" 
> function and control the results.
> 
> Literal numbers in the code are converted to floats by default. If prepended 
> by the "(decimal)" typecast, the decimal result is produced without an 
> intermediary float.
> 
> New declare directive "default_decimal" is added. When used, literals and 
> math operations return decimal by default instead of float. This is to 
> simplify creating source files working with decimals only.
> 
> New language construct "as_decimal()" is added to produce decimal math 
> results for literals and math operations instead of float without 
> intermediary float:
> 
> $var = 5 / 2; // returns float 2.5
> $var = as_decimal(5 / 2); // returns decimal 2.5
> 
> This is 

Re: [PHP-DEV] What is the prevailing sentiment about extract() and compact() ?

2023-11-28 Thread Stephen Reay


> On 29 Nov 2023, at 09:58, Larry Garfield  wrote:
> 
> On Tue, Nov 28, 2023, at 7:49 PM, Juliette Reinders Folmer wrote:
>> L.S.,
>> 
>> What with all the drives towards cleaner code, how do people feel 
>> nowadays about `extract()` and `compact()` still being supported ?
>> 
>> Both have alternatives. The alternatives may be a little more cumbersome 
>> to type, but also make the code more descriptive, lessens the risk of 
>> variable name collisions (though this can be handled via the $flags in 
>> extract), prevents surprises when a non-associative key would be 
>> included in an array and lessens security risks when used on untrusted data
> 
> *snip*
> 
>> I can imagine these could be candidates for deprecation ? Or limited 
>> deprecation - only when used in the global namespace ?
>> 
>> For now, I'm just wondering how people feel about these functions.
>> 
>> Smile,
>> Juliette
> 
> extract() has very limited use in some kinds of template engine, which use 
> PHP require() as a template mechanism.  I don't think compact() has any uses.
> 
> I very recently was just reminded that these even exist, as i had to tell one 
> of my developers to not use them.  I think it was compact() he was trying to 
> use.  I vetoed it.
> 
> I would not mind if they were removed, but I don't know how large the BC 
> impact would be.  They'd probably need a long deprecation period, just to be 
> safe.
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi,

While I think I understand the goal behind this, I think you're missing some 
factors here.

Regarding use-cases for compact: the most common one I can think of from my 
work, is for passing multiple local variables as context to a logging function, 
but I'd be surprised if its not also used to build faux hash structures too.

If your goal is to achieve an associative array (i.e a poor mans hash) of known 
variable names, using compact in php8+ has *less* risk of uncaught/unexpected 
errors than building it manually. Passing an undefined name (i.e. due a typo, 
or it just not being defined) produces a warning regardless of whether you 
build the array manually or pass the name(s) to compact(). Providing an array 
key name that doesn't match the variable name (e.g. due to a typo, or a 
variable being renamed) will produce no error when building the array manually, 
but will produce a warning with compact(). 

IDEs (e.g. PHPStorm/IDEA+PHP plugin) can already understand that the names 
passed to compact are a variable name, and make changes when a variable is 
renamed via the IDE. They simply cannot do the same for plain array keys.

Due to how variable scope works, the only way to re-implement compact() with 
the same key-typo-catching behaviour as a function in userland would be 
something that requires the user to pass the result of get_defined_vars() to 
every call.

So no, I don't think compact() should be deprecated, what I think *should* 
happen, is to promote the current warning on undefined variables, to an error, 
as per https://wiki.php.net/rfc/undefined_variable_error_promotion. Whether 
this is a foregone conclusion or not, I don't know because that RFC doesn't 
mention compact() specifically.


extract(), as Larry points out has historically been used by 'pure php' style 
template systems, in a manner that's generally "safe". Personally I'm less 
inclined to use this behaviour now (i.e. I'd prefer to access named & typed 
properties from a template than arbitrary local variable names) but I don't 
think that's enough of a case to remove it, because just like with compact, by 
nature of how variable scope works, it's very difficult/impossible to 
re-implement this in userland, in a way that's reusable and doesn't involve 
using worse constructs (e.g. eval'ing the result of a function)

I think there's possibly an argument to be made for improvements, such as 
changing the default mode of extract to something besides EXTR_OVERWRITE, or to 
have checks in place preventing the overwrite of superglobals.


Cheers


Stephen 

Re: [PHP-DEV] RFC Proposal - static modifier for classes

2023-11-23 Thread Stephen Reay



> On 24 Nov 2023, at 01:09, Rowan Tommins  wrote:
> 
> On Thu, 23 Nov 2023 at 14:20, Stephen Reay  wrote:
> 
>> 
>> Out of the box, with no package manager or module loader or anything, you
>> can do as little as call `spl_autoload_register` with no arguments, and
>> have working class autoloading.
>> 
> 
> 
> Sure, it's just about possible that you could paste that one line into each
> of your PHP files, and they'd all pick up the right classes. But it's more
> likely that you have some shared include called "startup.php",
> "boostrap.php", "header.php", etc, which has that line plus a bunch of
> other setup. So, the argument goes that adding a line "require
> 'namespace_foo_functions.php';" to that shared include isn't that big a
> problem.
> 
> (If it happens you are using Composer, the files and config are listed in a
> JSON file rather than a PHP one, and Composer generates the shared include,
> but the logic's basically the same.)
> 
> The strongest counter-argument, I think, is that it *scales* badly: once
> you have more than a handful of such include files, an autoloader solution
> becomes more attractive than listing all the files.
> 

I think attractive is the wrong word here, but yes in general the issue is that 
it becomes a developer overhead as the number and location of files increases, 
particularly if you want to keep the files organised in the filesystem in a 
similar fashion to classes (i.e. namespaces mapping to directory names).

> However, in itself that's not an argument for static classes; it's an
> argument for function autoloading; the argument for static classes needs to
> be either:
> 
> - "admit it, we're never going to get function autoloading";
> - or "I'd want this even if we had function autoloading" (in which case the
> discussion of require vs autoloading becomes irrelevant).
> 

I couldn't agree more - like I said at the start: I have no dog in this 
particular race about static classes, my only concern is the continued use of 
Composer as a flimsy argument about why features aren't required.



Cheers

Stephen 


> Regards,
> -- 
> Rowan Tommins
> [IMSoP]

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



Re: [PHP-DEV] RFC Proposal - static modifier for classes

2023-11-23 Thread Stephen Reay



> On 23 Nov 2023, at 19:42, Rowan Tommins  wrote:
> 
> On Thu, 23 Nov 2023 at 11:48, Stephen Reay  wrote:
> 
>> 
>> Respectively, I disagree that it's "not a big problem" if your goal is to
>> encourage people to use regular functions over classes with static methods.
>> 
> 
> 
> Just to be clear, my answer was specifically addressing your point about
> using Composer as an argument for not including things.
> 
> I was not saying "... and therefore the argument is true", only "... and
> therefore we can discuss the argument without mentioning Composer if we
> want to".
> 
> 

Fair enough, apologies for misunderstanding what you were saying there.

> 
>> PHP ships with a built in class autoloader function, and pretending that
> using 'require_once' everywhere a function is used, is just as easy for the
> developer seem disingenuous to be honest.
> 
> PHP ships with *the ability to configure* an autoloading function; it will
> not load any files without you first telling it where to look.

I'm talking about php's builtin *implementation* of an autoloader not just 
support for the *concept* of class autoloading using a userland function.

Out of the box, with no package manager or module loader or anything, you can 
do as little as call `spl_autoload_register` with no arguments, and have 
working class autoloading. Yes you *may* also end up setting the include path 
and/or autoload extensions at runtime, or even writing a custom autoload 
implementation - but none of that is required for it to work.

> The
> workaround being proposed is not to use require_once every time you want a
> function, it's to use require_once in the same place you configure your
> autoloader.
> 
> I totally agree that we can debate whether that workaround is sufficient.
> I'm just trying to frame that debate as "autoloading vs require", rather
> than a distraction of "Composer vs something else".
> 

Ok, again, apologies for the misunderstanding of the point you're making - and 
thank you, I agree that is a better way to frame the debate, when it comes to 
language / stdlib features.







> 
> Regards,
> -- 
> Rowan Tommins
> [IMSoP]

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



Re: [PHP-DEV] RFC Proposal - static modifier for classes

2023-11-23 Thread Stephen Reay

> On 23 Nov 2023, at 17:21, Rowan Tommins  wrote:
> 
> On Thu, 23 Nov 2023 at 06:00, Stephen Reay  wrote:
> 
>> I'm disappointed to see yet again that there's this implied notion that
>> working with PHP in 2023 means "well surely you must be using composer",
>> which leads to "but composer..."  somehow being an accepted argument when
>> it comes to missing/incomplete builtin functionality.
>> 
> 
> 
> While I appreciate your point in the general case, in this particular
> thread, the mentions of Composer are really just examples, or can be
> reworded that way:
> 
> Functions lack autoloading, but in practice this isn't a big problem
> because you can just require_once a file defining them, and as long as
> OpCache is running there's very little performance penalty. If you're using
> a package manager or module loading system to integrate multiple
> autoloaders, it's generally easy to add one or more required files as part
> of the package / module config - *for example* Composer has a "files" array
> in each package's "autoload" config.
> 
> So the actual assumption is "surely you must be using OpCache", which
> unlike Composer is bundled with PHP.
> 
> Regards,
> -- 
> Rowan Tommins
> [IMSoP]


(Resending from list-address)

Hi Rowan,

Respectively, I disagree that it's "not a big problem" if your goal is to 
encourage people to use regular functions over classes with static methods.

"No autoloading" is clearly a well known barrier to the use of userland 
functions, and "rewriting 'use composer' to 'use require_once'" isn't a 
comparable workaround, as evidenced by:

- https://wiki.php.net/rfc/core-autoloading (from April 2023) paragraph 2 says:

> The need for such a feature seems very clear as users will create “helper” 
> classes with static methods to take advantage of autoloading via the class 
> autoloading mechanism.

An email earlier in this thread makes the same point (shiny gold sticker if you 
remember who wrote this):

> The only issue being that we don't have good autoloading support for such 
> functions, and that's a whole different problem...



> you can just require_once a file defining them,

To paraphrase a certain secret agent: Do you want people writing faux-namespace 
classes? Because this is how you get people writing faux-namespace classes.


> So the actual assumption is


No, the assumption was very clearly written:

> Autoloading is frankly mostly solved by using the `files` block in your 
> composer.json's autoload config, and then you don't need to care.

Saying "a package loader" instead of "composer" isn't any better really. 
Autoloading of classes in PHP doesn't require a "package loader" to work. PHP 
ships with a built in class autoloader function, and pretending that using 
'require_once' everywhere a function is used, is just as easy for the developer 
seem disingenuous to be honest.



Cheers


Stephen

Re: [PHP-DEV] RFC Proposal - static modifier for classes

2023-11-22 Thread Stephen Reay



> On 21 Nov 2023, at 06:48, Mike Schinkel  wrote:
> 
> Wow. 
> 

Hi,

(This is not a direct reply to Mike, his just seems to be less shouty than 
other recent emails)

I'm not *particularly* bothered by the results of this specific RFC either way 
- a *similar enough* result is already possible by grouping static methods in 
an abstract class, but I'm disappointed to see yet again that there's this 
implied notion that working with PHP in 2023 means "well surely you must be 
using composer", which leads to "but composer..."  somehow being an accepted 
argument when it comes to missing/incomplete builtin functionality.

Despite the way some treat it, this isn't the composer internals list, nor is 
composer a required or even bundled part of PHP.

 
Does that mean you shouldn't use composer? No, if it works for your project, 
that's great.

Does that mean gaps in the php language/standard library should be 
automatically ignored/glossed over because composer may provide a work-around? 
Also, no.


PHP has for a very long time stood out amongst other web-focused languages for 
having a very rich standard library out of the box ('batteries included', I 
think the cool kids would say now).

Let's please not take PHP in the direction of "modern JavaScript" where 
language deficiencies mean that an entire alphabet of constantly changing 
third-party tooling is required to do anything but the simplest tasks.


Cheers


Stephen

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



Re: [PHP-DEV] [RFC] [Discussion] DOM HTML5 parsing and serialization support

2023-09-20 Thread Stephen Reay


> On 20 Sep 2023, at 03:03, Niels Dossche  wrote:
> 
> Hi Stephen
> 
> On 19/09/2023 09:58, Stephen Reay wrote:
>> 
>> 
>>> On 19 Sep 2023, at 14:30, Tim Düsterhus  wrote:
>>> 
>>> Hi
>>> 
>>> On 9/19/23 08:35, Stephen Reay wrote:
>>>> Regarding the private constructor: I understand the issue with the *old* 
>>>> class being confusing - but your new class doesn't have that issue, 
>>>> because there are no "loadXXX" methods: as you said, if you're loading an 
>>>> existing document, you're forced to do it via the static factory methods. 
>>>> With that change alone, there's zero risk of confusion in allowing direct 
>>>> constructor calls, because once the object is instantiated there is no 
>>>> subsequent way to load a document and inadvertently change the encoding.
>>>> Having a regular constructor and then one or more factory methods for 
>>>> specific cases is already a concept in PHP (i.e. DateTime[Immutable]'s  
>>>> `createFromXXX` as well as a constructor), and IMO needing to call a 
>>>> factory method to get an "empty" document seems out of place in PHP - it 
>>>> seems a bit like a Java-ism - using a factory, where one just isn't 
>>>> required.
>>> 
>>> I was one of the persons who discussed this updated API with Niels in 
>>> private and looking up the discussion it was me who proposed making the 
>>> constructor private and just providing named constructors.
>>> 
>>> From the perspective of the user of the API, I like the symmetry between 
>>> all the named constructors:
>>> 
>>> Whenever I want to create a new document, I use one of the fromXyz() 
>>> methods. And when I use those, I get exactly what it says on the tin.
>>> 
>>> Making the regular constructor available for use would effectively make 
>>> whatever that constructor does a special case / the default case. This 
>>> makes sense for DateTimeImmutable, because the __construct() variant is 
>>> likely much more often used than the various createFromXyz() variants. For 
>>> the HtmlDocument I find it less obvious that creating an empty document 
>>> would be the default case compared to loading an existing document from a 
>>> file.
>>> 
>>> We should probably rename the named constructors to include the "create" 
>>> prefix for consistency with DTI though.
>>> 
>>> Best regards
>>> Tim Düsterhus
>>> 
>> 
>> Hi Tim,
>> 
>> 
>> Thanks for providing context on where this idea came from.
>> 
>> 
>> The constructor + specialised factory methods pattern is not exactly new in 
>> PHP (e.g. it took about 3 minutes to find multiple Symphony classes doing 
>> this), and disabling the public constructor for purely cosmetic reasons 
>> sounds like a very weird, and ironic choice to me, when the stated goal is 
>> to make the API *less surprising* than the previous one.
>> 
> 
> Besides the points that have been mentioned by Tim and Larry, there's also 
> the expectation of the programmer that migrates to the new classes to take 
> into account.
> They're used to calling the constructor on the old class and calling a load 
> method afterwards.
> As there is still a constructor, but no load method, this might be confusing 
> for them.
> So in my opinion, disabling it makes it less surprising than the previous one.
> Also, just because Symfony does this doesn't mean it's automatically 
> something we should follow.
> 
>> 
>> Cheers
>> 
>> Stephen 
> 
> Kind regards
> Niels
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php

Hi Niels, Larry

To clarify my earlier message about having the factory methods on the 
faux-interface - when I said meta programming that was probably the wrong term 
to use, so I apologise for the confusion. 
It's true that the *developer* needs to know the expected type of the string 
being parsed. It's not true that the code directly invoking the 'fromString' 
method necessarily needs to know - passing classnames as a string and calling 
static methods on the string is also an established concept in PHP, which works 
really well when the method being called is defined on a single top-level class 
or interface.
A real world example I had in mind, is a Request (e.g. a curl request, or some 
other http-fetching) class that can decode responses into native PHP objects, 
with options for the callee to define the object type t

Re: [PHP-DEV] [RFC] [Discussion] DOM HTML5 parsing and serialization support

2023-09-19 Thread Stephen Reay



> On 19 Sep 2023, at 14:30, Tim Düsterhus  wrote:
> 
> Hi
> 
> On 9/19/23 08:35, Stephen Reay wrote:
>> Regarding the private constructor: I understand the issue with the *old* 
>> class being confusing - but your new class doesn't have that issue, because 
>> there are no "loadXXX" methods: as you said, if you're loading an existing 
>> document, you're forced to do it via the static factory methods. With that 
>> change alone, there's zero risk of confusion in allowing direct constructor 
>> calls, because once the object is instantiated there is no subsequent way to 
>> load a document and inadvertently change the encoding.
>> Having a regular constructor and then one or more factory methods for 
>> specific cases is already a concept in PHP (i.e. DateTime[Immutable]'s  
>> `createFromXXX` as well as a constructor), and IMO needing to call a factory 
>> method to get an "empty" document seems out of place in PHP - it seems a bit 
>> like a Java-ism - using a factory, where one just isn't required.
> 
> I was one of the persons who discussed this updated API with Niels in private 
> and looking up the discussion it was me who proposed making the constructor 
> private and just providing named constructors.
> 
> From the perspective of the user of the API, I like the symmetry between all 
> the named constructors:
> 
> Whenever I want to create a new document, I use one of the fromXyz() methods. 
> And when I use those, I get exactly what it says on the tin.
> 
> Making the regular constructor available for use would effectively make 
> whatever that constructor does a special case / the default case. This makes 
> sense for DateTimeImmutable, because the __construct() variant is likely much 
> more often used than the various createFromXyz() variants. For the 
> HtmlDocument I find it less obvious that creating an empty document would be 
> the default case compared to loading an existing document from a file.
> 
> We should probably rename the named constructors to include the "create" 
> prefix for consistency with DTI though.
> 
> Best regards
> Tim Düsterhus
> 

Hi Tim,


Thanks for providing context on where this idea came from.


The constructor + specialised factory methods pattern is not exactly new in PHP 
(e.g. it took about 3 minutes to find multiple Symphony classes doing this), 
and disabling the public constructor for purely cosmetic reasons sounds like a 
very weird, and ironic choice to me, when the stated goal is to make the API 
*less surprising* than the previous one.


Cheers

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



Re: [PHP-DEV] [RFC] [Discussion] DOM HTML5 parsing and serialization support

2023-09-19 Thread Stephen Reay


> On 19 Sep 2023, at 01:00, Niels Dossche 
> 
> Cheers
> Niels
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php



(Resending with history removed due to apparent size limit) 

Hi Niels,

Obviously, a method with different signatures (`fromEmptyDocument`) can't be in 
the parent, and I'll discuss that below, but having the other factory methods 
that do have the same signature in parent (even if only an abstract method, 
forcing concrete implementations to define it) means that it's possible to 
*safely* do meta-programming with these classes, where you load a string/file, 
using a classname from a variable. This use-case doesn't necessarily need to 
know which specific instance it's getting back, so long as it's an instance of 
the base class (or interface, if it had been one), but that information can 
still be presented, via the return type (either `static`, or `self` on the 
parent and the actual class name on each of the implementations).


Regarding the private constructor: I understand the issue with the *old* class 
being confusing - but your new class doesn't have that issue, because there are 
no "loadXXX" methods: as you said, if you're loading an existing document, 
you're forced to do it via the static factory methods. With that change alone, 
there's zero risk of confusion in allowing direct constructor calls, because 
once the object is instantiated there is no subsequent way to load a document 
and inadvertently change the encoding.

Having a regular constructor and then one or more factory methods for specific 
cases is already a concept in PHP (i.e. DateTime[Immutable]'s  `createFromXXX` 
as well as a constructor), and IMO needing to call a factory method to get an 
"empty" document seems out of place in PHP - it seems a bit like a Java-ism - 
using a factory, where one just isn't required.


Cheers

Stephen

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



Re: [PHP-DEV] [RFC] [Discussion] DOM HTML5 parsing and serialization support

2023-09-18 Thread Stephen Reay


> On 17 Sep 2023, at 18:28, Niels Dossche  wrote:
> 
> Hi Alexandru
> 
> On 9/17/23 11:59, Alexandru Pătrănescu wrote:
>> On Sat, Sep 16, 2023, 02:17 Niels Dossche  wrote:
>> 
>>> 
>>> We'll add a common abstract base class DOM\Document (name taken from the
>>> DOM spec & Javascript world).
>>> DOM\Document contains the properties and abstract methods common to both
>>> HTML and XML documents.
>>> 
>>> 
>> Hi,
>> 
>> Yes looks a lot better.
>> Great work overall! And thank you for taking on this effort.
>> 
>> I would have a small suggestion: to make the abstract class an interface.
>> This will allow even more flexibility on how things can be build further,
>> suggesting composition over inheritance.
>> In user land we cannot have interfaces with properties (yet) but in php
>> internal interfaces we have example with interface UnitEnum that has name
>> property, extendes by BackedEnum that adds value property.
>> 
> 
> Right, we discussed the use of an interface internally too.
> Indeed as you suggest, we chose an abstract class over an interface because 
> of the property limitation.
> Looking at UnitEnum & BackedEnum 
> (https://github.com/php/php-src/blob/bae30682b896b26f177f83648bd58c77ba3480a8/Zend/zend_enum.stub.php)
>  I don't see the properties defined on the interface. In practice, all enums 
> get the properties of course, just not via the interface.
> So as we cannot represent the properties on the interfaces (yet), we'll stick 
> with the abstract class for now.
> 
> 
>> Thank you,
>> Alex
>> 
> 
> Kind regards
> Niels
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
Hi Niels,

Can you expand on the reasoning for two of the decisions in your proposal? I'm 
not sure I really see the reason/benefit :

1. fromX() methods are on the individual classes, rather than the parent, which 
as I understand it, you're using as a poor-mans interface with properties. I'd 
have thought that at the very least the parent should declare those methods as 
abstract


2. Why "fromEmptyDocument()" rather than just allowing `new 
DOM\{XML,HTML}Document` via a public constructor?

The only mention of 'constructor' I see in the email or the RFC is the line 
below:

> the properties set by DOMDocument's constructor are overridden by its load 
> methods, which is surprising

But I don't really see how making the constructor private and forcing use of a 
static method changes this aspect, at all - it just introduces a different way 
to create an instance.


Otherwise, it's great to see some activity on DOM handling classes.


Cheers


Stephen 



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

2023-06-27 Thread Stephen Reay


> On 28 Jun 2023, at 02:53, Ben Ramsey  wrote:
> 
>> On Jun 27, 2023, at 04:01, Ilija Tovilo  wrote:
>> 
>> Hi Ben, Hi Rowan
>> 
>> On Mon, Jun 26, 2023 at 8:55 PM Ben Ramsey  wrote:
>>> 
 On Jun 20, 2023, at 06:06, Rowan Tommins  wrote:
 
 On Tue, 20 Jun 2023 at 10:25, Ilija Tovilo  wrote:
 
> Introduce a new function (currently named populate_post_data()) to
> read the input stream and populate the $_POST and $_FILES
> superglobals.
 
 How about "request_form_populate_globals"?
>> 
>> The word "form" seems a bit out of place (even though it appears in
>> both multipart/form-data and application/x-www-form-urlencoded),
>> because this function is mainly targeted at PUT/PATCH requests for
>> REST APIs. Maybe request_body_populate_globals?
>> 
>>> Another option for the name: `populate_multipart_form_data()`.
>> 
>> I avoided the term "multipart" because the function technically also
>> works for application/x-www-form-urlencoded requests. It's less
>> necessary for the reasons outlined in my previous email, but it would
>> allow for consistent handling of such requests for all HTTP methods.
>> 
>> Some people on GitHub voiced that they would prefer an INI setting.
>> Therefore I will create an RFC accordingly.
> 
> 
> I know this issue comes up enough because it’s confusing to developers that 
> there’s not a `$_PUT`, etc., but I’m not a fan of introducing something new 
> that populates globals.
> 
> While I’ve never used `application/x-www-form-urlencoded` data for `PUT` 
> requests (because I don’t think it’s a proper content-type for the semantics 
> of `PUT`), I do see how this content-type could be used with `PATCH`, and I 
> also don’t want to rule-out use cases of it for `PUT` or any other HTTP 
> method.
> 
> In the past, I’ve used something like the following to solve this:
> 
>parse_str(file_get_contents('php://input'), $data);
> 
> I haven’t looked up how any of the frameworks solve this, but I would be 
> willing to bet they also do something similar.
> 
> Rather than implementing functionality to populate globals, would you be 
> interested in introducing some new HTTP request functions. Something like:
> 
>http_request_body(): string
>http_parse_query(string $queryString): array
> 
> `http_request_body()` would return the raw body and would be the equivalent 
> of calling `file_get_contents('php://input')`. Of special note is that it 
> should _always_ return the raw body, even if `$_POST` is populated, for the 
> sake of consistency and reducing confusion.
> 
> `http_parse_query()` would be the opposite of `http_build_query()` and would 
> return a value instead of requiring a reference parameter, like `parse_str()`.
> 
> While these don’t address the confusion users face by not having a `$_PUT` 
> superglobal, I’d prefer not to overload the superglobals. Maybe we can update 
> the documentation to encourage use of these new functions instead of the 
> superglobals?
> 
> We also might want to introduce something like `http_query_string(): string` 
> that always returns the raw query string, instead of requiring use of the 
> superglobal `$_SERVER['QUERY_STRING']`.
> 
> Cheers,
> Ben


As a userland/library developer I *much* prefer this approach, but *please* 
also include `http_uploads()` (name/signature TBD), returning an array of file 
uploads using a structure akin to what $_POST (or http_parse_query) gives, 
based on the field name, rather than the current scenario where the presence of 
square brackets radically changes the structure of the $_FILES array.

My initial thought was that perhaps the leaf entities in said array could be a 
subclass of SplFileInfo referencing the uploaded temporary file, with 
additional read-only properties for the extra upload-related attributes - but 
really the important thing is just having a sane, consistent structure. Having 
an object rather than an array with constant keys would be a nice addition, but 
is much less important.



Cheers

Stephen 

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

2023-06-09 Thread Stephen Reay



> On 9 Jun 2023, at 20:55, Larry Garfield  wrote:
> 
> On Fri, Jun 9, 2023, at 5:34 AM, Stephen Reay wrote:
> 
>> If the property hooks RFC had already passed a vote, I’d suggest that 
>> some expansion of hooks could provide a cleaner solution here, but it 
>> hasn’t yet (and I understand it’s not desirable to tie the fate of one 
>> RFC to another so heavily) so here we are.
> 
> You're suggesting some kind of `clone` hook on properties?  That would be 
> interesting, but definitely out of scope for both RFCs at the moment. :-)
> 
> --Larry Garfield
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry,

Yes - in the same way that get/set hooks on properties allow much better 
alternatives to __get/__set magic methods, a clone hook could provide a better 
alternative when cloning (I could see two or three variations of how it might 
work that seem intuitive for various “clone” and “clone with” cases).

Agreed, I wasn’t suggesting that it should be attempted as part of this - I was 
more referencing that there are other “ugly” magic methods that are 
planned/expected to be dramatically improved by a property hook alternative, 
and thus IMO “this makes the clone magic method a bit fugly” is of much less 
concern long term, compared to “this does stuff the user can’t control and is 
non-obvious, but we have to maintain this behaviour ‘forever’ because to change 
it would be a BC break"


Cheers

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



Re: [PHP-DEV] RFC [Discussion]: Closure self-reference

2023-06-08 Thread Stephen Reay



> On 4 Jun 2023, at 02:11, Dan Ackroyd  wrote:
> 
> Hi internals,
> 
> I'm now opening the discussion for the Closure self-reference RFC:
> https://wiki.php.net/rfc/closure_self_reference
> 
> This was previously discussed as a draft here:
> https://externals.io/message/112216#112216
> 
> Thank-you to KapitanOczywisty for the implementation.
> 
> cheers
> Dan
> Ack
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Dan,

I quite like this idea, but, to (ab)use the analogy, the syntax bike shed 
definitely needs a few more sample tins.

The various syntax choices that introduce a new variable all seem like they can 
easily lead to developer confusion about where each of the two variables are 
actually defined and what is valid.. I can see plenty of “$closure = fn() as 
$closure => ….;` just because people are unsure.


Is there a syntax issue with e.g. `fn::self` / `function::self` for this? I 
realise this is mostly just a variation on `Closure::current()` but it “feels” 
a bit more natural, and has the added benefit that it *could* be extended to 
return a closure of **any** function, including regular named methods/functions 
etc in a later RFC, if there’s demand for it.



Cheers

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



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

2023-06-08 Thread Stephen Reay



> On 9 Jun 2023, at 07:11, Larry Garfield  wrote:
> 
> On Thu, Jun 8, 2023, at 5:39 PM, Stephen Reay wrote:
> 
>> Is there a specific reason `clone with (foo: $bar);` can’t simply pass 
>> the arguments given to with(), to the __clone() magic method?
>> 
>> It leaves the developer free to use the passed argument(s) or deep 
>> clone existing properties or a mix depending on what’s passed, and 
>> seems like it has the least “magic” or unknown behaviour in terms of 
>> when things happen.
>> 
>> Just a thought.  
> 
> I experimented with that a few years back.  The results showed it is actually 
> pretty awful in practice.
> 
> https://peakd.com/hive-168588/@crell/object-properties-part-2-examples
> 
> --Larry Garfield
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry

Sure, that example __clone() isn’t exactly what I’d call short-and-sweet, but 
it absolutely solves the problem of: “what happens, in which order, when you do 
`clone ($foo) with (bar: ‘baz’, moo: ‘foo’);` on an object with a __clone() 
method. There is zero ambiguity there because it’s expressed in php the 
developer can see/debug/trace.

Also, consider that for classes that have no nullable properties, the __clone 
method could be a lot simpler than your example shows, e.g.:

function __clone(?string $bar = null, ?int $baz = null, ?ComplexObj 
$foo = null) {
$this->bar = $bar ?? $this->bar;
$this->baz = $baz ?? $this->baz;
$this->foo = $foo ?? clone ($this->foo);
}


If the property hooks RFC had already passed a vote, I’d suggest that some 
expansion of hooks could provide a cleaner solution here, but it hasn’t yet 
(and I understand it’s not desirable to tie the fate of one RFC to another so 
heavily) so here we are.



Cheers


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



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

2023-06-08 Thread Stephen Reay



Sent from my iPhone

> On 9 Jun 2023, at 02:33, Larry Garfield  wrote:
> 
> On Thu, Jun 8, 2023, at 6:15 PM, Nicolas Grekas wrote:
>>> On Tue, May 30, 2023, at 10:04 PM, Alexandru Pătrănescu wrote:
> On Tue, May 30, 2023, 19:39 Larry Garfield 
 wrote:
> 
>>> On Mon, May 29, 2023, at 11:22 PM, Máté Kocsis wrote:
 To be honest, the current behavior seemed like the natural choice
>>> for
>>> me, and I didn't really consider to execute the __clone() method
>>> after
>> the
>>> clone assignments.
>>> Do you have a use-case in mind when you need to forward-pass
 information
>> to
>>> __clone()?
>> 
>> Not a specific one off hand.  It's more a conceptual question.  `with`
 has
>> more contextual awareness than __clone(), so it should have "first
 crack"
>> at the operation, so that if necessary it can make changes that
 __clone()
>> can then respond to.  The inverse doesn't make sense.
>> 
>> The only reason for `with` to come after would be to allow `with` to
>> "override" or "undo" something that __clone() did.  Generally
>>> speaking,
 if
>> you have to undo something you just did, you shouldn't have done it in
 the
>> first place, so that's a less compelling combination.
>> 
>> This one isn't a deal breaker, but we should be sure to think it
>>> through
>> as it's kinda hard to reverse later.
>> 
> 
> To me so far also it was natural to assume that __clone is first and
>>> only
> after that the rest of the operations.
> But `with` operations, be it properties assignment or even a closure,
 would
> run in the context of the caller of clone and sometimes this might be
>>> run
> not from a method of the cloned class.
> 
> An example:
> There is a class that represents persons of a fictive country/planet.
> Each person has many properties but has also a first name and a last
>>> name
> and there is a rule: the two names must not start with the same letter.
> Both names cannot be changed as they are defined readonly.
> Creation of new persons can be done using new for new random properties
 or
> using clone to preserve existing properties. But in both cases the
>>> first
> name and last name are randomly chosen.
> If we want to control the last name value during clone that would be
> possible using the `with` operation but the logic to allocate a first
 name
> will only happen in `__clone()`method.
> 
> To be able to achieve this we must have __clone last, as there we have
 the
> internal validations, operations and also access to private/protected
> members that are not accesible from where clone is being called.
> 
> Regards,
> Alex
 
 I... could not understand that in the slightest.  Can you show it in
>>> code?
 
 
>>> 
>>> Sorry for that. Here you go: https://3v4l.org/JIBoI/rfc#vgit.master
>>> If __clone would be first, there is no way to enforce the rule that a
>>> person cannot have their first name starting with the same letter as last
>>> name.
>>> 
>> 
>> I'm not sure that's what __clone should be used for.
>> This looks like a perfect use case for property hooks, isn't it?
>> 
>> On my side, I would find it unexpected that __clone is called after because
>> that would break cloning expectations:
>> Imagine you have a __clone that does some deep cloning (a much more typical
>> scenario for this construct),
>> Let's say __clone() does $this->foo = clone $this->foo;
>> 
>> Imagine now that you do: clone $obj with (foo: $bar)
>> I'd expect $obj->foo === $bar after this. But if __clone is called after,
>> that won't be true, and I don't see how that could be "fixed" if we swap
>> the order. Would you?
>> 
>> Nicolas
> 
> Oh, interesting.  There's a nice example case.  To make it a bit more 
> concrete, and think aloud... 
> 
> class Pet {
>  public function __construct(
>public readonly string $name = 'Fluffy',
>  ) {}
> }
> 
> class Address { ... }
> 
> class Person {
>  public function __construct(
>public readonly Pet $pet,
>public readonly Address $address,
>  }
> 
>  public function __clone() {
>// Legal now thanks to a previous RFC.
>$this->address = clone ($this->address);
>  }
> }
> 
> $p = new Person(new Pet(), new Address(blah));
> 
> // The person gets a new pet.
> $p2 = clone $p with (pet: new Pet('Bonzo'));
> 
> In this case, the order of operations is irrelevant.
> 
> // The person moves.
> $newAddr = new Address(whatever);
> $p3 = clone $p2 with (address: $newAddr);
> 
> In this case, if the `with` happens first, then the new address object is 
> cloned needlessly, but that *probably* doesn't hurt anything.  But $newAddr 
> !== $p3->address.
> 
> If the `__clone()` happens first, then the existing address object is cloned 
> needlessly, but that *probably* doesn't hurt anything.  Because the 
> assignment happens 

Re: [PHP-DEV] Declaration-aware attributes

2023-05-30 Thread Stephen Reay
(Resending to the list without all the history because qmail complained about 
message size)


>> 
>> Hi Andreas,
>> 
>> I too have wondered (and I think asked in room11?) about such a concept. 
>> >From memory the general response was “just do it in userland with a 
>> wrapper” so its good to see someone else is interested in this being part of 
>> the language.
>> 
>> While I agree that it’s most useful if the `Reflector` instance is available 
>> in the constructor, I’m not keen on the proposed magic “skipping” of 
>> arguments as you suggest. It seems way too easy to confuse someone 
>> (particularly if the attribute class itself has reason to be instantiated 
>> directly in code)
> 
> Good point! Almost made me change my mind completely. But I already
> changed it back :)
> 
> When instantiating in code, the "real" signature would have to be
> used, and the reflector argument passed explicitly.


That’s kind of my point: it’s not super intuitive why (or the specifics of how) 
it’s being skipped when it’s an attribute, vs when it’s instantiated from code. 
What if someone specifies an argument with the same name? If they specify args 
without names, can they just use null for that? Etc.

> This would be
> useful for unit tests that want to replicate the realistic behavior.
> Also it guarantees that the code of the attribute class can really
> count on this value to not be null, no matter how the class is
> instantiated.
> 
> 

I would expect that whether the Reflector object is required is simply a matter 
of whether or not the parameter is nullable.

If it’s not nullable, then yes, the explicit instantiation call will need to 
supply it at the correct location. If it’s only required when created from 
attribute usage, then it would accept null, and the constructor would have 
appropriate logic to handle that.



>> 
>> I think a better approach would be to suggest authors put the parameter at 
>> the *end* of the parameter list, so that no ‘skipping' is required when 
>> passing arguments without names (or put it where you like if you’re always 
>> using named arguments)
> 
> If I understand correctly, the proposal would technically not change,
> we just add a recommendation.

Technically, yes “my way” would work fine with the proposal you’ve suggested, 
if I choose to always put the parameter marked by #[ReflectionContext] last.

I’m just concerned about confusing usage if “insert this parameter anywhere” is 
the ‘recommended’ (i.e. documented example) way to use this feature.

Even with that concern, I still prefer this to most other solutions mentioned 
so far, for the same reasons: they’re all some degree of magic.

The only other solution I can think of that’s less “magic” and more explicit, 
is (and I have no idea if this is even feasible technically) to introduce a 
builtin trait for attribute classes to use, providing a protected method or 
property that gives access to the Reflector (how the trait has access is not 
really important, I assume it can be assigned to the object somehow before the 
constructor is called). I guess this could also be an abstract class, but a 
trait makes it much easier to adopt so that would be my preferred approach.

So something like

trait AttributeReflector {
protected function getReflector(): \Reflector {
// do internal stuff
}
}

#[Attribute]
class Foo {
Use \AttributeReflector;

public readonly string $name;

function __construct(?string $name = null) {
$this->name = $name ?? $this->getReflector()->name;
}
}

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



Re: [PHP-DEV] Declaration-aware attributes

2023-05-29 Thread Stephen Reay



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

Hi Andreas,

I too have wondered (and I think asked in room11?) about such a concept. From 
memory the general response was “just do it in userland with a wrapper” so its 
good to see someone else is interested in this being part of the language.

While I agree that it’s most useful if the `Reflector` instance is available in 
the constructor, I’m not keen on the proposed magic “skipping” of arguments as 
you suggest. It seems way too easy to confuse someone (particularly if the 
attribute class itself has reason to be instantiated directly in code)

I think a better approach would be to suggest authors put the parameter at the 
*end* of the parameter list, so that no ‘skipping' is required when passing 
arguments without names (or put it where you like if you’re always using named 
arguments)


Cheers

Stephen 

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



Re: [PHP-DEV] First-class callable partial application

2023-03-16 Thread Stephen Reay


> On 17 Mar 2023, at 05:33, Larry Garfield  wrote:
> 
> On Thu, Mar 16, 2023, at 4:14 AM, Rowan Tommins wrote:
>>> On 15/03/2023 21:12, Dan Ackroyd wrote:
>>> Would it be desirable to split those two things into two separate
>>> RFCs, by having the first RFC not have native syntax support, but
>>> instead another static method on Closure? e.g. something like:
>>> 
>>> Closure::partial($callable, array $position_params, array
>>> $named_params): Closure {}
>> 
>> 
>> Hm... now we have the first-class callable syntax, making it an instance 
>> method on Closure would allow this:
>> 
>> $mapFoo = array_map(...)->partial([$foo]);
>> $filterFoo = array_filter(...)->partial([1 => $foo]);
>> 
>> Which could copy over the full signature, so be equivalent to this:
>> 
>> $mapFoo = static fn(array ...$arrays): array => array_map($foo, ...$arrays);
>> $filterFoo = static fn(array $array, int $mode = 0): array => 
>> array_filter($array, $foo, $mode);
>> 
>> While being a similar length to a much less rich version:
>> 
>> $mapFoo = fn($array) => array_map($foo, $array);
>> $filterFoo = fn($array) => array_filter($array, $foo);
> 
> Fascinating!  I... don't know if we considered something like that or not 3 
> years ago.  It's been a while.
> 
> It's definitely not as nice as the integrated syntax, but it does have the 
> advantage of the implementation almost certainly being rather pedestrian in 
> comparison.  That approach would favor left-to-right application, but not 
> force it, which is probably sufficient.
> 
> As a thought experiment, if we had that syntax and functions that were 
> designed to be used with them, it would look like so:
> 
> function amap(callable $c, iterable $it) { ... }
> function implode(string $sep, iterable $it) { ... }
> function length(string $s) { ... }
> 
> $arr = [1, 2, 3];
> 
> $a2 = amap(...)->partial(chr(...))($arr);
> 
> $str = implode(...)->partial(',')($a2);
> 
> Or, if combined with pipes:
> 
> $size = $arr 
> |> amap(...)->partial(chr(...))
> |> implode(...)->partial(',')
> |> length(...);
> 
> Which... is not terrible, especially as it doesn't preclude using higher 
> order functions for more control.  
> 
> We would likely want partial() to accept positional args (left to right) and 
> named args.  And I'm more than happy to say now that the capture is only by 
> value, ever.
> 
> I wonder if there's a shorter name we could use than "partial" to make it 
> more readable?  Or perhaps an operator that applied only to closure objects?  
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

It’s not shorter than “partial” but given “bindTo()” exists, “bindArgs()” is at 
least clear about what it’s doing.

Cheers

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



Re: [PHP-DEV] Class Re-implementation Mechanism

2023-02-21 Thread Stephen Reay



> On 21 Feb 2023, at 18:52, someniatko  wrote:
> 
> Hi again, internals
> 
> My marathon of some crazy ideas continues :D, with less crazy one this time.
> 
> 
> ## Idea
> 
> Allow "reimplementing" the non-static public API (that is public
> properties and methods, excluding constructor) of a class by other
> classes like this:
> 
> ```php
> final class interface A {
>public string $s;
> 
>public function __construct(string $s) { $this->s = $s; }
> 
>public static function fromInt(int $i): self { return new
> self((string) $i); }
> 
>public function foo(): int { return 42; }
> }
> 
> final class B implements A {
>public string $s = 'hello';
> 
>public function foo(): int { return 69; }
> }
> 
> function usesA(A $param): void {}
> 
> usesA(new B); // this works
> ```
> 
> 
> ## Explanation
> 
> Consider there is a class like this:
> 
> ```php
> final class Service {
>public function __construct(private SomeDependency $dependency) {}
>// ...
> }
> 
> final class SomeDependency {
>// ...
> }
> ```
> 
> We want to write some tests for the Service class, but we don't want
> to use a real SomeDependency instance
> during tests. A common approach is to either extract an interface
> (JUST to make it testable), or to drop the
> `final` keyword and allow extending the class.
> 
> Both approaches have their flaws:
> - extracting an interface unnecessarily complicates the system, where
> only one "real" implementation of an interface is assumed.
> - dropping the `final` keyword allows for the rabbit-hole of
> inheritance abuse, like greatly described in this article:
> https://front-line-php.com/object-oriented
> 
> I believe I came up with a better idea: what if we could leave both
> benefits of prohibiting the inheritance abuse and also allow not to
> clutter our namespace with excess entities like interfaces? I hereby
> suggest to combine the responsibilities of a class and an interface
> into one thing like that:
> 
> ```php
> final class interface C {}
> final class D implements C {}
> ```
> 
> Now other classes can "implement" this class as well. Introduction of
> the new syntax (`class interface`) also solves BC problem - if you
> want to forbid your classes to be reimplemented whatsoever, you can
> still stick to the `final class` syntax. Although it is also possible
> to allow "reimplementing" ANY class, then new syntax is not needed -
> but some library writers like Marco Pivetta could be sad about that I
> suppose.
> 
> Soo..., what do you think? Could this be a valuable addition to the language?
> 
> Regards,
> Illia / someniatko
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi

It’s possible I’m missing something here, because it’s hard to tell which parts 
are new syntax you’re suggesting, and which parts are unfortunate typos…

Can you explain how using a regular interface (or even an abstract base class 
if you prefer) doesn’t already achieve what you want?



Cheers

Stephen 

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



Re: [PHP-DEV] Methods which auto-return the class instance

2022-12-24 Thread Stephen Reay


> On 25 Dec 2022, at 12:59, Ilija Tovilo  wrote:
> 
> Hi Daniele
> 
>> On Fri, Dec 23, 2022 at 1:09 AM joke2k  wrote:
>> 
>> Hi folks,
>> 
>> What do you think about having a method which returns the class instance
>> `$this` by default only IF its return type is set as `self`?
>> 
>> It is very common for fluent class methods to have a verbose `return
>> $this;` ending in their body.
> 
> Instead of adding special syntax to make writing fluent accessors
> easier, I wonder if something akin to Dart's cascade operator would be
> a better approach.
> 
> https://dart.dev/guides/language/language-tour#cascade-notation
> 
> $foo
>   ..setBar('bar')
>   ..setBaz('baz');
> 
> The syntax is just copied from Dart, there's probably a better fit for
> PHP. .. would invoke a method call but discard the return value,
> evaluating to the lhs of the method call instead.
> 
> With an operator solution one can use fluent method calls on APIs that
> aren't specifically designed for it when desired, accessors can become
> leaner as return $this is no longer necessary, and it becomes obvious
> at call-site that the chained methods are called on the same object.
> 
> I'm not sure about syntax or the fact that Dart allows property
> assignments in combination with .. as that makes the syntax ambiguous
> (or whitespace sensitive), but that wouldn't be necessary for what
> you're proposing.
> 
> Example of the ambiguity:
> 
> $foo
>..bar = $bar
>..baz()
> // Could be parsed as
> $foo..(bar = $bar)..baz()
> $foo..bar = ($bar..baz())
> 
> An alternative might be a C# style syntax which would make property
> assignments unambiguous.
> 
> $foo {
>setBar('bar'),
>baz = 'baz',
> }
> 
> But this is also longer and less readable (to me at least).
> 
> Anyway, just my unrefined thoughts. I would not support implicit
> `return $this` for self or static. At the very least, the return type
> should be $this (which is essentially a sub-type of static) but that
> too doesn't seem like an elegant solution to me.
> 
> Ilija
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Out of all the ideas discussed here the only one that doesn’t seem like it lead 
to confusion or unexpected behaviour to me is the c# style statement which at 
the surface seems quite similar to the now-deprecated JS “with” statement.

Cheers

Stephen 

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



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-11 Thread Stephen Reay



> On 12 Dec 2022, at 02:18, Larry Garfield  wrote:
> 
> On Thu, Dec 1, 2022, at 12:31 PM, Tim Düsterhus wrote:
>> Hi
>> 
>> On 11/29/22 21:29, Larry Garfield wrote:
>>> Thank you everyone for the feedback.  Based on this thread, we've made two 
>>> changes to the RFC:
>>> 
>>> 1. We've moved readonly back to forbidden with a-viz for now.  I've added a 
>>> section to Future Scope where we really should sort this out in the future, 
>>> but we'll do that in the future when we can all focus on the various 
>>> nuances of just that piece.
>>> 
>>> 2. I rewrote the section on __set to make it clearer.  That also included 
>>> Ilija and I digging into all the nuances that are already present.  The 
>>> text may still look a bit complex, but that's because the existing logic is 
>>> already complex with readonly.  Long story short, the a-viz RFC does not 
>>> change anything in the way __set works vis a vis asymmetric visibility; it 
>>> just inherits and continues what readonly already started, so it's 
>>> consistent.
>>> 
>>> The PR should be updated in the next week or two with the latest changes.  
>>> Baring any major need for change, we expect to call a vote for it shortly 
>>> after New Years.
>>> 
>> 
>> Okay, then I'd like to officially "request" that the abbreviated form 
>> [1] is dropped:
>> 
>> I believe 'protected(set) string $foo' is easily confused with 
>> 'protected string $foo' at a simple glance.
>> 
>> Also any implicit rules are something developers will need to learn by 
>> heart, whereas an explicit 'public protected(set) string $foo' could 
>> reasonably be understood by someone without any PHP experience and some 
>> basic experience of OO concepts.
>> 
>> Having two separate explicit keywords also makes it much clearer that 
>> asymmetric visibility is involved, because it's also asymmetric in the code.
>> 
>> I believe the only benefit of the abbreviated form is saving 6 
>> keystrokes (+ one hit to the spacebar) and I don't believe it's worth 
>> the lack of clarity for an important property of the defined property.
>> 
>> Best regards
>> Tim Düsterhus
>> 
>> [1] https://wiki.php.net/rfc/asymmetric-visibility#abbreviated_form
> 
> 
> Does anyone else have feelings on this point?  IMO, the shorthand makes a lot 
> of sense when used with readonly to avoid lines getting just annoyingly long, 
> but without it I can see the argument for not allowing it; it's about a wash 
> in terms of length with readonly today.  I'm comfortable going with the 
> consensus on this one for now.
> 
> --Larry Garfield
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

I’ll just re-iterate what I said in chat a while ago - I think requiring the 
dev to be explicit about making it public is a safer first step, and it has no 
BC risk if you wanted to later allow the implicit variant, and without the 
capability to combine with the readonly keyword (yet) it doesn’t seem like a 
huge problem to be explicit IMO.



Cheers

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



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-02 Thread Stephen Reay


> On 2 Dec 2022, at 18:31, Ilija Tovilo  wrote:
> 
> Hi Stephen
> 
>> So here’s my last attempt:
>> 
>> Please change this behaviour in your rfc.
>> 
>> You are explicitly making it mutually exclusive with readonly now, so that’s 
>> not a bc break - if/when it becomes compatible with readonly the authors of 
>> that rfc can either keep the limitation as it exists **for readonly 
>> properties** (I’m not an expert but I don’t believe this would be a BC break 
>> either), or decide to drop the limitation completely (deliberate BC break)
>> 
>> Keeping the limitation now on non-readonly properties makes no sense, and 
>> will be confusing to user land developers.
> 
> This behavior is already not limited to readonly, it works the same
> for normal typed properties.
> https://3v4l.org/WpBp4
> 
> The set-visibility is not relevant here: When unset has been called,
> __set will be called (and __get too). The set-visibility is only
> relevant when unset hasn't been called, as that will influence whether
> the property is written to or an error is thrown. The RFC is actually
> wrong saying this is specifically due to readonly properties. This
> behavior has been here for a while.
> 
> See the relevant commit:
> https://github.com/php/php-src/commit/f1848a4b3f807d21415c5a334b461d240b2a83af
> 
>> Assigning to an uninitialized typed property will no longer trigger
>> a call to __set(). However, calls to __set() are still triggered if
>> the property is explicitly unset().
> 
>> This gives us both the behavior people generally expect, and still
>> allows ORMs to do lazy initialization by unsetting properties.
> 
>> For PHP 8, we should fine a way to forbid unsetting of declared
>> properties entirely, and provide a different way to achieve lazy
>> initialization.
> 
> I'm not sure if anybody actually makes use of this trick. It might be
> worth removing this weird behavior by offering an alternative. In any
> case, this is out of scope for this RFC.
> 
> Regards,
> Ilija
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Ilija

I’m not sure if you missed my earlier emails but I’m pretty sure you’ve 
misunderstood what I’m asking about.

I’m not, and have never, asked for the behaviour of explicitly unset() 
properties to change. Not once, never, nada. I do agree that the behaviour 
weird, but its weird in a way that gives userland developers more 
power/capability, not less.


What I *am* asking for, is that when a non-readonly property is declared with 
protected or private `set` visibility, an attempt to set/write that property 
from outside the class will trigger __set(), exactly the way it does now for a 
property declared as protected or private.

If it’s not obvious the major reason for this is to allow dropping  __get 
boilerplate while maintaining the ability to have checks/custom logic on 
set/write (i.e. a poor mans property set accessor), and thus existing code that 
uses this can easily and safely upgrade to using asymmetric visibility without 
affecting the __set handler logic.


To make it crystal clear, here is an example:

```
class FooSym {
   protected string $bar;

   public function __set($name, $value) {
  if ($name === 'bar') {
 $this->bar = $value;
  }
   }

   public function __get($name) {
  if ($name === 'bar') {
 return $this->bar;
  }
   }
}

$f = new FooSym;
$f->bar = 'hello';
echo $f->bar;


class FooAsym {
   public protected(set) string $bar;

   public function __set($name, $value) {
  if ($name === 'bar') {
 $this->bar = $value;
  }
   }

}

$f = new FooAsym;
$f->bar = 'hello';
echo $f->bar;

```

The first class is a trivial example of what works right now. No use of unset() 
is required, it behaves as expected.

The proposed __set behaviour in this RFC will mean the second example **won’t 
work**, and that is both extremely unintuitive and IMO, technically unnecessary 
with regards to avoiding BC breaks.

Cheers

Stephen 







Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-12-01 Thread Stephen Reay



> On 2 Dec 2022, at 01:21, Larry Garfield  wrote:
> 
> On Wed, Nov 30, 2022, at 7:38 PM, Stephen Reay wrote:
> 
>>>> So please, can you explain to me why consistency with an implementation
>>>> detail of readonly properties is more important than consistency with
>>>> declared developer intention for regular properties via the magic
>>>> setter method?
>>> There's a couple of reasons.
>>> One, and arguably the most important, readonly and aviz being incompatible 
>>> is, hopefully, a temporary situation.  There's some fiddly bits to work out 
>>> design-wise, and based on earlier comments in the thread we're going to 
>>> punt on that for now to avoid that dragging down the whole RFC.  I believe 
>>> we absolutely should allow them together in the future (maybe in a later 
>>> 8.3 RFC, maybe a future version, TBD), which means ensuring, now, that they 
>>> are compatible in the future.  This approach involves the fewest future BC 
>>> breaks.
>>> Second, I wouldn't call the current behavior of readonly a mere 
>>> implementation detail.  It's weird and unexpected, I'd agree, but only as a 
>>> side effect of previous design decisions, some of which are even older than 
>>> readonly.  But it's an observed behavior that code can rely on, and in some 
>>> cases does.  For example:
>>> https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties
>>> The "unset a declared property to force it through __get once" is a trick 
>>> that some ORMs use extensively.  readonly just inherited that, leading to 
>>> the current behavior: __set depends on the write/set visibility of the 
>>> property and its settedness.  This RFC doesn't change anything there.  
>>> The alternative would be to have __set called always for a non-public-set 
>>> property.  However, that is a place for bugs, as you then can't not have a 
>>> back-door way to publicly set a property even if it's declared 
>>> private(set).  (Or, you have to be very careful in your __set to avoid it.) 
>>>  That is both inconsistent with the language today, and error prone.
>>> Finally, we're planning to work in the near-future on property hooks (aka 
>>> property accessors), which would allow per-property custom set routines.  
>>> That would largely remove the issue entirely, as the use of __set would go 
>>> way down and you'd basically never have to use it with a declared property, 
>>> fancy tricks or no, so this issue would never come up at all.
>>> --Larry Garfield
>>> --
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: https://www.php.net/unsub.php
>> Hi Larry,
>> I think there must be some confusion somewhere, based on some of your 
>> comments.
>> I’m not suggesting that the “unset to force a **public** property to go
>> through getter/setter methods” logic should be specifically different.
>> I’m suggesting that when the decision is made to call __set or not, the
>> properties **set** visibility is what should be considered, not it’s
>> **get** visibility.
>> Your own comment even describes this behaviour: "leading to the current
>> behavior: __set depends on the write/set visibility of the property"
>> But your RFC says that __set will depend on the **read/get** visibility
>> of the property.
>>> you then can't not have a back-door way to publicly set a property even if 
>>> it's declared private(set).  (Or, you have to be very careful in your __set 
>>> to avoid it.)  That is both inconsistent with the language today, and error 
>>> prone.
>> If a developer adds a _set() method that can write to a private(set)
>> property, I would expect that is working exactly as desired, exactly as
>> it does **now** where it’s just a “protected” property.
> 
> I think we're talking past each other a bit. :-)
> 
> The logic described in the RFC is, to the best of out knowledge, what already 
> happens in 8.1/8.2 with readonly.  Whether that is good or bad, obvious or 
> intuitive, it's what PHP already does, for better or worse.  We view readonly 
> as, effectively, a shorthand for "private(set) write-once" (which is what it 
> is), and want to ensure that future RFCs can do that explicitly so that we 
> can allow `public protected(set) readonly` in the future.
> 
> For that to be possible, not changing the existing behavior is a necessity.  
> Changing the behavior described in the RFC right now is a BC break.  That's 
> true whether the logic described in the RF

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Stephen Reay



> On 1 Dec 2022, at 08:38, Stephen Reay  wrote:
> 
> 
> 
>> On 30 Nov 2022, at 22:09, Larry Garfield  wrote:
>> 
>> On Tue, Nov 29, 2022, at 11:25 PM, Stephen Reay wrote:
>> 
>>> Hi Larry,
>>> 
>>> Thank you for clarifying the setter behaviour in more explicit terms, 
>>> but I have to say I’m quite disappointed in this continued “use the 
>>> logic of readonly to apply to something that is explicitly not 
>>> readonly” - this is even more stark now that you’ve explicitly made 
>>> them mutually exclusive behaviours.
>>> 
>>> I’m generally very in favour of maintaining consistency, but this seems 
>>> like it’s using technical consistency as an excuse to justify 
>>> unintuitive behaviour that breaks consistency in another, much more 
>>> obvious way.
>>> 
>>> 
>>> Can you explain why it makes more sense to maintain consistency with 
>>> “readonly” than it does to maintain consistency with the existing 
>>> “__set()” behaviour for properties, particularly now that you’ve 
>>> indicated these features (asymmetric visibility and readonly) are 
>>> mutually exclusive? 
>>> 
>>> While it’s stated multiple times that “readonly” introduced a limited 
>>> form of asymmetric visibility, and thus this is a continuation, in 
>>> terms of intuitiveness, the existing __set() rules are very easy to 
>>> comprehend even with readonly:
>>> 
>>> - if the property is declared as public, __set() is never called; if 
>>> it’s declared as protected, __set is called when the property is 
>>> accessed from outside that class or it’s hierarchy. Yes, I know that 
>>> readonly imposes an implicit visibility difference - but that is 
>>> essentially an implementation detail, from the point of view of the 
>>> userland developer, it’s not a clear statement of intended behaviour on 
>>> their part, expressed through the code as written.
>>> 
>>> For example, with `public readonly int $foo` it’s quite obvious why 
>>> __set() isn’t called, using the exiting well-understood logic: it’s a 
>>> public property. PHP applies a kind of asymmetric visibility to the 
>>> property behind the scenes, but that isn’t what the developer declared, 
>>> it’s the implementation. This behaviour matches that of regular, 
>>> non-readonly fields: when the field is declared public (or has implicit 
>>> public visibility) __set() is never called.
>>> 
>>> If we make that field protected, __set() will be called when the 
>>> property is written to from outside the class, regardless of whether 
>>> it’s readonly or not.
>>> 
>>> 
>>> What you’re proposing changes that, in a way that is completely 
>>> unintuitive: when attempting to *write* data to a property that is 
>>> marked as protected(set), the __set() method will not be called.
>>> 
>>> 
>>> So please, can you explain to me why consistency with an implementation 
>>> detail of readonly properties is more important than consistency with 
>>> declared developer intention for regular properties via the magic 
>>> setter method?
>> 
>> There's a couple of reasons.
>> 
>> One, and arguably the most important, readonly and aviz being incompatible 
>> is, hopefully, a temporary situation.  There's some fiddly bits to work out 
>> design-wise, and based on earlier comments in the thread we're going to punt 
>> on that for now to avoid that dragging down the whole RFC.  I believe we 
>> absolutely should allow them together in the future (maybe in a later 8.3 
>> RFC, maybe a future version, TBD), which means ensuring, now, that they are 
>> compatible in the future.  This approach involves the fewest future BC 
>> breaks.
>> 
>> Second, I wouldn't call the current behavior of readonly a mere 
>> implementation detail.  It's weird and unexpected, I'd agree, but only as a 
>> side effect of previous design decisions, some of which are even older than 
>> readonly.  But it's an observed behavior that code can rely on, and in some 
>> cases does.  For example:
>> 
>> https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties
>> 
>> The "unset a declared property to force it through __get once" is a trick 
>> that some ORMs use extensively.  readonly just inherited that, leading to 
>> the current behavior: __set depends on the write/set visibility of the 
>> property and its settedness.  This RFC doesn't change a

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Stephen Reay



> On 30 Nov 2022, at 22:09, Larry Garfield  wrote:
> 
> On Tue, Nov 29, 2022, at 11:25 PM, Stephen Reay wrote:
> 
>> Hi Larry,
>> 
>> Thank you for clarifying the setter behaviour in more explicit terms, 
>> but I have to say I’m quite disappointed in this continued “use the 
>> logic of readonly to apply to something that is explicitly not 
>> readonly” - this is even more stark now that you’ve explicitly made 
>> them mutually exclusive behaviours.
>> 
>> I’m generally very in favour of maintaining consistency, but this seems 
>> like it’s using technical consistency as an excuse to justify 
>> unintuitive behaviour that breaks consistency in another, much more 
>> obvious way.
>> 
>> 
>> Can you explain why it makes more sense to maintain consistency with 
>> “readonly” than it does to maintain consistency with the existing 
>> “__set()” behaviour for properties, particularly now that you’ve 
>> indicated these features (asymmetric visibility and readonly) are 
>> mutually exclusive? 
>> 
>> While it’s stated multiple times that “readonly” introduced a limited 
>> form of asymmetric visibility, and thus this is a continuation, in 
>> terms of intuitiveness, the existing __set() rules are very easy to 
>> comprehend even with readonly:
>> 
>> - if the property is declared as public, __set() is never called; if 
>> it’s declared as protected, __set is called when the property is 
>> accessed from outside that class or it’s hierarchy. Yes, I know that 
>> readonly imposes an implicit visibility difference - but that is 
>> essentially an implementation detail, from the point of view of the 
>> userland developer, it’s not a clear statement of intended behaviour on 
>> their part, expressed through the code as written.
>> 
>> For example, with `public readonly int $foo` it’s quite obvious why 
>> __set() isn’t called, using the exiting well-understood logic: it’s a 
>> public property. PHP applies a kind of asymmetric visibility to the 
>> property behind the scenes, but that isn’t what the developer declared, 
>> it’s the implementation. This behaviour matches that of regular, 
>> non-readonly fields: when the field is declared public (or has implicit 
>> public visibility) __set() is never called.
>> 
>> If we make that field protected, __set() will be called when the 
>> property is written to from outside the class, regardless of whether 
>> it’s readonly or not.
>> 
>> 
>> What you’re proposing changes that, in a way that is completely 
>> unintuitive: when attempting to *write* data to a property that is 
>> marked as protected(set), the __set() method will not be called.
>> 
>> 
>> So please, can you explain to me why consistency with an implementation 
>> detail of readonly properties is more important than consistency with 
>> declared developer intention for regular properties via the magic 
>> setter method?
> 
> There's a couple of reasons.
> 
> One, and arguably the most important, readonly and aviz being incompatible 
> is, hopefully, a temporary situation.  There's some fiddly bits to work out 
> design-wise, and based on earlier comments in the thread we're going to punt 
> on that for now to avoid that dragging down the whole RFC.  I believe we 
> absolutely should allow them together in the future (maybe in a later 8.3 
> RFC, maybe a future version, TBD), which means ensuring, now, that they are 
> compatible in the future.  This approach involves the fewest future BC breaks.
> 
> Second, I wouldn't call the current behavior of readonly a mere 
> implementation detail.  It's weird and unexpected, I'd agree, but only as a 
> side effect of previous design decisions, some of which are even older than 
> readonly.  But it's an observed behavior that code can rely on, and in some 
> cases does.  For example:
> 
> https://peakd.com/hive-168588/@crell/php-tricks-lazy-public-readonly-properties
> 
> The "unset a declared property to force it through __get once" is a trick 
> that some ORMs use extensively.  readonly just inherited that, leading to the 
> current behavior: __set depends on the write/set visibility of the property 
> and its settedness.  This RFC doesn't change anything there.  
> 
> The alternative would be to have __set called always for a non-public-set 
> property.  However, that is a place for bugs, as you then can't not have a 
> back-door way to publicly set a property even if it's declared private(set).  
> (Or, you have to be very careful in your __set to avoid it.)  That is both 
> inconsistent with the language today, and error prone

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-30 Thread Stephen Reay


> On 30 Nov 2022, at 15:41, Alexandru Pătrănescu  wrote:
> 
> 
> On Wed, Nov 30, 2022, 05:25 Stephen Reay  <mailto:php-li...@koalephant.com>> wrote:
> 
> 
> > On 30 Nov 2022, at 08:27, Larry Garfield  > <mailto:la...@garfieldtech.com>> wrote:
> > 
> > On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
> > 
> >> In the RFC, section Permitted visibility 
> >> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
> >> <https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility> 
> >> <https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
> >> <https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility>>):
> >>> The set visibility, if it differs from the main (get) visibility, MUST be 
> >>> strictly lesser than the main visibility. That is, the set visibility may 
> >>> only be protected or private. If the main visibility is protected, set 
> >>> visibility may only be private. Any violation of this rule will result in 
> >>> a compile time error.
> >>> 
> >> The first sentence does not forbid `public public(set)`, or `protected 
> >> protected(set)`, etc. (the `set` visibility does not differ from the 
> >> main visibility), but the rest of the paragraph does not allow it. That 
> >> should be clarified.
> > 
> > Er.  That's exactly what it says: "strictly lesser" than the main 
> > visibility.  The lines after are just restating it.  "public public(set)" 
> > is not allowed.
> > 
> > (We may relax that in the future to make it compatible with readonly, but 
> > that's for later.)
> > 
> >> 
> >> (Because forbidding `public public(set)`, etc., makes it slightly more 
> >> cumbersome to explain the rules, I am slightly in favour not to forbid 
> >> it.)
> >> 
> >>> There is one exception, that of a private readonly property. That would 
> >>> technically expand to private private(set) readonly, which is allowed.
> >> 
> >> That sentence should be deleted, as `readonly` is now forbidden.
> > 
> > Good catch, fixed.  Thanks.
> > 
> > --Larry Garfield
> > 
> > -- 
> > PHP Internals - PHP Runtime Development Mailing List
> > To unsubscribe, visit: https://www.php.net/unsub.php 
> > <https://www.php.net/unsub.php>
> > 
> 
> Hi Larry,
> 
> Thank you for clarifying the setter behaviour in more explicit terms, but I 
> have to say I’m quite disappointed in this continued “use the logic of 
> readonly to apply to something that is explicitly not readonly” - this is 
> even more stark now that you’ve explicitly made them mutually exclusive 
> behaviours.
> 
> I’m generally very in favour of maintaining consistency, but this seems like 
> it’s using technical consistency as an excuse to justify unintuitive 
> behaviour that breaks consistency in another, much more obvious way.
> 
> 
> Can you explain why it makes more sense to maintain consistency with 
> “readonly” than it does to maintain consistency with the existing “__set()” 
> behaviour for properties, particularly now that you’ve indicated these 
> features (asymmetric visibility and readonly) are mutually exclusive? 
> 
> While it’s stated multiple times that “readonly” introduced a limited form of 
> asymmetric visibility, and thus this is a continuation, in terms of 
> intuitiveness, the existing __set() rules are very easy to comprehend even 
> with readonly:
> 
> - if the property is declared as public, __set() is never called; if it’s 
> declared as protected, __set is called when the property is accessed from 
> outside that class or it’s hierarchy. Yes, I know that readonly imposes an 
> implicit visibility difference - but that is essentially an implementation 
> detail, from the point of view of the userland developer, it’s not a clear 
> statement of intended behaviour on their part, expressed through the code as 
> written.
> 
> For example, with `public readonly int $foo` it’s quite obvious why __set() 
> isn’t called, using the exiting well-understood logic: it’s a public 
> property. PHP applies a kind of asymmetric visibility to the property behind 
> the scenes, but that isn’t what the developer declared, it’s the 
> implementation. This behaviour matches that of regular, non-readonly fields: 
> when the field is declared public (or has implicit public visibility) __set() 
> is never called.
> 
> If we make that field protected, __set() will be called when the property is 
> written to from outside the class, regard

Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-29 Thread Stephen Reay



> On 30 Nov 2022, at 08:27, Larry Garfield  wrote:
> 
> On Tue, Nov 29, 2022, at 5:46 PM, Claude Pache wrote:
> 
>> In the RFC, section Permitted visibility 
>> (https://wiki.php.net/rfc/asymmetric-visibility#permitted_visibility 
>> ):
>>> The set visibility, if it differs from the main (get) visibility, MUST be 
>>> strictly lesser than the main visibility. That is, the set visibility may 
>>> only be protected or private. If the main visibility is protected, set 
>>> visibility may only be private. Any violation of this rule will result in a 
>>> compile time error.
>>> 
>> The first sentence does not forbid `public public(set)`, or `protected 
>> protected(set)`, etc. (the `set` visibility does not differ from the 
>> main visibility), but the rest of the paragraph does not allow it. That 
>> should be clarified.
> 
> Er.  That's exactly what it says: "strictly lesser" than the main visibility. 
>  The lines after are just restating it.  "public public(set)" is not allowed.
> 
> (We may relax that in the future to make it compatible with readonly, but 
> that's for later.)
> 
>> 
>> (Because forbidding `public public(set)`, etc., makes it slightly more 
>> cumbersome to explain the rules, I am slightly in favour not to forbid 
>> it.)
>> 
>>> There is one exception, that of a private readonly property. That would 
>>> technically expand to private private(set) readonly, which is allowed.
>> 
>> That sentence should be deleted, as `readonly` is now forbidden.
> 
> Good catch, fixed.  Thanks.
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry,

Thank you for clarifying the setter behaviour in more explicit terms, but I 
have to say I’m quite disappointed in this continued “use the logic of readonly 
to apply to something that is explicitly not readonly” - this is even more 
stark now that you’ve explicitly made them mutually exclusive behaviours.

I’m generally very in favour of maintaining consistency, but this seems like 
it’s using technical consistency as an excuse to justify unintuitive behaviour 
that breaks consistency in another, much more obvious way.


Can you explain why it makes more sense to maintain consistency with “readonly” 
than it does to maintain consistency with the existing “__set()” behaviour for 
properties, particularly now that you’ve indicated these features (asymmetric 
visibility and readonly) are mutually exclusive? 

While it’s stated multiple times that “readonly” introduced a limited form of 
asymmetric visibility, and thus this is a continuation, in terms of 
intuitiveness, the existing __set() rules are very easy to comprehend even with 
readonly:

- if the property is declared as public, __set() is never called; if it’s 
declared as protected, __set is called when the property is accessed from 
outside that class or it’s hierarchy. Yes, I know that readonly imposes an 
implicit visibility difference - but that is essentially an implementation 
detail, from the point of view of the userland developer, it’s not a clear 
statement of intended behaviour on their part, expressed through the code as 
written.

For example, with `public readonly int $foo` it’s quite obvious why __set() 
isn’t called, using the exiting well-understood logic: it’s a public property. 
PHP applies a kind of asymmetric visibility to the property behind the scenes, 
but that isn’t what the developer declared, it’s the implementation. This 
behaviour matches that of regular, non-readonly fields: when the field is 
declared public (or has implicit public visibility) __set() is never called.

If we make that field protected, __set() will be called when the property is 
written to from outside the class, regardless of whether it’s readonly or not.


What you’re proposing changes that, in a way that is completely unintuitive: 
when attempting to *write* data to a property that is marked as protected(set), 
the __set() method will not be called.


So please, can you explain to me why consistency with an implementation detail 
of readonly properties is more important than consistency with declared 
developer intention for regular properties via the magic setter method?



Cheers

Stephen 

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



Re: [PHP-DEV] [RFC] Asymmetric Visibility, with readonly

2022-11-14 Thread Stephen Reay

> On 14 Nov 2022, at 03:08, Larry Garfield  wrote:
> 
> Hi folks.  Ilija is nearly done with the implementation for asymmetric 
> visibility and flushing out edge cases, but we've run into one design 
> question we'd like feedback on.
> 
> There's two design decisions we've made at this point, both of which we think 
> are logical and reasonable:
> 
> 1. If specified, the set visibility must be tighter than the get visibility.  
> So `protected protected(set)` and `protected public(set)` are not permitted, 
> for instance.
> 
> 2. `readonly` is a "write once" flag that may be combined with asymmetric 
> visibility.  If no set visibility is specified, `readoly` implies 
> `private(set)`, but a different set visibility may also be provided.
> 
> These are both reasonable rules.  However, it creates a conflict.  
> Specifically, in the following cases:
> 
> public public(set) readonly string $foo
> 
> protected protected(set) readonly string $foo
> 
> These would be the only way to have a non-private-set readonly property.  
> While the first is in practice quite unlikely, the second has valid use 
> cases.  (In particular, a base class that provides properties expected to be 
> set by a child constructor, and then used by a method in the parent class.)  
> However, it would not be allowed under the rules above.  Working around it 
> would require specifying `public protected(set) readonly...`, which means 
> exposing a property that likely should not be exposed.
> 
> That creates an odd situation where readonly and asymmetric visibility may 
> only be combined "sometimes."  That is not deesireable.  The only way to 
> combine them in their current form is to allow `protected protected(set)` 
> only if readonly is in use, which is excessively complicated both to 
> implement and to explain/document/use.
> 
> We see two possible ways to resolve this conflict:
> 
> 1. Relax the set-is-tighter restriction.  That would allow `protected 
> protected(set)` etc. on any property.  It wouldn't be particularly useful 
> unless readonly is being used, but it would be syntactically legal and behave 
> as you'd expect.  We could still disallow "set is more permissive" 
> combinations (eg, `private public(set)`), as those have no apparent use case.
> 
> 2. Disallow readonly and asymmetric visibility being combined, because 
> readonly already has a hard-coded implied asymmetric visibility.  This option 
> removes some potential use cases (they would most likely drop the readonly), 
> but has the upside that it's easier to re-allow at some point in the future.
> 
> 3. Some other brilliant idea we've not thought of.
> 
> 
> Both are viable approaches with pros and cons.  We're split on which way to 
> go with this, so we throw it out to the group for feedback.  Which approach 
> would you favor, or do you have some other brilliant idea to square this 
> circle?
> 
> 
> -- 
>  Larry Garfield
>  la...@garfieldtech.com
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry,

I asked for some clarification / further thought about the magic 
getters/setters interaction of this RFC back when you announced it, and never 
heard much besides saying that you’re working on a consolidated response to the 
feedback, but I’ve not seen anything regarding what I’d asked about, and the 
RFC still seems to have the (IMO) confusing and inconsistent magic 
getters/setters interaction described.


As I understand it, you’re suggesting that a property declared as `public 
protected(set)` would never trigger __set().


While I understand that this is meant to “keep consistency with readonly”, I 
would imagine people would want to use native asymmetric visibility on objects 
that currently have protected (or private) properties that are accessed via 
magic getters and setters. I think it would be a natural assumption that 
asymmetric visibility would allow the user to remove the often boilerplate 
__get method, while maintaining the ability to have checks/other logic beyond 
simple type checks when a property is being set. Having the association of a 
*set* action tied to the *get* visibility is very unintuitive to me.

The impact of this “same” limitation on readonly properties is IMO greatly 
reduced, because of the nature of something being readonly. The ability to run 
some logic when writing to a property that’s otherwise readable is surely a 
concept that’s very common and easy to understand, it’s literally the next 
example after (1) “readonly” and (2)  “asymmetric visibility” in Nikita’s 
original property accessors RFC.

The stated reason (on both this and the readonly RFC) for not allowing __set() 
is "to avoid surprising behaviour”. To me, having a field marked as `public 
protected(set)` then not call __set() when setting a property from outside the 
class **is** the surprising behaviour.



Cheers

Stephen







Re: [PHP-DEV] Newcomer, PHP pre-processing, Magic Constants __FILE__ and __LINE__ override with #line like in C

2022-10-23 Thread Stephen Reay


> On 23 Oct 2022, at 20:43, Ludovic Pouzenc  wrote:
> 
> Hi,
> 
> I'm a newcomer here. I came from https://wiki.php.net/rfc/howto.
> 
> *TL;DR:* I want to know if a proposal of a #line parsing to alter __FILE__ 
> and __LINE__ in PHP like it exists in C could be a good idea.
> 
> I've searched about __LINE__ and __FILE__ in mailing archives and wiki, I 
> don't really find things matching. I hope it's not because "__" are stripped 
> before search. "Magic constants" didn't help neither. Let me know if I am 
> rethinking and old thing already imagined here in the past.
> 
> *Background / use case:* I think at first about webservices, maybe the useful 
> also with browser/human-facing use cases.
> 
> With PHP, it's hard to get high responsiveness under load if user code start 
> by loading a composer's autoload.php, then (lazy) loads a whole framework 
> with 10+ dependencies, then execute 1 SQL request, 1 json_encode() then 
> output and exit. Even with "Slim" framework that should be minimal, using 
> only the route feature, I see "strace" counting 200+ file-related syscalls 
> per request with recent linux/debian/apache/php-fpm.
> 
> It's not so hard to get it better with other langages : when they are 
> compiled, or when framework loading happens at server start and to at each 
> request.
> 
> Web projects have more and more a "compilation" phase for minimising JS, for 
> proprocessing scss to css, it is possible to hook it some PHP processing too.
> 
> In my university, I started using a purpose-written PHP Preprocessor to 
> minimize runtime dependency loading. It only understands #include like in C. 
> From a src/mywebservice/v1/some-endpoint.php it will generate and 
> build/mywebservice/v1/some-endpoint.php with all #include 
> "some/path/somedep.php" replaced by the file's contents.
> 
> So the generated some-endpoint.php have no run-time dependency at all: no 
> autoload, no include(), no require(). I think it evens maximize the gains 
> with APC caching.
> 
> The preprocessor also generate things like #line 2 "some/path/somedep.php" 
> where an #include was encountered, then a thing like #line 47 
> "src/mywebservice/v1/some-endpoint.php" right after the end of the inclusion. 
> In C, a great concrete example of #line importance is working with a 
> flex/bison parser generator.
> 
> If PHP parser interpret #line as in C, __FILE__ and __LINE__ Magic Constants 
> will be changed to source file and line, instead of generated file and line. 
> It could greatly improve development write-then-rerun cycle. (missing ";" at 
> line NN , other PHP Errors, Exception details/traces)
> 
> I hope it could unlock many use cases where "big" PHP frameworks get really 
> hard time to try to compete with other languages equivalents.
> 
> Do you think it's an idea that is suitable to discuss, improve and submit as 
> an RFC ?
> 
> Regards,
> 
> -- 
> 
> Ludovic Pouzenc
> www.pouzenc.fr
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Ludovic,

I can’t comment much on the actual change in the parser you’re asking about, 
but it sounds to me like preloading 
(https://www.php.net/manual/en/opcache.preloading.php 
, introduced via 
https://wiki.php.net/rfc/preload ) might be a 
workable solution that’s already available?


Cheers

Stephen 

Re: [PHP-DEV] Union type casts

2022-10-05 Thread Stephen Reay



> On 5 Oct 2022, at 12:41, Dusk  wrote:
> 
> On Oct 4, 2022, at 21:46, Eugene Sidelnyk  wrote:
>>   $foo = (int|float)$bar;
> 
> As written, I wouldn't know what to expect this to do with a string value -- 
> would it cast it to int or float?
> 
> Based on the behavior of your second example, the answer appears to be 
> "float", so this syntax seems to be equivalent to:
> 
>$foo = \is_int($bar) ? $bar : (float) $bar;
> 
> Or, even more concisely:
> 
>$foo = 0+$bar;
> 
> I'd be even less sure what to expect when casting to other union types. What 
> would the expected result of casting a string to (bool|array|object) be, for 
> example? I'm not sure there are many meaningful operations which could be 
> constructed here.
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 


Hi,

I think the intention is that it would follow precisely the same casting rules 
as function parameters do.

So e.g:

```
function foo(int|float $var) {
return $var; 
}

$f1 = foo(‘1’);
$c1 = (int|float) ‘1’;


$f2 = foo(‘1.1’);
$c2 = (int|float) ‘1.1’;

```

In both scenarios the $f1/$c1 and $f2/$c2 would result in the same type.

Your first example isn’t quite the same though; Passing ‘1’ to a parameter 
typed as `int|float` will cast it to an integer, your example casts such a 
value to a float.

The `0+$value` thing is interesting, but also definitely seems less intuitive 
to my eye.


Given your last comment I think its worth reiterating Eugene’s point is simply 
about exposing the **existing** cast behaviour that happens with typed 
parameters, to be usable on variables.


I can see some benefit in the proposal, but I think I’d be more interested in 
the ability to define local variables as being a given type (or union), and 
then have the engine cast (or error) when assigning to them - essentially how 
typed object properties work, but for regular variables.

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



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

2022-08-08 Thread Stephen Reay


> On 8 Aug 2022, at 20:21, Rowan Tommins  wrote:
> 
> On 08/08/2022 10:09, Stephen Reay wrote:
>> The RFC states that it’s to keep consistency with `readonly`, because __set 
>> on a readonly property that’s initialised throws an error - but isn’t that 
>> because of the nature of it being readonly, rather than because of the 
>> visibility rules? The error given is "Cannot modify readonly property” 
>> thrown from within the __set() method, not "Cannot access protected 
>> property” thrown from the outside calling context, when the __set() method 
>> is not implemented.
> 
> 
> If a property is "public readonly", the __set method is never called if you 
> try to reassign it: https://3v4l.org/8PioE The proposal is that the same 
> applies if it is "public private(set)": the assignment immediately fails, 
> rather than falling back to the __set method.
> 
> The logic, I think, is that a completely private property is "invisible", so 
> __set acts like it doesn't exist at all and runs *instead of* the assignment; 
> but a "public readonly" or "public private(set)" property is "visible", so 
> the assignment is attempted and fails.
> 
> However, I am concerned that the rules around where __set and __get are 
> called are becoming increasingly complex with a lot of different concepts 
> interacting - "declared", "defined", "typed", "initialized", "visible", 
> "modifiable", etc.
> 
> As I mentioned in a previous discussion, I think we need to work towards 
> simplifying this - e.g. merge "typed" and "untyped" properties by making 
> "public $foo" equivalent to "public mixed $foo", which would remove the 
> distinction between "defined" and "initialized".
> 
> Regards,
> 
> -- 
> Rowan Tommins
> [IMSoP]
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Rowan,

Thanks for trying to explain the logic here.

@Larry is Rowan’s assessment accurate?


Cheers

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



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

2022-08-08 Thread Stephen Reay

> On 6 Aug 2022, at 00:08, Larry Garfield  wrote:
> 
> Ilija Tovilo and I are happy to present the first new RFC for PHP 8.3: 
> Asymmetric Visibility.
> 
> https://wiki.php.net/rfc/asymmetric-visibility
> 
> Details are in the RFC, but it's largely a copy of Swift's support for the 
> same.
> 
> -- 
>  Larry Garfield
>  la...@garfieldtech.com
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry,


I like most of this, but I have one disagreement.

Can you expand a bit more on the reasoning for restricting the ability to 
combine __set() here?

The RFC states that it’s to keep consistency with `readonly`, because __set on 
a readonly property that’s initialised throws an error - but isn’t that because 
of the nature of it being readonly, rather than because of the visibility 
rules? The error given is "Cannot modify readonly property” thrown from within 
the __set() method, not "Cannot access protected property” thrown from the 
outside calling context, when the __set() method is not implemented.

If I set a property to readonly I would expect it to not be settable after 
initialisation, regardless of visibility, whether it’s via direct access or via 
__set, etc. (i.e. what readonly does now)

But if I set a property to `public private(set)` for example, I would 
**expect** that the __set method on that class (or in the hierarchy if using 
protected(set)) would be called when setting it from an inaccessible context, 
just as it would be called when setting a regular protected property.


It seems very unintuitive to me, that the first example here would work, but 
that the second would not work:

class Foo {

protected readonly int $bar;

public function __set(string $name, mixed $value): void {
$this->{$name} = $value;
}
}

$a = new Foo;
$a->bar = 1;


class Bar {

public protected(set) int $baz;

public function __set(string $name, mixed $value): void {
$this->{$name} = $value;
}
}

$b = new Bar;
$b->baz = 1;



Cheers

Stephen 




Re: [PHP-DEV] [RFC] [VOTE] Constants in traits

2022-07-10 Thread Stephen Reay


> On 11 Jul 2022, at 09:10, Mike Schinkel  wrote:
> 
>> On Jul 5, 2022, at 5:38 PM, shinji igarashi  wrote:
>> 
>> Hello internals,
>> 
>> I've started the vote for the Constants in Traits RFC:
>> https://wiki.php.net/rfc/constants_in_traits
>> 
>> The vote will end on 19. July 2022.
>> 
>> Thanks!
>> 
>> --
>> Shinji Igarashi
> 
> The reaction to this RFC has been truly eye-opening to me.  It never occurred 
> to me that Traits would be viewed so negatively by some on Internals. 
> 
> Personally I have found Traits to be one of the VERY BEST features of PHP for 
> a userland developer given their ability to reduce complexity and allow for a 
> cleaner code architecture within the applications I have worked on. OTOH I 
> have always found Traits to be an incomplete language feature whose design 
> gaps I have handled via rigidly standardizing how I use them and by 
> incorporating a lot of unfortunate boilerplate.
> 
> Though I was surprised at first that some people so strongly dislike Traits I 
> then thought more about the incompleteness of Traits and wonder if that is 
> not the reason they feel Traits are problematic?  I further wonder how their 
> use-cases differ from the ones I have been involved with?
> 
> Given the three people who spoke strongly against them on this thread work 
> heavily with PHP tools that make heavy use of reflection, code analysis, 
> and/or work on PHP core I wonder if their dislike for Traits have a lot to do 
> Trait-related problems they have when implementing PHP core itself, 
> frameworks, ORMs, testing tools, etc. rather than userland development? 
> 
> I am in no-way discounting the importance of core or tool development but I 
> wonder if they recognized issues in the implementation-of and design 
> decisions related-to Traits that most userland developers rarely ever see 
> because of their core and/or tool development work?
> 
> Further, I wonder if their dislike of Traits is more of an X-Y problem?  IOW, 
> that because they have seen issues with Traits they view the solution to tamp 
> down on Traits rather than the solution being to fill in the design gaps and 
> implementation issues with Traits?
> 
> --
> 
> So, can those who spoke against Traits please explain more details about:
> 
> 1. How do Traits have "built-in accidental complexity?"  
> 
> 2. How does `use TRAIT1, TRAIT2, TRAIT3` semantics result in "mind-boggling 
> over-complicated?"
> 
> 3. What extra compatibility checks are required for Traits?
> 
> 4. What are the potential error scenarios that are "unnecessary," why are 
> they unnecessary, and what alternative could you envision? 
> 
> 5. What about the implementation of Traits do you strongly dislike, what type 
> of implementation would be better, and could PHP change the implementation 
> and still retain backward compatibility?
> 
> -
> 
> I pose these questions in hopes to discern among Internals if Traits are 
> actually the problem or if instead Traits could be improved to solve the 
> concerns states in this tread, which might require some longer-term 
> deprecation of some of the problematic aspects of Traits.
> 
> -Mike
> P.S. I also want to talk about the issues I have with the RFC itself and what 
> other things I see that I think are design gaps in Traits, but I don't want 
> to create an email to the list with more than one focus.  I'll follow up 
> later with those other issues.
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 


I hadn’t planned to get involved in this discussion - my name is only on the 
RFC because Shinji very graciously left it there when he took the skeleton of a 
proposal I’d written a while ago, and completed it in ways I never could have. 
So first off: thank you again Shinji for putting the effort in to bring this 
RFC to a vote. I very much appreciate all the effort you put into it.

For context, my work with PHP is split, between application development, and 
library development - so for some of it I’m trying to make sure the code is 
re-usable without having to jump through too many hoops (library dev), and for 
some of it I’m trying to re-use provided code, without having to jump through 
too many hoops (app dev).

I think one of the best descriptions I’ve seen about how traits **could** be 
used, is from an article (https://www.garfieldtech.com/blog/beyond-abstract 
) Larry Garfield wrote just 
a couple of years after traits had been introduced. Larry presents the view 
that with the advent of traits in php, abstract classes could (should) be 
considered vestigial.

Having worked on library-style reusable code using abstract classes to provide 
extendable behaviour since around 2009, I really do like this approach, and I’d 
like to use traits a lot more like this.  But looking at numerous cases of 
existing abstract classes in my own work, even with all the other 

Re: [PHP-DEV] Re: [RFC] [Under Discussion] PDO driver specific sub-classes

2022-06-24 Thread Stephen Reay


> On 24 Jun 2022, at 22:45, Dan Ackroyd  wrote:
> 
> Larry Garfield wrote:
> 
>> "Create all DB sub-classes?" - I'd say they all should have subclasses, even
>> if empty.  It's more consistent* that way, and you can then also rely on
>> instanceof giving you useful information rather than "well, it's not one of
>> the special ones, so beyond that, NFI."
> 
> You can get the database type through 
> $db->getAttribute(PDO::ATTR_DRIVER_NAME);
> 
>> On Tue, 21 Jun 2022 at 15:39, Ben Ramsey  wrote:
>> 
>> Is there a reason we shouldn't go ahead and add subclasses for all
> database connection types,
> 
> YAGNI, and I'm lazy. But mostly, I don't think adding them now
> actually helps achieve anything.
> 
> Being able to check if the class has specialised methods is useful:
> 
> if ($pdo instanceof PDOSqlite) {
>$pdo->loadExtension(...);
>// do fun stuff with extension here.
> }
> 
> 
> But for the classes that have no specialised method:
> 
> if ($pdo instanceof PDOMysql) {
>   // What would be of utility here?
> }
> 
> cheers
> Dan
> Ack
> 
> * How to value being consistent is an aesthetic choice that many other
> programmers disagree with me on; "The fundamental guiding force to
> bear in mind is whether something is useful or not. Consistency might
> satisfy a personal desire for order and simplicity, but most of the
> time just having things be consistent is a lower priority than making
> choices that are useful." or in this case, less code to write and
> maintain.
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Dan,

Re: the usefulness of separate classes per driver:

One thing of note is for query builders that abstract concepts for the end 
user. It’s often necessary to know what the underlying DB type is when 
generating a query. Perfect example is MySQL’s non standard field quoting 
character for example.

It’s possible already using `PDO::getAttribute` call but if you’re going to 
know from the class type for SQLite it’d be useful to know for others too. 

It’s not the end of the world to not have that convenience but there’s 
definitely use for it.

Cheers

Stephen 

Re: [PHP-DEV] [RFC] [Under Discussion] PDO driver specific sub-classes

2022-06-20 Thread Stephen Reay





Sent from my iPhone
> On 21 Jun 2022, at 06:08, Dan Ackroyd  wrote:
> 
> Hi,
> 
> Following previous discussions, here is an RFC to have DB specific
> classes for PDO.
> 
> https://wiki.php.net/rfc/pdo_driver_specific_subclasses
> 
> cheers
> Dan
> Ack
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Dan, 

There’s a typo in the heading about the static factory method (pdf vs pdo)

Cheers

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



Re: [PHP-DEV] Adding `final class Deque` to PHP

2022-02-01 Thread Stephen Reay


> On 1 Feb 2022, at 21:46, tyson andre  wrote:
> 
> Hi internals,
> 
>> I've created a new RFC https://wiki.php.net/rfc/deque to add a `final class 
>> Deque`
>> 
>> This is based on the `Teds\Deque` implementation I've worked on
>> for the https://github.com/TysonAndre/pecl-teds PECL.
>> 
>> While `SplDoublyLinkedList` and its subclass `SplQueue`/`SplStack` exist in 
>> the SPL, they have several drawbacks
>> that are addressed by this RFC to add a `Deque` class (to use instead of 
>> those):
>> 
>> 1. `SplDoublyLinkedList` is internally represented by a doubly linked list,
>>making it use roughly twice as much memory as the proposed `Deque`
>> 2. `push`/`pop`/`unshift`/`shift` from `SplDoublyLinkedList` are slower due 
>> to
>>needing to allocate or free the linked list nodes.
>> 3. Reading values in the middle of the `SplDoublyLinkedList` is proportional 
>> to the length of the list,
>>due to needing to traverse the linked list nodes.
>> 4. `foreach` Iteration behavior cannot be understood without knowing what 
>> constructed the
>>`SplDoublyLinkedList` instance or set the flags.
>> 
>> It would be useful to have an efficient `Deque` container in the standard 
>> library
>> to provide an alternative without those drawbacks,
>> as well as for the following reasons:
>> 
>> 1. To save memory in applications or libraries that may need to store many 
>> lists of values or run for long periods of time.
>>Notably, PHP's `array` type will never release allocated capacity.
>>See 
>> https://www.npopov.com/2014/12/22/PHPs-new-hashtable-implementation.html
>> 2. To provide a better alternative to `SplDoublyLinkedList`, `SplStack`, and 
>> `SplQueue`
>>for use cases that require stacks or queues.
>> 3. As a more efficient option than `array` and `SplDoublyLinkedList`
>>as a queue or `Deque`, especially for `unshift`.
>> 
>> A `Deque` is more efficient than an `array` when used as a queue, more 
>> readable, and easier to use correctly.
>> While it is possible to efficiently remove elements from the start of an 
>> `array` (in terms of insertion order) (though this makes 
>> reset()/array_key_first() inefficient),
>> it is very inefficient to prepend elements to the start of a large `array` 
>> due to needing to either copy the array
>> or move all elements in the internal array representation,
>> and an `array` would use much more memory than a `Deque` when used that way 
>> (and be slower).
>> 
>> There are also several pitfalls to using an array as a queue for larger 
>> queue sizes,
>> some of which are not obvious and discovered while writing the benchmarks.
>> (Having a better (double-ended) queue datastructure (`Deque`) than the 
>> `SplDoublyLinkedList`
>> would save users from needing to write code with these pitfalls):
>> 
>> 1. `array_key_first()` and reset()`takes time proportional to the number of 
>> elements `unset` from the start of an array,
>>causing it to unexpectedly be extremely slow (quadratic time) after 
>> unsetting many elements at the start of the queue.
>>(when the array infrequently runs out of capacity, buckets are moved to 
>> the front)
>> 2. `reset()` or `end()` will convert a variable to a reference,
>>and php is less efficient at reading or writing to reference.
>>Opcache is also less efficient at optimizing uses of variables using 
>> references.
>> 3. More obviously, `array_unshift` and `array_shift` will take time 
>> proportional to the number of elements in the array
>>(to reindex and move existing/remaining elements).
> 
> I plan to start voting on https://wiki.php.net/rfc/deque on Friday, February 
> 4th.
> 
> Several changes have been made to https://wiki.php.net/rfc/deque#changelog
> after the feedback in https://externals.io/message/116100
> 
> - The class is now named `Collections\Deque`
> - The api documentation in https://wiki.php.net/rfc/deque#proposal was 
> expanded for methods.
> - Benchmarks were updated.
> - Like other standard datastructures, iteration over the deque is now over 
> the original object (instead of creating a copy), 
>  and mutating the deque will be reflected in `$iterator->current()` (and 
> moving the end with push()/pop() will affect where iteration ends).
> - Iteration will account for calls to shift/unshift moving the start of the 
> deque.
>  the offsets will be corrected and values won't be skipped or iterated over 
> multiple times.
>  (no matter how many iterators were created by `Deque->getIterator()`)
>  See https://wiki.php.net/rfc/deque#iteration_behavior
> - The get()/set() methods were removed, after feedback in 
> https://externals.io/message/116100#116214
> 
> A WebAssembly demo is available at 
> https://tysonandre.github.io/php-rfc-demo/deque/
> 
> Thanks,
> Tyson
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Tyson,

As a userland dev & library author it’s nice to see some progression on basic 

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

2021-11-19 Thread Stephen Reay



> On 17 Nov 2021, at 00:22, André Hänsel  wrote:
> 
> It is common (with DI systems for example) and to my knowledge not
> particularly discouraged to have function parameters that are supposed to
> accept something like Foo::class, which currently is a string.
> 
> It seems logical to ask for a special type that can hold class names, so
> that parameters that can accept a class name can be type hinted more
> specifically than just (any) "string".
> 
> Regardless of whether or not such a proposal would be accepted or declined
> (for complexity reasons maybe) I couldn't even find any such proposal. Has
> this really never been asked?
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 
Hi André,

I’ve wondered about this kind of functionality myself, but IMO to be 
particularly useful it’d need to support the ability to accept a classname that 
is a subtype of a parent class or interface. I can’t think of too many places 
where I’d want to know something is a classname reference, and not also want to 
know that it's a subclass or implementation of something specific.


This typeof functionality could support some very expressive solutions, when 
combined with union types, and anonymous classes. 




Cheers

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



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

2021-09-08 Thread Stephen Reay



> On 8 Sep 2021, at 13:33, Claude Pache  wrote:
> 
> 
> 
>> Le 7 sept. 2021 à 11:49, Craig Francis  a écrit :
>> 
>> 
>> Obviously I'd still like libraries to be able to protect everyone from
>> introducing Injection Vulnerabilities (as the majority of programmers don't
>> use static analysis), but that's for another day.
>> 
> 
> 
> Hi, 
> 
> We all want to protect from injection vulnerability, but I think there are 
> better way than is_literal.
> 
> One way is to use templates, an area where PHP is ironically lagging behind. 
> I suggest looking at JS tagged templates:
> 
> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
>  
> 
> 
> For example:
> 
> 
> $qb->select('u')
>  ->from('User', 'u')
>  ->where('u.id = ' . $_GET['id']); // INSECURE
> could be written as
> 
> 
>  $qb->exec `
> SELECT u
> FROM User u
> WHERE u.id = %{ $_GET['id'] }
> `
> ?>
> 
> where the part between %{ ... } is transformed into an SQL literal string 
> (with delimiters "...", not just “escaping”) when it is a string; into the 
> SQL expression NULL when it is null; into an SQL subexpression if it is an 
> object (provided by the library) that represents a well-formed SQL 
> subexpression, etc.
> 
> —Claude
> 

Resending from on-list address because I’m an idiot. Apologies for the dupe 
Claude/Craig.


Hi Claude,

I had my share of issues with Craig’s PR, but I think the original goal of it 
was a good and useful concept - provide developers (mostly lib authors, but its 
not like it couldn’t be used by end developers too) a way to _know_ that a 
string came from something hard coded in a php file. 


A ‘tagged template’ like that doesn’t help solve the problem in any way that 
parameterised queries can’t already do, and if you want to make it more 
’templated’ like that, you could implement the same thing already by passing a 
printf-compatible template and the arguments to a function/method.

None of that helps solve what the `is_literal` function (or potential type 
hint) would help with: when the part of the query that needs to be substituted, 
is something that cannot be parameterised at the SQL level (i.e. a column name) 
you _really_ don’t want that to accept user input of any kind.



Cheers

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



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

2021-06-30 Thread Stephen Reay



> On 29 Jun 2021, at 02:28, Jan Ehrhardt  wrote:
> 
> Nikita Popov in php.internals (Mon, 22 Mar 2021 10:24:51 +0100):
>> Hi internals,
>> 
>> It's time for another deprecation RFC:
>> https://wiki.php.net/rfc/deprecations_php_8_1
> 
> FWIW, a quick search returned these results.
> 
> ADOdb still uses strftime()
> https://adodb.org/dokuwiki/doku.php
> 
> 2 plugins of Matomo (formerly Piwik) still uses strftime in
> Login/PasswordResetter.php and RssWidget/RssRenderer.php
> 
> The simplepie library still uses strftime:
> https://github.com/simplepie/simplepie/blob/717d9ea4bf1a8533d5a26128b7acc1598388ce66/library/SimplePie/Item.php#L882
> 
> Limesurvey still uses strftime, in the ADOdb functions and in the kcfinder
> functions:
> https://github.com/LimeSurvey/LimeSurvey/blob/6437c998731e1e79da24c394ef205444cfa75cdf/third_party/kcfinder/core/class/browser.php#L784
> 
> Drupal 7 uses strftime in the date module and in the views module:
> https://www.drupal.org/project/date
> See date/date_api/date_api_sql.inc
> https://www.drupal.org/project/views
> See views/includes/handlers.inc
> 
> Drupal 8 uses strftime. Example:
> https://api.drupal.org/api/drupal/core!modules!views!src!Plugin!views!query!Sql.php/function/Sql%3A%3AgetDateFormat/8.2.x
> -- 
> Jan
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

(Bah! Sending again to the list, because me stupid)

I’m sure some of those are legitimate - but to my eye, the Drupal 8 example at 
least, is _not_ using `strftime` in *PHP*. 

I believe it’s making use of the `strftime` function in SQLite.
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



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

2021-06-24 Thread Stephen Reay



> On 24 Jun 2021, at 17:16, Craig Francis  wrote:
> 
> On Thu, 24 Jun 2021 at 10:55, Stephen Reay  wrote:
> 
>> but still I have to keep asking: Why integers at all?
>> 
> 
> 
> While I'm not a fan of this approach, there is a lot of existing code and
> tutorials that use:
> 
> $sql = 'WHERE id IN (' . implode(',', array_map('intval', $ids)) . ')';
> 
> $sql = sprintf('SELECT * FROM table WHERE id = %d;', intval($id));
> 
> Craig

Yeah you’ve said this about a dozen times now. Parameterisation exists. Query 
builders that do this already using parameterisation, exist.

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



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

2021-06-24 Thread Stephen Reay



> On 24 Jun 2021, at 17:07, Kamil Tekiela  wrote:
> 
> Hi Stephen,
> 
> I believe the idea was for dynamically generate table names, or numbered 
> tables/columns. E.g. 
> 
> function getTable(string $table){
> // is_literal check here
> }
> 
> $number = (int) $_GET['tableno'];
> if($number < 0 || $number > 10) {
> throw new Exception("Invalid number");
> }
> 
> $tablename = 'table_'.$number;
> getTable($tablename);
> 
> The number is concatenated to the table name. 
> 
> —Kamil

Hi Kamil,

Thanks for at least trying to answer this question.

I’m sure someone somewhere does that and thinks its a good idea. I respectfully 
(to you; probably less respectfully to someone if they tell me they do this) 
disagree. I don’t think PHP should necessarily shy away from features because 
they’re potentially dangerous, but I also don’t think it should be adding new 
features/functions that are more dangerous, just to make some weird (IMO 
bad-practice) edge cases easier.

I’d suggest if they insist on that bizarre naming pattern, _and_ want to use a 
literal string check, they could define an array of string numbers that 
represent their table names.

$tbls = [‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ...];

getTable(’table_’ . $tbls[$number]);


Cheers

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



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

2021-06-24 Thread Stephen Reay


> On 24 Jun 2021, at 14:29, Scott Arciszewski  wrote:
> 
> On Thu, Jun 24, 2021 at 2:10 AM Stephen Reay  wrote:
>> 
>> 
>> 
>> On 24 Jun 2021, at 08:30, Scott Arciszewski  wrote:
>> 
>> On Wed, Jun 23, 2021, 9:23 PM Bruce Weirdan  wrote:
>> 
>> On Thu, Jun 24, 2021 at 3:41 AM Scott Arciszewski 
>> wrote:
>> 
>> The failure condition of this query is
>> "return all rows from the table already being queried", not "return
>> arbitrary data the attacker selects from any table that the
>> application can read".
>> 
>> 
>> Imagine that was a DELETE rather than SELECT and the failure condition
>> becomes 'the table is emptied'.
>> It may have less disastrous consequences (depending on how good your
>> backup / restore procedures are) compared to arbitrary reads you
>> demonstrated, but it is still, quite clearly, a glaring security hole
>> caused by user input in SQL query - AKA SQL injection in layman's
>> terms.
>> 
>> it differs from Injection vulnerabilities in one
>> fundamental way: The attacker cannot change the structure of the SQL
>> query being executed.
>> 
>> 
>> I would say replacing a column name with value is changing the
>> structure of SQL query, and, basically, in exactly the way you
>> describe SQL injection: confusing the code (column name) with data.
>> 
>> I wholeheartedly welcome this RFC as it was originally proposed:
>> is_literal() doing exactly what it says on the tin, without any
>> security claims. But it has gone far from there real quick and now
>> people can't even name the thing.
>> 
>> 
>> --
>> Best regards,
>> Bruce Weirdan mailto:
>> weir...@gmail.com
>> 
>> 
>> 
>> 
>> We can agree that it is a bug. We don't agree on the definition of SQL
>> injection.
>> 
>> Changing a column name to a number (which prepared statements shouldn't
>> allow in the first place) is a bug. This changes the effect of the command,
>> but the *structure* of the query remains unchanged.
>> 
>> 
>> Hi Scott,
>> 
>> I wrote that example where an integer could be dangerous.
>> 
>> So firstly - just to clarify, because some replies seemed to be confused on 
>> the topic, as was literally mentioned in the original comment, it is 
>> definitely not correct behaviour - it’s a developer mistake that might work 
>> some of the time, and thus go unnoticed in testing. If you can show me a 
>> developer who’s never inadvertently passed the wrong parameter in some 
>> condition, I’ll show you an imaginary developer.
>> 
>> 
>> Additionally - pointing out that this is a "developer error” doesn’t help 
>> your case. Using non-parameterised queries should already be a “developer 
>> error” for anyone who can walk and breathe at the same time - and yet that 
>> usage is being actively encouraged if this function supports integers. I’ve 
>> still seen zero responses about legitimate reasons this needs to support 
>> integers - giving people a shitty way to build an IN() clause is not 
>> legitimate. Parameterisation exists, and works.
>> 
>> 
>> I don’t even understand why you mentioned prepared statements (I guess you 
>> meant using parameterised queries?) - the column name inherently can’t be 
>> parameterised - hence having to use a string substitution in the query.
>> 
>> 
>> That part was weird and confusing, but not as odd as your claim that 
>> altering the query, so that it causes the where clause to become moot, is 
>> not an SQL Injection? REALLY? That’s your claim?
>> 
>> 
>> I did a little research, and it turns out Wikipedia 
>> (https://en.wikipedia.org/wiki/SQL_injection#Technical_implementations), 
>> Cloudflare 
>> (https://www.cloudflare.com/en-au/learning/security/threats/sql-injection/), 
>> and OWASP (https://owasp.org/www-community/attacks/SQL_Injection#example-2) 
>> all have examples with a `1=1` type query manipulation. Do you want to write 
>> and tell them that they’re all wrong, or should I ask them to call you?
>> 
>> Also, while researching the specifics of what is considered an “SQL 
>> Injection” I came across an article, that talks specifically about the 
>> dangers of allowing user input (i.e. the thing `is_trusted` is meant to 
>> prevent) as a column or table identifier. It’s from this little 
>> organisation, you may have heard of them: “Paragon Initiative” 
>> (https://paragonie.com/blog/2015/05/preventing-sql

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

2021-06-24 Thread Stephen Reay



> On 24 Jun 2021, at 14:14, Scott Arciszewski  wrote:
> 
> On Thu, Jun 24, 2021 at 2:10 AM Stephen Reay  wrote:
>> Hi Scott,
>> 
>> I wrote that example where an integer could be dangerous.
> 
> I don't disagree that it's an example where an integer could be dangerous.
> 
> Danger is too broad to have a meaningful discussion about. You can, of
> course, always do dangerous things if you're determined or creative
> enough.
> 
>> So firstly - just to clarify, because some replies seemed to be confused on 
>> the topic, as was literally mentioned in the original comment, it is 
>> definitely not correct behaviour - it’s a developer mistake that might work 
>> some of the time, and thus go unnoticed in testing. If you can show me a 
>> developer who’s never inadvertently passed the wrong parameter in some 
>> condition, I’ll show you an imaginary developer.
> 
> Agreed.
> 
>> Additionally - pointing out that this is a "developer error” doesn’t help 
>> your case. Using non-parameterised queries should already be a “developer 
>> error” for anyone who can walk and breathe at the same time - and yet that 
>> usage is being actively encouraged if this function supports integers. I’ve 
>> still seen zero responses about legitimate reasons this needs to support 
>> integers - giving people a shitty way to build an IN() clause is not 
>> legitimate. Parameterisation exists, and works.
> 
> I don't have a strong opinion on this.
> 
>> I don’t even understand why you mentioned prepared statements (I guess you 
>> meant using parameterised queries?) - the column name inherently can’t be 
>> parameterised - hence having to use a string substitution in the query.
> 
> They're effectively synonyms.

I mean, they’re not - you can prepare a statement with zero parameters in it. 
But my point was why you even mentioned parameterised queries OR prepared 
statements at all. You cannot parameterise the column name, hence the entire 
reason this RFC exists. The entire point is to make sure that the bits that you 
_need_ to insert variables, are something the developer wrote, not some input 
from the user.

If that isn’t the purpose of the RFC, then it describes its actual goal really 
poorly.

> 
>> That part was weird and confusing, but not as odd as your claim that 
>> altering the query, so that it causes the where clause to become moot, is 
>> not an SQL Injection? REALLY? That’s your claim?
> 
> Yes, let me try to explain this more clearly.
> 
> If you can inject code, it's a code injection vulnerability. SQL
> injection is a specific type of code injection vulnerability. If you
> can trick the SQL into doing something invalid *without* injecting
> code, and you call it "SQL injection", that's a category error.
> 
> Supplying an integer in the place of a column name is a bug. The bug
> can even be dangerous. The bug can EVEN be a security problem for the
> system.
> 
> But calling it SQL injection is categorically incorrect. Changing the
> behavior of a SQL command **without injecting additional code** is not
> SQL injection.
> 
> If we're trying to stop all forms of misuse and insecurity that can
> result from string concatenation, cool. But be very clear about that.
> 
>> I did a little research, and it turns out Wikipedia 
>> (https://en.wikipedia.org/wiki/SQL_injection#Technical_implementations), 
>> Cloudflare 
>> (https://www.cloudflare.com/en-au/learning/security/threats/sql-injection/), 
>> and OWASP (https://owasp.org/www-community/attacks/SQL_Injection#example-2) 
>> all have examples with a `1=1` type query manipulation. Do you want to write 
>> and tell them that they’re all wrong, or should I ask them to call you?
> 
> If you **inject a `1=1` clause where one didn't exist before**, that's
> injection. Notice the introduction of an OR operator in the examples
> you cited.

Please, explain to us all, how `where foo=‘bar’ OR 1=1` is functionally 
different than `where 123=123` because the developer screwed the pooch in some 
specific condition and passed the ID twice, rather than the column name and the 
id, respectively.

> 
> My classification of the original example as "Not Injection" has
> nothing to do with the fact that numbers are being compared with
> numbers. Rather, there was no code injection.
> 
>> Also, while researching the specifics of what is considered an “SQL 
>> Injection” I came across an article, that talks specifically about the 
>> dangers of allowing user input (i.e. the thing `is_trusted` is meant to 
>> prevent) as a column or table identifier. It’s from this little 
>> organisation, you may have heard of them: “Parago

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

2021-06-24 Thread Stephen Reay


> On 24 Jun 2021, at 08:30, Scott Arciszewski  wrote:
> 
> On Wed, Jun 23, 2021, 9:23 PM Bruce Weirdan  > wrote:
> 
>> On Thu, Jun 24, 2021 at 3:41 AM Scott Arciszewski 
>> wrote:
>>> The failure condition of this query is
>>> "return all rows from the table already being queried", not "return
>>> arbitrary data the attacker selects from any table that the
>>> application can read".
>> 
>> Imagine that was a DELETE rather than SELECT and the failure condition
>> becomes 'the table is emptied'.
>> It may have less disastrous consequences (depending on how good your
>> backup / restore procedures are) compared to arbitrary reads you
>> demonstrated, but it is still, quite clearly, a glaring security hole
>> caused by user input in SQL query - AKA SQL injection in layman's
>> terms.
>> 
>>> it differs from Injection vulnerabilities in one
>>> fundamental way: The attacker cannot change the structure of the SQL
>>> query being executed.
>> 
>> I would say replacing a column name with value is changing the
>> structure of SQL query, and, basically, in exactly the way you
>> describe SQL injection: confusing the code (column name) with data.
>> 
>> I wholeheartedly welcome this RFC as it was originally proposed:
>> is_literal() doing exactly what it says on the tin, without any
>> security claims. But it has gone far from there real quick and now
>> people can't even name the thing.
>> 
>> 
>> --
>>  Best regards,
>>  Bruce Weirdan mailto:
>> weir...@gmail.com
> 
> 
> 
> We can agree that it is a bug. We don't agree on the definition of SQL
> injection.
> 
> Changing a column name to a number (which prepared statements shouldn't
> allow in the first place) is a bug. This changes the effect of the command,
> but the *structure* of the query remains unchanged.

Hi Scott,

I wrote that example where an integer could be dangerous.

So firstly - just to clarify, because some replies seemed to be confused on the 
topic, as was literally mentioned in the original comment, it is definitely not 
correct behaviour - it’s a developer mistake that might work some of the time, 
and thus go unnoticed in testing. If you can show me a developer who’s never 
inadvertently passed the wrong parameter in some condition, I’ll show you an 
imaginary developer.


Additionally - pointing out that this is a "developer error” doesn’t help your 
case. Using non-parameterised queries should already be a “developer error” for 
anyone who can walk and breathe at the same time - and yet that usage is being 
actively encouraged if this function supports integers. I’ve still seen zero 
responses about legitimate reasons this needs to support integers - giving 
people a shitty way to build an IN() clause is not legitimate. Parameterisation 
exists, and works.


I don’t even understand why you mentioned prepared statements (I guess you 
meant using parameterised queries?) - the column name inherently can’t be 
parameterised - hence having to use a string substitution in the query. 


That part was weird and confusing, but not as odd as your claim that altering 
the query, so that it causes the where clause to become moot, is not an SQL 
Injection? REALLY? That’s your claim?


I did a little research, and it turns out Wikipedia 
(https://en.wikipedia.org/wiki/SQL_injection#Technical_implementations 
), Cloudflare 
(https://www.cloudflare.com/en-au/learning/security/threats/sql-injection/ 
), 
and OWASP (https://owasp.org/www-community/attacks/SQL_Injection#example-2 
) all have examples with 
a `1=1` type query manipulation. Do you want to write and tell them that 
they’re all wrong, or should I ask them to call you?

Also, while researching the specifics of what is considered an “SQL Injection” 
I came across an article, that talks specifically about the dangers of allowing 
user input (i.e. the thing `is_trusted` is meant to prevent) as a column or 
table identifier. It’s from this little organisation, you may have heard of 
them: “Paragon Initiative” 
(https://paragonie.com/blog/2015/05/preventing-sql-injection-in-php-applications-easy-and-definitive-guide
 
).



I would absolutely make use of a function that tells me if the string given is 
in fact from something controlled by the developer. But once that same string 
can also include input from the request or the environment or whatever by 
nature of integers, the function becomes useless for the stated purpose.


Cheers

Stephen



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

2021-06-22 Thread Stephen Reay


Sent from my iPhone

> On 23 Jun 2021, at 03:08, Lauri Kenttä  wrote:
> 
> On 2021-06-22 21:38, Stephen Reay wrote:
>>>> On 22 Jun 2021, at 21:38, Craig Francis  wrote:
>>> If you can point me to an example where including integers in this has
>>> introduced a security vulnerability then please do, and I mean it, that’s
>>> what this process is for, I genuinely want people to come forward with them
>>> so we can refine this.
>> It took me about a minute to think of this:
>> "select * from customer_purchases where {$column} = :value”.
>> The developer inadvertently passes the same “trusted value” in as the
>> `$column` substitute and the value parameter. It must be safe because
>> we ran it through `is_trusted`!
>> The query now executes as:
>> "select * from customer_purchases where 12345 = 12345”
>> You cannot magically make all dynamically generated queries safe -
>> they tried that about a quarter of a century ago. Hint: it did not end
>> well - and explicitly allowing some user input is just mind boggling
>> given the stated goals.
> 
> 
> Your example is interesting and kind of valid. Looks like there is a bug in 
> the code: $column is sometimes an user-defined integer and sometimes a valid 
> literal column name, clearly this should not happen. (If it was supposed to 
> be integer, you would pass it as a parameter just like :value, right?)
> 
> Is this RFC about preventing bugs (accidentally used wrong variable) or 
> preventing bad code (user input intentional but used the wrong way)? I 
> thought it was more the about bad code. Bugs can live even in literal queries 
> as well as outside queries, where is_literal/is_trusted can't reach them.
> 
> Another line of thought: One possible approach would be to accept only 
> explicit integer casts (sprintf %d and %u, and a new function like 
> implode_ints() and/or strval_int()) and otherwise only accept strings. This 
> would avoid the accidental case where $x is supposed to be a trusted string 
> but is an untrusted integer instead, like the given example.
> 
> -- 
> Lauri Kenttä
> 

Yes it very deliberately shows a case where developer error can lead to 
incorrect behaviour, because of a bug. I don’t think it’s a stretch to say that 
not validating the dynamic elements used to generate a query would also be 
considered a bug caused by developer error.

Given that this is meant to be a security feature, an approach of “well this is 
probably fine” seems like a pretty cavalier approach to start from, especially 
given that there are existing solutions to prevent injections of integer values.

Rather than people keep repeating “integers aren’t injections”, perhaps someone 
can show just one example why you’d need to use a literal integer as an 
identifier in sql (ie a table name etc) and thus can’t use parameterisation.

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

2021-06-22 Thread Stephen Reay


> On 22 Jun 2021, at 21:38, Craig Francis  wrote:
> 
> If you can point me to an example where including integers in this has
> introduced a security vulnerability then please do, and I mean it, that’s
> what this process is for, I genuinely want people to come forward with them
> so we can refine this.


It took me about a minute to think of this:

 "select * from customer_purchases where {$column} = :value”. 

The developer inadvertently passes the same “trusted value” in as the `$column` 
substitute and the value parameter. It must be safe because we ran it through 
`is_trusted`!

 The query now executes as:

 "select * from customer_purchases where 12345 = 12345”


You cannot magically make all dynamically generated queries safe - they tried 
that about a quarter of a century ago. Hint: it did not end well - and 
explicitly allowing some user input is just mind boggling given the stated 
goals.





Re: [PHP-DEV] Sql Object Model Parser & Sanitizer (was [RFC] is_literal)

2021-06-22 Thread Stephen Reay



> On 22 Jun 2021, at 20:39, Mike Schinkel  wrote:
> 
>> On Jun 22, 2021, at 9:00 AM, Kamil Tekiela  wrote:
>> 
>> Hi Mike,
>> 
>> Please don't do this. We already have PDO with prepared statements. The data 
>> must be bound. This is the secure way of writing SQL queries. 
> 
> The problem is that over 40% of the web currently runs on PHP code that using 
> mysqli.  That CMS does not support PDO nor prepared statements, and is 
> unlikely to switch to it anytime some in the foreseeable future.  
> 
> A SQL object model parser and sanitizer could more easily be used 
> incrementally by that CMS since PDO does not share connections with mysqli 
> (AFAIK, anyway.)
> 

(Resending from on-list address)

Apparently you didn't know mysqli supports parameterised queries?
Wordpress could have adopted parameterised queries when they grudgingly 
switched to mysqli, years after both it and PDO were introduced.
There’s zero reason to believe they would adopt this unless forced to.

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



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

2021-06-22 Thread Stephen Reay

> On 22 Jun 2021, at 20:13, Craig Francis  wrote:
> 
> On Tue, 22 Jun 2021 at 09:59, Stephen Reay  <mailto:php-li...@koalephant.com>> wrote:
> So I just want to make sure I understand the progression on this so far. It 
> started out with people wanting a way to check that a string was a literal 
> string, in code somewhere, and does not come from user input. Ok makes sense. 
> The name makes sense too.
> 
> 
> 
> The primary reason was never just to define literal strings, the intention 
> has always been to create a practical, implementable solution to address the 
> issue of Injection Vulnerabilities (SQl/HTML/CLI/etc).
> 

Preventing injection vulnerabilities may be your goal but I’m talking about the 
intended behaviour of this one function. Your original email says this:

>> Distinguishing strings from a trusted developer from strings that may be 
>> attacker controlled



If you feel that somehow doesn’t mean the same as "check that a string was a 
literal string, in code somewhere, and does not come from user input”, then we 
need to crack open a dictionary and work out which words one of us doesn’t know 
the meaning of.




> The name `is_literal()` has always just been a placeholder, it came up when I 
> first started looking at this problem because that was the most obvious thing 
> I knew we could anchor around. (Unfortunately I think it was easy to make 
> assumptions based solely on that name, rather than focussing on the issue it 
> is meant to address).
> 
> So, we cannot look for literals only - while it was part of the solution, it 
> was very much incomplete. Bearing in mind, there is considerable amount of 
> existing code and tutorials out there which include integers in their 
> SQL/HTML/CLI/etc, and they are perfectly safe in doing so. Making a solution 
> which does not support integers is not going to be adopted/used because the 
> task of rewriting and changing everything, for no benefit, will not be 
> considered by developers.
> 

There is a considerable amount of existing code that includes strings in SQL, 
HTML without danger too. Plenty of string values are fine, and plenty of 
integer values are fine. That doesn’t mean we should just blindly trust a value 
that came from the user, just because it’s a number.
The saying goes “never trust user input” not “never trust user input unless 
it’s a number”. 


> Likewise, a lot of code already builds SQL/HTML/CLI/etc strings via 
> concatenation and sprintf(), and forcing everyone to use a query builder is 
> likely to cause most people to not even consider using this.
> 

If they won’t adopt an existing solution to the problem why would they adopt 
this?
You’ve said very recently that this is not intended to be used directly by most 
developers, and instead used within libraries and frameworks. It seems a little 
weird to then make concessions that will defeat the stated goal, in the name of 
adoption. 


> It's all well thinking of one thing that might theoretically/idealistically 
> solve the issue, but it also needs to have a plan on how this will be 
> practically implemented and used by developers (which this has done).
>  


Having a plan for how to implement something doesn’t help much when the thing 
you’re implementing deliberately ignores a specific type of ‘untrusted’ input..






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

2021-06-22 Thread Stephen Reay


> On 22 Jun 2021, at 15:58, Stephen Reay  wrote:
> 
> 
> 
>> On 22 Jun 2021, at 06:28, Craig Francis > <mailto:cr...@craigfrancis.co.uk>> wrote:
>> 
>> On Tue, 22 Jun 2021 at 12:18 am, Benjamin Morel > <mailto:benjamin.mo...@gmail.com> <mailto:benjamin.mo...@gmail.com 
>> <mailto:benjamin.mo...@gmail.com>>>
>> wrote:
>> 
>>> On Tue, 22 Jun 2021 at 01:06, Derick Rethans  wrote:
>>> 
>>>> On 21 June 2021 23:37:56 BST, Yasuo Ohgaki  wrote:
>>>>> 
>>>>> The name "is_trusted" is misleading.
>>>>> Literal is nothing but literal.
>>>> 
>>>> I agree with this. The name is_trusted is going to be the same naming
>>>> mistake as "safe mode" was. Developers will put their trust in it that it
>>>> is 100% guaranteed safe.
>>> 
>>> 
>>> FWIW, agreed, too. Trusted is vague and may imply some false sense of
>>> security. Literal is literally what it says on the tin.
>>> 
>> 
>> 
>> I can follow up properly tomorrow, but by popular request we do support
>> integers as well (could be seen as stretching the definition of “literal” a
>> bit).
>> 
>> And we did ask for suggestions last week, which ended up with a vote (as I
>> couldn’t decide).
>> 
>> That said, I’m really glad that the only issue we seem to have is the name.
>> 
>> Craig
> 
> So I just want to make sure I understand the progression on this so far.
> 
> 
> It started out with people wanting a way to check that a string was a literal 
> string, in code somewhere, and does not come from user input. Ok makes sense. 
> The name makes sense too.
> 
> Then someone said they wanted to check if an integer was a literal too - but 
> because of technical limitations, it now allows any integer, regardless of 
> where it came from, to be treated as a literal.
> 
> Then because it’s not actually checking for literals, people thought the name 
> “trusted” made more sense?
> 
> 
> That nobody thinks “any user supplied integer must be surely safe” is kind of 
> hilarious, and sad at the same time.
> 
> Knowing that a string is literal would be very helpful. Knowing that the 
> string potentially still contains user input, in spite of the one thing it 
> claims to do, is not just unhelpful, it makes the entire thing useless.
> 
> 
> I can’t vote, but this whole thing would be a No from me unless it was the 
> original scope - a variable is a literal defined in code somewhere. If there 
> are technical limitations with some types, then leave them off the list of 
> what it will check.

s/nobody/anybody/

I blame a lack of caffeine.

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

2021-06-22 Thread Stephen Reay


> On 22 Jun 2021, at 06:28, Craig Francis  wrote:
> 
> On Tue, 22 Jun 2021 at 12:18 am, Benjamin Morel  >
> wrote:
> 
>> On Tue, 22 Jun 2021 at 01:06, Derick Rethans  wrote:
>> 
>>> On 21 June 2021 23:37:56 BST, Yasuo Ohgaki  wrote:
 
 The name "is_trusted" is misleading.
 Literal is nothing but literal.
>>> 
>>> I agree with this. The name is_trusted is going to be the same naming
>>> mistake as "safe mode" was. Developers will put their trust in it that it
>>> is 100% guaranteed safe.
>> 
>> 
>> FWIW, agreed, too. Trusted is vague and may imply some false sense of
>> security. Literal is literally what it says on the tin.
>> 
> 
> 
> I can follow up properly tomorrow, but by popular request we do support
> integers as well (could be seen as stretching the definition of “literal” a
> bit).
> 
> And we did ask for suggestions last week, which ended up with a vote (as I
> couldn’t decide).
> 
> That said, I’m really glad that the only issue we seem to have is the name.
> 
> Craig

So I just want to make sure I understand the progression on this so far.


It started out with people wanting a way to check that a string was a literal 
string, in code somewhere, and does not come from user input. Ok makes sense. 
The name makes sense too.

Then someone said they wanted to check if an integer was a literal too - but 
because of technical limitations, it now allows any integer, regardless of 
where it came from, to be treated as a literal.

Then because it’s not actually checking for literals, people thought the name 
“trusted” made more sense?


That nobody thinks “any user supplied integer must be surely safe” is kind of 
hilarious, and sad at the same time.

Knowing that a string is literal would be very helpful. Knowing that the string 
potentially still contains user input, in spite of the one thing it claims to 
do, is not just unhelpful, it makes the entire thing useless.


I can’t vote, but this whole thing would be a No from me unless it was the 
original scope - a variable is a literal defined in code somewhere. If there 
are technical limitations with some types, then leave them off the list of what 
it will check.









Re: [PHP-DEV] Trait constants

2021-05-12 Thread Stephen Reay


> On 12 May 2021, at 16:44, Nikita Popov  wrote:
> 
> On Wed, May 12, 2021 at 11:38 AM Guilliam Xavier  <mailto:guilliam.xav...@gmail.com>>
> wrote:
> 
>> 
>> 
>> On Sun, Jun 28, 2020 at 2:34 PM Nikita Popov  wrote:
>> 
>>> On Sat, Jun 27, 2020 at 3:53 PM Stephen Reay 
>>> wrote:
>>> 
>>>> Hi,
>>>> 
>>>> It’s always struck me as slightly odd that traits don’t support
>>> constants
>>>> the way classes and interfaces do.
>>>> I tried to find an explanation of the lack of support in the original
>>> RFC,
>>>> and came up empty.
>>>> 
>>>> A consequent discussion in R11 has led me here.
>>>> Can anyone working on internals explain why traits don’t allow constants
>>>> (either technically or philosophically)?
>>>> Moreover, what’s the opinion(s) of the list, on adding support for this?
>>>> Would an RFC be needed?
>>>> 
>>> 
>>> Sounds like a reasonable addition. An RFC will be needed to specify the
>>> details, which tend to be tricky whenever traits are involved. Some
>>> suggestions:
>>> 
>>> * Constants mustn't be accessible directly on the trait, i.e.
>>> TraitName::FOOBAR throws.
>>> 
>> 
>> Sorry for asking so late, but: why?
>> Note that currently both TraitName::$foobar and TraitName::foobar() work:
>> https://3v4l.org/eGlYm
>> 
> 
> Yes, unfortunately this currently works by accident, but support for it
> will be removed (
> https://wiki.php.net/rfc/deprecations_php_8_1#accessing_static_members_on_traits
>  
> <https://wiki.php.net/rfc/deprecations_php_8_1#accessing_static_members_on_traits>
> ).
> 
> Regards,
> Nikita

Hi Nikita - thanks for your earlier input on this. As we’re heading towards 8.1 
now seems as good a time as any to pick this back up.


Any thoughts on 
https://github.com/stephenreay/php-rfcs/blob/master/trait-constants.md 
<https://github.com/stephenreay/php-rfcs/blob/master/trait-constants.md> ?



Cheers

Stephen 

Re: [PHP-DEV] [RFC] Autoloader Classmap

2021-04-05 Thread Stephen Reay



> On 6 Apr 2021, at 05:05, Mark Randall  wrote:
> 
> On 15/03/2021 17:41, Mark Randall wrote:
>> I would like to propose the addition of a new mechanism of autoloading 
>> classes - a classmap that will be consulted prior to checking the 
>> spl_autoload_register'd callbacks.
>> https://wiki.php.net/rfc/autoload_classmap
> 
> Does anyone else have any more feedback on this? If not I plan on opening 
> voting in a couple of weeks or so.
> 
> The tl;dr:
> 
> * Autoloading is one of the routines called most frequently in any request.
> 
> * It's a very minor boost in autoloading performance, around 5% vs invoking a 
> userland function. This will easily be swamped by any IO and invalidated 
> entirely by preloading.
> 
> * I expect 99.% of users will never know it exists, and it will instead 
> just be an option for tools like composer that will provide a small 
> transparent boost.
> 
> * It provides a very minor benefit to debugging as you get to skip over the 
> autoloading frames which so very often come up during a request.
> 
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Mark,

Just to clarify something - wouldn't the loader use ‘require’ behaviour, not 
‘require_once’ behaviour? If you’re hitting the autoloader, that means the 
class in the file you’re about to load isn’t defined yet, which means the file 
hasn’t been loaded already. Using require_once you’d be doing a check if the 
file has loaded in a scenario where it would have never been loaded anyway.



Cheers

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



Re: [PHP-DEV] [RFC] Autoloader Classmap

2021-03-16 Thread Stephen Reay



> On 17 Mar 2021, at 03:11, Jordi Boggiano  wrote:
> 
> 
> On 16/03/2021 15:02, Stephen Reay wrote:
>>> On 16 Mar 2021, at 20:07, Jordi Boggiano  wrote:
>>> 
>>> 
>>> P.S: While I am here looking at spl_* docs, it seems to me like 
>>> spl_autoload_call should be deprecated in favor of class_exists, and 
>>> spl_autoload_extensions + spl_autoload also probably should be deprecated 
>>> or at least marked as antiquated in the docs, and not migrated to 
>>> autoload_* like you suggested doing for spl_autoload_register/unregister in 
>>> another RFC.
>>> 
>>> 
>> 
>> Edit: wrong sending address, again. Sending for list, apologies for the dupe.
>> 
>> I don’t have a huge amount of interest in this, except to say: If someone 
>> wants to add a core function to make Composer’s autoloader work faster, 
>> that’s fine and dandy, it doesn’t hurt to provide the building blocks for 
>> common patterns. But pushing your own biases about non-Composer class 
>> autoloading being “antiquated” or “deprecated” is a step too far.
> 
> I assume that refers to my P.S. note.
> 
> I did not mean to offend anyone, I merely have never seen anyone use these 
> before. It seems like this relies on include_path being set and then having 
> big dirs full of class files that now become autoloadable, but that doesn't 
> play well with namespaces and doesn't let you organize stuff very much unless 
> you set every dir in the include_path. Call me biased but that does not seem 
> very user friendly.
> 
> Anyway this is completely unrelated to the RFC at hand, it was a side note, 
> so let's leave it at that I guess.
> 
> -- 
> 
> Jordi Boggiano
> @seldaek - https://seld.be
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

It’s not about “offending” anyone. It’s about the inappropriateness of the 
author of a userland library that includes an autoload component, calling for 
the removal/docu-shunning of a built-in autoload function, with apparently zero 
actual knowledge of how it works, to boot.

`spl_autoload` works just fine with namespaces, and files organised into 
subdirectories (under an include_path entry) mapped to the namespace names. It 
has worked that way since 5.3.3 - over a decade ago.

Your comments about this are both factually wrong, and inappropriate, given 
your “role”.

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



Re: [PHP-DEV] [RFC] Autoloader Classmap

2021-03-16 Thread Stephen Reay


> On 16 Mar 2021, at 20:07, Jordi Boggiano  wrote:
> 
> Hey,
> 
> Here some perspective on this from the Composer side of things. To the best 
> of my knowledge the Composer autoloader is the default autoloader used by 
> most PHP projects at this point except for WordPress. I am sure there are a 
> few more outliers and people using custom autoloaders in addition of, or 
> instead of the Composer-generated one, but generally speaking it has 
> supplanted many custom implementations in frameworks over the years.
> 
> First of all big +1 here, if we can make things faster for non-preloaded 
> workloads it's great. The autoloader is definitely a big fixed 
> "infrastructure cost" in many such apps currently, and I don't think we can 
> squeeze any more perf from userland.
> 
> On 15/03/2021 19:32, Mark Randall wrote:
>> On 15/03/2021 17:59, Levi Morrison via internals wrote:
>>> IMO, these should be the defined case of the class, or we should be
>>> insensitive about it. It's one thing that our symbols are case
>>> insensitive; it is wholly another to _require_ it for this feature by
>>> requiring lowercase names. I assume there is some motivation for this;
>>> I would like to hear it.
>> 
>> EG(class_table) is stored lowercase, the case of the class name itself is 
>> only known once it has been found which could only occur after the 
>> autoloader has run.
>> 
>> By forcing lowercase we have a single key to lookup for any variation, 
>> without it we would have to either match the case exactly (which would be 
>> different from how internals currently works) or would have to iterate over 
>> every item in the classmap array each time, performing case a insensitive 
>> comparisons on every key until one was found, or in the worst case, the 
>> entire set.
> 
> - The Composer ClassLoader [1] uses a case-sensitive classmap which overall 
> has not caused major issues except when people do class_exists or new calls 
> with the wrong case. That said, if we were to support this new API we would 
> for sure be able to generate a lowercased classmap, we just haven't done it 
> until now because spl_register_autoload calls the callback with the original 
> case, and having to lowercase the passed class name on every call seemed 
> wasteful. If internals already does this anyway that sounds fine by me.
> 
> - It also uses `include` vs the proposed require_once in this RFC. I am not 
> entirely sure what the implications are here, nor if there are still 
> performance differences to one over the other, but IIRC we do include because 
> it's the fastest, and as a class never gets autoloaded twice a file does not 
> really risk being included again.
> 
> - Right now we have to run includes through a proxy function [2] to avoid 
> granting the included file access to $this and other in-scope variables. It's 
> not that much overhead but can quickly lead to a thousand extra function 
> calls within a request's lifecycle, so just for completeness I figured I'd 
> mention it.
> 
> - As Mike Schinkel mentioned, the proposed API should really support multiple 
> maps. Composer a prepend-autoloader option which controls whether the 
> generated autoloader will be prepended or appended when spl_autoload_register 
> is called. This is required in some cases where multiple autoloaders coexist. 
> So the ability to add multiple maps, including optionally prepending them 
> would be a must IMO. The ability to remove an autoloader and its associated 
> classmap would also be very welcome so one can unregister things cleanly.
> 
> So taking the above in consideration, and keeping consistency with existing 
> spl_* functions in mind, I would propose an API more like:
> 
>autoload_register_classmap(array $map, bool $prepend = false)
>autoload_unregister_classmap(array $map)
> 
> 
> P.S: While I am here looking at spl_* docs, it seems to me like 
> spl_autoload_call should be deprecated in favor of class_exists, and 
> spl_autoload_extensions + spl_autoload also probably should be deprecated or 
> at least marked as antiquated in the docs, and not migrated to autoload_* 
> like you suggested doing for spl_autoload_register/unregister in another RFC.
> 
> [1] 
> https://github.com/composer/composer/blob/b6826f352390b4c952be8fd75d60cfd4f6f39f11/src/Composer/Autoload/ClassLoader.php
> 
> [2] 
> https://github.com/composer/composer/blob/b6826f352390b4c952be8fd75d60cfd4f6f39f11/src/Composer/Autoload/ClassLoader.php#L478-L481
> 
> -- 
> Jordi Boggiano
> @seldaek - https://seld.be
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 


Edit: wrong sending address, again. Sending for list, apologies for the dupe.

I don’t have a huge amount of interest in this, except to say: If someone wants 
to add a core function to make Composer’s autoloader work faster, that’s fine 
and dandy, it doesn’t hurt to provide the building blocks for common patterns. 
But pushing your 

Re: [PHP-DEV] PDO integer changes in 8.1 will stop many websites I support

2021-02-27 Thread Stephen Reay


> On 27 Feb 2021, at 15:56, Matty The Mad  wrote:
> 
> PHP 8.1 PDO has been changed so that when MySQL returns an integer it will 
> no longer be returned as a string, but as an int.
> 
> The problem is this breaks any sites that use UNSIGNED ZEROFILL integer 
> fields in MySQL.
> 
> I support a number of websites where the phone numbers and post codes are all 
> UNSIGNED ZEROFILL.
> 
> The post codes in MySQL are stored as 0800.
> 
> In PHP 8.0 returned as string 0800
> In PHP 8.1 returned as integer 800
> 
> 8.0.2
> string(10) "074200"
> 
> 8.1.0-dev
> int(74200)
> 
> PDO shouldn't really be changing the data.
> 
> I propose that:
> • any ZEROFILL integers are returned as string [or]
> • there's an option to control this when making the connection (I don't want 
> to str_pad() at every place I've used ZEROFILL in the past) [or]
> • this backwards compatibility breaking change is removed until PHP 9.
> 
> Matthew Asia
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

I agree it should be configurable, but storing digit strings as integers is 
asking for trouble.

Edit: Whoops, sending again from on-list address.
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Whitespace around Paamayim Nekudotayim (double colon)

2021-02-14 Thread Stephen Reay


> On 15 Feb 2021, at 12:14, Matthew Brown  wrote:
> 
> Hey all,
> 
> Is there interest in prohibiting whitespace around double colons in the
> next major PHP version?
> 
> I was surprised to learn that PHP treats :: similar to ->, allowing double
> colons like
> 
> A::
> b();
> 
> Looking at the top 2,000 packages in Packagist I can't find any evidence of
> people using a double colon with whitespace around, and my suspicion is
> that the use of it is basically non-existent.
> 
> I wonder if there's a benefit to removing a small potential footgun from
> the language? I can't really see any benefit to _keeping_ it (unless it
> turns out my analysis is wrong, and it's actually wildly popular).
> 
> Best wishes,
> 
> Matt


Hi Matt,

As a user-land developer, I would be very much against changing this.

I’m sure it’s probably not a particularly common way to format code, but the 
ability to chain method calls, starting from a static call and have it 
formatted with one method call per-line is quite useful IMO, eg:

```
MyModelClass
::find(1)
->where(‘foo’, time(), ‘>’)
->where(‘bar’, null, ‘is not’)
->readAll();
```



But more generically - I can’t see why you’d think that this one particular 
instance of extra whitespace being insignificant is a problem, when extra 
whitespace is not significant anywhere?

In other worse, can you explain why you think it’s a problem that whitespace is 
not significant in static method calls, but it’s not a problem everywhere else 
where it’s not significant?

The two following examples are the extremes of extra whitespace vs minimal 
whitespace, and your suggestion would introduce an arbitrary inconsistency for 
one specific case. 

```

```

```

```


Cheers


Stephen

Re: [PHP-DEV] [RFC] \PHP namespace usage heuristics

2020-07-08 Thread Stephen Reay


> On 8 Jul 2020, at 13:16, Michał Marcin Brzuchalski 
>  wrote:
> 
> Hi Stephen,
> 
> śr., 8 lip 2020 o 07:09 Stephen Reay  napisał(a):
> 
>> ...
>> IMO (and I know it’s not universal) acronyms should remain upper case.
>> Camel case is about upper casing the first letter of each word. The letters
>> of an acronym are all the first letters of words, thus DOM not Dom, etc.
>> 
> 
> It doesn't really matter much though, since core symbols are already known
> on runtime so symbol resolution works by case insensitive manner.
> So it's only a matter of preference on documentation side.
> 
> namespace Foo\Bar {
>class BaZ {}
> }
> namespace {
>var_dump(new foo\bar\baz());
> }
> 
> Cheers,
> --
> Michał Marcin Brzuchalski

Hi Michal,

I realise that - I was replying to a specific question about bike shedding the 
capitalisation - that it works in other cases is irrelevant IMO.

Cheers

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



Re: [PHP-DEV] [RFC] \PHP namespace usage heuristics

2020-07-07 Thread Stephen Reay


> On 8 Jul 2020, at 05:11, Larry Garfield  wrote:
> 
> On Tue, Jul 7, 2020, at 4:22 PM, Miguel Rosales wrote:
>> Larry Garfield wrote on 07/07/2020 16:46:
>>> This has reached the 2 week mark, but there's not been much discussion.  
>>> Anyone else want to weigh in?
>>> 
>> 
>> I guess I'm missing something obvious here, but the RFC says:
>> 
>>> 5. Component or sub-component namespaces MUST use CamelCase naming 
>> conventions.
>> 
>> But then in the examples you've got e.g. \PHP\DOM\ or \PHP\SPL\... isn't 
>> that incorrect?
>> 
>> And slightly related, is there any reason to use \PHP  instead of \Php?
>> 
>> Sorry if this has been discussed before, I haven't seen it.
>> 
>> Cheers,
>> Miguel
> 
> Mm, mainly because I added the CamelCase clause late and didn't think about 
> abbreviations.  Whether it should be PHP/XML/DOM or Php/Xml/Dom has been an 
> ongoing debate for at least since PHP 5.0.  I have no preference strong 
> enough to die on that hill, though, so whatever voters are willing to go for 
> I'm good with.
> 
> Anyone care enough to offer a bikeshed color?
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 

Hi Larry,

IMO (and I know it’s not universal) acronyms should remain upper case. Camel 
case is about upper casing the first letter of each word. The letters of an 
acronym are all the first letters of words, thus DOM not Dom, etc.

Cheers

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



Re: [PHP-DEV] Trait constants

2020-07-07 Thread Stephen Reay

> On 28 Jun 2020, at 19:33, Nikita Popov  wrote:
> 
> On Sat, Jun 27, 2020 at 3:53 PM Stephen Reay  <mailto:php-li...@koalephant.com>>
> wrote:
> 
>> Hi,
>> 
>> It’s always struck me as slightly odd that traits don’t support constants
>> the way classes and interfaces do.
>> I tried to find an explanation of the lack of support in the original RFC,
>> and came up empty.
>> 
>> A consequent discussion in R11 has led me here.
>> Can anyone working on internals explain why traits don’t allow constants
>> (either technically or philosophically)?
>> Moreover, what’s the opinion(s) of the list, on adding support for this?
>> Would an RFC be needed?
>> 
> 
> Sounds like a reasonable addition. An RFC will be needed to specify the
> details, which tend to be tricky whenever traits are involved. Some
> suggestions:
> 
> * Constants mustn't be accessible directly on the trait, i.e.
> TraitName::FOOBAR throws. self::FOOBAR within the trait is legal in that
> "self" is remapped to the using class, as usual.
> * The same constants important from multiple traits should follow the
> rules of properties, i.e. require that values match. Conflict resolution
> for constants should very much *not* be supported.
> 
> Regards,
> Nikita

Hi All,

I finally found some time to write something to get this started. I’m following 
the advice given, and putting this on GH initially, any and all 
comments/feedback/suggestions are welcome!

https://github.com/stephenreay/php-rfcs/blob/master/trait-constants.md 
<https://github.com/stephenreay/php-rfcs/blob/master/trait-constants.md>


Note: I realise it doesn’t lay out voting choices, target version etc: It seems 
more pertinent to focus on nailing down some kind of fixed target of what 
should be achieved, before detailing the when/etc.


Cheers


Stephen 

[PHP-DEV] Trait constants

2020-06-27 Thread Stephen Reay
Hi,

It’s always struck me as slightly odd that traits don’t support constants the 
way classes and interfaces do.
I tried to find an explanation of the lack of support in the original RFC, and 
came up empty.

A consequent discussion in R11 has led me here.
Can anyone working on internals explain why traits don’t allow constants 
(either technically or philosophically)?
Moreover, what’s the opinion(s) of the list, on adding support for this? Would 
an RFC be needed? 


Cheers 



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



Re: [PHP-DEV] About the use of the terms master/slave and blacklist, proposal to replace.

2020-06-15 Thread Stephen Reay


> On 15 Jun 2020, at 22:43, Daniel Rodrigues Lima 
>  wrote:
> 
> Hi internals,
> 
> I think the time has come for the PHP internals to discuss the use of 
> master/slave and blacklist terminologies.
> As everyone can see, we are going through times of change in the world, see 
> #blackLivesMatter for example.
> Therefore, I propose that we discuss the non-use of terms master/slave, 
> because the use of this can allude to the slavery and negative feelings about 
> black people.
> 
> Some projects that changed the terminology:
> 
> * 
> https://github.com/sebastianbergmann/phpunit/commit/8e9c76d33dab4095c9066072076f368193e4166d
> * https://go-review.googlesource.com/c/go/+/236857/
> * https://issues.apache.org/jira/browse/COUCHDB-2248
> * https://bugs.python.org/issue34605
> 
> Greets,
> 
> Daniel Rodrigues.
> 
> geek...@php.net
> https://twitter.com/geekcom2
> https://www.linkedin.com/in/danielrodrigueslima/
> 

Hi Daniel,

I’m sympathetic to your goals. I’ve had a client ask me in the last hour, while 
discussing a Redis issue “can we replace those terms ‘slave’ and ‘master’ with 
“primary” and “replica”.


In technology circles, the terms master and slave are almost always referred to 
in terms of replicated data stores, and the ‘normal’ replacements are “primary” 
and “replica”. The terms “whitelist” and “blacklist”  generally refer to 
allowing or disallowing things explicitly.


I’m not going to say it’s not practical to do this or that it’s a BC break, 
because without some context of what you believe needs to change in PHP itself, 
this whole conversation seems very abstract.

Can you identify actual references to the terms “master”, “slave”, “blacklist”, 
“whitelist” somewhere in php that you feel should be changed?



Cheers


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



Re: [PHP-DEV] Draft RFC callable types + callable type/function autoloading

2020-05-21 Thread Stephen Reay


> On 20 May 2020, at 20:07, Dan Ackroyd  wrote:
> 
> Hi internals,
> 
> A while ago, I spent some time thinking about callables, and how they
> are not very consistent, which makes people sad:
> https://wiki.php.net/rfc/consistent_callables
> 
> The reason I didn't pursue that RFC is that although tidying up PHP
> core to be more consistent would be nice, it would be a large amount
> of work, that wouldn't dramatically improve the developer experience
> when programming in PHP. In fact it would mostly just break otherwise
> working code.
> 
> What would be better would be an RFC to make callables be more useful,
> specifically by allowing you to define the parameter and return types
> for them. Making it possible to autoload those types would be
> required, and function autoloading is also a feature that has been
> desired for a while.
> 
> So here are two draft RFCs:
> 
> Callable types
> https://github.com/Danack/FunctionTypes/blob/master/1_callable_type_rfc.md
> 
> Function + callable type autoloading
> https://github.com/Danack/FunctionTypes/blob/master/2_autoloading_part_2.md
> 
> I'll leave them on github for the moment, as it is easier to do PRs
> and track issues there but I wanted to gather initial feedback before
> getting closer to the RFC cutoff date.
> 
> I'll move them to the wiki and formally submit them for discussion
> when the implementation is closer to being done.
> 
> cheers
> Dan
> Ack
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

Hi Dan,

From a userland perspective I like both of these, a lot.

I have a question though, and i wasn’t sure if you’d rather discuss particular 
points here on in a GH issue.

Would the changes to spl_autoload_* impact on the built in autoload 
implementation, spl_autoload? 

Cheers

Stephen 

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



Re: [PHP-DEV] Any interest in a list type?

2020-04-23 Thread Stephen Reay


> On 23 Apr 2020, at 23:05, Larry Garfield  wrote:
> 
> On Thu, Apr 23, 2020, at 12:02 AM, Matthew Brown wrote:
>>> This is the *design* process for a language, and it's important...
>> Stepping back to reconsider how collections work generally, and how we can
>> improve them in a graceful way that leads to a clean end-state, would be
>> very valuable.
>> Though you have much more experience with internals than I do, I think that
>> building a consensus around a bold new vision for PHP collections would be
>> a near-Sisyphean task.
> 
> Disclosure: I've been around the list for over a decade and talked a lot, but 
> the recent pipe RFC is my first core patch. I'm still one of the little 
> people around here. :-)  Though I have successfully engaged in Sisyphean 
> tasks before.  (GoPHP5, Drupal 8, FIG, etc.)
> 
>> Adding a list/vector type would be a much smaller, more easily definable
>> task – it was one of the first new types that Hack added, and by all
>> accounts they're pretty happy with that decision.
> 
> I think we may be talking past each other.  I don't mean "rewrite all the 
> things."  Just taking the time to think through "if we have a list type, 
> generators, and array/dicts, what should all of the ancillary bits around 
> them be to make them as smooth as possible?"  Viz, how do we NOT have 
> array_map, list_map, and generator_map as 3 separate functions, because that 
> would be awful.  Are list generators and array/dict generators different 
> things or the same thing, or...?  Would comprehensions make sense as part of 
> such a plan?  (IMO yes.)  But then, do comprehensions produce lists or dicts 
> or...?  
> 
> That's the sort of knock-on effects that should be thought through before we 
> commit code, because in the long run it would reduce the amount of code to 
> commit (and the amount of WTF for users).
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php

Hi Larry,

I may be missing something here,  but couldn’t the three types be handled by a 
set of `iterator_{map,filter,...}` functions?

Array_map probably has to stay as is because it’s signature and method of 
operation is (IMO) not something that should be carried over, but array filter 
could possibly just become an alias to iterator_filter?

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



Re: [PHP-DEV] RFC: Server-Side Request and Response Objects (v2)

2020-03-13 Thread Stephen Reay

> On 14 Mar 2020, at 02:59, Mike Schinkel  wrote:
> 
>> On Mar 13, 2020, at 3:23 PM, Stephen Reay  wrote:
>> 
>> Hi Mike,
>> 
>> (I realise some of these points are possibly more addressed to Paul than 
>> yourself, this is just where my brain went when I dug into what you were 
>> mentioning)
> 
> (after responding to your reply I think I was commenting on the RFC and I 
> think it is possible that you may have missed as few aspects of the RFC such 
> as a 'server' property on the ServerRequest variable. If that is the case 
> then we might be saying the same things. See 
> https://github.com/pmjones/ext-request#superglobal-related) 
> 
> Yes, I should have made it more explicit. As author of the RFC I was speaking 
> to Paul in suggesting that if we are going to name the proposed objects to be 
> more specific to requests and response that we move the server-specific 
> aspects out and into their own object.  
> 
> Otherwise I feel that dropping the "Server" from the name the object 
> clarifies one aspect and obfuscates another, albeit clarifying the larger 
> part.  Better to make it all clear with another object named for what it 
> represents; server information.
> 
>> I apologise if I’ve missed part of the discussion but what do you mean by 
>> “make sure it matches *exactly*.
> 
> I was referencing your comments where my takeaway from reading what you wrote 
> is that you were asking that the naming match exactly what you were viewing 
> the objects to be doing, and that is to work with HTTP:
> 
> "This extension and the classes it provides are inherently about HTTP 
> requests made to a php ‘server’, and the response it sends back - and yet 
> it’s called Server{Request,Response,Buffer} etc…. The “server” part is 
> superfluous in the context of a php web application, because it’s all 
> “server” side, and while uncommon it’s not impossible to write *other* types 
> of network server using PHP."
> 
> "TLDR: if you aren’t concerned about the concept of php-initiated 
> outgoing HTTP requests, I think `HTTP{Request,Response,Buffer}` is quite 
> clear in terms of naming. If you wanted to be more explicit about their 
> purpose (and/or prevent possible confusion with either user land or potential 
> future extensions handling outgoing requests), `IncomingHTTPRequest` and 
> `OutgoingHTTPResponse` are very explicit, if a bit verbose."
> 
> My point is simply that the server-specific aspects have nothing to do with 
> HTTP requests or HTTP responses, and if Paul was to rename his classes to 
> more closely align with HTTP requests and HTTP responses then he should 
> extract the server aspects out into their own class.

I think we’re probably talking about different ’server specific’ parts of the 
$_SERVER super global array.. I’m talking about the stuff that’s documented (on 
https://www.php.net/manual/en/reserved.variables.server.php 
<https://www.php.net/manual/en/reserved.variables.server.php>) and much of 
which comes from/seems inspired by the CGI spec, which is inherently related to 
a http request. I.e. the SERVER_* keys, the REMOTE_* keys, the doc root, etc.

> 
> 
>> Do you mean how `->server` is listed as being a copy of the `$_SERVER` super 
>> global? If so, can someone point me to the specific logic behind that, given 
>> how many parts of it are already exposed via ‘dedicated’ properties of the 
>> proposed class?  From what I can see (and I may have missed some) the parts 
>> of $_SERVER not exposed in some way “directly” on ServerRequest (nee 
>> CurrentRequest) are the actual “server” parts: the `SERVER_*` keys, doc 
>> root, PHP_SELF; and the ‘client’ parts: REMOTE_*; plus few random stragglers 
>> like PATH_INFO, and for some reason REQUEST_TIME[_FLOAT]?
> 
> I don't think direct exposure is required; indirect exposure via an array 
> still means that aspects not related to HTTP requests and HTTP responses are 
> currently contained in the ServerRequest->server which to me is okay if it is 
> called "ServerRequest" but not okay if it is called "HttpRequest," 
> "WebRequest," "IncomingRequest," or "CurrentRequest."
> 
>> Can those two things not be organised as a hash of those values, under 
>> `server` and `client` (or `remote` if you want to keep the terminology - yes 
>> I know it will be the originating TCP connection host not necessarily the 
>> browser host)? As I said, I’ve missed some of the discussion but I fail to 
>> see the benefit of a class to make all the details of a web request and it’s 
>> response available…. And then just stick the existing superglobals in it 
>> unto

Re: [PHP-DEV] RFC: Server-Side Request and Response Objects (v2)

2020-03-13 Thread Stephen Reay



> On 14 Mar 2020, at 01:40, Mike Schinkel  wrote:
> 
> 
>> On Mar 13, 2020, at 10:55 AM, Paul M. Jones  wrote:
>> 
>> One other alternative John & I contemplated was 
>> `Web{Request,Response,ResponseSender}` -- do you think that might be a 
>> reasonable alternative to HTTP, one that is "adjacent" but not 
>> overly-specific? That would net us:
>> 
>> - WebRequest
>> - WebResponse
>> - WebResponseSender
>> 
>> I didn't like the look of it previously, and I don't think I like the look 
>> of it now, but ... (/me shrugs).
>> 
>> 
>>> However, that also may be confusing if people expect it to be a construct 
>>> for making outgoing requests. 
>> 
>> Yes, that's another tricky bit in the naming -- making a distinction between 
>> the objects as representative of client operations (send request, receive 
>> response) and server operations (receive request, send response). Thus the 
>> current `Server` prefix (however unsatisfactory it may be) to indicate their 
>> operational context.
>> 
>> Your `Incoming` and `Outgoing` prefixes, minus the HTTP, would net us:
>> 
>> - IncomingRequest
>> - OutgoingResponse
>> - OutgoingResponseSender
>> 
>> I will need to ponder on those.
>> 
>>> The user land implementation I’ve been using ’solves’ this by using a 
>>> `HTTP` namespace, and then provides `Request` and `Response` (for an 
>>> outgoing - i.e. curl - HTTP Request, and the corresponding HTTP Response) 
>>> objects and then `CurrentRequest` and `CurrentResponse` for what your RFC 
>>> proposes (i.e. the active request made to php). 
>> 
>> Yes, userland does operate that way. However, I think adding an HTTP 
>> namespace to PHP itself is something to be avoided, so emulating userland 
>> here is not an option.
>> 
>> 
>>> As with anything any of us has written, I’m not 100% sold on 
>>> ‘Current{Request,Response}` even after writing it, but I think it’s at 
>>> least a little more specific about what they do, when the namespace is 
>>> taken into account.
>> 
>> `Current{...}` is not something we had previously considered; that would net 
>> us, in the global namespace:
>> 
>> - CurrentRequest
>> - CurrentResponse
>> - CurrentResponseSender
>> 
>> I will need to ponder on those as well.
>> 
>> Any further thoughts or opinions on this, Stephen? Or from anyone else?
> 
> One issue that I have is, if we are going to fine-tune the naming to make 
> sure it matches  *exactly* then I think that CurrentRequest->server does not 
> make sense.
> 
> Maybe if you choose one of these names you should break out the 
> server-specific items into their own class/object?
> 
> -Mike
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

Hi Mike,

(I realise some of these points are possibly more addressed to Paul than 
yourself, this is just where my brain went when I dug into what you were 
mentioning)

I apologise if I’ve missed part of the discussion but what do you mean by “make 
sure it matches *exactly*. Do you mean how `->server` is listed as being a copy 
of the `$_SERVER` super global? If so, can someone point me to the specific 
logic behind that, given how many parts of it are already exposed via 
‘dedicated’ properties of the proposed class?  From what I can see (and I may 
have missed some) the parts of $_SERVER not exposed in some way “directly” on 
ServerRequest (nee CurrentRequest) are the actual “server” parts: the 
`SERVER_*` keys, doc root, PHP_SELF; and the ‘client’ parts: REMOTE_*; plus few 
random stragglers like PATH_INFO, and for some reason REQUEST_TIME[_FLOAT]?

Can those two things not be organised as a hash of those values, under `server` 
and `client` (or `remote` if you want to keep the terminology - yes I know it 
will be the originating TCP connection host not necessarily the browser host)? 
As I said, I’ve missed some of the discussion but I fail to see the benefit of 
a class to make all the details of a web request and it’s response available…. 
And then just stick the existing superglobals in it untouched.

Things like the query params and body params make sense to be accessible 
essentially (albeit with better names) as-is, because they’re a hash of unknown 
shape by their very nature - but the keys in _SERVER (barring http headers, 
which are already special cased) are known, and have pretty clear definition of 
their meaning.

Is the proposal really suggesting that a developer would still need to do 
`if(!empty($request->server[‘HTTPS’]) && $request->server[‘HTTPS’] !== ‘off’) 
{…}` rather than just providing a `secureTransport` property (or `https` if you 
prefer)? 

One last point, regarding the ‘break out a server specific class’ part. I don’t 
think it’s “wrong” to access these properties from something that is ostensibly 
related to the “current request”, but it feels quite ‘wonky’ to me, the way 
it’s proposed with the full ->server array just copied as-is, AND exposed via 
dedicated properties.




Cheers

Stephen
--

Re: [PHP-DEV] RFC: Server-Side Request and Response Objects (v2)

2020-03-13 Thread Stephen Reay



> On 13 Mar 2020, at 20:39, Paul M. Jones  wrote:
> 
> Hi Stephen,
> 
>> On Mar 13, 2020, at 02:41, Stephen Reay  wrote:
>> 
>> I realise this is just bike shedding - the naming seems quite odd to me.
>> 
>> This extension and the classes it provides are inherently about HTTP 
>> requests made to a php ‘server’, and the response it sends back - and yet 
>> it’s called Server{Request,Response,Buffer} etc…. The “server” part is 
>> superfluous in the context of a php web application, because it’s all 
>> “server” side, and while uncommon it’s not impossible to write *other* types 
>> of network server using PHP.
> 
> I share your feeling here, and I don't think it's bike shedding. The naming 
> is still an open question on the RFC.
> 
> I mentioned some other candidate names here ...
> 
>  https://externals.io/message/108436#108702
> 
> ... and re-reading your comment above, it looks like you saw that one.
> 
> Do you have alternative suggestions or preferences on the names? Or, do you 
> feel that "Request" and "Response" and "ResponseSender" (without any prefixes 
> at all) would be sufficiently obvious?
> 
> Let me know, and thanks for bringing it up!
> 
> 
> -- 
> Paul M. Jones
> pmjo...@pmjones.io
> http://paul-m-jones.com
> 
> Modernizing Legacy Applications in PHP
> https://leanpub.com/mlaphp
> 
> Solving the N+1 Problem in PHP
> https://leanpub.com/sn1php
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

Hi Paul,


TLDR: if you aren’t concerned about the concept of php-initiated outgoing HTTP 
requests, I think `HTTP{Request,Response,Buffer}` is quite clear in terms of 
naming. If you wanted to be more explicit about their purpose (and/or prevent 
possible confusion with either user land or potential future extensions 
handling outgoing requests), `IncomingHTTPRequest` and `OutgoingHTTPResponse` 
are very explicit, if a bit verbose.


I think I did see that message, but I must admit I haven’t followed all the 
responses in the discussion.

Personally I think `HTTP` makes a pretty obvious prefix (I’m not gonna get into 
a capitalisation debate), because these things are explicitly related to HTTP 
request and response messages.

However, that also may be confusing if people expect it to be a construct for 
making outgoing requests. 
The user land implementation I’ve been using ’solves’ this by using a `HTTP` 
namespace, and then provides `Request` and `Response` (for an outgoing - i.e. 
curl - HTTP Request, and the corresponding HTTP Response) objects and then 
`CurrentRequest` and `CurrentResponse` for what your RFC proposes (i.e. the 
active request made to php). As with anything any of us has written, I’m not 
100% sold on ‘Current{Request,Response}` even after writing it, but I think 
it’s at least a little more specific about what they do, when the namespace is 
taken into account.


Cheers

Stephen

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



Re: [PHP-DEV] RFC: Server-Side Request and Response Objects (v2)

2020-03-13 Thread Stephen Reay



> On 11 Mar 2020, at 23:36, Paul M. Jones  wrote:
> 
> Hi all,
> 
> Conversation on this RFC seems to have diminished. As far as I know, I have 
> answered all criticisms/concerns/complaints one way or another.
> 
> So if there are no more questions, and there is no objection, I will plan to 
> call the vote on this proposal some time tomorrow or Friday.
> 
> Thanks to everyone who has participated!
> 
> 
> -- 
> Paul M. Jones
> pmjo...@pmjones.io
> http://paul-m-jones.com
> 
> Modernizing Legacy Applications in PHP
> https://leanpub.com/mlaphp
> 
> Solving the N+1 Problem in PHP
> https://leanpub.com/sn1php
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

Hi Paul,

I appreciate what this is trying to achieve (I think - like others I’ve written 
user land wrappers that achieve similar things, so having a usable 
implementation in core is likely helpful), but - and I realise this is just 
bike shedding - the naming seems quite odd to me.

This extension and the classes it provides are inherently about HTTP requests 
made to a php ‘server’, and the response it sends back - and yet it’s called 
Server{Request,Response,Buffer} etc…. The “server” part is superfluous in the 
context of a php web application, because it’s all “server” side, and while 
uncommon it’s not impossible to write *other* types of network server using PHP.



Cheers

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



Re: [PHP-DEV] [RFC] Attributes v2

2020-03-09 Thread Stephen Reay


> On 9 Mar 2020, at 23:27, Benjamin Eberlei  wrote:
> 
> 
> 
> On Mon, Mar 9, 2020 at 5:18 PM Stephen Reay  <mailto:php-li...@koalephant.com>> wrote:
> 
> 
> > On 9 Mar 2020, at 21:42, Benjamin Eberlei  > <mailto:kont...@beberlei.de>> wrote:
> > 
> > Hi all,
> > 
> > I want to resurrect Dmitrys Attributes RFC that was rejected for 7.1 in
> > 2016 with a few changes, incorporating feedback from the mailing list back
> > then and from talking to previous no voters.
> > 
> > The RFC is at https://wiki.php.net/rfc/attributes_v2 
> > <https://wiki.php.net/rfc/attributes_v2>
> > 
> > A working patch is at https://github.com/beberlei/php-src/pull/2 
> > <https://github.com/beberlei/php-src/pull/2> though
> > work around the details is still necessary.
> > 
> > The RFC contains a section with common criticism and objections to
> > attributes, and I hope to have collected and responded to a good amount
> > already from previous discussions.
> > 
> > There is also a fair amount of implementation detail still up for debate,
> > which is noted in "Open Issues". I have pre-committed to one approach, but
> > listed alternatives there. On these issues I am looking for your feedback.
> > 
> > greetings
> > Benjamin
> 
> Hi Benjamin,
> 
> I can’t comment on the feasibility of this RFC or the patch, but I like the 
> approach it takes to this ‘problem’. I can already imagine a number of 
> ‘nicer’ ways to achieve similar/same results using this, so thanks for taking 
> up the baton!
> 
> My one small query/request is about the `Reflection*::getAttributes` method. 
> Is there a philosophical and/or technological reason for why it can only 
> ‘filter’ the attributes by a single given name, rather than being variadic 
> and filtering against multiple names (i.e. returning those that match any of 
> the given names)? I would imagine many uses (particularly within libraries) 
> would end up wanting to retrieve multiple attribute types they’re aware of 
> all at once, no?
> 
> The name filtering works when using a common base class or interface, so if a 
> library has a class "My\BaseAttribute" and all related attributes extend from 
> it, then in the code you can do:
> 
> $attributes = $reflectionClass->getAttributes(\My\BaseAttribute::class);
> 
> This would return all attributes matching.
> 
> 
> Cheers
> 
> 
> Stephen 


Ah! I had wondered if that type of filtering would be possible (another benefit 
of using classes for the attributes) but I didn’t see it mentioned, and 
wondered if the intention was to leave it to userland. 

Cheers

Stephen

Re: [PHP-DEV] [RFC] Attributes v2

2020-03-09 Thread Stephen Reay



> On 9 Mar 2020, at 21:42, Benjamin Eberlei  wrote:
> 
> Hi all,
> 
> I want to resurrect Dmitrys Attributes RFC that was rejected for 7.1 in
> 2016 with a few changes, incorporating feedback from the mailing list back
> then and from talking to previous no voters.
> 
> The RFC is at https://wiki.php.net/rfc/attributes_v2
> 
> A working patch is at https://github.com/beberlei/php-src/pull/2 though
> work around the details is still necessary.
> 
> The RFC contains a section with common criticism and objections to
> attributes, and I hope to have collected and responded to a good amount
> already from previous discussions.
> 
> There is also a fair amount of implementation detail still up for debate,
> which is noted in "Open Issues". I have pre-committed to one approach, but
> listed alternatives there. On these issues I am looking for your feedback.
> 
> greetings
> Benjamin

Hi Benjamin,

I can’t comment on the feasibility of this RFC or the patch, but I like the 
approach it takes to this ‘problem’. I can already imagine a number of ‘nicer’ 
ways to achieve similar/same results using this, so thanks for taking up the 
baton!

My one small query/request is about the `Reflection*::getAttributes` method. Is 
there a philosophical and/or technological reason for why it can only ‘filter’ 
the attributes by a single given name, rather than being variadic and filtering 
against multiple names (i.e. returning those that match any of the given 
names)? I would imagine many uses (particularly within libraries) would end up 
wanting to retrieve multiple attribute types they’re aware of all at once, no?


Cheers


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



Re: [PHP-DEV] [RFC] anti-coalescing-operator

2019-10-24 Thread Stephen Reay


> On 25 Oct 2019, at 00:33, Dan Ackroyd  wrote:
> 
>> On Thu, 24 Oct 2019 at 18:21, Ken Stanley  wrote:
>> 
>> Since PHP 7.0 brought forward the Null Coalescing Operator (??), writing
>> more succinct code for how to handle null values has been a blessing. But,
>> what about the inverse when you want to do something when a value is not
>> null?
> 
> Hi Ken,
> 
> It may help to give a real world example, rather than a metasyntactic
> one, as I can't immediately see how this would be useful.
> 
> People have been expressing a concern over 'symbol soup' for similar
> ideas. The null colalesce scenario happens frequently enough, that it
> seemed to overcome the hurdle needed for acceptance. Again, giving a
> real world example of what you currently need to do frequently might
> help other people understand the need.
> 
> cheers
> Dan
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

Hi Ken,

This sounds like an alternative approach (for solving the same basic problem) 
to the nullsafe operator discussed a while back, no?
https://wiki.php.net/rfc/nullsafe_calls


Cheers
Stephen 



Re: [PHP-DEV] Internals "camps"

2019-10-11 Thread Stephen Reay



> On 11 Oct 2019, at 13:42, Walter Parker  wrote:
> 
> 
> 
> On Thu, Oct 10, 2019 at 11:11 PM Stephen Reay  wrote:
> 
> 
> > On 11 Oct 2019, at 12:40, Walter Parker  wrote:
> > 
> > G
> > 
> > On Thu, Oct 10, 2019 at 10:10 PM Stephen Reay 
> > wrote:
> > 
> >> 
> >> 
> >>> On 11 Oct 2019, at 02:59, Walter Parker  wrote:
> >>> 
> >>> On Thu, Oct 10, 2019 at 10:36 AM Chase Peeler 
> >> wrote:
> >>> 
> >>>> 
> >>>> 
> >>>> On Thu, Oct 10, 2019 at 1:30 PM Walter Parker 
> >> wrote:
> >>>> 
> >>>>>> 
> >>>>>> 
> >>>>>> No. The compromise is funding a ferry system. Or laying Internet
> >> between
> >>>>>> them. Or a passenger pigeon mail route.
> >>>>>> 
> >>>>>> Sometimes compromise requires deep discussion about the motivations
> >> for
> >>>>>> each side and coming to a lateral, mutually acceptable, solution.
> >>>>>> 
> >>>>>> But we'd rather not discuss motivations and just bicker about the
> >>>>> surface
> >>>>>> results. I.e., argue the X, rather than the Y, of these little XY
> >>>>> problems
> >>>>>> we're solving.
> >>>>>> 
> >>>>>> 
> >>>>>> 
> >>>>> Build a ferry system is alternative to building bridge. I can see that
> >> as
> >>>>> a
> >>>>> compromise, I can also see that as a separate project created to serve
> >>>>> demand after the the bridge project is rejected. Where a ferry system
> >> is
> >>>>> started because there is still demand for transit, just not enough
> >> demand
> >>>>> to pay for a bridge.
> >>>>> 
> >>>>> With respect to the backtick proposal, what is the "ferry" project? Do
> >> we
> >>>>> have to come up with one before we can cancel the "bridge" project or
> >> can
> >>>>> we cancel the "bridge" project on its own merits and then discuss a
> >> future
> >>>>> project that solves the actual underlying problem?
> >>>>> 
> >>>>> "Ferry" projects might be: more/better training on PHP, better
> >>>>> documentation so that the backtick is no longer an "obscure" feature to
> >>>>> those that don't have a shell/Unix/Perl background, tooling to warn
> >> people
> >>>>> when they misuse this feature.
> >>>>> 
> >>>>> 
> >>>>> 
> >>>> To the side that says "There is absolutely no reason we need to go to,
> >> or
> >>>> communicate with, the island in the first place," a ferry project isn't
> >> a
> >>>> compromise. The position of the "anti-bridge" builders isn't because
> >> they
> >>>> are against building bridges - it's because they are against spending
> >>>> resources on attempts to get to the island in the first place. The other
> >>>> side might have valid arguments on why we need to get to the island,
> >> but,
> >>>> just proposing different ways to get there isn't compromising with the
> >> side
> >>>> that doesn't want to go there.
> >>>> 
> >>> 
> >>> I think you may have just created a strawman for the anti-bridge
> >> position.
> >>> There are famous anti-bridge cases, like the Bridge to Nowhere in Alaska
> >>> (if you don't remember, there was an island in Alaska that had 50 people
> >>> and Senator Stevens wanted to replace the existing ferry system with a
> >> $398
> >>> million bridge). People complained about the bridge not because they
> >> wanted
> >>> the islanders to to isolated, but because it was poor use of money when
> >>> there where bigger and more urgent problems.
> >>> 
> >>> To bring this back to PHP, is the backtick really a urgent problem of
> >>> enough magnitude that it justifies the cost of a BC break in unknown
> >> amount
> >>> of PHP code that has been functional for years. If this proposal passes
> >>> (and the follow up to remove it which I'm certain will be pr

Re: [PHP-DEV] Internals "camps"

2019-10-10 Thread Stephen Reay



> On 11 Oct 2019, at 02:59, Walter Parker  wrote:
> 
> On Thu, Oct 10, 2019 at 10:36 AM Chase Peeler  wrote:
> 
>> 
>> 
>> On Thu, Oct 10, 2019 at 1:30 PM Walter Parker  wrote:
>> 
 
 
 No. The compromise is funding a ferry system. Or laying Internet between
 them. Or a passenger pigeon mail route.
 
 Sometimes compromise requires deep discussion about the motivations for
 each side and coming to a lateral, mutually acceptable, solution.
 
 But we'd rather not discuss motivations and just bicker about the
>>> surface
 results. I.e., argue the X, rather than the Y, of these little XY
>>> problems
 we're solving.
 
 
 
>>> Build a ferry system is alternative to building bridge. I can see that as
>>> a
>>> compromise, I can also see that as a separate project created to serve
>>> demand after the the bridge project is rejected. Where a ferry system is
>>> started because there is still demand for transit, just not enough demand
>>> to pay for a bridge.
>>> 
>>> With respect to the backtick proposal, what is the "ferry" project? Do we
>>> have to come up with one before we can cancel the "bridge" project or can
>>> we cancel the "bridge" project on its own merits and then discuss a future
>>> project that solves the actual underlying problem?
>>> 
>>> "Ferry" projects might be: more/better training on PHP, better
>>> documentation so that the backtick is no longer an "obscure" feature to
>>> those that don't have a shell/Unix/Perl background, tooling to warn people
>>> when they misuse this feature.
>>> 
>>> 
>>> 
>> To the side that says "There is absolutely no reason we need to go to, or
>> communicate with, the island in the first place," a ferry project isn't a
>> compromise. The position of the "anti-bridge" builders isn't because they
>> are against building bridges - it's because they are against spending
>> resources on attempts to get to the island in the first place. The other
>> side might have valid arguments on why we need to get to the island, but,
>> just proposing different ways to get there isn't compromising with the side
>> that doesn't want to go there.
>> 
> 
> I think you may have just created a strawman for the anti-bridge position.
> There are famous anti-bridge cases, like the Bridge to Nowhere in Alaska
> (if you don't remember, there was an island in Alaska that had 50 people
> and Senator Stevens wanted to replace the existing ferry system with a $398
> million bridge). People complained about the bridge not because they wanted
> the islanders to to isolated, but because it was poor use of money when
> there where bigger and more urgent problems.
> 
> To bring this back to PHP, is the backtick really a urgent problem of
> enough magnitude that it justifies the cost of a BC break in unknown amount
> of PHP code that has been functional for years. If this proposal passes
> (and the follow up to remove it which I'm certain will be proposed), then
> this is one that leaves people on the island as they will either be stuck
> on an old version of PHP or have to pay to update the code. This pushes the
> costs on them to solve a an existing issue that 20 years after it was
> created and is now an issue because a new generation of coders, unaware of
> history, find the existing syntax not to there taste/a poor design. Why are
> we giving priority to people that haven't taken the time to educate
> themselves over people that did and used programming style that used to
> common?
> 
> 
>> 
>> 
>>> Walter
>>> 
>>> --
>>> The greatest dangers to liberty lurk in insidious encroachment by men of
>>> zeal, well-meaning but without understanding.   -- Justice Louis D.
>>> Brandeis
>>> 
>> 
>> 
>> --
>> Chase Peeler
>> chasepee...@gmail.com
>> 
> 
> 
> -- 
> The greatest dangers to liberty lurk in insidious encroachment by men of
> zeal, well-meaning but without understanding.   -- Justice Louis D. Brandeis

(Sorry, wrong account previously, so didn’t sent to the list)

Hi Walter,

The RFC at the centre of this ridiculous string of analogies is about one 
thing: deprecate (i.e. show a deprecation message) about the backtick operator. 

The RFC specifically doesn’t lay out a timeline for actual removal, it doesn’t 
even hint at “well it’ll just be automatically removed”.

So this RFC breaks *nothing*. 

Yes, it does lead to the situation where it’s likely that a followup RFC will 
propose removing the (then) deprecated feature - perhaps 9.0, perhaps it’ll be 
discussed pre-9.0, and held off until 10.0? But any such change will then 
require *another* vote, with another round of discussions and no doubt 
ridiculous analogies.

And at that time, after several years of warnings about deprecation, Nikita or 
someone else will likely pop up with some analysis of projects to show usage 
*at the time*.

If the only reason to keep a dangerous operator is “well a small subset of 
people use it”, marking it as *deprecated* is how you signal to those 

Re: [PHP-DEV] [RFC] Deprecate Backtick Operator (V2)

2019-10-08 Thread Stephen Reay



> On 9 Oct 2019, at 01:34, Björn Larsson  wrote:
> 
> Den 2019-10-08 kl. 20:22, skrev Stephen Reay:
>> 
>>> On 9 Oct 2019, at 01:08, Björn Larsson  wrote:
>>> 
>>> Den 2019-10-08 kl. 17:49, skrev Stephen Reay:
>>>>> On 8 Oct 2019, at 22:21, Andreas Hennings  wrote:
>>>>> 
>>>>> The problem with the backtick operator syntax is that it is an obscure
>>>>> but innocent-looking syntax for something that can have a huge,
>>>>> perhaps devastating, impact.
>>>>> It is rare enough in the field (as far as regular packages and
>>>>> applications are concerned) that you can spend 5 years working with
>>>>> PHP without ever learning about it. When you see it for the first
>>>>> time, you will be surprised that this actually executes the code like
>>>>> shell_exec(). This kind of surprise can make you shiver, and will
>>>>> leave a bad taste about the language.
>>>>> 
>>>>> The ">>>> application code outside of templates. If we were to design the
>>>>> language from scratch (which we are not), we would surely not require
>>>>> to start each file with a ">>>> the olden days..
>>>>> But removing this in a BC-breaking way would be too costly atm..
>>>>> The only thing I could imagine here is to introduce a distinct type of
>>>>> PHP file which does not require the initial ">>>> further php open or close tags are illegal.
>>>>> 
>>>>> Back to the backtick:
>>>>> If it was just about regular applications and packages, then I think
>>>>> we should get rid of it to prevent the kind of nasty surprise and bad
>>>>> taste I mentioned before.
>>>>> 
>>>>> But as Zeev pointed out, this syntax might be more prevalent in admin
>>>>> scripts, which might have been running on a server for ages and the
>>>>> person who created them might no longer be around. Here the removal
>>>>> would have an unpleasant impact.
>>>>> 
>>>>> The surprise from seeing the backtick operator will differ depending
>>>>> how you see the language: As an application language, as a shell
>>>>> enhancement tool, or as a template engine? PHP can be all three of
>>>>> that, but not every developer will think about it that way.
>>>>> 
>>>>> -- Andreas
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> 
>>>>> On Tue, 8 Oct 2019 at 16:30, Chase Peeler  wrote:
>>>>>> On Sun, Oct 6, 2019 at 9:18 AM Reinis Rozitis  wrote:
>>>>>> 
>>>>>>>> -Original Message-
>>>>>>>> From: Olumide Samson [mailto:oludons...@gmail.com]
>>>>>>>> 
>>>>>>>> it should be deprecated  for exec usage since they both do same thing
>>>>>>> With that logic >>>>>> it
>>>>>>> does the same thing and is hard to find in internet search engines (was 
>>>>>>> in
>>>>>>> some other argument).
>>>>>>> 
>>>>>>> 
>>>>>> And we should deprecate the "print" command, since it's the same as echo.
>>>>>> We should deprecate 'printf', since you can just do 'echo sprintf' and, 
>>>>>> now
>>>>>> that I think about it, we should deprecate sprintf as well, since you can
>>>>>> just use vsprintf. It's a simple change too... sprintf($s,$a,$b,$c) =>
>>>>>> vsprintf($s,[$a,$b,$c]);. I'm just it can be done with just a simple 
>>>>>> regex
>>>>>> search/replace.
>>>>>> 
>>>>>> The fact that are SO many different ways to output text is REALLY 
>>>>>> confusing
>>>>>> for new developers. I think it's imperative we fix all of these items 
>>>>>> RIGHT
>>>>>> NOW. By doing so, I'm sure all the .NET developers that are talking smack
>>>>>> about PHP will suddenly denounce c# and start using PHP as well!
>>>>>> 
>>>>>> 
>>>>>>>> This isn't high cost breaking changes coz it has a verifiable, ready
>>>>>>> alternative to upgrade to without huge Regex searches.
>>>>>>>

Re: [PHP-DEV] [RFC] Deprecate Backtick Operator (V2)

2019-10-08 Thread Stephen Reay



> On 9 Oct 2019, at 01:08, Björn Larsson  wrote:
> 
> Den 2019-10-08 kl. 17:49, skrev Stephen Reay:
>> 
>>> On 8 Oct 2019, at 22:21, Andreas Hennings  wrote:
>>> 
>>> The problem with the backtick operator syntax is that it is an obscure
>>> but innocent-looking syntax for something that can have a huge,
>>> perhaps devastating, impact.
>>> It is rare enough in the field (as far as regular packages and
>>> applications are concerned) that you can spend 5 years working with
>>> PHP without ever learning about it. When you see it for the first
>>> time, you will be surprised that this actually executes the code like
>>> shell_exec(). This kind of surprise can make you shiver, and will
>>> leave a bad taste about the language.
>>> 
>>> The ">> application code outside of templates. If we were to design the
>>> language from scratch (which we are not), we would surely not require
>>> to start each file with a ">> the olden days..
>>> But removing this in a BC-breaking way would be too costly atm..
>>> The only thing I could imagine here is to introduce a distinct type of
>>> PHP file which does not require the initial ">> further php open or close tags are illegal.
>>> 
>>> Back to the backtick:
>>> If it was just about regular applications and packages, then I think
>>> we should get rid of it to prevent the kind of nasty surprise and bad
>>> taste I mentioned before.
>>> 
>>> But as Zeev pointed out, this syntax might be more prevalent in admin
>>> scripts, which might have been running on a server for ages and the
>>> person who created them might no longer be around. Here the removal
>>> would have an unpleasant impact.
>>> 
>>> The surprise from seeing the backtick operator will differ depending
>>> how you see the language: As an application language, as a shell
>>> enhancement tool, or as a template engine? PHP can be all three of
>>> that, but not every developer will think about it that way.
>>> 
>>> -- Andreas
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> On Tue, 8 Oct 2019 at 16:30, Chase Peeler  wrote:
>>>> On Sun, Oct 6, 2019 at 9:18 AM Reinis Rozitis  wrote:
>>>> 
>>>>>> -Original Message-
>>>>>> From: Olumide Samson [mailto:oludons...@gmail.com]
>>>>>> 
>>>>>> it should be deprecated  for exec usage since they both do same thing
>>>>> With that logic >>>> does the same thing and is hard to find in internet search engines (was in
>>>>> some other argument).
>>>>> 
>>>>> 
>>>> And we should deprecate the "print" command, since it's the same as echo.
>>>> We should deprecate 'printf', since you can just do 'echo sprintf' and, now
>>>> that I think about it, we should deprecate sprintf as well, since you can
>>>> just use vsprintf. It's a simple change too... sprintf($s,$a,$b,$c) =>
>>>> vsprintf($s,[$a,$b,$c]);. I'm just it can be done with just a simple regex
>>>> search/replace.
>>>> 
>>>> The fact that are SO many different ways to output text is REALLY confusing
>>>> for new developers. I think it's imperative we fix all of these items RIGHT
>>>> NOW. By doing so, I'm sure all the .NET developers that are talking smack
>>>> about PHP will suddenly denounce c# and start using PHP as well!
>>>> 
>>>> 
>>>>>> This isn't high cost breaking changes coz it has a verifiable, ready
>>>>> alternative to upgrade to without huge Regex searches.
>>>>> 
>>>>> Since `` are used for literal strings (for poorly chosen reserved words as
>>>>> field, table names (which happens from time to time)) in MySQL (multiline)
>>>>> queries I doubt there is a simple way to distinguish and replace 
>>>>> everything
>>>>> to exec().
>>>>> 
>>>>> rr
>>>>> 
>>>>> --
>>>>> PHP Internals - PHP Runtime Development Mailing List
>>>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>>>> 
>>>>> 
>>>> --
>>>> Chase Peeler
>>>> chasepee...@gmail.com
>>> -- 
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: http://www.php.net/unsub.php
&

Re: [PHP-DEV] [RFC] Deprecate Backtick Operator (V2)

2019-10-08 Thread Stephen Reay



> On 8 Oct 2019, at 22:21, Andreas Hennings  wrote:
> 
> The problem with the backtick operator syntax is that it is an obscure
> but innocent-looking syntax for something that can have a huge,
> perhaps devastating, impact.
> It is rare enough in the field (as far as regular packages and
> applications are concerned) that you can spend 5 years working with
> PHP without ever learning about it. When you see it for the first
> time, you will be surprised that this actually executes the code like
> shell_exec(). This kind of surprise can make you shiver, and will
> leave a bad taste about the language.
> 
> The " application code outside of templates. If we were to design the
> language from scratch (which we are not), we would surely not require
> to start each file with a " the olden days..
> But removing this in a BC-breaking way would be too costly atm..
> The only thing I could imagine here is to introduce a distinct type of
> PHP file which does not require the initial " further php open or close tags are illegal.
> 
> Back to the backtick:
> If it was just about regular applications and packages, then I think
> we should get rid of it to prevent the kind of nasty surprise and bad
> taste I mentioned before.
> 
> But as Zeev pointed out, this syntax might be more prevalent in admin
> scripts, which might have been running on a server for ages and the
> person who created them might no longer be around. Here the removal
> would have an unpleasant impact.
> 
> The surprise from seeing the backtick operator will differ depending
> how you see the language: As an application language, as a shell
> enhancement tool, or as a template engine? PHP can be all three of
> that, but not every developer will think about it that way.
> 
> -- Andreas
> 
> 
> 
> 
> 
> 
> On Tue, 8 Oct 2019 at 16:30, Chase Peeler  wrote:
>> 
>> On Sun, Oct 6, 2019 at 9:18 AM Reinis Rozitis  wrote:
>> 
 -Original Message-
 From: Olumide Samson [mailto:oludons...@gmail.com]
 
 it should be deprecated  for exec usage since they both do same thing
>>> 
>>> With that logic >> does the same thing and is hard to find in internet search engines (was in
>>> some other argument).
>>> 
>>> 
>> And we should deprecate the "print" command, since it's the same as echo.
>> We should deprecate 'printf', since you can just do 'echo sprintf' and, now
>> that I think about it, we should deprecate sprintf as well, since you can
>> just use vsprintf. It's a simple change too... sprintf($s,$a,$b,$c) =>
>> vsprintf($s,[$a,$b,$c]);. I'm just it can be done with just a simple regex
>> search/replace.
>> 
>> The fact that are SO many different ways to output text is REALLY confusing
>> for new developers. I think it's imperative we fix all of these items RIGHT
>> NOW. By doing so, I'm sure all the .NET developers that are talking smack
>> about PHP will suddenly denounce c# and start using PHP as well!
>> 
>> 
>>> 
 This isn't high cost breaking changes coz it has a verifiable, ready
>>> alternative to upgrade to without huge Regex searches.
>>> 
>>> Since `` are used for literal strings (for poorly chosen reserved words as
>>> field, table names (which happens from time to time)) in MySQL (multiline)
>>> queries I doubt there is a simple way to distinguish and replace everything
>>> to exec().
>>> 
>>> rr
>>> 
>>> --
>>> PHP Internals - PHP Runtime Development Mailing List
>>> To unsubscribe, visit: http://www.php.net/unsub.php
>>> 
>>> 
>> 
>> --
>> Chase Peeler
>> chasepee...@gmail.com
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

If a server has “scripts” that work now, and there’s no admin involved 
maintaining it (i.e. updating said scripts) - how is this going to be a 
problem? If there’s no one to maintain the script, there’s equally no one to 
update to an entirely new version of PHP either.

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



Re: [PHP-DEV] [RFC] Deprecate Backtick Operator (V2)

2019-10-05 Thread Stephen Reay
Hi!


> On 6 Oct 2019, at 02:44, Stanislav Malyshev  wrote:
> 
> Hi!
> 
>> Like I said, I can see arguments both ways, but use as a command 
>> substitution operator is hardly a universal thing.
> 
> Nobody said it's "universal thing”.

I never claimed anyone said it’s universal. I simply said it isn’t universal.

> Virtually nothing is "universal
> thing" among over 9000 programming languages that exist. I just claimed
> it's a common thing which reasonably experienced user have high chance
> of encountering and recognizing.

Ok, so of those 9000 programming languages how many use it for shell execution?
So far I’m aware of PHP, Perl, Ruby and Shell. I would argue that this means 
those (first three) languages likely have a common inspiration from Shell, not 
that the feature is “common” amongst programming languages.

> Arguing that non-universality would be the reason to remove syntax from
> PHP is like arguing we should remove the use of whitespace because some
> languages have significant whitespace (like Python) and you can't google
> whitespace (especially if you don't know the word "whitespace") so
> clearly this is super-confusing and should be removed.
> 

Again, I wasn’t saying non-universality was “the reason” to remove the syntax. 
My point was that if *you* claimed it’s “common” amongst programming languages 
- and ignored that it’s used for *other, less dangerous* constructs in many 
more languages than it’s used for shell execution.

> I don't mean this as a personal criticism on the RFC author, who clearly
> took some thought about it and is entitled to his own opinions, but
> arguments like this look a bit ridiculous to me. We have tons of stuff
> to improve in PHP without messing with things that aren't broken and
> don't need any improvement at all, and will have high BC costs.
> -- 
> Stas Malyshev
> smalys...@gmail.com
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

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



Re: [PHP-DEV] [RFC] Deprecate Backtick Operator (V2)

2019-10-05 Thread Stephen Reay



> On 5 Oct 2019, at 11:34, Stanislav Malyshev  wrote:
> 
> Hi!
> 
>> https://wiki.php.net/rfc/deprecate-backtick-operator-v2
> 
> Reading the justifications, I must say I do not find them very
> convincing. Specifically:
> 
>> * Alternative functions exist which are more descriptive, easily
> understood, and more readily searchable (for example, many common Google
> searches omit the “`” token entirely when searching).
> 
> It is very easy to understand `` since it has analogues in other script
> languages, also searching for "php backtick" easily leads to PHP manual.
> 
>> Backticks are visually easily confused with single quotes despite
> exhibiting radically different behaviour.
> 
> In my font they are not even close. This sounds like calling to stop
> using letter O because it looks like 0. Maybe if it's a problem - use
> one of the many available programmer's fonts which solve such problems
> easily.
> 
>> It could be considered unintuitive that single quoted strings do not
> support variable substitution, but single backticks do.
> 
> This sounds like a non-sequitur - why a different syntactic construct
> would behave exactly like single quote?
> 
>> It could be considered unintuitive that backticks already rely on the
> safe-mode and disabled-function settings for shell_exec
> 
> Safe mode is dead, so I don't think it makes sense to address this.
> 
> In general, the justifications look a bit thin, and very far from
> passing the bar that is necessary to justify BC break. Please note that
> "you have to read the manual to know all the options for a function" is
> not something unacceptable and certainly not grounds for removing the
> function.
> 
> -- 
> Stas Malyshev
> smalys...@gmail.com
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 


Hi Stas, all,

I’m not overly for or against this change - I can see arguments both ways, but 
please keep in mind that the “other languages” argument works both ways:

In php, shell/similar, ruby and perl, backticks are command substitution. This 
surely due to shared influence.

In plenty of other languages they do very different things, from string 
literals, to interpolation/templates, escaping, identifier quoting, or even 
comments.


Like I said, I can see arguments both ways, but use as a command substitution 
operator is hardly a universal thing.


Cheers


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



Re: [PHP-DEV] Changing fundamental language behaviors

2019-09-13 Thread Stephen Reay



> On 13 Sep 2019, at 15:28, Mark Randall  wrote:
> 
> the notion of
> 
> declare(sloppy=1);
> 
> Has already been jokingly proposed,

Who ever  said it was a joke proposal? :-P

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



Re: [PHP-DEV] Changing fundamental language behaviors

2019-09-12 Thread Stephen Reay


> On 13 Sep 2019, at 01:07, Chase Peeler  wrote:
> 
> 
> 
> On Thu, Sep 12, 2019 at 1:58 PM Stephen Reay  wrote:
> 
> > On 13 Sep 2019, at 00:41, Chase Peeler  wrote:
> > 
> > On Thu, Sep 12, 2019 at 1:33 PM Matthew Brown 
> > wrote:
> > 
> >> What if Java suddenly said that all properties are suddenly private, and
> >>> can only be accessed through getter/setter methods?
> >>> 
> >> 
> >> If Java announced that the next major version was to make the change after
> >> 95% of userland developers favoured it and over 2/3rds of their internals
> >> team did, I'd think "huh ok I guess they have good reasons".
> >> 
> >> For 20 years people have developed code based on that feature. It was
> >>> never considered an error, and often not even considered bad practice
> >> 
> >> 
> >> You seem to be arguing against *ever* changing something that a majority
> >> once thought was good, and fundamental to a given system. Lots of things
> >> fall into that category - restricting voting to men, segregation, etc.
> >> 
> > 
> > Now you're just being silly. I actually don't have a problem with
> > fundamental language change, provided that the positives that are gained
> > far outweigh the negatives of the BC break and there is no other way to
> > accomplish those positives without such a BC break.
> > 
> > There are a myriad of ways to achieve what the RFC attempts to achieve.
> > Whether that's analysis tools, custom error handlers, detailed code
> > reviews, etc. Nothing prevents anyone from initializing all of their
> > variables or performing as many sanity checks on a variable before
> > accessing it as they want to. Nothing in the RFC is required to implement
> > other new functionality like enums, union types, variable typing, etc.
> > 
> > I also think it's a bit of a stretch to compare something like variable
> > initialization with things that denied people their basic human rights.
> > 
> > -- 
> > Chase Peeler
> > chasepee...@gmail.com
> 
> 
> Please, will someone arguing against making use of undefined variables a 
> higher severity, explain to me why the same argument was not made for use of 
> undefined constants, for which the RFC to deprecate/remove support, passed 
> 41:0.
> 
> How is one undefined symbol more acceptable than another undefined symbol?
> 
> First of all, I wasn't as involved with this list back then as I was now. 
> However, I can see a fundamental difference in the two. Not needing to 
> initialize variables just for the sake of initializing them (e.g. just doing 
> $i++ without $i=0 before it) is something that is going to behave as expected 
> almost all of the time. When it doesn't, you can easily initialize $i to a 
> non-zero value, or, you can initialize it to zero if you want - it doesn't 
> hurt anything.
> 
> An undefined constant getting converted to a string, though, is much less 
> likely to be the intended behavior. String literals are required to be in 
> quotes. Constants can never be in quotes. Assuming that the token that looks 
> like a constant, but can't be because the constant didn't exist, so, we'll 
> pretend it's a string even though it doesn't match the proper syntax for such 
> a token is drastically different than assuming the variable you are 
> incrementing that wasn't initialized is 0, or, that the variable you are 
> concatenating to, but wasn't initialized, is an empty string. 
> 
> Finally, let's pretend that the undefined constants RFC was a horrible RFC 
> that shouldn't have passed. The fact that it did has no impact on whether or 
> not this RFC should pass. 
> 
> -- 
> Chase Peeler
> chasepee...@gmail.com


Apologies if you thought I was specifically replying to you Chase, I simply hit 
reply-all to the last message I had.


The RFC I referred to explicitly describes the use-case for the (mis-)feature 
it removed:

> The current behaviour appears to have been added as an attempt to guess the 
> user's intention, and continue gracefully.

Sounds familiar, doesn’t it? “If I write $foo++ and $foo is undefined, it 
should know what I mean”.

> The value of keeping the current behaviour would be for programs written to 
> deliberately take advantage of it. In particular, I have seen sample code of 
> the form $_GET[bar] where bar is taken to be the string key bar. 

So, it clearly was (ab)used.


IMO this also flies in the face of the “we can’t change behaviour” argument - 
bare word strings were added around 20 years ago, and yet not a single person 
thought it worthwhile voting against the deprecation and removal of this 
behaviour?

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



Re: [PHP-DEV] Changing fundamental language behaviors

2019-09-12 Thread Stephen Reay


> On 13 Sep 2019, at 00:41, Chase Peeler  wrote:
> 
> On Thu, Sep 12, 2019 at 1:33 PM Matthew Brown 
> wrote:
> 
>> What if Java suddenly said that all properties are suddenly private, and
>>> can only be accessed through getter/setter methods?
>>> 
>> 
>> If Java announced that the next major version was to make the change after
>> 95% of userland developers favoured it and over 2/3rds of their internals
>> team did, I'd think "huh ok I guess they have good reasons".
>> 
>> For 20 years people have developed code based on that feature. It was
>>> never considered an error, and often not even considered bad practice
>> 
>> 
>> You seem to be arguing against *ever* changing something that a majority
>> once thought was good, and fundamental to a given system. Lots of things
>> fall into that category - restricting voting to men, segregation, etc.
>> 
> 
> Now you're just being silly. I actually don't have a problem with
> fundamental language change, provided that the positives that are gained
> far outweigh the negatives of the BC break and there is no other way to
> accomplish those positives without such a BC break.
> 
> There are a myriad of ways to achieve what the RFC attempts to achieve.
> Whether that's analysis tools, custom error handlers, detailed code
> reviews, etc. Nothing prevents anyone from initializing all of their
> variables or performing as many sanity checks on a variable before
> accessing it as they want to. Nothing in the RFC is required to implement
> other new functionality like enums, union types, variable typing, etc.
> 
> I also think it's a bit of a stretch to compare something like variable
> initialization with things that denied people their basic human rights.
> 
> -- 
> Chase Peeler
> chasepee...@gmail.com


Please, will someone arguing against making use of undefined variables a higher 
severity, explain to me why the same argument was not made for use of undefined 
constants, for which the RFC to deprecate/remove support, passed 41:0.

How is one undefined symbol more acceptable than another undefined symbol?
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Reclassifying engine warnings

2019-09-12 Thread Stephen Reay


> On 12 Sep 2019, at 14:40, Claude Pache  wrote:
> 
>> Le 10 sept. 2019 à 15:31, Nikita Popov  a écrit :
>> 
>> On Wed, Aug 28, 2019 at 11:33 AM Nikita Popov  wrote:
>> 
>>> Hi internals,
>>> 
>>> I think it's time to take a look at our existing warnings & notices in the
>>> engine, and think about whether their current classification is still
>>> appropriate. Error conditions like "undefined variable" only generating a
>>> notice is really quite mind-boggling.
>>> 
>>> I've prepared an RFC with some suggested classifications, though there's
>>> room for bikeshedding here...
>>> 
>>> https://wiki.php.net/rfc/engine_warnings
>>> 
>>> Regards,
>>> Nikita
>>> 
>> 
>> Heads up: This RFC may go to vote tomorrow.
>> 
>> Nikita
> 
> 
> I have objections to those two reclassifications:
> 
> * Undefined offset: %d — Notice → Warning
> * Undefined index: %d — Notice → Warning
> 
> 
> From experience, having to dutifully initialise each and every key in an 
> array is burdensome. I understand the rationale of enforcing that in some 
> coding standard; but whether those particular missing index should be 
> considered as unexpected (therefore deserving a Warning) is mostly a question 
> of coding style.
> 
> This is in principle a similar issue as using uninitialised variables, which, 
> as noted in this thread, is a perfectly accepted coding pattern in some 
> languages (the issue being distinct from *undeclared* variables). I say “in 
> principle”, because a perfectly reasonable coding style may choose to enforce 
> initialisation of variables, but not of array keys.
> 
> PHP has the advantage of supporting various coding styles. We should give the 
> opportunity to the users to say declaratively (and precisely) what, in their 
> coding style, is considered as acceptable, e.g.
> 
> declare(
>uninitialized_variables: error
>uninitilalized_index: none
> );
> 
> of course, possibly at a package-level declare. That would, for example, 
> enable people to place legacy code in lax mode and chose a stricter mode for 
> new code, even letting the precise notion of strictness vary with fashion 
> without having to review working code written two years ago.
> 
> That said, as long as those issues are handled as errors (as in: 
> set_error_handler()) rather than exceptions, one may write a proper error 
> handler that does the distinction (I do that). However, an error handler has 
> the disadvantage of being global, making difficult the integration of code 
> written with differing coding standards.
> 
> —Claude
> 
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 


I’ve seen a number of people that have concerns about PHP throwing actual 
errors (as opposed to notices) because they try to use a variable/offset that 
doesn’t exist, and of course there is often a proposal to have a declare 
statement or something similar, to allow their “code style” to run without 
errors.


So, my proposal to the situation is to introduce a single declare that solves 
that problem, once and for all.


declare(sloppy=1);


This would suppress any errors about undefined variables, array offsets, would 
reverse the “bare words" change when encountering an undefined constant, etc. 
Heck, for good measure this mode could even re-implement register_globals and 
magic_quotes, because why not? 



If you want to write sloppy code, that is entirely your prerogative, but please 
just own it for what it is, and stop pretending that it’s some herculean task 
to either define variables/offsets first; or check if they’re defined; or use 
an appropriate method to access them that specifically allows for undefined 
variables/offsets (i.e. the ?? and ??= operators)

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



Re: [PHP-DEV] Union Class Types (was Union Type (singular) straw man proposal)

2019-09-08 Thread Stephen Reay
> On 9 Sep 2019, at 02:11, Mike Schinkel  wrote:
> 
> I did not realize you were proposing a different solution, too. Sorry I 
> missed that.
> 

I didn’t mean in terms of an actual proposal, more so identifying what I think 
would be more intuitive (mostly based on what others have 
discussed/mentioned/proposed previously) in what I thought was a similar 
‘problem space’ - but it turns out we’re talking about quite different things 
anyway!

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



Re: [PHP-DEV] Union Class Types (was Union Type (singular) straw man proposal)

2019-09-08 Thread Stephen Reay
own object.  You can do this:
> 
> $local_guid = $guid instanceof \Guid ? $guid : null;
> 
> But it seems ro me so much more elegant — and readable — if you could just do 
> this:
> 
> $local_guid = $guid->toGuid();
> 
>> If a method has a signature using a ‘Union Class type’ which has a `types 
>> GUID|string` keyword, you _still_ have to verify that the result of value() 
>> (or toString()) is in fact a valid GUID
> 
> Yes, and no.   In the proposal $guid->toGuid() would return null, so no need 
> to have to check if you can use the presence of null as an indicator.
> 
> But if you did need to check that is why the proposal includes the 
> $guid->type() method, that works well with `switch` statements; something we 
> do not otherwise have in PHP because of the distinction between `gettype()` 
> vs. `get_class()`.  The proposal's approach means less potentially confusing 
> boilerplate logic.
> 
> As an aside, turning classes into first-class language elements would be 
> super powerful and I would really like to see that, but that feels like too 
> big of an ask for the PHP community so I have been thinking it would not be 
> worth the effort to create such a proposal.
> 
>> because the calling site has just given you a string, and the ‘magic’ has 
>> boxed that up into an object.. so you can call a method to get back the same 
>> value, right?
> 
> Not sure I am following that question unless you are just confirming that 
> when $guid->type() === 'string' that is_string( $guid->toString()) is true?
> 
> One benefit to this approach I realize my proposal did not emphasize as that 
> of a union becoming a first-class entity, with the ability to extend the base 
> union when not using anonymous unions, and to add to or modify its methods. 
> This is something we won't get if we simply use type aliases in Nikitia's 
> proposal.
> 
> But in hindsight maybe I am trying to propose types as first-class objects 
> after all, using a use-case where there would be real tangible benefits vs. 
> the general case?  
> 
> What I think I am recognizing is that while this functionality works 
> brilliantly in Go it may not be of the nature that makes sense for the PHP 
> world.
> 
> Anyway, thank you again for following up.  If I am unable to reply to any 
> responses for the next week+ it will be because I am focusing on the 
> conference I will be attending.
> 
> -Mike
> 
> 
>> - because the calling site has just given you a string, and the ‘magic’ has 
>> boxed that up into an object.. so you can call a method to get back the same 
>> value, right?
> 
> 
>> On Sep 8, 2019, at 9:56 AM, Stephen Reay  wrote:
>> 
>> Hi Mike,
>> 
>> Sorry for the delay responding to this.
>> 
>> So I would agree that magic methods are generally a less-obvious solution, 
>> and interfaces are generally a better alternatives for new solutions.
>> 
>> In terms of how I would see it working - the same way that implementing the 
>> `Iterator` (or `IteratorAggregate`) interfaces allows a class to be iterated 
>> using foreach, my thought (and im pretty sure I’ve seen a similar concept 
>> suggested by others on internals before too) was that e.g. when passing an 
>> object that implements the `stringable` interface to a type that expects a 
>> string, it would convert it to such, even in strict mode, without warning or 
>> error. The same could be used for any built in basic type (scalars and 
>> arrays).
>> 
>> Heck, a `Money` class could implement `stringable` (return a formatted 
>> string), `intable` (return the amount in the minor currency unit - i.e. 
>> cents for most dollar currencies)  and `floatable` (return an approximation 
>> of the amount as major.minor.
>> 
>> Again - I know those names are not fantastic, but you get the idea.
>> 
>> 
>> For classes, I don’t know what the solution would be - and I’m honestly less 
>> clear on how much demand there is for that level of predictable, 
>> developer-controlled automatic casting anyway.
>> 
>> I’m almost certain I’ve thus-far missed some point of what you were trying 
>> to convey, but I _think_ I understand now… sort of.
>> 
>> Are you suggesting that rather than (or as well as?), as per Nikita’s 
>> proposal,  where a function to handle a date/time may for example accept an 
>> integer or an instance of \DateTimeInterface and thus be given a variable of 
>> either type and need to do whatever appropriate checks to use it, instead it 
>> would set a type hint of e.g `DateOrTimestamp` which is a class defining 
>> that it’s either an int or \Date

Re: [PHP-DEV] Union Class Types (was Union Type (singular) straw man proposal)

2019-09-08 Thread Stephen Reay


> On 6 Sep 2019, at 17:21, Mike Schinkel  wrote:
> 
> Hi Stephen,
> 
> Thank you again for the reply.
> 
>> and wasn’t really built for that purpose AFAIK, but in ‘weak’ mode (i.e. no 
>> strict_types=1) it would be invoked if the destination type specified a 
>> string. I was implying that this behaviour could be expanded both with other 
>> integer casting methods and to allow it to work in ’strict’ mode with an 
>> approach similar to how php works now, rather than suggesting that it works 
>> right now.
> 
> I guess I was asking how you would see that working and not referring to 
> existing implementation.  
> 
> After working through a variety of examples I can't find one where a smart 
> compiler can deduce that a __toString() can map to a string type.  But that 
> only works for types where we have a magic class, right?  We don't have 
> __toInt(), __toFloat(), __toArray() (yet), __toObject(), etc. And there was a 
> lot of dissent on the __toArray() RFC if I am not mistaken?
> 
> Also, what about unions of class instances?  I don't think it is realistic to 
> propose we'd have a __to*() magic method for every classname that is in our 
> application, e.g. __toFoo(), __toBar(), etc.?  if not, how would we handle it 
> the general case of converting to a specific type?
> 
> What I was proposing would have provided a single consistent model to handle 
> typing. It is probably not perfect and there is probably a better way.  But 
> magic methods don't seem to be flexible enough to provide a consistent method 
> across all potential type. Unless I am missing something?
> 
> 
>> It’s true you can’t cast to an object (besides stdclass) - but again, my 
>> point was not so much that the functionality already exist, more so that 
>> your proposal seems to ignore any history of how php handles this type of 
>> thing,
> 
> I don't think it is fair to say the proposal ignored PHP's history. I 
> considered PHP's history at length, but I did not find anything in the 
> current history that seems to be to be able to handle the use-case elegantly. 
> 
>>  and is - to my eyes - very foreign in its approach.
> 
> I certainly can't argue with this. Your perceptions are indeed yours, and 
> they are relevant.
> 
> The questions I ask though are:
> 
> 1. Can we find a way to address the concern that is not foreign to PHP 
> developers?
> 2. If we cannot find a way, is there a harm to introducing new concepts to 
> PHP developers?
> 
> I'm happy either way. I'm just interested in seeing the language moved 
> forward.
> 
> BTW, I guess I don't see it as foreign because of my experience with some 
> other languages.
> 
> 
>> Also, your proposal seems to only work for an object that effectively 
>> represents a single value (otherwise how does `setValue/getValue` work 
>> without a property name?) - I’m not sure how many examples there are of 
>> classes that just wrap literally a single value into something else?
> 
> I think maybe I did not make the crux of the proposal clear.  I was not 
> proposing any given class should be handled with these mechanisms. I was 
> proposing a mechanism to allow defining of bespoke classes for unions, and 
> then other mechanisms to handle them for passing and receiving parameters, 
> and assigning values to types properties. 
> 
> I am also not sure how the mechanisms I proposed would even be relevant to 
> other classes. Can you think of examples I am missing?
> 
>> With ArrayObject, Exception etc (I assume you mean, when a class extends 
>> one) the behaviour is well understood - while the internals of how it works 
>> may differ, it’s conceptually no different than extending another user land 
>> class. Concepts like late static binding, the parent class, etc -how does 
>> for example an overriden method call the ‘built-in’ method? Or are the 
>> built-in methods effectively ‘final’? 
> 
> I feel like I can say exactly the same thing about the proposed union classes 
> with the exception that I would need to say "the behaviour will be well 
> understood."  The point is that PHP has some classes and interfaces with 
> magic that us mere mortals in userland are not empowered to use.  The goals 
> of this proposal is to scope out just a tiny bit more of that magic.
> 
> But everything else about how the classes work would work exactly the same as 
> classes currently work, at least for any existing behavior.  (Selected new 
> behavior defined in the proposal would be exclusive to union classes, but 
> that is orthogonal to your stated concern.)
> 
> Per the proposal an overridden method would be no different than an 
> overridden method in any other class, unless there are edge-cases I am 
> missing?
> 
> Methods could potentially be final if the community adopted this proposal and 
> that was preferred, but I think it would be better to allow them to be 
> overridden.
> 
> 
>> If your goal is to allow a typed property/parameter to accept an object and 
>> “know” how to convert it 

Re: [PHP-DEV] Union Class Types (was Union Type (singular) straw man proposal)

2019-09-06 Thread Stephen Reay


> On 6 Sep 2019, at 14:37, Mike Schinkel  wrote:
> 
> Hi Stephen,
> 
> Thank you for taking the time to comment.
> 
>> It seems like you’re trying to allow for type conversions in a predictable 
>> manner,
> 
> Correct.
> 
>> but in a very different way than php already does that with built in types 
>> and interfaces
> 
> I proposed the best approach I could envision given the constraints of the 
> scenario.  
> 
> I elaborated in my first comment in my reply to Kalle; can you look at that 
> reply rather than have me repeat it?
> 
> OTOH, it would be wonderful it you could envision an approach that could use 
> types and/or interfaces and still have an approaching syntax when using 
> unions in an anonymous context when declaring parameters to a function or 
> method.
> 
> 
>> (__toString, the proposed __toArray, plus the various (de)serialiser options)
> 
> Unless I misunderstand, __toString() and __toArray() do not provide type 
> safety at the call site without casting.  
> 
> And since you cannot cast an object type in PHP — e.g. (Number)$myobject — it 
> seems magic methods are not suitable for task here?
> 
> Or can you envision a different alternative?
> 
> 
>> Your proposal seems to imply some kind of automatic method generation by the 
>> engine itself (or the examples are all missing that boilerplate??) which is 
>> very non obvious to me and I think would be to others too.
> 
> Hmm.  I was thinking of it being a lot like ArrayObject, Exception, Closure, 
> Generator,   in that you get methods built-in.
> 
> I wonder if the lack of obviousness would simply require a one-time learning, 
> or if it would be problematic for people on an ongoing basis?
> 
> Digressing, as I said in other messages I proposed this as much as a 
> discussion starter as anything.  So I am excited to discuss any alternate 
> approach others might suggest.
> 
>> From my perspective a more obvious solution for this type of thing would be 
>> a set of interfaces to define that a class can be safely cast to another 
>> type when used with typed properties/arguments/returns.
> 
> How would interfaces work in this context and for this use-case?  
> 
> I tried to leverage interfaces while writing the proposal as I know many 
> people prefer enhancements be packaged as interfaces, but I could not 
> envision how they could be applied to meet the goals here. 
> 
> And to reiterated my proposals goals they were to establish a concise syntax 
> that leverages existing language features for better type safety when 
> multiple types can correctly be passed as parameters and/or assigned to 
> properties.
> 
> 
>> (or magic methods to match __toString but I know they’re less preferred by 
>> some these days) 
> 
> Is it possible to get type safety from using __toString() in a manner as I am 
> struggling to envision one?
> 
>> tthat a class can be safely cast to another type when used with typed 
>> properties/arguments/returns.
> 
> What about for types where there is no syntax for casting?  Such as when one 
> ones to union instances of a class?
> 
> Anxious to hear your additional thoughts, if you have time.  
> 
> But either way, I very much appreciate the time you've taken to comment.
> 
> -Mike
> 
> 
>> On Sep 6, 2019, at 2:18 AM, Stephen Reay  wrote:
>> 
>> Hi Mike,
>> 
>> From a userland perspective I don’t really “get” your proposal.
>> 
>> It seems like you’re trying to allow for type conversions in a predictable 
>> manner, but in a very different way than php already does that with built in 
>> types and interfaces (__toString, the proposed __toArray, plus the various 
>> (de)serialiser options)
>> 
>> Your proposal seems to imply some kind of automatic method generation by the 
>> engine itself (or the examples are all missing that boilerplate??) which is 
>> very non obvious to me and I think would be to others too.
>> 
>> 
>> From my perspective a more obvious solution for this type of thing (and I’m 
>> not necessarily sure I’d use the feature myself to be honest) would be a set 
>> of interfaces (or magic methods to match __toString but I know they’re less 
>> preferred by some these days) to define that a class can be safely cast to 
>> another type when used with typed properties/arguments/returns.
>> 
>> 
>> Cheers
>> 
>> Stephen
> 

Hi Mike,

I did read your other replies before responding.


__toString is much older than type hints (and especially scalar type hints) in 
php and wasn’t really built for that purpose AFAIK, but in ‘weak’ mode (i.e. no 
str

Re: [PHP-DEV] Union Class Types (was Union Type (singular) straw man proposal)

2019-09-06 Thread Stephen Reay


> On 6 Sep 2019, at 11:22, Mike Schinkel  wrote:
> 
> Hi Côme,
> 
>> This example is really confusing me more than anything else.
> 
> 
> Thank you very much for your feedback.  You illustrated perfectly why I 
> should not have produced that proposal in haste.
> 
> Your confusion was due to my first draft errors, which thanks to your 
> feedback I have hopefully had a chance to correct. I effectively rewrote and 
> extended the proposal which you should be able to find at the same URL:
> 
> https://gist.github.com/mikeschinkel/50aec7094f5643223d28674639f9f117 
> 
> 
> I would be greatly appreciative if you could give is a second look.
> 
> 
>> All in all I do not understand the benefits of this approach compared to 
>> Nikita’s RFC.
> 
> I have moved the benefits to the beginning of the document and expanded the 
> list I elaborate on. 
> 
> Hopefully they will be clear now?
> 
> 
> -Mike Schinkel
> 
> P.S. Someone graciously emailed me off list and mentioned that my comments 
> regarding Nikitia sounded like a criticism. If anyone else thought the same — 
> and especially Nikita — please understand I was attempting to praise him but 
> trying to do so in a humorous manner. 
> 
> As the person who emailed me made me realize, sometimes my humor may not 
> translate via a mailing list and especially not for those who are not native 
> English speakers. So I will do my best to avoid using humor on the list in 
> the future.  
> 
> To be clear, I am in awe of Nikita and both his abilities and efforts to 
> benefit the PHP community and greatly appreciate his efforts. I hope that 
> clarifies my earlier intent.
> 
> 
>> On Sep 5, 2019, at 4:51 AM, Côme Chilliet  wrote:
>> 
>> Why does the class Number in the example has a $number property and use 
>> $this->number->value() rather than $this->value() ?
>> 
>> What is the difference between its getNumber method and its value method?
>> 
>> Is $this->number and $this->number->number pointing the same object or is 
>> $this->number->number NULL?
>> 
>> This example is really confusing me more than anything else.
>> 
>> The "function showNumber" example is using $this->number instead of $number 
>> I think.
>> 
>> All in all I do not understand the benefits of this approach compared to 
>> Nikita’s RFC.
>> What does this allow you to do that you cannot do without?
>> 
>> Côme
> 

Hi Mike,

From a userland perspective I don’t really “get” your proposal.

It seems like you’re trying to allow for type conversions in a predictable 
manner, but in a very different way than php already does that with built in 
types and interfaces (__toString, the proposed __toArray, plus the various 
(de)serialiser options)

Your proposal seems to imply some kind of automatic method generation by the 
engine itself (or the examples are all missing that boilerplate??) which is 
very non obvious to me and I think would be to others too.


From my perspective a more obvious solution for this type of thing (and I’m not 
necessarily sure I’d use the feature myself to be honest) would be a set of 
interfaces (or magic methods to match __toString but I know they’re less 
preferred by some these days) to define that a class can be safely cast to 
another type when used with typed properties/arguments/returns.


Cheers

Stephen

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



Re: [PHP-DEV] [RFC] Reclassifying engine warnings

2019-08-28 Thread Stephen Reay



> On 28 Aug 2019, at 23:04, Chase Peeler  wrote:
> 
> On Wed, Aug 28, 2019 at 11:37 AM Kalle Sommer Nielsen  wrote:
> 
>> Hi
>> 
>> Den ons. 28. aug. 2019 kl. 17.54 skrev Chase Peeler >> :
>>> You going to come and fix the issues? It's an internal application and
>>> most of those messages are coming from legacy areas of the code which are
>>> mainly "it works, so leave it alone" things. Instead of going back and
>>> spending time trying to fix those boondoggles, we invest the time of our
>>> developers (there are 2 others besides myself) into building new features
>>> that help our business grow. Time permitting, we try and update some of
>> the
>>> legacy areas, but, we usually find it's a better investment to just
>> rebuild
>>> them at that point.
>>> 
>>> Bottom line is that we live with the not-so-good stuff so that we can
>> focus
>>> on adding new great stuff. The not-so-good stuff isn't holding us back,
>> and
>>> trying to fix things like undeclared variables would have absolutely ZERO
>>> positive effect on our business, which uses this application every day.
>> If
>>> I went to our executive team and said "Can we delay that new scheduling
>>> system that will really help our business so I can go back and update
>> code
>>> to get rid of these undeclared variable notices?" I'd get laughed at!
>>> 
>>> Like I've said before - can we please stop pretending we understand
>>> everyone else's situation? Maybe my situation is unique. My gut tells me
>> it
>>> might be unique among people on this list, but, that it's actually pretty
>>> common among the myriad of developers out there which never get involved
>> in
>>> these discussions.
>> 
>> I'm sorry, but like Mark Randall has already pointed out then this is
>> a classic example of technical depth. At one point you must choose,
>> "Do I want to upgrade to the latest version of PHP or do I want to fix
>> the issues which is caused by the technical depth in my stack?".
> 
> 
> I don't get to make that choice, though. The executives do.
> 

I thought you said you were the tech lead? Part of building an application is 
maintaining it.

And honestly, your claim about “it’s technical debt that is no longer growing” 
is incorrect. Like financial debt, technical debt will accrue “interest” - in 
this case, it’s going to prevent you from upgrading to a newer release of PHP.


Believe me I understand your situation, in terms of code very well. This RFC, 
the short open tags one, and probably some more before 8.0 is frozen will all 
affect an active client project I’m tech lead for.

In every case, I’m still for the change: because making the change means one 
less type of sloppy-but-“working” code I’m going to see and have to task 
someone to fix in the future.

If you can’t currently schedule some percentage of development time to 
maintaining/fixing existing code, (you *did* say you’re the tech lead, right?) 
this RFC makes your job easier then: you have an external control factor that 
your executives (who apparently make technical decisions?) cannot argue 
against, and cannot deny.

> 
>> I get
>> it, writing new code is always more fun, it really is,
> 
> 
> It's not about what is more fun. It's about what is necessary for our
> company to grow, move forward, and survive. What good is fixing old code if
> our company withers away while we do it since we aren't supporting them
> with the new things the need to move forward? We aren't building things on
> top of that old code, so, the new things we build aren't accruing
> additional technical debt as a result of the existing technical debt.
> 


Well presumably a working, secure application/website is necessary for the 
company to just survive, let alone grow.


> I have
>> previously worked with companies with that same attitude that "we'll
>> fix it later", but at one point that becomes such a burden and if your
>> management doesn't believe in putting in resources to actual
>> maintenance of your infrastructure, then I'm sorry but it does not
>> sound like a healthy place to be (no offense meant).
>> 
>> That's not exactly our attitude. If something is really broken, we fix it.
> We are not focusing our limited resources on updating things that currently
> work just because we don't like how they were built. Most of it was done
> 10-15 years ago, and, even if we had the resources to update it, we'd be
> better off just rebuilding it altogether. Let me focus on the technical
> debt that has high interest, instead of the debt that doesn't really impact
> anything, like undeclared variables.

Exactly how many instances of undeclared variables do you have? This talks 
about PHP8, so its expected 7.4 due late November  this year will be the last 
version that doesn’t error on your code. 7.4 will have 2 years of full support 
and a further year of security support. Can you *really* not find the time to 
fix undeclared variables in the next 39 months?

> 
>> Right now your argument is merely trying to 

Re: [PHP-DEV] [RFC] Namespace-scoped declares, again

2019-08-13 Thread Stephen Reay



> On 14 Aug 2019, at 00:05, Rowan Collins  wrote:
> 
>> On 13/08/2019 12:01, Mark Randall wrote:
>>> On 13/08/2019 10:02, Rowan Collins wrote:
>>> I really like this approach. It allows a package definition file to exist, 
>>> without either the language or the header of each file having to define its 
>>> location.
>> 
>> #
>> # File: /lib/company/project1/a/b/MyClass.php
>> #
>> 
>> > 
>>   declare_import(company[:label]);
>> 
>>   namespace company/project1/a/b;
>> 
>>   ...
>> 
>> 
>> #
>> # File: /lib/company/__nsmeta.php
>> #
>> 
>> > 
>>   namespace company;
>> 
>>   namespace_declare [:label] {
>> strict_types=1;
>> strict_operators=1;
>> upgrade_errors_to_exceptions=E_ALL;
>>   }
>> 
>>   final class __nsmeta {
>> /* does nothing except be findable by the autoloader */
>> /* and defaults to private constructor so it can't be used */
>>   }
> 
> 
> This seems to be more complicated than Nicolas's version, and involve much 
> more special magic, like the name __nsmeta, and the class that does nothing. 
> I'm also not clear on how you're picturing the relationship between 
> namespaces and packages.
> 
> The way I understood the suggestion, you'd end up with something more like 
> this, which feels much simpler and cleaner:
> 
> #
> # File: /lib/company/project1/a/b/MyClass.php
> #
> 
>  
> declare(package=company/project1);
> // or with a new keyword
> package company/project1;
> 
> namespace company/project1/a/b;
> 
> ...
> 
> 
> #
> # File: /lib/company/project1.php
> #
> 
>  
> namespace company;
> 
> class project1 extends \PHP\Package {
> public function getParserDirectives() {
> return [
> 'strict_types' => 1,
> 'strict_operators' => 1,
> 'upgrade_errors_to_exceptions' => E_ALL
> ];
>  }
> }
> 
> Regards,
> 
> -- 
> Rowan Collins
> [IMSoP]
> 
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
> 

I think this approach is easier to follow (less magic) but has a (small) 
potential for conflict with existing code that may then require renaming or 
more (eg if a class existed with that proposed name, and is either a singleton 
and/or already extends another class).

Is it feasible to instead require the class implements an interface that 
defines a static method? 


Building on that, could the concept of “do something to initialise this 
package” be made more generic: when a file declares it’s a member of a given 
package, the static method on the class that matches the package name is 
called, and it’s up to the developer what it does in that method. That would of 
course also then require a new function to set the declares with package scope 
to be useful for this particular problem,  but it also allows more control and 
power for the concept of packages in general.

Cheers

Stephen 

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



  1   2   >