15 comments

[ 3.1 ms ] story [ 39.5 ms ] thread
(comment deleted)
Can someone smarter than me explain what they mean by "reified generics", "erased generics", and a use case for when to use one over the other?
With reified generics, the code

  class Foo<X> {
    X x;
  }

  Foo<int> fooInt;
  fooInt.x = 5;
  Foo<float> fooFloat;
  fooFloat.x = 5.0;
compiles to:

  class Foo_int {
    int x;
  }

  class Foo_float {
    float x;
  }

  Foo_int fooInt;
  fooInt.x = 5;
  Foo_float fooFloat;
  fooFloat.x = 5.0;

On the other hand, erased generics compiles to this:

  class Foo {
    void* x;
  }

  Foo fooInt;
  fooInt.x = new int(5);
  Foo fooFloat;
  fooFloat.x = new float(5.0);
I may be missing something about how the PHP compiler/interpreter works, but I don't quite understand why this is apparently feasible to implement:

    class BlogPostRepository extends BaseRepository<BlogPost> { ... }
    $repo = new BlogPostRepository();
but the following would be very hard:

    $repo = new Repository<BlogPost>();
They write that the latter would need runtime support, instead of only compile time support. But why couldn't the latter be (compile time) syntactic sugar for the former, so to speak?

(As long as you don't allow the generic parameter to be dynamic / unknown at compile time, of course.)

In the sense of an affirmative vote, the proper word is "yea."
write PHP a lot. every day.

I wish we had typed arrays. Totally not gonna happen, theres been RFCs but I have enough boilerplate classes that are like

Class Option Class Options implements Iterator, countable, etc.

Options[0], Options[1], Options[2]

or Options->getOption('some.option.something');

A lot of wrapper stuff like that is semi tedious, the implementation can vary wildly.

Also because a lot of times in php you start with a generic array and decide you need structure around it so you implement a class, then you need an array of class,

Not to mention a bunch of WSDLs that autogenerate ArrayOfString classes...

We used to have a lot of classes like that, but for us PHPStan is sufficient and we effectively have generics now through static analysis warning us of improper usage of types in our CI and IDEs.

Is this not suitable for you?

In Hack, collection objects were one of the biggest early mistakes that the took a huge amount of effort to undo. It turns out that the copy-on-write semantics of PHP array were extremely important for performance and good APIs. Being able to pass arrays to things without fear of mutation allowed for tons of optimizations and not needing to copy things just in case. This is why Hack switched to using `dict`, `vec`, and `keyset` rather than collection objects.

More generally, it's weird to see a whole blog post about generics for PHP not even mentioning Hack's generics designs. A lot of thought and iteration went into this like 5-10 years ago.

See https://docs.hhvm.com/hack/arrays-and-collections/object-col... and https://docs.hhvm.com/hack/arrays-and-collections/vec-keyset...

I thought Hack is dead or not intended for public use anymore.

But after some quick checking, I learned that Hack is still actively maintained, surprisingly.

I am not much of a programmer so I was trying to figure out what generics are. And I am sure they are great, but my inner gremlin goes in sarcastic tone "we want these elaborate type systems, but we also want typeless because that is far more convenient to use, so we invented generics, a method to untype your type system"

But really while I was reading up on what generics are I went, isn't that just python, strongly typed but your functions don't have built in type checks.

As you say, generics really only apply to typed languages, and they help solve very legitimate annoyance in most of those languages -- you often have some library helper or algorithm that can apply to a wide range of things, but those things differ in some way that's irrelevant to the algorithm.

For example, a mergesort algorithm works on any kind of array, as long as you can compare the elements in the array to each other. There's no point in re-implementing the algorithm for each kind of array. Yet, without generics, you'd need to do just that. At the same time, the generated code for sorting each different kind of array might need to be a little different - comparing strings and floats isn't the same assembly, for instance. So the programming language and compiler work together: you specify the algorithm once in a certain way, and the compiler can generate the right version of algorithm for each way that you need to use it.

There are many, many good reasons why you might want to work in a typed language, even though specifying the types is a bit of extra book-keeping; generics are one way to keep the pointless work down. Of course, if you can get away with a python script, there's no need to bother with all this typing business just yet, either.

> "we want these elaborate type systems, but we also want typeless because that is far more convenient to use, so we invented generics, a method to untype your type system"

It's rather the exact opposite. Parametric types are a way to properly type "deeply" instead of just the topmost layer. Just like inference, type parameters don't remove types.

> isn't that just python, strongly typed but your functions don't have built in type checks.

That doesn't really make any sense? Static types mean you don't have runtime type checks, since the types are known statically.

The introduction to me reads as very confused:

One of the most sought-after features for PHP is Generics: The ability to have a type that takes another type as a parameter. It's a feature found in most compiled languages by now, but implementing generics in an interpreted language like PHP, where all the type checking would have to be done at runtime, has always proven Really Really Hard(tm), Really Really Slow(tm), or both.

* The topic of the article is implementing generics at compile time, but this claims that PHP is not compiled.

* Type checking is orthogonal to compilation vs interpreter.

* Types are not checked at runtime. It is kinda the point of types that they are checked before code runs. Runtime checks are on values. You can reify types at runtime but this breaks a useful property of generics (parametricity) and it prevents the very useful feature of types without a runtime representation (often known as newtypes).

* If you want to use types in the colloquial "dynamic type" meaning as tags on values, and you also want to talk about generics (a feature that only makes sense for types-as-compile-time-properties) you need to be really careful in your terminology or confusion will abound!

Nay, enough of complexity as it is, for now.
So, PHP started off as a loosely typed language, then got types... and now they want to implement generics to have more loosely typed code? But as I understand it, types are still optional, so you can still use untyped variables for "generic" code? I'm probably missing something here, is it because of performance concerns? Or the edge case of absolutely wanting strongly typed PHP throughout (except for the part where they want generics)?