Cинтаксический сахар для PHP

Только ленивый, точнее, ну очень ленивый не скажет про PHP пару ласковых. Стоит мимолётом покритиковать разработчиков за то, что больше половины попыток исправить ситуацию с фаршированием стандартной библиотеки, несогласованности и отсутствием того, что очень сильно понравилось в *подставить свой любимый язык* только её (ситуацию) ухудшают, а те, что влияют положительно — не доработаны; Конечно же это провокация и ведёт к неизбежному холивару, но давайте постараемся избежать этого. Из довольно продолжительных размышлений на эту тему и родилась одна затея…

Скажите, а ведь вы хотите что-то изменить в языке, поправить? Знакомясь с новыми языками и подходами, лично у меня — эта мысль крепла. Я испробовал довольно много подходов, начиная от попытки написать собственный интерпретатор, не обладая достаточными знаниями — попытка провалилась, заканчивая переписыванием php исходников (не интерпретатора, а самих *.php файлов) — вначале нативный интерпретатор парсит изменённые исходники, затем транслирует в код\сохраняет данные и уже их интерпретирует, но, добившись определённых результатов — и эта попытка была погребена благодаря своему неудобству и «костылеобразности». И, уже почти разочаровавшись в этой затее — мне помог докладчик на DevConf (если не ошибаюсь — Александр NightTiger), сам того не подозревая. Доклад был про аспектно-ориентированное программирование и одной из просьб докладчика, которая и подтолкнула меня на правильный путь, была: «Поднимите руки те, кто знает про php фильтры».

Немного покопавшись в мануале, перечитав исходники Aspect фреймворка (их, к слову, на гитхабе нашлось несколько — совершенно разных), погуглив — я наконец пришёл к тому результату, которого я ждал — «Эврика!», воскликнул я. Дело осталось за малым, набросать на коленке за пару часов рабочий код и дело было в шляпе — всё о чём мечтал — свойства, перечисления, именованные параметры, нормальное приведение типов и много чего ещё, всё что можно вообразить, без расширений, без костылей и геморроя — вот оно счастье! То, на что я потратил несколько месяцев раздумий, попыток написать что-то и сотни струнок нервов из нержавейки — неужели мечта, так бережно лелеянная мною скоро воплотится? Каково же было моё удивление, когда мой «говнокод» (да простит меня общество за столь непристойный термин) действительно заработал, и даже так, как я почти хотел.
Для затравки:
<?php
import Accessors, Enum, Properties from std;
 
namespace Ololo 
{
        enum Color
        {
                Red,
                Blue,
                Green,
                Yellow
        }
 
        class Some
        {
                private:
                        $asdasd = 23;
                        $some   = 42;

                public $some
                {
                        get; 
                        set($value) 
                        {
                                return (int)$value + 42;
                        }
                }
 
                public function __construct()
                {
                        echo Color::Red . \Ololo\Color::Blue;
                }
        }
}


Далее следовало:
1) Написание плана (роадмапа) проекта
2) Полное переписывание того двухчасового ужаса, что я набросал
3) Исследование комьюнити. Мнения, пожелания, взлетит\нафиг_оно_надо

С первым было больше всего проблем, я остановился на варианте встраивания того, что полностью совместимо с языком — по-умолчанию. Все указания типов в параметрах, свойства и прочее-прочее должны быть доступны сразу — оно не ломает ничуть обратную совместимость, для остального же решил использовать подход, похожий на питон — конструкцию import, которая указывает:

import ЧТО from ПАКЕТ;

где «ЧТО» — название файла\класса согласно спецификации PSR-0, а «ГДЕ» — указание на набор пакетов, будь то стандартные, либо добавленные\написанные пользователем вручную. Текущий вариант стандартных пакетов включает в себя:
Сам список:
* draft Приведение типов
* todo function __init — автоматически вызываемый метод при инициализации класса (require файла с ним)
* todo Свойства
* todo Перечисления
* todo Аспекты
* todo Именованные параметры
* todo Упрощенное объявление области видимости свойств\методов
* todo Стандартизация всех функций и вынос их в отдельные пространства
* todo Скаляры в виде объектов

где draft — уже сделанное и более-менее готовое к употреблению, а todo — только на этапе разработки\переписывания\обсуждений.

Второй пункт тоже вполне получился. Исходники довольно приятные (я считаю, сильно не бейте :D) на ощупь: github.com/SerafimArts/Mirror

И наконец под третьим пунктом — интересно именно ваше мнение, уважаемое хабрасообщество.

Вместо послесловия хочу отметить:
— На данный момент полностью готово ядро.
— Реализовано приведение типов в параметрах методов\функций github.com/SerafimArts/Mirror/wiki/Type-Casting включая рабочий пример: github.com/SerafimArts/Mirror/blob/master/examples/TypeCasting/test.php
— Нет юнит-тестов
— Нет документации, но есть полностью документированный код
— Отсутствует установка через Composer
— Зато есть собранный phar пакет

Использование:
<?php
require('phar://mirror.phar');   // или "lib/Mirror/bootstrap.php"
require_mirror('path\to\file.php');

и внутри подключённого с помощью функции require_mirror (либо include_mirror) файла, включая абсолютно все внутренние инклуды (даже с помощью стандартных функций) будет возможность использовать синтаксис Mirror — именно так я назвал данное поделие — как отражение языка, а пакеты — стёкла или призмы (Glass) с помощью которых можно изменять язык.

В последующих статьях (если они всё же случатся) я хочу ознакомить вас с внутренним устройством библиотеки — как написать свою «призму», как работает кеширование, подробными планами на будущее и ещё чем-нибудь, что вас заинтересует. Проект довольно сырой (был написан за время отпуска на чёрном море — сами понимаете), так что статья нацелена именно на ваши отзывы и пожелания, что бы заранее не накосячить с разработкой. Спасибо большое за внимание.

UPD: Поправил английский перевод слова «стёкла»
Поддержать автора
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 22

    0
    glasses — стаканёши же :)
      0
      Ох, залез в переводчик — перевело как «очки», напутал я со множественной формой слова, спасибо, поправлю.
      0
      А почему php 5.4 и выше? И не получится ли, что в итоге придётся писать экстеншн для php?
        0
        Исходил из той версии, которая позволяет использовать вариацию множественного наследования — трейты. Некоторые пункты в плане, например «свойства» — проще и чище реализуются именно через его подключение. После обработки библиотекой — в класс подключается вот такой трейт, который и будет реализовывать данную логику: github.com/SerafimArts/Chidori-2.1/blob/version-2.1/framework/Chidori/Traits/Properties.php
          0
          А `__get` и `__set` из трейта не будут конфликтовать с другими `__get`/`__set`?
            0
            Будет перегрузка, да, но в таких случаях можно проверять наличие этих методов в наследнике и дописывать в директиву use, например следующее:

            use Properties {
            Properties::__set as BLAH;
            Properties::__get as BLAH;
            }

            а в существующих методах наследника добавлять: `$this->BLAH();`, где BLAH — произвольно сгенерированное имя.
          +1
          На счёт расширения — я категорически против. Видел уже довольно много действительно крутых расширений, которые умерли просто потому, что: а) выходит новая версия языка — расширение заточено под старую. б) Очень редко кто берётся за развитие заброшенного кем-то расширения. в) Большинство площадок не позволяет ставить сторонние расширения.

          Плюс, хочу отметить, что пока не сталкивался с особыми проблемами, когда потребуется именно расширение — всё реализуется именно средствами самого языка, только зачастую это неудобно писать, да и выглядит коряво.

          +2
          Вцелом выглядит как такой себе CoffeeScript для PHP.

          Думаю, проект взлетит, если как и кофи, будет решать насущные проблемы, а не вводить новые элементы ради новых элементов.
          Первое, что имхо, надо сделать — сократить синтаксис. Коль это синтаксический сахар, то в примере, не слишком сладко получается.
          Код не слишком удобен для чтения, и не слишком читабельный. Эти вещи можно бы сначала оптимизировать, а потом двигаться дальше, предлагая какие коснтукции реально могут упростить жизнь и какие есть пракические примеры их использования.
            0
            Хлам — очень веский довод. Сейчас постарался взглянуть с другой стороны — Вы правы. Сам пример выглядит монстрообразно, почти как битрикс в расцвете сил. Постараюсь на днях решить эту проблему — акцентировать на самом главном, указать моменты, упрощающие жизнь, вынести на обсуждение потребность в них.

            В любом случае кофе — полностью заменяет синтаксис и для непосвящённого человека — выглядит более чем устрашающе. В данном варианте — вместо того, что бы полностью переписывать весь синтаксис или писать что-то в комментариях (как это делается в aspect) — реализовать тот синтаксис, который был бы понятен любому PHP разработчику, без углублений в тонкости реализации.
              0
              реализовать тот синтаксис, который был бы понятен любому PHP разработчику, без углублений в тонкости реализации.

              Да, такой вариант вполне устроит :) Буду ждать следующего драфта.
            0
            Эх, подлил я масла в огонь со своими фильтрами )
            Однако приятно, что мои слова помогли изучить такую интересную технику. Реализация получилась весьма интересная, однако надо учесть много факторов, таких как опкод-кэшеры, корректную работу со стримами и прочее. А то в реальном применении все свалится благополучно, потому что код будет закэширован опкод-кэшером.
              0
              таких как опкод-кэшеры

              Вроде ж остался только один, нет?
              0
              На счёт опкод-кешеров — сомневаюсь, разработка велась на php 5.5 (встроенный Zend Optimizer+), но на EAccelerator и проч. — не проверял. Сам кеш реализован простой сверкой filemtime файла в кеше и существующего файла.

              На счёт корректной работы со стримами — немного не понял. Проверял на «Hello World» Yii 1.1 приложении — всё работало замечательно, но не стал указывать это в статье, т.к. ни замеров скорости, но полных тестов не проводил, да и «хелло ворлд» — не показатель. В любом случае в репозитории есть пример типизации в параметрах методов — полностью рабочий, без ошибок.
                +1
                Имхо, самый большой недостаток-это ругань IDE на этот сахар. Не имея нормальной поддержки для этих конструкций на уровне IDE, сама разработка уже не покажется сахаром.
                  0
                  Есть такое дело, да. Но самые популярные, ака phpStrom, Sublime, Dreamweaver (тьфу-тьфу) и т.д. — поддерживают расширения, вполне возможно получится как-то это дело поправить. Спасибо за подсказку — добавлю в планы посмотреть гайд по написанию расширений, хотя бы для первых двух.
                  0
                  Документация и тем более комментарии в коде на русском — это, мягко говоря, плохая практика
                    0
                    Ну там всего два комментария на русском в последнем пуше, можно простить, учитывая то, что остальное подавляющее большинство на английском. На счёт документации сложнее — я страдаю болезнью «медвежий английский», так что будет проблематично описывать тонкости и уж тем паче написать какое-нибудь руководство на языке, отличного от русского. Единственный вариант — нанять переводчика, но пока я не готов к таким расходам, а гугл транслейт выглядит довольно по-детски.
                      0
                      может совпадение, но действительно первые два файла, которые я глунял были с русскими комментариями :) больше не смотрел, поскольку с мобилы читал :) по поводу английского, надо писать как получится, а народу если понравится, то поймут и поправят, чтоб было красиво и понятно ;)
                        0
                        Пока библиотека не станет хоть немного популярна — никто править не будет — это говорит хотя бы о том, что вчера обнаружил фантастическую багу, которая ломала всё, если в операторе include\require присутствует что-нибудь отличное от строки, не думаю что если бы хоть один человек скачал и попробовал — этого бы не обнаружил =) А тут всего лишь комментарии.
                          0
                          Ведь встречают по одёжке… :) Я бы тоже посмотрел, но я не разделяю Ваше мнение относительно всего того сахара, что вы предлагаете.
                            0
                            Ну так ради этого я и написал этот пост. Есть возможность что-то изменить, но нет того количества отзывов пользователей, которое скажет «это действительно нужно», а «вот это бред, не надо» ;) Я уже и сам начал потихоньку разочаровываться в затее.
                              0
                              Это действительно нужно. Хотя, может быть, и не в таком виде, как сейчас.
                              Из-за веселых русских комментариев в коде и README затея кажется несерьезной, и, честно говоря, не верится, что вы закончите начатое.
                              На всякий случай посмотрите интересную библиотеку:
                              github.com/jakubledl/dissect/blob/master/docs/index.md

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое