Какие функциональные языковые приемы можно использовать в императивных языках?
Какие методы или парадигмы, обычно ассоциируемые с функциональными языками, могут продуктивно использоваться и в императивных языках?
например:
- Рекурсия может быть проблематичной в языках без оптимизации хвостового вызова, ограничивая ее использование узким набором случаев, поэтому она имеет ограниченную полезность
- Карта и фильтр нашли свое применение в нефункциональных языках, хотя они имеют функциональный вид
Мне действительно нравится не беспокоиться о состоянии в функциональных языках. Если бы я был особенно упрям, я мог бы писать программы на C без изменения переменных, только заключая в капсулу мое состояние в переменных, передаваемых в функции, и в значениях, возвращаемых из функций.
Хотя функции не являются значениями первого класса, я могу заключить их в объект в Java, скажем, и передать их в другой метод. Как и функциональное программирование, просто меньше удовольствия.
Итак, для ветеранов функционального программирования, когда вы программируете на императивных языках, какие идеи из FP вы успешно применили?
5 ответов
Почти все из них?
Если вы понимаете функциональные языки, вы можете написать императивные программы, которые "информированы" функциональным стилем. Это уведет вас от побочных эффектов и к программам, в которых чтение текста программы в любой конкретный момент достаточно, чтобы вы действительно знали, в чем смысл программы в этот момент.
Еще на заре времени мы привыкли беспокоиться о "сцеплении" и "сплоченности". Изучение FP приведет вас к написанию систем с оптимальной (минимальной) связью и высокой связностью.
Вот вещи, которые мешают делать FP на языке не-FP:
- Если язык не поддерживает лямбда / замыкания и не имеет синтаксического сахара, который легко взломать, вы мертвы в воде. Вы не называете карту / фильтр без замыканий.
- Если язык статически типизирован и не поддерживает дженерики, вы мертвы в воде. Все хорошие вещи FP используют универсальность.
- Если язык не поддерживает хвостовую рекурсию, вам мешают. Вы можете написать реализацию, например, 'map' итеративно; также часто ваши данные могут быть не слишком большими, и рекурсия будет в порядке.
- Если язык не поддерживает алгебраические типы данных и сопоставление с образцом, вы будете слегка затруднены. Просто раздражает не иметь их, как только ты попробуешь их.
- Если язык не может выражать классы типов, ну да ладно... вы обойдетесь, но, черт побери, если это не просто самая удивительная функция, но Haskell - единственный удаленно популярный язык с хорошей поддержкой.
Отсутствие первоклассных функций действительно мешает написанию функциональных программ, но есть несколько вещей, которые вы можете сделать, которые не требуют их. Во-первых, следует избегать изменчивого состояния - постараться, чтобы большинство или все ваши классы возвращали новые объекты, которые представляют измененное состояние, вместо того, чтобы вносить изменения внутренне. Например, если вы пишете связанный список с add
операции, вы хотели бы вернуть новый связанный список из add
в отличие от модификации объекта.
Хотя это может сделать ваши программы менее эффективными (из-за увеличения числа создаваемых и уничтожаемых объектов), вы получите возможность более легко отлаживать программу, поскольку состояние и работа объектов становятся более предсказуемыми, не говоря уже о возможности Гнездовая функция вызывает более глубоко, потому что они имеют входы и выходы состояния.
Я успешно использовал функции высшего порядка, особенно те, которые передаются, а не те, которые возвращаются. Вид, который возвращается, может быть немного утомительным, но может быть смоделирован.
Все виды аппликативных структур данных и рекурсивных функций хорошо работают на императивных языках.
Вещи, которые я скучаю больше всего:
Почти никакие императивные языки не гарантируют оптимизацию каждого хвостового вызова.
Я не знаю ни одного императивного языка, который бы поддерживал анализ случаев путем сопоставления с образцом.
Я знаю, что это старый вопрос, но ответы с примерами можно увидеть в этом видео на infoQ, которое углубляется в это.