On Mon, Mar 11, 2024, at 4:13 PM, Bruce Weirdan wrote:
> On Tue, Feb 27, 2024 at 6:22 PM Bruce Weirdan <weir...@gmail.com> wrote:
>>
>> Hi Larry and others
>>
>> On Fri, Feb 23, 2024 at 12:57 AM Larry Garfield <la...@garfieldtech.com> 
>> wrote:
>> >
>> >
>> > I've added an FAQ section explaining why the Python/JS approach wouldn't 
>> > really work.  To be clear, Ilija and I spent 100+ hours doing research and 
>> > design before we started implementation (back in mid-late 2022).  We did 
>> > seriously consider the JS-style syntax, but in the end we found it created 
>> > more problems than it solves.  For the type of language PHP is (explicit 
>> > typed properties), doing it on the property itself is a much cleaner 
>> > approach.
>>
>>
>> The section you added [1] seems to focus on having both `public string
>> $fistName` and `public function get/set firstName():string`, and how
>> it's hard to keep types and visibility in sync. But I'm not sure if
>> you considered making properties and accessors mutually exclusive. I
>> mean the following:
>>
>> ```php
>> class Person
>> {
>>     public string $firstName;      // compile time error, setter/getter 
>> defined
>>
>>     public function __construct(private string $first, private string $last) 
>> {}
>>
>>     public function get firstName(): string       // compile time
>> error, property defined
>>     {
>>         return $this->first . " " . $this->last;
>>     }
>>
>>     public function set firstName(string $value): void     // compile
>> time error, property defined
>>     {
>>         [$this->first, $this->last] = explode(' ', $value);
>>     }
>> }
>> ```
>>
>> This seems to address most of the counterpoints you listed, to some degree:
>>
>> > What is the property type of the $firstName property?
>>
>> Well, you propose to allow wider write-types yourself, so the question
>> would apply there as well. But presumably, the property type is its
>> read type - so whatever getter returns.
>>
>> > but there's nothing inherent that forces, public string $firstName, get 
>> > firstName()s return and set firstName()s parameter to be the same. Even if 
>> > we could detect it as a compile error, it means one more thing that the 
>> > developer has to keep track of and get right, in three different places.
>>
>> With mutually exclusive accessors and properties it becomes just two
>> places. And yes, accessor consistency would need to be checked at
>> compile time. But the same can be said for the widening of write type
>> you proposed.
>>
>> > What about visibility? Do the get/set methods need to have the same 
>> > visibility as the property?
>>
>> When there's no property the question becomes moot.
>>
>> > If not, does that become a way to do asymmetric visibility?
>>
>> Yes.
>>
>> > What about inconsistency between the method's visibility and the property 
>> > visibility? How is that handled?
>>
>> There's no inconsistency when there's no property. Accessor visibility
>> can be different - allowing the asymmetric visibility you wanted to
>> implement in your other RFC.
>>
>> > How do you differentiate between virtual and non-virtual properties?
>>
>> This one is hard to answer without asking another question: why would
>> you need to? Does the requirement to know it stem from engine
>> implementation details, or do you need as a person writing code in
>> PHP?
>>
>> > For non-virtual properties, if you need to triple-enter everything, we're 
>> > back to constructors pre-promotion. Plus, the accessor methods could be 
>> > anywhere in the class, potentially hundreds of lines away. That means just 
>> > looking at the property declaration doesn't tell you what its logic is; 
>> > the logic may be on line 960, which only makes keeping its type/visibility 
>> > in sync with the property harder.
>>
>> Forbidding property declaration reduces that to double. The rest is
>> mostly stylistic and can be said about traditional
>> (non-constructor-promoted) properties as well.
>>
>> Now this approach naturally has some open questions, foremost about
>> inheritance. But we probably don't need to go into those details if
>> you already explored this way and found some technical obstacles. If
>> you did, it would probably make sense to list them in the FAQ section.
>>
>> [1] 
>> https://wiki.php.net/rfc/property-hooks#why_not_pythonjavascript-style_accessor_methods
>
>
> Resending this since I've never got a reply and it's quite possible
> the message got lost due to mail list issues.

What you suggest might be possible, but it still runs into the problem of 
backed properties.  Plain methods work fine for virtual properties, which makes 
sense for Python and JS as they don't have pre-defined properties.  Once the 
language has predefined properties, a method-centric approach leaves a lot more 
to be manual, which makes it more work to achieve the same end.  And then what 
if you want hooks on a property used in constructor promotion?  Or if you 
cannot declare a property and similarly named hook-method, how do you add hooks 
to a plain property in a child class, something generated code like ORMs will 
most likely want to do?

Even if it could be done, what would be the advantage?  Other than "it looks 
like JS", I don't really see any benefit, just a lot of complexity we'd have to 
sort out and find the edge cases on all over again, and basically rewrite the 
whole RFC.  Unless someone can show why the property-centric approach is 
fundamentally broken (and given that we have a successful implementation 
already I think that is unlikely), there's little reason to revisit the 
fundamentals of the RFC at this point.

(And, mind you, the above discussion does not demonstrate that a method-centric 
approach is in fact equally feasible.  At best, there are probably ways to make 
most things work, but without actually doing it there's no way to be sure it 
wouldn't run into a brick wall somewhere.)

--Larry Garfield

Reply via email to