Recursion strikes back
В туториале по Хаскелю экзамплы намного интересней имхо.
public bool IsEven(uint a)
{
if (0 == a)
{
return true;
}
else if (1 == a)
{
return false;
}
else
{
return IsEven(a - 2);
}
}
это ты свой цикл преобразовал в соответствии со статьёй?
Нет, я на этом примере детям в матлагере объяснял рекурсию.
тогда при чём он здесь?
Какая-то очень примитивная статья, очевидные примеры разжевывают, ничего интересного. Чего ты в ней нашел?
Автор утверждает, что "Learning recursion yields maintainable, consistent, provably correct code".
То есть если вот сделать такое простое преобразование кода, то все издержки компилятор сам уберёт,
а код получается из "хуй проссышь без дебагера" сразу maintainable и consistent.
> code". То есть если вот сделать такое простое преобразование кода, то все издержки компилятор
> сам уберёт, а код получается из "хуй проссышь без дебагера" сразу maintainable и consistent.
ГЫ. Утверждать все умеют. А вот обосновать - другое дело...
Кстати, очень показательно, что в пример код через цикл значительно (раза в 2) короче чем через рекурсию. Хорошо показывает, что же проще на самом деле.
> короче чем через рекурсию. Хорошо показывает, что же проще на самом деле.
Хорошо показывает? Замечательно, C++ сосёт у OCaml.
Но автор говорит не о "простоте", а о maintanability, и здесь число строк кода совсем не показатель.
Если в код нужно будет через год врубаться заново, то 20000 строк понятного кода лучше,
чем 10000 хуёвого, даже если они делают одно и то же.
Причём, врубаться - означает понять уже написанное решение некоторой задачи,
а там абстракция "свести подзадачу к уже рассмотренной" гораздо полезнее,
чем "повторять, пока не будет достигнуто нужное состояние", так как во втором случае приходится
распутывать способы достижения нужных состояний.
Повторное использование переменных приводит к необходимости использования отладчиков
(ГЫ: "я глубоко убеждён..." для того, чтобы понять что же именно происходит в коде
и к созданию новых ошибок, вызванных недопониманием всех тонкостей (через год их забыть можно).
Уже это говорит, что на поддержку такого кода после его написания потребуется
значительно больше ресурсов, чем на написание нормального кода сразу.
Автор лишь показывает, что он не умеет (или не хочет, что более вероятно) грамотно писать на С++. Например, зачем ему использовать списки? Реализация на массиве была бы гораздо быстрее (хождение по списку особенно медленно на современных процессорах с конвеерной архитектурой).
> "повторять, пока не будет достигнуто нужное состояние", так как во втором случае приходится
распутывать способы достижения нужных состояний.
Согласен, ИЯ обладают рядом недостатков. Но ФЯ - тоже не сахар. Не надо их идеализировать, у них тоже масса проблем. Мы видим пока лишь рассуждения в духе "ИЯ плохи", но никто не объясняет, почему недостатки ФЯ слабее чем недостатки ИЯ.
> Автор лишь показывает, что он не умеет (или не хочет, что более вероятно) грамотно писать на С++.
> Реализация на массиве была бы гораздо быстрее ...
Контекст был "короче => проще (для понимания?)" при реализации
одного и того же алгоритма, что в данном случае выполнено.
И более общий контекст - возможность поддержки кода, что вообще говоря,
отодвигает производительность на второй план.
Поэтому "грамотно писать на С++" в смысле сделать "гораздо быстрее"
к этой теме отношения не имеет.
Кстати, автор вроде бы не против улучшения кода решений,
так что вывод "не хочет" явно поспешен.
>> "повторять, пока не будет достигнуто нужное состояние",
>> так как во втором случае приходится
>> распутывать способы достижения нужных состояний.
> Согласен, ИЯ обладают рядом недостатков. Но ФЯ - тоже не сахар.
> Не надо их идеализировать, у них тоже масса проблем.
Абстрактные проблемы в вакууме это, конечно, очень интересно,
но в реальных задачи, требования что-то допускают, а что-то нет.
Например, требования надёжности могут достигаться ценой производительности
(кому нужна машинистка, печатающая 240 символов в минуту, если фигня получается?).
Необходимость поддержки кода не позволяет всю оставшуюся жизнь просидеть,
распутывая и отлаживая заново одни и те же куски.
> Мы видим пока лишь рассуждения в духе "ИЯ плохи", но никто не объясняет,
> почему недостатки ФЯ слабее чем недостатки ИЯ.
"Мы видим"?
Я вижу совсем другое.
Есть требование и предлагается подход, который к выполнению этого требования приближает.
Про ФЯ, ФП и "ИЯ плохи" здесь нет вообще ничего, а только отдельные элементы функционального подхода,
как средство обеспечения полезных свойств при решении тех же самых задач теми же самыми способами.
Язык был и остался императивным.
> но в реальных задачи, требования что-то допускают, а что-то нет.
Реальная проблема ФЯ состоит в том, что явный отказ от состояний, переменных итп, приводит к тому что для выполнения таких задач где они нужны (хранение состояний, ввод-вывод) приходятся использовать разные изощренные конструкции типа монад, монадических преобразователей. А это очень сильно усложняет и запутывает программы. I/O-ориентированные программы на ФЯ писать очень тяжело, на том же C++ гораздо проще выходит.
Честно говоря, я вообще не понимаю, причём тут ФЯ.
В первой статье про них ни слова, во второй тоже
(пример на OCaml там с императивными циклами).
Так что это всё уже оффтоп.
> ... что явный отказ от состояний, переменных итп, приводит к тому
> что для выполнения таких задач где они нужны (хранение состояний, ввод-вывод)
> приходятся использовать разные изощренные конструкции типа монад,
> монадических преобразователей.
Монада - конструкция не изощрённая, а очень даже тупая, там всего две простых операции.
> А это очень сильно усложняет и запутывает программы.
> I/O-ориентированные программы на ФЯ писать очень тяжело, на том же C++ гораздо проще выходит.
Написать такое иногда бывает тяжело, прочитать и понять потом легко.
Пример с транзакциями на хаскеле, где использовались отложенные действия для отката,
у меня занял около 70 строк, из которых примерно половина - построение монады,
половина - объявления обратимых IO операций для примера и 2 строки сам пример.
Сколько будет весить откат транзакций на C++? Насколько он будет понятен?
Насколько он будет универсален?
Писать нужно на том, на чём удобнее.
Сколько будет весить откат транзакций на C++? Насколько он будет понятен?А сколько в нем будет ошибок!
Насколько он будет универсален?
Оставить комментарий
Chupa
IBM учит плохому: http://www-128.ibm.com/developerworks/linux/library/l-recurs.html