Да простят мне ссылку на авторитет, но равенство между математикой и программированием оспаривает не только Влад. Генри Бейкер, на статью (http://home.pipeline.com/~hbaker1/ForthStack.html) о линейной логике которого пару раз ссылался thesz, тоже критикует этот взгляд.
Про комбинаторы - опять же, не совсем соглашусь. Ценность нерекурсивных определений для оптимизаций, rewrite rules и т.д. очевидна, а вот понятность - штука формально неопределенная, тут есть о чем поспорить. По-моему, однозначная экономия получается, если у нас есть под рукой готовые функции, которые можно передать комбинатору, получается короткое и понятное point-free выражение, в этом случае я согласен с тезисом о более высоком уровне абстракции и wholemeal programming. Если же для того, чтобы воспользоваться комбинатором, функцию нужно написать специально так, чтобы комбинатору понравилось, и понятность, и экономия уже не так очевидны. В point-free стиле начинается кошмар из (flip (.) . flip flip), а в pointful стиле рекурсивная и нерекурсивная версии изоморфны, экономятся считанные символы, а количество информации совпадает. Например, в твоем примере incAll содержит в себе неявный case-analysis, есть значение, которое нужно возвращать в случае пустого списка - [], и функция, которая вызывается в случае непустого списка. Сэкономили на визуальных подсказках, которые в данном случае не очень нужны, а в другом месте понадобились бы. Например, когда я определяю монадную версию условного оператора: (ifM cond t e = cond >>= \ x -> if x then t else e), при его применении мне не хватает ключевых слов then и else, вот такая мелочь, а неприятно. Другой пример: сколько раз ни пробовал использовать unfoldr, рекурсивная версия оказывалась понятнее.
no subject
Date: 2009-02-03 03:30 pm (UTC)Про комбинаторы - опять же, не совсем соглашусь. Ценность нерекурсивных определений для оптимизаций, rewrite rules и т.д. очевидна, а вот понятность - штука формально неопределенная, тут есть о чем поспорить. По-моему, однозначная экономия получается, если у нас есть под рукой готовые функции, которые можно передать комбинатору, получается короткое и понятное point-free выражение, в этом случае я согласен с тезисом о более высоком уровне абстракции и wholemeal programming. Если же для того, чтобы воспользоваться комбинатором, функцию нужно написать специально так, чтобы комбинатору понравилось, и понятность, и экономия уже не так очевидны. В point-free стиле начинается кошмар из (flip (.) . flip flip), а в pointful стиле рекурсивная и нерекурсивная версии изоморфны, экономятся считанные символы, а количество информации совпадает. Например, в твоем примере incAll содержит в себе неявный case-analysis, есть значение, которое нужно возвращать в случае пустого списка - [], и функция, которая вызывается в случае непустого списка. Сэкономили на визуальных подсказках, которые в данном случае не очень нужны, а в другом месте понадобились бы. Например, когда я определяю монадную версию условного оператора:
(ifM cond t e = cond >>= \ x -> if x then t else e),
при его применении мне не хватает ключевых слов then и else, вот такая мелочь, а неприятно.
Другой пример: сколько раз ни пробовал использовать unfoldr, рекурсивная версия оказывалась понятнее.