Несколько определений о функциональном программировании

Это не про функции!

В программировании есть два больших подхода — императивное и функциональное. Они существенно отличаются логикой работы, ещё и создают путаницу в названиях. Сейчас объясним.

Нет. Функциональное — это не про функции. Функции есть почти в любых языках программирования: и в функциональных, и в императивных. Отличие функционального программирования от императивного — в общем подходе.

Метафора: инструкция или книга правил

Представьте, что вы открываете кафе-столовую. Сейчас у вас там два типа сотрудников: повара и администраторы.

Для поваров вы пишете чёткие пошаговые инструкции для каждого блюда. Например:

  1. Налить воды в кастрюлю

  2. Поставить кастрюлю с водой на огонь

  3. Добавить в кастрюлю с водой столько-то соли

  4. Если нужно приготовить 10 порций, взять одну свёклу. Если нужно приготовить 20 порций, взять две свёклы.

  5. Почистить всю свёклу, которую вы взяли

  6. … Повар должен следовать этим инструкциям ровно в той последовательности, в которой вы их написали. Нельзя сначала почистить свёклу, а потом взять её. Нельзя посолить кастрюлю, в которой нет воды. Порядок действий важен и определяется вами. Это пример императивного программирования. Вы повелеваете исполнителем. Можно сказать, что исполнители выполняют ваши задания.

Для администратора вы пишете не инструкцию, а как бы книгу правил:

  • У нас нельзя со своим. Если гости пришли со своим, то сделать им замечание такое-то.

  • В зале должно быть чисто. Если в зале грязно, вызвать уборщика.

  • Если образовалась очередь, открыть дополнительную кассу.

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

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

Программисты, не бомбите.

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

Как же без них?

Абстракция

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

Несмотря на то что рассказы будут сильно отличаться между собой, у них будет несколько общих моментов про телефон:

  • у телефона есть трубка;

  • в трубку мы говорим, из трубки — слушаем;

  • можно набрать номер нужного человека и позвонить ему;

  • если вам позвонят по телефону, вы это услышите и примете звонок.

Получается, что если представить абстрактный телефон, то получится такое устройство с динамиком, микрофоном и средством набора номера.

Это и есть абстракция: когда мы описываем только самые существенные детали, которые важны для задачи.

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

Абстракция - это когда мы сосредотачиваемся только на существенных для задачи деталях и игнорируем всё остальное. В ООП абстракция означает, что для каждого объекта мы задаём минимальное количество методов, полей и описаний, которые позволят нам решить задачу. Чем меньше характеристик, тем лучше абстракция, но ключевые характеристики убирать нельзя.

Чтобы работать с абстракциями, используют интерфейсы.

Интерфейс

Итак, у нас есть некое устройство с трубкой, микрофоном, динамиком и средством набора номера. Но если вы вспомните рассказы мамы, бабушки и подруги, то обнаружите вот что:

  • в микрофон говорят, чтобы собеседник мог вас услышать;

  • чтобы слышать самому, ухо прикладывают к динамику;

  • чтобы набрать номер, нужно с помощью номеронабирателя вызвать нужную последовательность цифр;

  • когда идёт вызов, слышны гудки в динамике.

Всё это - интерфейсы.

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

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

Интерфейсы - это действия над объектом, доступные другим объектам (поэтому они называются публичными).

Есть ещё инкапсулированные, то есть внутренние методы. Например, у микрофона есть публичный метод «Слушать голос», и есть внутренний метод «Преобразовать голос в электрические сигналы». С его помощью он взаимодействует с другими частями нашего абстрактного телефона при поддержке средств инкапсуляции.

Сложная терминология

Строго говоря, интерфейсы - это не действия, а методы.

Сейчас объясним.

В программировании есть операции — это простейшие действия, например, скопировать значение из одной переменной в другую.

Из простых действий составляются функции — это когда несколько операций «склеиваются» в нечто единое. Мы даём этой склейке название и получаем функцию.

Например, может быть функция «проверить правильность электронного адреса», которая состоит из нескольких десятков простых операций.

На языке ООП функции, привязанные к объектам, называются методами. Просто такой термин. По сути, это функции, то есть склеенные вместе операции.

Итого: метод — это набор простых действий, которые склеили в единое целое и засунули в объект.

Для чего это всё

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

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

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

Где применяется и кому подходит

Самое подходящее место для применения, это стартапы и небольшие проекты.

Для стартапов будет плюсом высокая скорость разработки и мгновенная обратная связь от пользователей, поэтому большинство новых проектов делается именно так.

Что немаловажно, в небольших проектах чаще всего важнее уложиться в бюджет.

Вместо эпилога

Руководствуясь вышеизложенным, было разработано логическое ядро инструмента с интерфейсной абстракцией для проведения функционального программирования процессов управления аппаратными компонентами на бинарной логике в том числе и медийной инкапсуляцией команд:

Комментарии (22)


  1. panzerfaust
    08.09.2022 18:09
    +9

    Вы в начале описываете декларативный подход, а не функциональный. Есть определения для того и другого. Как правило, ФП присуща декларативность, но это не тождественные понятия. Например, SQL декларативный язык, но не то что бы очень функциональный. А, например, функторы и декларативны и повсеместно встречаются в ФП.


    1. beeptec Автор
      08.09.2022 21:30
      -2

      Не стал дублировать ответ


      1. tzlom
        09.09.2022 13:04

        Жалоба на минусы не разрешает проблему что SQL декларативный но не функциональный, а например лисп функциональный но не декларативный.

        Ваша аналогия про ФП не верна


        1. beeptec Автор
          09.09.2022 13:34
          -1

          SQL тоже как бы декларативный, но неожиданно все его команды являются императивными по сути. SELECT, CREATE, ALTER, DROP, INSERT, UPDATE, DELETE и т. д., а декларативными являются только описания условий их выполнения.
          Кстати тот же Prolog, который обычно и приводят в качестве примера декларативного языка программирования, аналогично «замаскирован» императивным оператором в виде знака вопроса. Он кажется естественным и логичным, как же без него? Но по своей сути, это императивная конструкция.
          Wiki Вам в помощь, найти чисто-декларативный язык программирования без императивных операторов.
          В контексте в.с. я все же прошу обратить внимание на 2-ю часть публикации.
          Любой интерфейс, это действительно декларативная часть императивного языка!
          ООП - это обкатанная практикой технология, которая совмещает декларатив с императивом и позволяет освоившим ее вкусно кушать и мягко спать!


          1. tzlom
            09.09.2022 14:11
            +1

            но неожиданно все его команды являются императивными

            Нет, не являются. Каждый запрос это отдельная программа, это видно из BNF языка

            аналогично «замаскирован» императивным оператором в виде знака вопроса

            Знак вопроса в прологе не императивный - перестановка последовательности ?- не приводит к изменению ответа.

            В контексте в.с.

            Те, кто применяет ООП, будут согласны с тем что в.у. 

            Сокращения были мною не поняты, может стоит без них?


            1. beeptec Автор
              09.09.2022 15:31

              Нет, не являются. Каждый запрос это отдельная программа, это видно из BNF языка

              В SQL, Prolog и во многих других декларативных языках всегда присутствует внутренний механизм поиска решений, т.е. некий вычислитель.
              Декларативный стиль написания программ стал появляться только после создания высокоуровневых языков программирования. И основная цель создания данных языков сместилась на поиск решения под конечного пользователя, а не на упрощение генерации бинарных файлов с машинными инструкциями.

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

              Программисты, не бомбите.


              1. tzlom
                09.09.2022 18:46
                +1

                присутствует внутренний механизм поиска решений, т.е. некий вычислитель.

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

                ФП это про программирование без (изменяемых) переменных, а не про декларативный синтаксис


                1. beeptec Автор
                  09.09.2022 21:45

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


  1. slavenski
    08.09.2022 18:30
    +2

    Немного потерял нить, сначала речь идет о сравнение подходов, потом плавно перетекает в определения для ООП, или не для ООП, в общем, пока непонятно, надо перечитать, но сравнения интересные)


    1. beeptec Автор
      08.09.2022 21:18
      -1

      На момент написания этой статьи я был вдохновлен авторским анализом оригинальной публикации Eric Elliott, перевод оригинала здесь , что собственно в более краткой, не утомительной форме постарался изложить в контексте с ООП на уровне вербальных примеров.
      Судя по старту минусаторов, я это предвидел, было бы интересно вместо пустых минусов, услышать их мнение.
      Платформа, которая здесь в финале представлена, есть результат именно функционального программирования. Ядро платформы построено на G.


    1. beeptec Автор
      08.09.2022 21:28
      -1

      Тот факт, что ООП, в основе которого заложены именно методы для функционального программирования, однажды было создано и развивается по сей день для людей, которые не хотят или не имеют возможности углубляться в "настоящее" программирование, но сами хотят добиться результата. Те, кто применяет ООП, будут согласны с тем что в.у. разрешает думать по-человечески, и одновременно создавать программы. Кстати той же концепции придерживается National Instruments при создании такого интересного языка программирования как G.


      1. slavenski
        08.09.2022 21:45
        +5

        Это все великолепно, я понимаю о чем речь, но тогда статью надо было называть "я сделал это с помощью ФП", просто посыл в начале для меня был в том, что вы сравниваете эти вещи, а в целом получилось просто статья о том, что вот что такое ФП, и вот, что я сделал


        1. beeptec Автор
          08.09.2022 21:55

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


          1. slavenski
            08.09.2022 22:37
            +2

            потому что я вот заходил с целью действительно почитать про сравнение, а получил другое)


  1. GBR-613
    09.09.2022 07:41

    По-моему, то, что Вы описываете, во времена моего детства называлось "логическое программирование" (язык Prolog так работал). Говорить, что на этом построен ООП - это, мне кажется, совсем притянуто за уши.


    1. beeptec Автор
      09.09.2022 09:19
      -1

      Вы явно путаете, это да, построено с применением ООП.
      Что касается Prolog? это далеко не там и из другой области, больше для Data Science его парадигма - сопоставление с образцом в деревьях синтаксического анализа одного из естественных машинных языков. Язык стал неактуальным по причине аппаратной революции и какое то время был прикладным в образовании и исследованиях.
      Но как вижу тема не задалась, вместо комментов сыпят минусы, не удивляюсь, что свойственно на хабре и об этом много рассуждений...
      Ну и ладно.


  1. a2v86
    09.09.2022 19:02

    На мой взгляд в статьях про программирование надо всегда показывать код и конкретные примеры

    Странно что автор не решился перечислить какие языки функциональные, какие императивные т.д.


    1. beeptec Автор
      09.09.2022 19:16

      В публикации продемонстрирован видеоролик, который демонстрирует результат декларативного программирования на языке G, он же ООП, его ядро скомпилировано на 70% на С++. Что касается прочих языков в контексте статьи, я не стал дублировать множество статей на эту тему. У меня здесь в комментах одна такая шикарная ссылка указана, автор Eric Eliot.


      1. a2v86
        09.09.2022 20:56

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

        Из курса университета точно помню что в первую очередь это парадигмы языков программирования, функциональное, императивное, ооп, логичечкие (пролог) т.д вот ещё например,непонимаю,вы отнесли интерфейс к методам.Либо уточните в каком языке интерфейс == метод.В ООП это абстрактный тип данных.

        Лайк не ставил ,дислайк тоже,лично по мне не хватает точности определениям, нет примеров :(


        1. beeptec Автор
          09.09.2022 21:58

          Как выше в ответах уточнил, абстракция интерфейса как и логическое ядро выполнены в среде G (инженерный ООП).


  1. vep
    09.09.2022 19:24

    Пост выглядит сырым. Автору рекомендую книгу "Хит на Хабр".


    1. beeptec Автор
      09.09.2022 21:53

      Почитаю, ожидал от публикации несколько другой вектор обсуждений.
      Однако не писатель, вслух говорить намного сложней чем мысленно рассуждать...