Функциональное программирование просто другое или оно действительно сложнее ?
Скажем, кто-то, кто никогда раньше не учился программированию и обучен функциональному программированию. против кого-то, кто никогда не изучал программирование вообще, и обучается императивному программированию. что он найдет более жестким? или то же самое?
Мой вопрос: скажем, проблема сейчас в том, чтобы на верблюде
такой, который qwe_asd_zxc_rty_fgh_vbn
становитсяqweAsdZxcRtyFghVbn
Процессуальный путь это:
- разделить его вдоль
_
- перебрать массив, пропуская первый элемент
- для каждой записи мы пишем с заглавной буквы первую букву
- объединить результаты вместе
Функциональным способом является:
- если не могу найти
_
возвратinput
- разрезать
input
по первому_
(так, что мы получимqwe
иasd_zxc_rty_gfh_cvb
) - Прописать первую букву
head
и заключить, что сf(tail)
Хорошо, если у вас есть функциональный опыт и значительный опыт в процедурном программировании, я хотел бы спросить: вам понадобится больше времени, чтобы выяснить процедурный путь, или вам понадобится больше времени, чтобы выяснить функциональный путь?
Если у вас есть процедурный опыт, но у вас есть многолетний опыт работы с функциональным программированием, я хотел бы задать тот же вопрос: вам понадобится больше времени, чтобы выяснить процедурный путь, или вам потребуется больше времени, чтобы выяснить функционал путь?
map
шаг 3 вместо мутирующего цикла. Второй подход - это то, что я бы рассмотрел, только если в стандартной библиотеке нет функции разбиения (в этом случае ее следует сравнить с императивным решением, которое также не используетsplit
).x=x+1
может взорвать неожиданный мозг. Функциональное программирование естественно, это не более чем чисто и удобные строго математические функции.Ответы:
Просто другой. Функциональное программирование гораздо более тесно связано с математикой, с которой большинство людей знакомо. Вся эта вещь «неизменяемых переменных» только шокирует императивных программистов, где «изменчивое» мышление глубоко укоренилось.
Для новичков часто интуитивно понятно, что нельзя просто изменить стоимость чего-либо.
Там, где я изучал CS, нам преподавали функциональный язык как наш самый первый курс. И каждый, кто изучал C ++ или Java, раньше боролся с этим. Те, кто был новичком в программировании, подобрали его довольно легко.
источник
Это просто разные
Когда вы программируете, вы, по сути, переводите то, как вы мыслите, в код, расстояние между вашими мыслями и окончательным решением можно назвать «когнитивным разрывом». Чем больше разрыв, тем сложнее будет вам его преодолеть.
Если вы исходите из процедурного прошлого, вы научитесь мыслить процедурно, поэтому разрыв будет меньше, чем в функциональном коде, и наоборот.
Единственный способ для парадигмы программирования быть по своей природе проще, чем для чего-либо еще, - это если она сопоставляется с чем-то, что вы уже знаете, например с обычным языком, так что вы начинаете с более короткого разрыва.
Функциональное и процедурное в любом случае довольно изменчивое понятие, и они имеют тенденцию перекрываться
источник
Да, функциональное программирование, как правило, трудно понять многим людям (я бы сказал, особенно тем, кто сначала уже знаком с процедурным программированием).
Я бы также сказал, что ваш пример функционального программирования на самом деле не очень хороший пример функционального программирования. Он использует рекурсию и просто составляет результат вместо изменения состояния, но не намного.
Чтобы получить лучший пример функционального программирования, рассмотрим более общую проблему: вместо того, чтобы «искать знак подчеркивания и преобразовывать следующую букву в верхний регистр», рассмотрите это лишь как один особый случай поиска шаблона и выполнения некоторого произвольного кода, когда это найдено.
Многие языки поддерживают это, но для этого они требуют, чтобы мы указали шаблон как нечто вроде регулярного выражения. Регулярные выражения, тем не менее, представляют собой не что иное, как специализированный язык программирования, а реализация RE является компилятором и / или интерпретатором для этого языка. Результатом компиляции RE в основном является функция, которая выполняется (в специальной виртуальной машине RE), чтобы сопоставить выражение с некоторым вводом.
В чем-то вроде Perl вы используете специальный язык для определения шаблона и специальный компилятор для преобразования этой строки в какую-то функцию, похожую на функцию, и специальный интерпретатор, который принимает эту функцию как функцию для ее выполнения. На функциональном языке вы обычно используете сам язык для определения шаблона и используете собственный компилятор языка для создания реальной функции. Мы можем сгенерировать эту функцию на лету (примерно так же, как мы можем скомпилировать RE, когда захотим), но когда мы это сделаем, результат может выполняться как любая другая функция в языке, вместо того, чтобы требовать специальные вещи RE для этого.
В результате мы можем относительно легко обобщить описанную выше проблему. Однако вместо жесткого кодирования «_» и «верхнего регистра» непосредственно в преобразовании мы можем получить что-то вроде:
Но, в отличие от чего-то, где мы указываем шаблон как RE, мы можем указать шаблон непосредственно как реальную функцию и по-прежнему использовать его, что-то вроде:
И затем мы передаем эту функцию в S & R. Прямо сейчас это довольно тривиальная функция, и мы закодировали ее полностью статически. Функциональный язык в значительной степени становится интересным, когда мы используем его, как можем RE, и генерируем совершенно новую функцию на лету, основываясь на чем-то вроде пользовательского ввода, но в отличие от RE эта функция не требует специального интерпретатора RE для запуска - это просто нормальная функция, как и любая другая.
источник
Вот полный код в Racket :
Как функциональный программист с процедурным опытом, я не думаю, что мне понадобится больше времени, чтобы «найти» процедурное решение, но, несомненно, мне потребуется больше времени, чтобы его напечатать.
Кстати, пример ожидаемого результата в исходном сообщении неверен: в конце пропущена буква «h».
источник
Моя любимая теория заключается в том, что модели программирования легче понять, чем ближе они к реальной работе компьютеров. Указатели трудно понять, пока вы не поймете, что это по сути машинные адреса. Трудно понять рекурсию, пока вы сознательно не пройдете небольшой пример, не увидите кадры стека и не поймете, где хранятся различные значения одной и той же переменной. Это не означает, что программирование на ассемблере проще, чем программирование высокого уровня, но, увидев, как это делается, творит чудеса для ментальной модели, которая является ключом к мастерству - будь то программирование или вообще удобство использования.
Теперь процедурная модель несколько ближе к обычной архитектуре машины: присваивания - записи в память (или регистр). Вызовы процедур на самом деле просто причудливые переходы, на
if
самом деле условный переход и т. Д. Но в Лиспе, например, нет простого низкоуровневого эквивалента лексической привязке или лямбда-выражению. Понимание этого требует, чтобы вы представили совершенно отдельную абстрактную функциональную машину между уровнем языка и физической машиной, потому что, очевидно, большинство людей никогда не заходят так далеко.(Я буду знаком с идеей о том , что архитектура фона Неймана в конечном счете произвольно, и мы не должны умам лишать новичок с такими несущественными деталями архитектуры машины, и вместо того, чтобы непосредственно ввести их в семантику языков программирования. На самом деле, у меня есть Я сам преподавал несколько таких курсов, но все чаще чувствую, что это благородная, но ошибочная цель: люди учатся программированию, опираясь на понимание снизу вверх, а путь к функциональному программированию просто немного длиннее.)
источник
011011001001101...
будут самым простым языком для изучения!