2010-12-07 2 views
5

Я считаю, что одна из самых интересных особенностей как Haskell, так и Perl6 - способность откладывать вычисления значений до тех пор, пока они не понадобятся.Примеры ленивых методов оценки в Perl 5?

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

  • принимая ссылку на @_ в подпрограмме создает ссылку на массив, который является псевдонимом для идентификаторов в списке аргументов, даже если некоторые из этих идентификаторов не содержат значения еще.
  • возвращает перегруженные/связанные объекты из таких подпрограмм, которые содержат \@_ внутри, а затем разыгрывают их по мере необходимости. (И существуют различные CPAN модули, абстрагироваться от галстука/детали перегрузки)

Я экспериментировал с различными методами ленивых программирования в Perl (у меня есть модуль в работах, реализующий справедливый бит Haskell Прелюдия в Perl5 (такие вещи, как совместная рекурсия: $_ = list 0, 1, zipWith {&sum} $_, tail $_ for my $fibs; для определения последовательности Фибоначчи уже работают)). Но я чувствую, что в коде есть скрытые ошибки, которые могут проявляться, когда функции используются в больших выражениях/программах.

Так что мне интересно, есть ли какие-нибудь хорошие примеры (CPAN/блоги/книги), которые все знают о том, что Haskell/Perl6 используют как ленивость в Perl5? В частности, я хотел бы прочитать любой код значительного размера, который использует этот тип лень.

Я бы также интересно знать, если кто-то возникнут какие-либо подводные камни или неразрешимые проблемы, связанные с осуществлением ленивой оценки в Perl 5.

+3

Я предполагаю, что вы читали Perl высшего порядка. В нем много материала об итераторах, бесконечных потоках и лени. – 2010-12-07 23:07:22

ответ

9

Perl (свободно доступный online) имеет главу под названием «Бесконечные потоки». Может быть, это хорошая отправная точка.

3

Я думаю, что самая большая проблема является «Столкновением Magics». Когда вы пытаетесь сделать что-то, что, по вашему мнению, великодушное, а какой-то другой автор модуля пытается что-то, что, по их мнению, является шипким, а результат - неопределенностью. Чья магия побеждает?

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

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

+1

Если бы это было по-настоящему волшебное, это бы прочитало мой разум и DWIM. – Ether 2010-12-08 00:00:04

6

Ну, Moose делает это с lazy loading of attributes:

по умолчанию и модифицирующие методы
Атрибуты могут иметь значения по умолчанию, и Moose предлагает два способа указать, что по умолчанию.
[опции «по умолчанию» и «строитель» описаны ...]

Лень
Moose позволяет отсрочить население атрибутов, сделав атрибут «ленивым»:

has 'size' => (
    is  => 'ro', 
    lazy => 1, 
    builder => '_build_size', 
); 

Когда «ленивым», правда, по умолчанию не создается, пока метод читатель не называется, а не во время построения объекта. Существует несколько причин: вы можете сделать это.

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

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

Мы рекомендуем сделать любой атрибут с построителем или нетривиальным по умолчанию «ленивым», как само собой разумеющееся.

Смежные вопросы