Ми зробили це за допомогою функціонального програмування


Насамперед вибачаюсь за те, про що хочу розповісти та продемонструвати викладено російською мовою. Я багато років не живу в Україні, а там, де мешкаю, нічого спільного зі слов’янськими мовами не пов’язано, крім вихідців із країн колишнього СРСР.

Я щиро вірю у вашу перемогу і підтримую вашу батьківщину своїми справами. Слава та перемога Україні.

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

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

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

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

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

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

  1. Налить воды в кастрюлю
  2. Поставить кастрюлю с водой на огонь
  3. Добавить в кастрюлю с водой столько-то соли
  4. Если нужно приготовить 10 порций, взять одну свёклу. Если нужно приготовить 20 порций, взять две свёклы.
  5. Почистить всю свёклу, которую вы взяли
  6. ... Повар должен следовать этим инструкциям ровно в той последовательности, в которой вы их написали. Нельзя сначала почистить свёклу, а потом взять её. Нельзя посолить кастрюлю, в которой нет воды. Порядок действий важен и определяется вами. Это пример императивного программирования. Вы повелеваете исполнителем. Можно сказать, что исполнители выполняют ваши задания.

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

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

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

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

Абстракция.

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

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

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

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

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

Интерфейс.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Жопа — универсальный интерфейс. Потому что через жопу можно сделать всё что угодно.
© народная мудрость

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

Хотите понять, почему программы такое дерьмо? Посмотрите на то, что люди пишут для людей, когда касается правил и законов. Даже тех самых инструкций. Вот и в программировании так же: многие нормы придуманы не чтобы сделать программу эффективнее или понятнее, но чтобы прикрыть жопы её издателей, чтобы устроить показушную показуху, и ещё 100500 артефактов системы, где люди совы — эффективные менеджеры оценивают людей.

Парадигма функціонального та імперативного методів програмування

Функціональна парадигма протиставляється процедурній або ООП.
Імперативний підхід зазвичай протиставляють декларативному (який може бути як функціональним, так і логічним або ООП)

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

Незалік. Ідіть вчіть далі.

смысл функционального программирования в том, чтобы описать не сами чёткие шаги к цели, а правила, по которым компилятор сам должен дойти до нужного результата.
Будь ласка, якшо ви подужали всю публiкацiю, прокоментуйте вiдео приклад, що надан у кiнцевiй частинi
чтобы описать не сами чёткие шаги к цели, а правила, по которым компилятор сам должен дойти до нужного результата.
декларативному (який може бути як функціональним, так і логічним або ООП)

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

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

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

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

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

Помигать ледом 10 раз на ассембле (архитектура STM32):
Код:

@GNU AS

@ Настройки компилятора
.syntax unified @ тип синтаксиса
.thumb @ тип используемых инструкций Thumb
.cpu cortex-m3 @ микроконтроллер

.include «STM32F100.INC» @ файл определений микроконтроллера

@ макрос псевдокоманды MOV32, пока просто используем, не вникая как, что и почему
.macro MOV32 regnum,number
MOVW \regnum,:lower16:\number
MOVT \regnum,:upper16:\number
.endm

@ таблица векторов прерываний
.section .text

.word 0×20010000 @ Вершина стека
.word Riset+1 @ Вектор сброса

Riset:
mov r0,r0
mov r0,r0
mov r0,r0
@ включим тактирование GPIOH
MOV32 R0, RCC_APB2ENR @ адрес
MOV32 R1, 0×04 @ значение
LDR R2, [R0] @ прочитали значение регистра
ORR R1, R1, R2 @ логическое, побитовое ИЛИ: R1= R1 ИЛИ R2
STR R1, [R0] @ запись R1 по адресу указанному в R0

@ установим режим GPIOH PH2
MOV32 R0, GPIOA_CRL @ адрес
MOV32 R1, 0×[email protected]×2000 @ значение
LDR R2, [R0] @ прочитали значение регистра
ORR R1, R1, R2 @ логическое, побитовое ИЛИ: R1= R1 ИЛИ R2
STR R1, [R0] @ запись R1 по адресу указанному в R0

BLINK_LOOP:
@ включим светодиод
MOV32 R0, GPIOA_BSRR @ адрес
MOV32 R1, 0×08 @ значение
STR R1, [R0] @ запись R1 по адресу указанному в R0

MOV32 R0, GPIOA_ODR
LDR R2, [R0]

@BL DELAY @ пауза
@ выключим светодиод
@MOV32 R0, GPIOA_BSRR @ адрес
@MOV32 R1, 0×08 << (1*16) @ значение 1-размер поля, 16-во второе полуслово
@STR R1, [R0] @ запись R1 по адресу указанному в R0

@BL DELAY @ пауза

B BLINK_LOOP @ делаем цикл

DELAY:
MOV32 R2, 0×00100000 @ повтор цикла задержки 0×0010 0000 раз.
Delay_loop:
SUBS R2, R2, 1
BNE Delay_loop
BX LR
.end
===================
Аналогично, вместо кода функциональные инструкции декларативно в абстрактном построенном на ООП интерфейсе (архитектура х86):
habrastorage.org/...​44e2641a51b675bc76809.jpg
Вот и рассуждайте теперь, как с каланчи классического кодера, по ходу пораскинуть здесь ветки, устроить кострище и увиденное придать анафеме.

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

Про функції, а функції котрі є в почті в любих язиках, не завжди функції. Так сказать в не функціональних мовах, не все то функція, шо назване функцією.

Підписатись на коментарі