Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-04-01 Thread Rowan Tommins [IMSoP]

On 29/03/2024 18:14, Robert Landers wrote:

When generating proxies for existing types, you often need to share
some state between the proxies. To do that, you put static
methods/properties on the proxy class and hope to the PHP Gods that
nobody will ever accidentally name something in their concrete class
with the name you chose for things. To help with that, you create some
kind of insane prefix.



Separating static and non-static methods wouldn't solve this - the 
concrete class could equally add a static method with the same name but 
a different signature, and your generated proxy would fail to compile.


In fact, exactly the same thing happens with instance methods in testing 
libraries: test doubles have a mixture of methods for configuring mock / 
spy behaviour, and methods mimicking or forwarding calls to the real 
interface / class. Those names could collide, and require awkward 
workarounds.


In a statically typed language, a concrete class can have two methods 
with the same name, but different static types, e.g. when explicitly 
implementing interfaces. In a "duck typing" system like PHP's, that's 
much trickier, because a call to $foo->bar() doesn't have a natural way 
to choose which "bar" is meant.




I'd much rather see static and non-static methods being able to
have the same name


Allowing this would lead to ambiguous calls, because as others have 
pointed out, :: doesn't always denote a static call. Consider this code:


class Test {
  public function test() { echo 'instance test'; }
  public static function test() { echo 'static test'; }
}

class Test2 extends Test {
  public function runTest() { parent::test(); }
}

(new Test2)->runTest();

Currently, this can call either of the test() methods if you comment the 
other out: https://3v4l.org/5HlPE https://3v4l.org/LBALm


If both are defined, which should it call? And if you wanted the other, 
how would you specify that? We would need some new syntax to remove the 
ambiguity.



Regards,

--
Rowan Tommins
[IMSoP]


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-04-01 Thread Rowan Tommins [IMSoP]

On 29/03/2024 02:39, 하늘아부지 wrote:

I created a wiki for __callStatic related issues.
Please see:
https://wiki.php.net/rfc/complete_callstatc_magic



Hi,

Several times in the discussion you have said (in different words) 
"__callStatic is called for instance methods which are private or 
protected", but that is not how it is generally interpreted.


If you are calling a method from outside the class, as far as you're 
concerned only public methods exist; private methods are, by definition, 
hidden implementation details. This is more obvious in languages with 
static typing, where if you have an instance of some interface, only the 
methods on that interface exist; the concrete object might actually have 
other methods, but you can't access them.


That is what is meant by "inaccessible": __call and __callStatic are 
called for methods which, as seen from the current scope, *do not exist*.



You could still argue that static context is like a different scope, or 
a different statically typed interface - as far as that context is 
concerned, only static methods exist. But that's also not a common 
interpretation, for (at least) two reasons:


Firstly, there is no syntax in PHP which specifically marks a static 
call - Foo::bar() is used for both static calls, and for forwarding 
instance calls, most obviously in the case of parent::foo().


Secondly, until PHP 8, marking a method as static was optional; an error 
was only raised once you tried to access $this in a context where it 
wasn't defined. In PHP 4, this was correct code; in PHP 5 and 7, it 
raised diagnostics (first E_STRICT, later E_DEPRECATED) but still ran 
the method:


class Foo {
    function bar() {
    echo 'Hello, World!';
    }
}
Foo::bar();


I think that's part of the reason you're getting negative feedback: to 
you, the feature seems like an obvious extension, even a bug fix; but to 
others, it seems like a complete change to how static calls are interpreted.


Regards,

--
Rowan Tommins
[IMSoP]


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-31 Thread 하늘아부지
2024년 4월 1일 (월) 오전 2:31, Larry Garfield 님이 작성:

> On Fri, Mar 29, 2024, at 6:12 PM, 하늘아부지 wrote:
>
> >> It would be more accurate to say "calling non-static methods in a
> static-like manner is common *in Laravel*
> >
> > It might be correct to say that this is specific to Laravel. The
> > problem, however, is that Laravel is used so extensively that it cannot
> > be ignored.
>
> True, but as someone else noted, Laravel already has a workaround in place
> for this.  WordPress is orders of magnitude more popular than Laravel, but
> we don't generally design the language to work "the WordPress way," because
> that is well-recognized as a not-good way to work.
>
> Popularity matters, but quality matters more.
>
> > There's a point of embarrassing me. It's as if my proposal, if
> > accepted, would create problems that did not previously exist. Yet, the
> > existence of `__callStatic` already allows for the issues you've
> > pointed out to occur. You can already write code like
> > `foo::bar()::baz()` with the current PHP. The possibility of more
> > problems arising could indeed be true. In that sense, I understand your
> > point.
>
> To be clear: I have no interest or desire to embarrass you personally.  I
> have never met you before so have no opinion about you one way or another,
> and trust the feeling is mutual.  That you're interested in improving PHP
> is to your credit, and I thank you for that.
>
> However, that is separate from the proposal itself, which for reasons
> stated I think is not a good one.  That should not reflect on you
> personally in any way, and is explicitly not intended as such.  Certainly
> I've had enough of my proposals rejected around here. :-)
>
> --Larry Garfield
>

I understand.
I didn't assume my proposal would be accepted without question. I just
started because I hate doing nothing.

Daddyofsky


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-31 Thread Larry Garfield
On Fri, Mar 29, 2024, at 6:12 PM, 하늘아부지 wrote:

>> It would be more accurate to say "calling non-static methods in a 
>> static-like manner is common *in Laravel* 
>
> It might be correct to say that this is specific to Laravel. The 
> problem, however, is that Laravel is used so extensively that it cannot 
> be ignored.

True, but as someone else noted, Laravel already has a workaround in place for 
this.  WordPress is orders of magnitude more popular than Laravel, but we don't 
generally design the language to work "the WordPress way," because that is 
well-recognized as a not-good way to work.

Popularity matters, but quality matters more.

> There's a point of embarrassing me. It's as if my proposal, if 
> accepted, would create problems that did not previously exist. Yet, the 
> existence of `__callStatic` already allows for the issues you've 
> pointed out to occur. You can already write code like 
> `foo::bar()::baz()` with the current PHP. The possibility of more 
> problems arising could indeed be true. In that sense, I understand your 
> point.

To be clear: I have no interest or desire to embarrass you personally.  I have 
never met you before so have no opinion about you one way or another, and trust 
the feeling is mutual.  That you're interested in improving PHP is to your 
credit, and I thank you for that.

However, that is separate from the proposal itself, which for reasons stated I 
think is not a good one.  That should not reflect on you personally in any way, 
and is explicitly not intended as such.  Certainly I've had enough of my 
proposals rejected around here. :-)

--Larry Garfield


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-30 Thread Robert Landers
On Sat, Mar 30, 2024 at 1:06 AM 하늘아부지  wrote:
>
>
>
> 2024년 3월 30일 (토) 오전 2:15, Robert Landers 님이 작성:
>>
>> On Fri, Mar 29, 2024 at 3:41 AM 하늘아부지  wrote:
>> >
>> > Hello.
>> >
>> > I created a wiki for __callStatic related issues.
>> > Please see:
>> > https://wiki.php.net/rfc/complete_callstatc_magic
>> >
>> > I look forward to your interest and advice.
>> >
>> > Best Regards.
>> > Daddyofsky
>>
>> Hey there,
>>
>> Some general feedback:
>>
>> The RFC is a bit hard for me to follow, for example:
>>
>> > However, the IDE cannot find active method, and the Go to Definition 
>> > feature cannot be used.
>>
>> This sounds like a bug or feature request with your IDE, not a problem with 
>> PHP.
>>
>> > This code is very clear, aside from the fact that the method is not static.
>>
>> Clear to whom? As a developer this looks downright confusing. I can't
>> even guess what the actual behavior is. If you call a non-static
>> method statically, its currently an error. Why would this not be an
>> error?
>>
>> > The IDE recognizes active methods well and the Go to definition feature 
>> > also works properly.
>>
>> What is stopping the IDE to taking you to the __callStatic method?
>> That would be the correct behavior IMHO, not the implementation for
>> instance methods.
>>
>> > Even if there are only a few core methods, it cannot be made into a single 
>> > file.
>>
>> There is nothing stopping you from putting multiple classes in a file.
>>
>> > As can be seen in the above examples, the code becomes clearer, and 
>> > navigation through the IDE works much better.
>>
>> I completely disagree. It mixes concerns and makes spaghetti code into
>> incomprehensible code. Also, maybe you should take up IDE navigation
>> with your IDE?
>>
>> > Instead of throwing an error when a non-static public method is called 
>> > statically, the _ _callStatic method should be invoked.
>>
>> I completely agree with this, btw. Your examples could use some work
>> and shows all the reasons why it shouldn't call __callStatic(). A real
>> life example, that has nothing to do with a specific framework:
>>
>> When generating proxies for existing types, you often need to share
>> some state between the proxies. To do that, you put static
>> methods/properties on the proxy class and hope to the PHP Gods that
>> nobody will ever accidentally name something in their concrete class
>> with the name you chose for things. To help with that, you create some
>> kind of insane prefix. If __callStatic() were called ALWAYS in a
>> static context, even if a non-static method exists, then collisions
>> would literally be impossible. But at that point, why can't I just
>> write:
>>
>> class Test {
>>   public static function test(): string { return "hello world"; }
>>   public function test(): int { return random_int(); }
>> }
>>
>> ??? I feel like this is your real RFC and should be allowed if we're
>> allowed to __callStatic() to instance methods. I don't think it makes
>> sense to have one without the other, and then what you want with
>> __callStatic() comes naturally, instead of this weird and confusing
>> RFC.
>>
>>
>> Robert Landers
>> Software Engineer
>> Utrecht NL
>
>
> Hello.
>
> I'm not very familiar with documentation. It would be helpful if you could 
> suggest how to fix the problematic parts.
>
> Using the example of the IDE meant to illustrate that it should be intuitive 
> enough for the IDE to find it directly.
>
> Even currently, `__callStatic` is called in cases of non-static methods that 
> are not public methods. `__callStatic` already acts as a rule-breaker. It 
> seems like there's a desire for the magic method to be named as such without 
> actually causing much magic. The current `__callStatic` is like a magician 
> who can use high-level magic to hit targets behind doors or invisible targets 
> but can't use basic magic to hit a visible door.
>
> While it's good that the PHP kindly notifies errors, I think it would also be 
> beneficial to provide users with options to do other things, specifically 
> when they intentionally use `__callStatic`. That's the core point of this 
> proposal.
>
> If there are better examples or ways to explain, I would appreciate learning 
> about them.
>
> Daddyofsky

My main issue with the RFC comes down to the fact that it suggests
that this is valid:

// https://3v4l.org/0ufkt
class Test {
  public function test() {}
  public static function test() {}
}

Having two functions with the same name, one static and one non-static
is (currently) an error. Allowing callStatic to break this rule
without being able to write the above code, feels inconsistent. While
PHP is full of inconsistencies, adding more of them isn't the right
way. I'd much rather see static and non-static methods being able to
have the same name -- in which case it would make sense for callStatic
to work as described in the RFC.

Robert Landers
Software Engineer
Utrecht NL


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread Morgan

On 2024-03-30 13:06, 하늘아부지 wrote:


Even currently, `__callStatic` is called in cases of non-static methods 
that are not public methods. `__callStatic` already acts as a 
rule-breaker.




I think the problem here is a confusion based on the idea that there is 
necessarily some direct correspondence between method names and strings 
passed to __callStatic. It's like confusing URLs with file paths.


The fact that an object *may* have a private method named "foo" doesn't 
have any bearing on whether classname::foo() invokes __callStatic('foo') 
or not. The existence or otherwise of such methods in the class is 
irrelevant. __callStatic receives a string, and what it does with that 
string is entirely up to whoever is writing it.




class First {
protected static function test(): string {
return "Calling First::test\n";
}
}

class Second extends First
{
public static function __callStatic(string $name, array $args): string {
return "Calling callStatic::$name\n";
}

public static function pass(): string {
return Second::test(); // The inherited method
}
}


echo Second::pass();
echo Second::test(); // Not the inherited method


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread 하늘아부지
2024년 3월 30일 (토) 오전 2:15, Robert Landers 님이 작성:

> On Fri, Mar 29, 2024 at 3:41 AM 하늘아부지  wrote:
> >
> > Hello.
> >
> > I created a wiki for __callStatic related issues.
> > Please see:
> > https://wiki.php.net/rfc/complete_callstatc_magic
> >
> > I look forward to your interest and advice.
> >
> > Best Regards.
> > Daddyofsky
>
> Hey there,
>
> Some general feedback:
>
> The RFC is a bit hard for me to follow, for example:
>
> > However, the IDE cannot find active method, and the Go to Definition
> feature cannot be used.
>
> This sounds like a bug or feature request with your IDE, not a problem
> with PHP.
>
> > This code is very clear, aside from the fact that the method is not
> static.
>
> Clear to whom? As a developer this looks downright confusing. I can't
> even guess what the actual behavior is. If you call a non-static
> method statically, its currently an error. Why would this not be an
> error?
>
> > The IDE recognizes active methods well and the Go to definition feature
> also works properly.
>
> What is stopping the IDE to taking you to the __callStatic method?
> That would be the correct behavior IMHO, not the implementation for
> instance methods.
>
> > Even if there are only a few core methods, it cannot be made into a
> single file.
>
> There is nothing stopping you from putting multiple classes in a file.
>
> > As can be seen in the above examples, the code becomes clearer, and
> navigation through the IDE works much better.
>
> I completely disagree. It mixes concerns and makes spaghetti code into
> incomprehensible code. Also, maybe you should take up IDE navigation
> with your IDE?
>
> > Instead of throwing an error when a non-static public method is called
> statically, the _ _callStatic method should be invoked.
>
> I completely agree with this, btw. Your examples could use some work
> and shows all the reasons why it shouldn't call __callStatic(). A real
> life example, that has nothing to do with a specific framework:
>
> When generating proxies for existing types, you often need to share
> some state between the proxies. To do that, you put static
> methods/properties on the proxy class and hope to the PHP Gods that
> nobody will ever accidentally name something in their concrete class
> with the name you chose for things. To help with that, you create some
> kind of insane prefix. If __callStatic() were called ALWAYS in a
> static context, even if a non-static method exists, then collisions
> would literally be impossible. But at that point, why can't I just
> write:
>
> class Test {
>   public static function test(): string { return "hello world"; }
>   public function test(): int { return random_int(); }
> }
>
> ??? I feel like this is your real RFC and should be allowed if we're
> allowed to __callStatic() to instance methods. I don't think it makes
> sense to have one without the other, and then what you want with
> __callStatic() comes naturally, instead of this weird and confusing
> RFC.
>
>
> Robert Landers
> Software Engineer
> Utrecht NL
>

Hello.

I'm not very familiar with documentation. It would be helpful if you could
suggest how to fix the problematic parts.

Using the example of the IDE meant to illustrate that it should be
intuitive enough for the IDE to find it directly.

Even currently, `__callStatic` is called in cases of non-static methods
that are not public methods. `__callStatic` already acts as a rule-breaker.
It seems like there's a desire for the magic method to be named as such
without actually causing much magic. The current `__callStatic` is like a
magician who can use high-level magic to hit targets behind doors or
invisible targets but can't use basic magic to hit a visible door.

While it's good that the PHP kindly notifies errors, I think it would also
be beneficial to provide users with options to do other things,
specifically when they intentionally use `__callStatic`. That's the core
point of this proposal.

If there are better examples or ways to explain, I would appreciate
learning about them.

Daddyofsky


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread 하늘아부지
2024년 3월 30일 (토) 오전 1:21, Larry Garfield 님이 작성:

> On Fri, Mar 29, 2024, at 3:33 PM, 하늘아부지 wrote:
> > 2024년 3월 29일 (금) 오후 10:21, Larry Garfield 님이 작성:
> >> On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote:
> >> > Hello.
> >> >
> >> > I created a wiki for __callStatic related issues.
> >> > Please see:
> >> > https://wiki.php.net/rfc/complete_callstatc_magic
> >> > I look forward to your interest and advice.
> >>
> >> I am firmly against this proposal.
> >>
> >> I think my objection boils down to this line in the RFC:
> >>
> >> > Of course, calling non-static methods in a static-like manner can be
> confusing, but in modern PHP, it has already become common practice.
> >>
> >> I would argue this statement is false.  Calling non-static methods in a
> static-like manner is confusing, which is why in modern PHP one should
> never do that, and respect that static and non-static methods exist in a
> separate universe.  Static methods are methods *on a type*.  Non-static
> methods are methods *on an instance*.  Those are not the same thing.[1]
> >>
> >> It would be more accurate to say "calling non-static methods in a
> static-like manner is common *in Laravel*," where the badly-named "facades"
> system serves as a poorly designed, hard to debug, hard to test, archaic
> alternative to using dependency injection.  While there may have once been
> an argument that DI was "too hard" for simple cases a decade ago or more
> (though even then I think it was a bade trade-off), the combination of
> auto-wiring DI Containers (which Laravel pioneered in PHP) and constructor
> promotion (introduced in PHP 8.0, 3.5 years ago.) completely eliminates
> those arguments.  The level of effort to do actual DI today is trivially
> small, and the benefits over magic hidden globals are massive.
> >>
> >> Laravel Facades are a relic of an older time best avoided, even in
> Laravel projects.  (I am far from the only person to argue this; many even
> within Laravel's inner community make this argument.)
> >>
> >> Adding features to the language that seemingly exist only to make that
> particular buggy hack easier to do is a step backwards, and I would argue
> harmful for the language.  On the contrary, I would favor going the other
> direction: Calling a static method as though it were non-static currently
> works, and I would support making that an error, to further emphasize that
> static and non-static methods are not interchangeable.
> >>
> >> [1] https://peakd.com/hive-168588/@crell/cutting-through-the-static
> >>
> >> --Larry Garfield
> >
> > Thank you for your feedback.
> > I agree that static and non-static should be distinct, which is a given.
> >
> > There are a few points I'd like to make.
> >
> > First, my proposed RFC is not about allowing non-static methods to be
> > used statically. Although all my examples use `::`, they internally
> > operate on an instance. Inside `__callStatic`, an instance is created
> > and used for operations.
> >
> > Second, as already possible through the `__callStatic` method,
> > non-static methods can be called as if they were static (as mentioned,
> > this does not mean they operate statically). For protected and private
> > methods, the `__callStatic` function is invoked even for non-static
> > methods. This might not be to everyone's liking, and to others, it
> > might be a favorite feature. It might operate differently from the
> > initial intention when `__callStatic` was introduced. However, I don't
> > think this is necessarily a bad thing. Isn't it developers who bring to
> > life ingenious ideas that were unforeseen?
>
> Developers also bring to life horrible monstrosities that are an afront to
> all that is holy.  I am a developer.  It's what we do. :-)  Especially when
> VC money is involved.
>
> Not all "innovation" is good.
>
> > Third, as you can see from my examples, what I propose could be a
> > solution to the current issues. Since it does not work for public
> > methods while it does for protected and private ones, it has led to
> > code becoming more obscure and layered through facade-like patterns.
> > It's like taking a longer route because the road is blocked, or
> > creating a dog door because the main door is closed.
>
> It simplifies a practice that should not be a practice in the first
> place.  That's not a net-win.
>
> > From the perspective of those who develop the PHP language itself, my
> > proposal might not be appealing. However, I believe from the user's
> > standpoint, my proposal could lead to more convenient and cleaner
> > coding practices. Didn't PHP start as a language meant to be
> > user-friendly?
>
> I don't actually work on the PHP engine, I just write RFC text for other
> people; I have ~25 years of experience writing user-space PHP.  And no,
> anything involving stealth globals via statics is the opposite of "more
> convenient and cleaner."
>
> --Larry Garfield
>

Hi.

> It would be more accurate to say "calling non-static methods in a
static-like 

Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread Robert Landers
On Fri, Mar 29, 2024 at 3:41 AM 하늘아부지  wrote:
>
> Hello.
>
> I created a wiki for __callStatic related issues.
> Please see:
> https://wiki.php.net/rfc/complete_callstatc_magic
>
> I look forward to your interest and advice.
>
> Best Regards.
> Daddyofsky

Hey there,

Some general feedback:

The RFC is a bit hard for me to follow, for example:

> However, the IDE cannot find active method, and the Go to Definition feature 
> cannot be used.

This sounds like a bug or feature request with your IDE, not a problem with PHP.

> This code is very clear, aside from the fact that the method is not static.

Clear to whom? As a developer this looks downright confusing. I can't
even guess what the actual behavior is. If you call a non-static
method statically, its currently an error. Why would this not be an
error?

> The IDE recognizes active methods well and the Go to definition feature also 
> works properly.

What is stopping the IDE to taking you to the __callStatic method?
That would be the correct behavior IMHO, not the implementation for
instance methods.

> Even if there are only a few core methods, it cannot be made into a single 
> file.

There is nothing stopping you from putting multiple classes in a file.

> As can be seen in the above examples, the code becomes clearer, and 
> navigation through the IDE works much better.

I completely disagree. It mixes concerns and makes spaghetti code into
incomprehensible code. Also, maybe you should take up IDE navigation
with your IDE?

> Instead of throwing an error when a non-static public method is called 
> statically, the _ _callStatic method should be invoked.

I completely agree with this, btw. Your examples could use some work
and shows all the reasons why it shouldn't call __callStatic(). A real
life example, that has nothing to do with a specific framework:

When generating proxies for existing types, you often need to share
some state between the proxies. To do that, you put static
methods/properties on the proxy class and hope to the PHP Gods that
nobody will ever accidentally name something in their concrete class
with the name you chose for things. To help with that, you create some
kind of insane prefix. If __callStatic() were called ALWAYS in a
static context, even if a non-static method exists, then collisions
would literally be impossible. But at that point, why can't I just
write:

class Test {
  public static function test(): string { return "hello world"; }
  public function test(): int { return random_int(); }
}

??? I feel like this is your real RFC and should be allowed if we're
allowed to __callStatic() to instance methods. I don't think it makes
sense to have one without the other, and then what you want with
__callStatic() comes naturally, instead of this weird and confusing
RFC.


Robert Landers
Software Engineer
Utrecht NL


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread Aleksander Machniak

On 29.03.2024 14:03, Larry Garfield wrote:

On the contrary, I would favor going the other direction: Calling a static 
method as though it were non-static currently works, and I would support making 
that an error, to further emphasize that static and non-static methods are not 
interchangeable.


It's side-tracking, but I'd like to note that I would vote against such 
an idea.


I don't have a strong opinion on the proposed RFC yet.

--
Aleksander Machniak
Kolab Groupware Developer[https://kolab.org]
Roundcube Webmail Developer  [https://roundcube.net]

PGP: 19359DC1 # Blog: https://kolabian.wordpress.com


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread Larry Garfield
On Fri, Mar 29, 2024, at 3:33 PM, 하늘아부지 wrote:
> 2024년 3월 29일 (금) 오후 10:21, Larry Garfield 님이 작성:
>> On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote:
>> > Hello.
>> >
>> > I created a wiki for __callStatic related issues.
>> > Please see:
>> > https://wiki.php.net/rfc/complete_callstatc_magic
>> > I look forward to your interest and advice.
>> 
>> I am firmly against this proposal.
>> 
>> I think my objection boils down to this line in the RFC:
>> 
>> > Of course, calling non-static methods in a static-like manner can be 
>> > confusing, but in modern PHP, it has already become common practice. 
>> 
>> I would argue this statement is false.  Calling non-static methods in a 
>> static-like manner is confusing, which is why in modern PHP one should never 
>> do that, and respect that static and non-static methods exist in a separate 
>> universe.  Static methods are methods *on a type*.  Non-static methods are 
>> methods *on an instance*.  Those are not the same thing.[1]
>> 
>> It would be more accurate to say "calling non-static methods in a 
>> static-like manner is common *in Laravel*," where the badly-named "facades" 
>> system serves as a poorly designed, hard to debug, hard to test, archaic 
>> alternative to using dependency injection.  While there may have once been 
>> an argument that DI was "too hard" for simple cases a decade ago or more 
>> (though even then I think it was a bade trade-off), the combination of 
>> auto-wiring DI Containers (which Laravel pioneered in PHP) and constructor 
>> promotion (introduced in PHP 8.0, 3.5 years ago.) completely eliminates 
>> those arguments.  The level of effort to do actual DI today is trivially 
>> small, and the benefits over magic hidden globals are massive.
>> 
>> Laravel Facades are a relic of an older time best avoided, even in Laravel 
>> projects.  (I am far from the only person to argue this; many even within 
>> Laravel's inner community make this argument.)
>> 
>> Adding features to the language that seemingly exist only to make that 
>> particular buggy hack easier to do is a step backwards, and I would argue 
>> harmful for the language.  On the contrary, I would favor going the other 
>> direction: Calling a static method as though it were non-static currently 
>> works, and I would support making that an error, to further emphasize that 
>> static and non-static methods are not interchangeable.
>> 
>> [1] https://peakd.com/hive-168588/@crell/cutting-through-the-static
>> 
>> --Larry Garfield
>
> Thank you for your feedback.
> I agree that static and non-static should be distinct, which is a given.
>
> There are a few points I'd like to make.
>
> First, my proposed RFC is not about allowing non-static methods to be 
> used statically. Although all my examples use `::`, they internally 
> operate on an instance. Inside `__callStatic`, an instance is created 
> and used for operations.
>
> Second, as already possible through the `__callStatic` method, 
> non-static methods can be called as if they were static (as mentioned, 
> this does not mean they operate statically). For protected and private 
> methods, the `__callStatic` function is invoked even for non-static 
> methods. This might not be to everyone's liking, and to others, it 
> might be a favorite feature. It might operate differently from the 
> initial intention when `__callStatic` was introduced. However, I don't 
> think this is necessarily a bad thing. Isn't it developers who bring to 
> life ingenious ideas that were unforeseen?

Developers also bring to life horrible monstrosities that are an afront to all 
that is holy.  I am a developer.  It's what we do. :-)  Especially when VC 
money is involved.

Not all "innovation" is good.

> Third, as you can see from my examples, what I propose could be a 
> solution to the current issues. Since it does not work for public 
> methods while it does for protected and private ones, it has led to 
> code becoming more obscure and layered through facade-like patterns. 
> It's like taking a longer route because the road is blocked, or 
> creating a dog door because the main door is closed.

It simplifies a practice that should not be a practice in the first place.  
That's not a net-win.

> From the perspective of those who develop the PHP language itself, my 
> proposal might not be appealing. However, I believe from the user's 
> standpoint, my proposal could lead to more convenient and cleaner 
> coding practices. Didn't PHP start as a language meant to be 
> user-friendly? 

I don't actually work on the PHP engine, I just write RFC text for other 
people; I have ~25 years of experience writing user-space PHP.  And no, 
anything involving stealth globals via statics is the opposite of "more 
convenient and cleaner."

--Larry Garfield


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread 하늘아부지
2024년 3월 29일 (금) 오후 10:21, Larry Garfield 님이 작성:

> On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote:
> > Hello.
> >
> > I created a wiki for __callStatic related issues.
> > Please see:
> > https://wiki.php.net/rfc/complete_callstatc_magic
> > I look forward to your interest and advice.
>
> I am firmly against this proposal.
>
> I think my objection boils down to this line in the RFC:
>
> > Of course, calling non-static methods in a static-like manner can be
> confusing, but in modern PHP, it has already become common practice.
>
> I would argue this statement is false.  Calling non-static methods in a
> static-like manner is confusing, which is why in modern PHP one should
> never do that, and respect that static and non-static methods exist in a
> separate universe.  Static methods are methods *on a type*.  Non-static
> methods are methods *on an instance*.  Those are not the same thing.[1]
>
> It would be more accurate to say "calling non-static methods in a
> static-like manner is common *in Laravel*," where the badly-named "facades"
> system serves as a poorly designed, hard to debug, hard to test, archaic
> alternative to using dependency injection.  While there may have once been
> an argument that DI was "too hard" for simple cases a decade ago or more
> (though even then I think it was a bade trade-off), the combination of
> auto-wiring DI Containers (which Laravel pioneered in PHP) and constructor
> promotion (introduced in PHP 8.0, 3.5 years ago.) completely eliminates
> those arguments.  The level of effort to do actual DI today is trivially
> small, and the benefits over magic hidden globals are massive.
>
> Laravel Facades are a relic of an older time best avoided, even in Laravel
> projects.  (I am far from the only person to argue this; many even within
> Laravel's inner community make this argument.)
>
> Adding features to the language that seemingly exist only to make that
> particular buggy hack easier to do is a step backwards, and I would argue
> harmful for the language.  On the contrary, I would favor going the other
> direction: Calling a static method as though it were non-static currently
> works, and I would support making that an error, to further emphasize that
> static and non-static methods are not interchangeable.
>
> [1] https://peakd.com/hive-168588/@crell/cutting-through-the-static
>
> --Larry Garfield
>

Thank you for your feedback.
I agree that static and non-static should be distinct, which is a given.

There are a few points I'd like to make.

First, my proposed RFC is not about allowing non-static methods to be used
statically. Although all my examples use `::`, they internally operate on
an instance. Inside `__callStatic`, an instance is created and used for
operations.

Second, as already possible through the `__callStatic` method, non-static
methods can be called as if they were static (as mentioned, this does not
mean they operate statically). For protected and private methods, the
`__callStatic` function is invoked even for non-static methods. This might
not be to everyone's liking, and to others, it might be a favorite feature.
It might operate differently from the initial intention when `__callStatic`
was introduced. However, I don't think this is necessarily a bad thing.
Isn't it developers who bring to life ingenious ideas that were unforeseen?

Third, as you can see from my examples, what I propose could be a solution
to the current issues. Since it does not work for public methods while it
does for protected and private ones, it has led to code becoming more
obscure and layered through facade-like patterns. It's like taking a longer
route because the road is blocked, or creating a dog door because the main
door is closed.

>From the perspective of those who develop the PHP language itself, my
proposal might not be appealing. However, I believe from the user's
standpoint, my proposal could lead to more convenient and cleaner coding
practices. Didn't PHP start as a language meant to be user-friendly?

Regards
Daddyofsky


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread Larry Garfield
On Fri, Mar 29, 2024, at 2:39 AM, 하늘아부지 wrote:
> Hello.
>
> I created a wiki for __callStatic related issues.
> Please see:
> https://wiki.php.net/rfc/complete_callstatc_magic
> I look forward to your interest and advice.

I am firmly against this proposal.

I think my objection boils down to this line in the RFC:

> Of course, calling non-static methods in a static-like manner can be 
> confusing, but in modern PHP, it has already become common practice. 

I would argue this statement is false.  Calling non-static methods in a 
static-like manner is confusing, which is why in modern PHP one should never do 
that, and respect that static and non-static methods exist in a separate 
universe.  Static methods are methods *on a type*.  Non-static methods are 
methods *on an instance*.  Those are not the same thing.[1]

It would be more accurate to say "calling non-static methods in a static-like 
manner is common *in Laravel*," where the badly-named "facades" system serves 
as a poorly designed, hard to debug, hard to test, archaic alternative to using 
dependency injection.  While there may have once been an argument that DI was 
"too hard" for simple cases a decade ago or more (though even then I think it 
was a bade trade-off), the combination of auto-wiring DI Containers (which 
Laravel pioneered in PHP) and constructor promotion (introduced in PHP 8.0, 3.5 
years ago.) completely eliminates those arguments.  The level of effort to do 
actual DI today is trivially small, and the benefits over magic hidden globals 
are massive.

Laravel Facades are a relic of an older time best avoided, even in Laravel 
projects.  (I am far from the only person to argue this; many even within 
Laravel's inner community make this argument.)

Adding features to the language that seemingly exist only to make that 
particular buggy hack easier to do is a step backwards, and I would argue 
harmful for the language.  On the contrary, I would favor going the other 
direction: Calling a static method as though it were non-static currently 
works, and I would support making that an error, to further emphasize that 
static and non-static methods are not interchangeable.

[1] https://peakd.com/hive-168588/@crell/cutting-through-the-static

--Larry Garfield


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread 하늘아부지
2024년 3월 29일 (금) 오후 5:43, Stéphane Hulard 님이 작성:

> Le vendredi 29 mars 2024 à 03:39, 하늘아부지  a écrit :
>
> > Hello.
> >
>
> > I created a wiki for __callStatic related issues.
> > Please see:
> > https://wiki.php.net/rfc/complete_callstatc_magic
> >
>
> > I look forward to your interest and advice.
> >
>
> > Best Regards.
> > Daddyofsky
>
> Hello !
>
> I took a look at your proposal and I think about important issues if we go
> this way.
>
> A static method mustn't used the `$this` variable because it simply
> doesn't exists in the static context. The examples you're adding in the RFC
> are fine but they always rely to a specific `__callStatic` implementation
> that will use a new instance of the object to forward the call.
>
> There are multiple cases where it'll be complicated to use it this way.
> Two of them I have in mind:
>
> - What if the object needs important parameters in its constructor that
> aren't available in the static context ? Or those parameters need to be
> initialized outside of the `__callStatic` method?
> - What if the underlying non static method we are trying to invoke is
> using the `$this` variable?
>
> In those two examples, I would prefer having a fatal error that explains
> that I'm not doing the call correctly (calling a non static method in the
> static context) to ensure it'll be easy to understand and fix.
>
> The use cases you are describing here have been fixed in the user space by
> the Laravel team. It's a very specific way of working that's mostly
> specific to Laravel.
>
> For sure it makes the code harder to read since you can't jump to a real
> method easily (because most of the methods are magic ones and are forwarded
> to underlying objects). I don't tell it's wrong but I'm not sure it's
> relevant to make the whole language simplify this process.
>
> If there is a way to work correctly with those static vs non static calls
> and capture relevant errors to expose them to users, that's fine.
>
> However, I think this is an important behavior change because it'll allow
> a new way to work with method that were forbidden before.
>
> Regards
> Stéphane


Hello.

Thank you for your interest.
In fact, `__callStatic` is often used for static-like singletons, and such
examples are likely to be the majority.

Regarding the two issues you pointed out, the first can be resolved by
adding an initialization method like `init`. It's common to use a separate
initialization function when dealing with general class operations,
especially when there is a lot to initialize.

The second issue is actually the same problem that exists today. Since
`__callStatic` is called in the case of static calls to private or
protected methods, the use of `$this` is not exclusive to public methods.
In other words, the `$this` issue applies the same way it does now.
Allowing public methods does not create a problem that didn't exist before.

If it had been the case that calling non-static methods statically always
resulted in an error, the issues you raised would have been significant.
However, private and protected methods can already be called without error.
Even if this RFC is not accepted, the points you mentioned still apply.

Regards
Daddyofsky


Re: [PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-29 Thread Stéphane Hulard
Le vendredi 29 mars 2024 à 03:39, 하늘아부지  a écrit :

> Hello.
> 

> I created a wiki for __callStatic related issues.
> Please see:
> https://wiki.php.net/rfc/complete_callstatc_magic
> 

> I look forward to your interest and advice.
> 

> Best Regards.
> Daddyofsky

Hello !

I took a look at your proposal and I think about important issues if we go this 
way.

A static method mustn't used the `$this` variable because it simply doesn't 
exists in the static context. The examples you're adding in the RFC are fine 
but they always rely to a specific `__callStatic` implementation that will use 
a new instance of the object to forward the call.

There are multiple cases where it'll be complicated to use it this way. Two of 
them I have in mind:

- What if the object needs important parameters in its constructor that aren't 
available in the static context ? Or those parameters need to be initialized 
outside of the `__callStatic` method?
- What if the underlying non static method we are trying to invoke is using the 
`$this` variable?

In those two examples, I would prefer having a fatal error that explains that 
I'm not doing the call correctly (calling a non static method in the static 
context) to ensure it'll be easy to understand and fix.

The use cases you are describing here have been fixed in the user space by the 
Laravel team. It's a very specific way of working that's mostly specific to 
Laravel.

For sure it makes the code harder to read since you can't jump to a real method 
easily (because most of the methods are magic ones and are forwarded to 
underlying objects). I don't tell it's wrong but I'm not sure it's relevant to 
make the whole language simplify this process.

If there is a way to work correctly with those static vs non static calls and 
capture relevant errors to expose them to users, that's fine.

However, I think this is an important behavior change because it'll allow a new 
way to work with method that were forbidden before.

Regards
Stéphane

signature.asc
Description: OpenPGP digital signature


[PHP-DEV] [RFC] Invoke __callStatic when non-static public methods are called statically

2024-03-28 Thread 하늘아부지
Hello.

I created a wiki for __callStatic related issues.
Please see:
https://wiki.php.net/rfc/complete_callstatc_magic

I look forward to your interest and advice.

Best Regards.
Daddyofsky