Comments 17
Статью плюсанул, потому что это большой труд, и в целом поддерживаю, что дженерики нужны. Спасибо за хорошую попытку.
Однако, в то, что такой подход на кодогенерации хоть сколько-нибудь распространится - тут есть сомнения. Все такие решения: асинхронность через костыли, дженерики через кодогенерацию - обычно остаются в небольших группах фанатов.
Поэтому ждем, когда (если) добавят это в сам язык
Вариант с кодогенерацией плох тем, что PHP проверяет все в runtime.
Даже если добавить какие-то проверки типов во время генерации, то это будет противоречить общему принципу работы PHP.
По поводу добавления дженериков в сам язык - после изучения RFC и его обсуждений пришел к выводу, что должно произойти что-то кардинальное, чтобы их добавили:
+ RFC не сформирован до конца. Даже синтаксис (за 7 лет);
+ у текущего синтаксиса есть проблемы с парсингом (https://github.com/PHPGenerics/php-generics-rfc/issues/35#issuecomment-571546650);
+ сообщестовом отвергается варианты, которые идут по простому пути или противоречат общему принципу работы PHP. Вариант моей библиотеки, реализованный в самом PHP, может сильно увеличить расход памяти, хотя он не очень сложен в реализации. (https://github.com/PHPGenerics/php-generics-rfc/issues/42).
Исходя из этого, я не вижу предпосылок для добавления дженериков в сам PHP (хотя в Hack они добавлены в каком-то виде).
Спасибо за труд и вклад.
В комментах пишут можно ли использовать или не использовать.
Но дело в другом, это эксперимент, который делает попытки сдвинуть то что не способно сдвинуться само.
Спасибо.
Возможно эта библиотека попадет в англоязычное сообщество, и люди начнут поддерживать. Или может в IDE появится поддержка.
Когда-то node.js был экспериментом. А сейчас это серьёзный инструмент.
TypeScriptи тоже генерирует код, и все довольны.
Пока видны некоторые проблемы в этой библиотеке. Давайте о опишем эти проблемы, поставим заплачу и план.
Может правка этих задач будет через несколько лет, но главное что начало есть, и может получится что-то великолепное для всех.
PHP выполняет проверки типов в runtime.Значит, все аргументы дженериков должны быть доступны через reflection в runtime.А этого не может быть, потому что информация о аргументах дженериков после генерации конкретных классов стирается.
Как вариант - добавить в сгенерированые классы атрибуты, в которых уже эти данные предоставить
Разработчики указывали что с дженериками есть проблемы технического характера. Дженерики в виде PHPDOC уже существуют и из поддержка появилась в последнем PHPStorm
Тоже поставил плюс за старания, но я сомневаюсь, что это реально кто-то будет использовать. Как говорится "лекарство хуже болезни". Если честно, то я вообще очень скептически отношусь к современным попыткам сделать из php подобие джавы. У php много минусов, но все же, если ты хорошо знаешь подводные камни, то на данный момент, он остается самым практичным языком для веб разработки.
Статья хорошая, спасибо. Кстати, те же phpstan или psalm вполне позволяют использовать дженерики с помощью template (psalm-template) аннотаций.
Статья интересная, спасибо!
Но
библиотека легко устанавливается и может использоваться на реальных проектах
упаси Господь.
Уважаемый автор. Я так же силножелающий Дженериков.
Я прежде участвовал в описании характеристик Generic PHP на Github в черновике. (Та ветка уже закрыта/удалена.)
Кроме желаемого от дженериков в PHP я так же узнал различные нюансы.
1.Полная поддержка дженериков может быть в статическая и динамическая.
2.Динамическая поддержка может быть Полная и игнорируемая.
Мы должны придерживаться не только поддержки Дженериков но и сохранить скорость исполнения.
Если с каждым новым Дженериком будет генерироваться новый PHP файл, то разумеется это снизит производительность.
Попов на эту тему уже давал комментарии.
Прежде был предложен вариант, в котором Атрибуты в Дженериках будут просто игнорироваться PHP движком, как бы он их будет не замечать.
Таким образом PHP не сможет следить за атрибутами Дженериков в полном объеме.
Но так и не надо.
TypeScript так же не имеет типов после компиляции.
Главное чтобы за Generic типами следил IDE редактор: VSCode, NetBeans, Eqlipse, PHPStorm.
С этой точки зрения сохранится скорость работы самого PHP, и мы получим полную статическую поддержку Дженериков.
Могли Вы бы скомпилировать еще одну версию где атрибуты дженериков будут удалятся?
И так же прошу Вас написать новую статью на Хабре на разработке новой версии.
Спасибо Вам большое.
Ой, еще маленькую задачку, предложу Вам.
Если у Вас получится собрать версию PHP где дженерики игнорируются. Может быть Вы сделаете плагин для любого из редакторов кода который будет поддерживать Дженерики, Быть может для VSCode, либо для того редактора, которым Вы сейчас пользуетесь.
Я думаю что в этом случае комментарии будут уже другими, так как это будет уже по настоящему быстроработающая машина PHP без тормозов и с поддержкой Дженериков.
Спасибо за комментарий!
Дженерики в PHP - это не тоолько про typehint. Это еще, например, вариантность типов, наследование типов.
Вот тут можно почитать дискуссию о стираемых типах в PHP.
Вот тут можно почитать про наследование типов атрибутов.
Но даже если мы отбросим все это и оставим typehint только на стороне статического анализатора, то простого стирания атрибутов все равно будет недостаточно для нормальной работы PHP.
Вот пример со стиранием атрибутов, когда все будет работать отлично:
<?php
class Generic<T> {
public function add(T $val) {
$this->val = $val;
}
}
Вот пример, когда мы не можем просто так взять и стереть атрибуты:
<?php
class Generic<T> {
public function add($val) {
if(!$val instanceof T) {
throw new \Exception();
}
var_dump(T::class);
return new T();
}
}
Пример вымешленный, но идея должно быть понятна.
В этом случае для каждого такого уникального атрибуты нужно завести отдельный класс с уникальным названием. Что я и сделал, оставив все typehint для runtime.
P.S. Вижу, что вы пишите про компиляцию PHP. Хочу пояснить, что библиотека полностью написана на PHP и не требует перекомпиляции самого движка PHP.
Я предлагаю чтобы дженерики целиком игнорировались.
Чтобы Выше описанный код дженерика воспринимался и обрабатывался так:
<?php
class Generic {
public function add($val) {
$this->val = $val;
}
}
Т.е. такое поведение PHP будет работать без генерации допклассов, с той скоростью как оригинальный.
А анализом типов дженериков будет заниматься IDE.
В принципе типизация нужна чтобы писали люди код правильно. Если проблему типизации решит IDE это то что нужно, по аналогии TS.
Вначале в PHP были просто переменные, потом добавили типизированные переменные, быть может попробуем сделать промежуточную остановку сделаем дженерики игнорируемые. А уж тогда потом будем делать дженерики на уровне PHP с полной поддержкой.
Моё предложение позволит разработчикам сразу войти в дженерики, даже в продакшине и на высоконагруженных серверах. А после можно переходить к Вашей реализации.
Допускаю что в Вашей реализации могут быть не очевидные тонкости приводящие к непредсказуемым результатам или ошибкам. А код уже будет у людей написан и его нужно переписывать. А при создании PHP с игнорированием дженериков, код будет работать всегда так как он будет аналогичен оригинальному.
Потому что пока люди спорят как надо, мы ни когда их не получим. А получив стираемые дженерики, мы можем сравнивать их в разных IDE
В таком случае уже есть Psalm Template Annotations)
Они как раз не добавляют ничего нового в язык. Не нужна генерация кода. Весь код проверяется статическим анализатором (отдельным или в IDE)
А что если тип T не будет как тип , и его нельзя будет использовать.
Или Вы написали пример что нельзя просто так игнорировать Т. Но тогда вместо Т сделайте $Т или __T.
Если предполагать, что типами в дженериках могут быть только "встроенные типы"(и то не все, а только самые простые вроде int/string), то это довольно сильно урезает функционал дженериков и тогда становится возможным полное удаление атрибутов из кода.
Но, как я отписался выше, для этого уже есть инструменты.
Здравствуйте.
Инструменты то есть, но такие инструменты сложны для эксплуатации, одно дело тип написать, а другое дело Аннотация писать. Приемущество полного удаления атрибутов кода все таки имеет удобвство. На эту тему можно спорить. Но если была бы такая реализация с поддержкой статических типов в IDE, было бы уже чем то рабочим и внедряемым в реальные проекты.
Если даже не думать на эту тему.
Подскажите пожалуйста, быть может есть у Вас какая нибудь мысль как реализовать дженерики, но без генерации кода? Может что то удалять придется или в памяти держать массив типов.
Вы можете что нибудь подсказать в этой в таком контексте.
Извините меня, Вы правы я сам не понимал как оно работает. Вы объяснили, стало ясно что Ваш модуль может быть только такой и ни какой другой.
Подскажите, а Вы пробовали отправить Ваш модуль в OpenServer, WAMP, php разработчикам?.
У PHP есть вроде каталог модулей, может они сошласибюлисьбы добавить Ваш модуль в своей каталог.
PHP Generics. Right here. Right now