Моя любовь к функциональному программированию привела меня к уроку рекурсии. Тема, которая очень часто превращается в мемы, достаточно забавна, чтобы отпугнуть меня от изучения. И понял, что это дерн, на который еще не ступала нога. Итак, однажды я набрался храбрости и начал гуглить.

Я встречал много статей в блогах и видео на YouTube, в которых пытаются научить рекурсии, создавая функцию, которая выполняет факториал. Они действительно хороши, это помогает мне как можно быстрее изучить рекурсию, как функция может вызывать сама себя и продолжать повторяться, пока не вернет желаемый результат. Итак, если я могу помочь вам вспомнить это, код будет примерно таким (в LiveScript):

Факториал

До того, как вы перешли к этой статье, вы, вероятно, видели где-то похожий способ выполнения факториальной рекурсии. И если я могу вам это напомнить, функция «факт» - это рекурсивная функция, которая, когда ей задано число в качестве аргумента, будет продолжать умножать число, которое вы дали другой функции «факт», которая дает текущее число, вычтенное на 1. Это будет продолжаться до тех пор, пока данный аргумент не вернет 1, и он больше не будет выполнять рекурсию, а вместо этого вернет только 1.

Возможно, вам достаточно этого вида факториальной рекурсии, и вы ищете более сложный вариант для решения. Итак, я пролистал википедию, блестящую, ханскую академию, в поисках математической задачи с рекурсивным характером. И я нашел метод вычисления Пи, предложенный Грегори + Лейбницем, который выглядит примерно так:

Это, безусловно, более обширный способ вычисления числа Пи, чем обычный '22, разделенный на 7 ', но он обеспечивает лучшую точность результата числа Пи, когда его повторяют много раз. Каждый раз, когда вы складываете больше деления 4 на нечетное число, точность результата будет увеличиваться. И вы также можете заметить, что на каждом этапе оператор сложения и вычитания переключается, и я не хочу достаточно глубоко погружаться в математическую сферу, почему это было написано так или как это может дать более точное число Пи. Я, вероятно, оставлю это на вики-странице самого «Пи Лейбница».

Итак, с нашим текущим пониманием того, как работает рекурсия и как эта конкретная формула, кажется, имеет в ней рекурсивную природу, мне так хотелось попытаться создать рекурсивную функцию числа Пи, что при задании нечетного числа она будет повторяться до тех пор, пока он останавливается и возвращает намеченный результат. А теперь вот код, который я придумал:

Пи

Если честно, мне потребовался целый день, прежде чем я подошел к этой функции, просто чтобы показать вам, насколько я новичок в функциональном программировании, и все же сделал это полностью. Итак, позвольте мне объяснить, что функция делает с переданным ей нечетным аргументом.

Когда функции пи дано нечетное число 15 как len и ничего как истина, она вернет (4 / 15) + (* -1) pi (15 - 2), null, что означает, что повторяющееся пи в ней вернет (4 / 13) + (* 1) pi (13 - 2), true и так далее, она будет продолжать уменьшать аргумент len на 2, пока не достигнет (4 / 3) + (* -1) pi (3-1), который вернет 4 вместо того, чтобы повторять его снова. Он был разработан, чтобы прекратить рекурсию, когда он достигает 1 в качестве аргумента len и возвращает 4, или он будет продолжать уменьшаться и повторяться бесконечно.

Итак, когда мы вызываем функцию пи и даем 21 в качестве аргумента, она вернет результат 3,23, что довольно далеко от наиболее известного числа пи (3,14). Но когда мы вызываем его снова, передавая 357 в качестве аргумента, он вернет результат 3,14, который теперь намного ближе к предполагаемому результату. По мере увеличения передаваемого числа len оно будет приближаться к реальному числу Пи, хотя никогда не достигнет его.

Построив эту функцию Пи, я наконец набрался смелости, чтобы использовать рекурсию при каждой возможности, которая у меня может появиться. Поэтому, когда я вижу рекурсивную природу / схему проблемы, я пытаюсь концептуализировать, как бы решить ее с помощью рекурсии. И я думаю, что могу смело сказать:

Когда вы (можете) увидеть рекурсивный характер проблемы, вы можете применить рекурсию для ее решения. Всегда.

Затем я оглядываюсь на проект, над которым сейчас работаю, и несколько других, и поражаюсь тому, сколько проблем содержит рекурсивный паттерн, и начинаю создавать для них рекурсивные функции. Таким образом, я совершаю множество изменений, которые устраняют старые функции, а некоторые из них были сделаны мной. Подходящий пример может быть таким:

Настоящая проблема

Как, если бы я хотел превратить каждую найденную в ней строку в заглавную и сделать из нее новый объект и сохранить его структуру данных. Или как, если я хочу получить каждую строку и собрать их в массив. Или замените каждый найденный алфавит «y» в каждой строке на «x». Как бы то ни было, мы хотели бы иметь функцию, которая при задании любого объекта или массива с любой структурой должна возвращать желаемый результат, и именно здесь на помощь приходит рекурсия.

Проблема, аналогичная описанной выше, может быть найдена в моем текущем проекте mithril-autoform, библиотеке, которая помогает разработчику MithrilJS создавать формы и все их функции, просто определяя схему. Вы можете взглянуть и увидеть, как часто я использую рекурсию, чтобы библиотека работала, и поэтому это будет рассматриваться как доказательство того, что рекурсия может решать больше, чем математические задачи.

Желаю, чтобы эта статья помогла вам и побудила меня узнать больше об огромном мире функционального программирования, и я тоже.

Рики Пердана, разработчик Full Stack Meteor, покрыт MithrilJS, и в моем сердце FP. Давайте узнаем друг друга https://github.com/rikyperdana

✉️ Подпишитесь на рассылку еженедельно Email Blast от CodeBurst 🐦 Подпишитесь на CodeBurst на Twitter , просмотрите 🗺️ Дорожная карта веб-разработчиков на 2018 год и 🕸️ Изучите веб-разработку с полным стеком .