> On Aug 19, 2024, at 1:08 PM, Derick Rethans <der...@php.net> wrote:
> 
> Hi!
> 
> Arnaud, Larry, and I have been working on an article describing the 
> state of generics and collections, and related "experiments".
> 
> You can find this article on the PHP Foundation's Blog:
> https://thephp.foundation/blog/2024/08/19/state-of-generics-and-collections/
> 
> cheers,
> Derick

Great job on providing so much detail in your blog post.

JMTCW, but I am less of a fan of boil-the-ocean generics and more of a fan of 
focused pragmatic solutions like you proposed with the Collection types.  The 
former can result in really complex to read and understand code  whereas the 
latter — when done well — results in easier to read and understand code.
 
It seems Java-style Generics are viewed as the proper archetype for Generics in 
PHP?  I would challenge the wisdom of taking that road considering how 
different the compilers and runtimes are between the Java and PHP.  PHP should 
seek out solutions that are a perfect fit for its nature and not pursue parity 
with Java.  

As PHP is primarily a web development language — vs. a systems language like C 
or Rust, or an enterprise application language like Java or C# — reducing code 
complexity for reading and understanding is a very important attribute of the 
language.

PHP is also a unique language and novel solutions benefit a unique language. 
PHP should pursue solutions that result in less complex code even if not found 
in other languages. Your collections idea is novel — which is great — but there 
are probably even more novel solutions to address other needs vs. going full-on 
with Java-style generics. 

Consider if adding type aliases; or augmenting, enhancing, or even merging 
classes, interfaces, and/or traits to address the needs Java-style generics 
would otherwise provide. I would work on some examples but I think you are more 
likely to adopt the features you come up with on your own.

--------

As for type-erasure, I am on the fence, but I find the proposed "how" 
problematic. I can see wanting some code to be type-checked and other code not, 
but I think more often developers would want code type-checked during 
development and testing but not for staging or production. And if the switch 
for that behavior is in every file that means modifying every file during 
deployment. IMO that is just a non-starter.

If you are going to pursue  type-erasure I recommend introducing a file in the 
root — call it `.php.config` or similar — that contains a wildcard enabled 
tree-map of code with attributes settable for each file, directory, group of 
files and/or group of directories where one attribute is type-checked or other 
attributes are reserved for future use. This config file should also be able to 
delegate the `.php.config` files found elsewhere, such as config files for each 
package in the vendor directory. It would be much better and easier to swap out 
a few `.php.config` files during CI/CD than to update all files.

Additionally PHP could use an environment variable as prescribed by 12 Factor 
apps to identify the root config file. That way a hosting company could allow 
someone to configure their production server to point to 
`.php.production.config` instead of ``.php.development.config`. 

-Mike

P.S. Also consider offering the ability for a function or class method to 
"type" a parameter or variable based on an interface and then allow values that 
satisfy that interface structurally[1] but not necessarily require the class to 
explicitly implement the interface. 

This is much like how `Stringable` is just automatically implemented by any 
class that has a `__ToString()` method, but making this automatic 
implementation available to userland. Then these automatically-declared 
interfaces can cover some of the use-cases for generics without the complexity 
of generics.

For example — to allow you to visualize — consider a `Printable` interface that 
defines a `print()void` method. If some PHP library has a class `Foo` and it 
has a method with signature `print()void` then we could write a function to use 
it, maybe like so:

---------
interface Printable {
   print($x any)void
}

// The prefix `?` on `Printable` means `$printer` just has to match the 
`Printable` interface's signature
function doSomething($printer ?Printable) { 
   $printer->print()
}

$foo = new Foo();
doSomething($foo);
---------

Something to consider?  

[1] https://en.wikipedia.org/wiki/Structural_type_system

Reply via email to