Кейс : я работаю в компании, пишу приложение на Python, которое обрабатывает много данных в массивах. На данный момент я являюсь единственным разработчиком этой программы, но, вероятно, она будет использоваться / изменяться / расширяться в будущем (1-3 года) другим программистом, в данный момент мне неизвестным. Я, вероятно, не буду там напрямую помогать, но, возможно, окажу некоторую поддержку по электронной почте, если у меня будет время.
Итак, как разработчик, который изучил функциональное программирование (Haskell), я склонен решать, например, фильтрацию следующим образом:
filtered = filter(lambda item: included(item.time, dur), measures)
Остальная часть кода - ОО, это всего лишь несколько небольших случаев, когда я хочу решить это следующим образом, потому что, на мой взгляд, он намного проще и красивее.
Вопрос : сегодня нормально писать такой код?
- Как разработчик, который не написал / изучил FP, реагирует на такой код?
- Это читабельно?
- Изменяемые?
Должен ли я написать документацию, как объяснить ребенку, что делает строка?
# Filter out the items from measures for which included(item.time, dur) != True
Я спросил моего босса, и он просто сказал: «FP - это чёрная магия, но если она работает и является наиболее эффективным решением, то можно использовать её».
Каково ваше мнение по этому поводу? Как не-FP программист, как вы реагируете на код? Является ли код "googable", чтобы вы могли понять, что он делает? Я хотел бы получить отзыв об этом.
# Select the item's from measures for which included(item.time, dur) == True
избегание двойного отрицания всегда улучшает понимание.Ответы:
Для меня: да, но я пришел к выводу, что сообщество Python часто считает списочные выражения более чистым решением, чем использование
map()
/filter()
.Фактически, GvR даже рассматривал возможность отказа от этих функций вообще.
Учти это:
Кроме того, преимущество заключается в том, что понимание списка всегда возвращает список.
map()
аfilter()
с другой стороны вернет итератор в Python 3.Примечание. Если вы хотите использовать вместо этого итератор, его просто заменить
[]
на()
:Честно говоря, я вижу мало причин для использования
map()
илиfilter()
в Python.Да, конечно, однако, есть одна вещь, которая делает это проще: сделать это функцией, а не лямбда-выражением.
Если ваше состояние становится более сложным, это значительно облегчит масштабирование, а также позволит повторно использовать ваш чек. (Обратите внимание, что вы можете создавать функции внутри других функций, это может держать его ближе к месту, где оно используется.)
Он ищет документацию по Python и знает, как она работает через пять минут. В противном случае он не должен программировать на Python.
map()
иfilter()
являются чрезвычайно просто. Не то чтобы ты просил их понять монады. Вот почему я не думаю, что вам нужно писать такие комментарии. Используйте правильные имена переменных и функций, тогда код почти не требует пояснений. Вы не можете предугадать, на каком языке разработчик не знает. Насколько вы знаете, следующий разработчик может не знать, что такое словарь.То, что мы не понимаем, обычно не читаемо для нас. Таким образом, вы можете утверждать, что оно не менее читабельно, чем понимание списка, если вы никогда не видели ни одного из них раньше. Но, как упоминал Джошуа в своем комментарии, я тоже считаю, что важно соответствовать тому, что используют другие разработчики - по крайней мере, если альтернатива не дает существенного преимущества.
источник
map
иfilter
в Python 3.reduce
контрпример к тому, что вы всегда можете использовать аргумент для понимания списка , поскольку его относительно сложно заменитьreduce
встроенным генератором или списком.Поскольку сообщество разработчиков восстанавливает интерес к функциональному программированию, нередко можно встретить некоторые функциональные программы на языках, которые изначально были полностью объектно-ориентированными. Хорошим примером является C #, где анонимные типы и лямбда-выражения позволяют быть намного короче и выразительнее благодаря функциональному программированию.
При этом функциональное программирование странно для начинающих. Например, когда во время учебного курса я объяснял новичкам, как они могут улучшить свой код с помощью функционального программирования на C #, некоторые из них не были убеждены, а некоторые говорили, что исходный код легче понять для них. Я привел им следующий пример:
Код перед рефакторингом:
Тот же код после рефакторинга с использованием FP:
Это заставляет меня думать, что:
вам не стоит беспокоиться, если вы знаете, что у следующего разработчика, который будет поддерживать ваш код, будет достаточно общего опыта и некоторых знаний функционального программирования, но:
в противном случае либо избегайте функционального программирования, либо оставьте подробный комментарий, объясняющий одновременно синтаксис, преимущества и возможные предостережения вашего подхода по сравнению с нефункциональным программированием.
источник
Я не программист FP, и недавно я должен был изменить код моего коллеги в JavaScript. Был Http-запрос с обратным вызовом, который очень напоминал включенное вами утверждение. Я должен сказать, что мне потребовалось некоторое время (например, полчаса), чтобы все это выяснить (в целом код был не очень большим).
Там не было никаких комментариев, и я думаю, что в этом не было необходимости. Я даже не попросил своего коллегу помочь мне понять его код.
Учитывая, что я работаю около 1,5 лет, я думаю, что большинство программистов смогут понять и изменить такой код, поскольку я это сделал.
Кроме того, как сказал в своем комментарии Йоахим Зауэр, во многих языках часто встречаются фрагменты FP, например C # (indexOf, например). Так много не-FP программистов имеют дело с этим довольно часто, и фрагмент кода, который вы включили, не является чем-то ужасным или непонятным.
источник
Я бы сказал определенно да!
Существует много аспектов функционального программирования, и использование функций высшего порядка, как в вашем примере, является лишь одним из них.
Например, я считаю, что написание чистых функций чрезвычайно важно для любого программного обеспечения, написанного на любом языке (где под «чистым» я подразумеваю отсутствие побочных эффектов), потому что:
Я также часто избегаю мутирования значений и переменных - еще одна концепция, заимствованная из FP.
Оба эти метода отлично работают в Python и других языках, которые обычно не классифицируются как функциональные. Они часто даже поддерживаются самим языком (то есть
final
переменными в Java). Таким образом, будущие программисты по обслуживанию не столкнутся с огромным барьером для понимания кода.источник
У нас было то же самое обсуждение компании, в которой я работал в прошлом году.
Дискуссия касалась «магического кода», и нужно ли его поощрять или нет. Если взглянуть на это немного больше, то казалось, что у людей совершенно разные взгляды на то, что на самом деле было «магическим кодом». Те, кто поднял обсуждение, в основном имели в виду, что выражения (в PHP), которые использовали функциональный стиль, были «магическим кодом», тогда как разработчики, которые происходили из других языков, которые использовали больше стиля FP в своем коде, похоже, думали, что магический код был скорее когда вы сделали динамическое включение файлов через имена файлов и так далее.
Мы никогда не пришли к какому-либо хорошему заключению по этому поводу, более того, люди думают, что код, который выглядит незнакомым, «магический» или трудно читаемый. Так стоит ли избегать кода, который кажется незнакомым другим пользователям? Я думаю, что это зависит от того, где это используется. Я бы воздержался от использования выражений в стиле fp (динамическое включение файлов и т. Д.) В основном методе (или важных центральных частях приложений), где данные должны передаваться в туннеле понятным и простым для чтения, интуитивно понятным способом. С другой стороны, я не думаю, что нужно бояться выдвигать конверт, другие разработчики, вероятно, быстро изучат FP, если столкнутся с кодом FP и, возможно, найдут хороший внутренний ресурс для консультаций по этим вопросам.
TL; DR: Избегайте высокоуровневой центральной части приложений (которые необходимо прочитать для обзора функциональности приложения). В противном случае используйте это.
источник
Сообщество C ++ недавно также получило лямбду, и я считаю, что у них примерно такой же вопрос. Ответ не может быть тем же, хотя. С ++ эквивалент будет:
Сейчас
std::copy
это не ново, и_if
варианты тоже не новы, но лямбда есть. Тем не менее, он довольно четко определен в контексте:dur
он захвачен и, следовательно, является постоянным,Item i
изменяется в цикле, и одинreturn
оператор выполняет всю работу.Это выглядит приемлемым для многих разработчиков C ++. Я не пробовал мнения о лямбдах более высокого порядка, и я бы ожидал гораздо меньшего принятия.
источник
Отправьте фрагмент кода партнеру, который не так свободно говорит на python, и спросите его, может ли он потратить 5 минут на проверку кода, чтобы понять, понимает ли он его.
Если да, вы, вероятно, хорошо идти. Если нет, вы должны сделать это более понятным.
Может ли ваш коллега быть глупым и не понимать чего-то, что должно быть очевидным? Да, но вы всегда должны программировать в соответствии с KISS.
Может быть, ваш код более эффективен / красив / элегантен, чем более простой и защищенный от идиотов подход? Тогда вам нужно спросить себя: нужно ли мне это делать? Опять же, если ответ отрицательный, не делайте этого!
Если после всего этого вы все еще думаете, что вам нужно и хотите сделать это способом FP, тогда непременно сделайте это. Доверьтесь своим инстинктам, они лучше подходят для ваших нужд, чем большинство людей на любом форуме :)
источник