Пишу, по большей части, про историю, свою жизнь и немного про программирование.

Itertools для PHP

Внимание! Библиотеку я модифицировал, описанные ограничения уже не соответствуют действительности!

В прошлом, программируя на «Пайтоне» я не раз восторгался модулем itertools и тем как «Пайтон» легко позволяет обращаться с генераторами — есть несколько способов, хорошее разнообразие.

В ПХП недавно генераторы тоже появились, в версии 5.5 есть ключевое слово yield, позволяющее их создавать. Вчера у меня появилась мысль познакомиться с ними поближе и я решил переписать библиотеку itertools на PHP. В интернете я уже встречал несколько таких попыток, но ни одна из этих реализаций не использовала генераторы.

Пример использования ниже (для запуска примера и работы библиотеки требуется ПХП 5.6 и выше):

require 'itertools.php';

use function itertools\islice, itertools\cycle, itertools\iter;

foreach (islice(cycle(iter("ABC")), 10) as $el) {
    echo $el;
}

От оригинальной библиотеки несколько отличий.

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

Во-вторых, в «пакет» добавлены несколько полезных функций, которые входят в ядро «Пайтона» — iter, slice, enumerate и xrange, работают они так же, как и в «Пайтоне».

В-третьих, поскольку у ПХП нет возможности именовать параметры при вызове, у фунций product и izip_longest изменён порядок аргументов. От этого тоже можно было бы избавиться, потерей указаний типов в прототипе, но я, опять же, не стал этого делать.

Если не заброшу библиотеку, то, возможно, всё-таки откажусь от указания типов и приведу всё к более совместимому виду.

19 комментариев
Артур Мудрик 2015

Ужас, раньше было просто Пайтон, вместо нормальной русской транскрипции Питон, а сейчас так вообще Пайтон в кавычках, жесть. П — «Пайтон».

Евгений Степанищев (bolknote.ru) 2015

Комментарий для Артур Мудрик:

Транскрипция как раз «Пайтон». «Питон» — перевод, да ещё и неверный. Название образовано от «Летающего цирка Монти Пайтона». А кавычки чем вам не понравились?

Pavelpat 2015

Всегда думал, что yield совместно с return в одной функции — это syntax error.

Евгений Степанищев (bolknote.ru) 2015

Комментарий для Pavelpat:

Нет, можно считать, что в конце функции всегда происходит вызов return — снаружи эти две ситуации (ф-я без return и с пустым return) вообще неразличимы. «Планово» закончить генератор в PHP пока можно только одним способом — выйти из функции, вот этим пустым return я из неё и выхожу.

Pavelpat 2015

php -r ’function() { yield 123; return 123; }’
PHP Fatal error: Generators cannot return values using «return» in Command line code on line 1

php -v
PHP 5.5.12-2ubuntu4.3 (cli) (built: Mar 16 2015 20:50:26)

Pavelpat 2015

В 5.6 видимо такое добавили.

Pavelpat 2015

Все, понял. Вопрос снимается. Return должен быть пустым.

Pavelpat 2015

Либо return null, что эквивалентно.

hshhhhh.name 2015

Комментарий для Евгения Степанищева:

Не хочу показаться евгешей, но вы не объясните в двух словах зачем нужны генераторы?

Сколько не читал документации так и не понял зачем они нужны, исключительно как синтаксический сахар?

Евгений Степанищев (bolknote.ru) 2015

Комментарий для hshhhhh.name:

Это просто другой способ программировать (см. функциональное программирование). Из заметных плюсов — часто можно памяти сэкономить.

Сергей Морозов (morozov.livejournal.com) 2015

К слову, в «Пи-эйч-пи 7» генераторы уже могут возвращать любые значения: https://wiki.php.net/rfc/generator-return-expressions​.

Евгений Степанищев (bolknote.ru) 2015

Комментарий для morozov.livejournal.com:

Там более интересная штука появится — yield from. Мне в библиотеке её нехватало.

Roman 2015

Предлагаю «iter, slice, enumerate и xchange» заменить на «итер, слайс, инумирэйт и ексчэйндж». И остальное аналогичным образом для консистентности.

Евгений Степанищев (bolknote.ru) 2015

Комментарий для Roman:

Бессмыслица.

Евгений Степанищев (bolknote.ru) 2015

Комментарий для Roman:

Вы не разобрались в принципе, поэтому ваша шутка выставляет вас не с лучшей стороны.

Руслан 2015

Комментарий для Евгения Степанищева:

Евгений, в целом куда удобнее просто читать не спотыкаясь о необычные конструкции в тексте, а не разбираться в принципе. Это ведь как с орфографическими ошибками — как правило они не мешают пониманию текста, но отвлекают от содержания.
Это ваш блог и, конечно, вам решать как писать посты, тем более, что они полезны независимо от способа написания, но все-таки непонятно в чем смысл делать так и потом тратить какие-то усилия на объяснение позиции. Если это популяризация подхода, то на мой взгляд, аудитории одного блога недостаточно — неэффективно получается.

Евгений Степанищев (bolknote.ru) 2015

Комментарий для Руслан:

Эти ваши «обычные конструкции» подарила нам Перестройка, когда в страну хлынул поток иностранного и страна не справилась с переводом. Я помню времена, когда приняли закон, что хотя бы инструкция на продаваемом товаре должна быть на русском.

Я просто сопротивляюсь бардаку и вкладываю свою лепту в наведении порядка. Почитайте доперестоечные журналы («Науку и жизнь», например), посмотрите как там иностранные бренды написаны.

А названия функция писать по-русски не нужно, они не часть языка, это операторы, которые можно считать часть символьной системы. Это примерно как сделать фото знака «кирпича» и написать по-русски «кирпич» рядом. Или вместо знака «✈» написать «самолёт». Символьная система не требует записывания русскими буквами, у неё и роль другая.

Roman 2015

Да, я действительно не разобрался с принципом, почему Python превратился в «Пайтон», а PHP в кривой ПХП, да еще и без кавычек. А еще я считаю, что все связанное с IT должно преподаваться и писаться на английском языке.

Евгений Степанищев (bolknote.ru) 2015

Комментарий для Roman:

А всё что связано с производством — на китайском, очевидно.