[Moscow.pm] Coro

Alexandr Gomoliako zzz на zzz.org.ua
Чт Янв 19 16:25:56 PST 2012


On Thu, Jan 19, 2012 at 11:56 PM, Ruslan Zakirov <ruz at bestpractical.com> wrote:
> Покажите. Я хочу посмотреть красивый код на любой событийной либе,
> который будет иметь минимальное количество вложеных блоков, ананомных
> функций и просто будет аккуратен и читабелен. Я хочу научится.

Понимаемость и читабельность - разные вещи. Анонимные функции как раз
позволяют очень сильно улучшить понимаемость.

Вот пример http/1.0 запроса:
    https://github.com/zzzcpan/nginx-perl/blob/master/src/http/modules/perl/Util.pm#L42

Можно еще глянуть на CPS:
    http://search.cpan.org/~pevans/CPS-0.12/lib/CPS.pm


Наверное надо куда-то пост сделать на эту тему и развить ее немного. Пока здесь:

ПРИЧИНЫ СЛОЖНОСТИ КОДА

Вообще есть две основные причины сложности (понимаемости) кода:
  - изменение состояний;
  - последовательность выполнения (control);

Т.е. если состояния меняются не явно или последовательность задана
там, где она не имеет значения, то код сложный. Это еще называют
случайная сложность (accidental complexity).

СЛОЖНОСТЬ И PERL

В Perl проблема последовательности решается возвращением результата в
колбэк. Т.е. последовательность задается явно, с помощью определения
функции, куда будет возвращен результат выполнения.

А проблема неявного изменения состояний решается с помощью
использования анонимных функций в качестве этих колбэков и
использовании переменных из пэдов (closures).

И оказывается, что это все еще и идеально подходит для асинхронных приложений.
Лет 5 назад это было не очень хорошо, потому что perl сильно тек с
таким подходом. Но сейчас самое время.

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

ПРИМЕР

Вот пример. В нем порядок выполнения двух функций роли не играет и это
задано явно. А еще состояние $done меняется явно

sub foo ($&) {
    my ($arg, $cb) = @_;
    my $done = 0;

    do_something $arg, sub {
        my ($res) = @_;
        &$cb ($res)  unless  $done;
        $done++;
    };

    do_something2 $arg, sub {
        my ($res) = @_;
        &$cb ($res)  unless  $done;
        $done++;
    };
}

Подробнее о сложности кода в functional relational programming.


Подробная информация о списке рассылки Moscow-pm