Отладка программы: 3 типа ошибок

Содержание

Часть 3 – Отладка программы

В предыдущей части мы рассмотрели исходный код и его составляющие.

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

Отладка программы

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

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

отладка программы

Синтаксические ошибки

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

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

Семантические ошибки

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

Рассмотрим данный пример:

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

3 + 5, заключенные в скобки, дадут желаемый результат, а именно 48.

Ошибки в процессе выполнения

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

Вот хороший пример:

Фрагмент кода выше будет скомпилирован успешно, но input 25 приведет к ZeroDivisionError. Это ошибка во время выполнения. Другим популярным примером является StackOverflowError или IndexOutofBoundError. Важно то, что вы идентифицируете эти ошибки и узнаете, как с ними бороться.

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

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

Отладка программы

Вот несколько советов о том, как правильно выполнять отладку:

Двигаемся дальше

Поздравляем! Слово «ошибка» уже привычно для вас, равно как и «отладка программы». В качестве новичка вы можете изучать кодинг по книгам, онлайн-урокам или видео. И даже чужой код вам теперь не страшен :)

В процессе кодинга измените что-нибудь, чтобы понять, как он работает. Но будьте уверены в том, что сами написали.

Функциональное тестирование программного обеспечения

Функциональное тестирование программного обеспечения

Функциональное тестирование программного обеспечения

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

В зависимости от степени доступа к коду системы можно выделить два типа функциональных испытаний:

⦁ тестирование black box (черный ящик) – проведение функционального тестирования без доступа к коду системы,
⦁ тестирование white box (белый ящик) – функциональное тестирование с доступом к коду системы.
Тестирование black box проводится без знания внутренних механизмов работы системы и опирается на внешние проявления ее работы. При этом тестировании проверяется поведение ПО при различных входных данных и внутреннем состоянии систем. В случае тестирования white box создаются тест-кейсы, основанные преимущественно на коде системы ПО. Также существует расширенный тип black-box тестирования, включающего в себя изучение кода, – так называемый grey box (серый ящик).

Ключевые преимущества

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

Основные этапы функционального тестирования

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

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

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

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

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

Системное тестирование — Проверка соответствия ПО требованиям, заявленным в спецификации

Тестирование мобильных приложений — Выявление дефектов в работе графического интерфейса

Тестирование установки — Тестирование процесса инсталляции/деинсталляции программного обеспечения

Конфигурационное тестирование — Проверка работы ПО на различных программных и аппаратных окружениях.

Интеграционное тестирование — Тестирование взаимодействий между компонентами системы и между несколькими системами.

Smoke-тестирование — Короткий цикл тестов для выявления правильной работы основных функций приложения.

Тестирование документации — Проверка документов на соответствие принятым стандартам, а также соответствие определенным характеристикам

Обеспечение тестового покрытия — Оценка плотности покрытия системы тестами

Тестирование удобства использования — Определение степени удобства использования, понятности и привлекательности разрабатываемого продукта

Регрессионное тестирование

Функциональное тестирование программного обеспечения

Каждый раз при внесении изменений в систему, либо дополнения ее новым функционалом, существует

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

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

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

Ключевые преимущества

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

Основные этапы

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

Интеграционное тестирование

Функциональное тестирование программного обеспечения

Многие современные ИТ-системы взаимодействуют с другими системами и модулями, поэтому крайне

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

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

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

Ключевые преимущества

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

⦁ Предотвращение появления критичных ошибок в опытно-промышленной эксплуатации;
⦁ Снижение влияния человеческого фактора;
⦁ Экономия затрат на исправление дефектов.

Основные задачи

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

Способы проведения интеграционного тестирования подбираются в зависимости от интеграционных решений.

Этапы

⦁ Разработка тест-плана – руководства к действию для тестировщиков;
⦁ Формирование тестовых данных и создание тест-кейсов;
⦁ Реализация сценариев для запуска тест-кейсов;
⦁ Выполнение тест-кейсов и исправление ошибок;
⦁ Повторение цикла тестирования до успешной интеграции.

Тестирование безопасности

Функциональное тестирование программного обеспечения

Тестирование безопасности проводится с целью оценки устойчивости системы к противоправным

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

таких систем функционального тестирования оказывается недостаточно.

Ключевые преимущества

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

Основные задачи

⦁ Анализ архитектуры и построение модели угроз и рисков
⦁ Определение критериев защищенности
⦁ Поиск уязвимостей в исходном коде
⦁ Fuzz тестирование
⦁ Тестирование на проникновение
⦁ Тестирование, основанное на рисках
⦁ Проведение нагрузочного тестирования

Этапы

⦁ Подготовка: сбор информации, уточнение деталей;
⦁ Планирование: анализ уязвимостей системы и возможных угроз, составление матрицы рисков;
⦁ Проектирование: определение параметров защищенности системы, анализ кода, элементарные тесты;
⦁ Разработка: ввод неожиданных, неправильных, нетипичных данных (fuzz-тестирование), оценка нефункциональных составляющих ПО, модель тестирования на рисках;
⦁ Внедрение: ⦁ нагрузочное тестирование, тесты на проникновение.

Smoke-тестирование

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

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

Ключевые преимущества

⦁ Выявление критичных ошибок в первые несколько часов (минут) после установки
⦁ Снижение рисков вывода некачественного продукта;
⦁ Минимизация рисков при интеграции систем;
⦁ Сокращение затрат на исправление дефектов;
⦁ Ускорение проверки за счет автоматизации.

Основные задачи

⦁ Выбор тестовых сценариев, таким образом, чтобы обеспечить тестовое покрытие наиболее приоритетных функций системы.
⦁ Определение количества SMOKE-тестов и времени их выполнения. Обычно для SMOKE-тестов выбирается не более 10 сценариев с временем их выполнения в несколько часов.
⦁ Написание сценариев тестирования, описание шагов воспроизведения и ожидаемых результатов их выполнения. По желанию клиента сценарии могут быть автоматизированы.
⦁ Выполнение SMOKE-тестов.

Системное тестирование

Функциональное тестирование программного обеспечения

Системное тестирование предназначено для тестирования

готового ПО в том состоянии, в котором оно будет внедряться в опытно-промышленную эксплуатацию.

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

Ключевые преимущества

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

Основные задачи

⦁ Определение подхода к составлению тестовых сценариев
⦁ Создание плана и методики испытаний
⦁ Подготовка тестовых данных
⦁ Проведение тестирования
⦁ Выявление некорректного использования ресурсов

Этапы

⦁ Тестовый план
⦁ Разработка тестов
⦁ Подготовка тестовых данных
⦁ Тестовые прогоны – автоматизированные и обычные
⦁ Составление отчета
⦁ Регрессионое тестирование после исправления ошибок

Тестирование документации

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

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

Ключевые преимущества

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

Тестирование документации включает тестирование нескольких уровней документации:

⦁ Бизнес-требования
⦁ Функциональные требования
⦁ Техническое задание
⦁ Руководства пользователей

Тестирование мобильных приложений

Функциональное тестирование программного обеспечения

Тестирование – важнейший этап разработки мобильных приложений. Этот вид тестирования позволяет проверить работоспособность приложения на различных устройствах и операционных системах в соответствии с заданными требованиями.

Ключевые преимущества

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

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

Обеспечение тестового покрытия

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

Ключевые преимущества

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

Основные задачи

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

Тестирование установки

Тестирование установки (инсталляционное тестирование) позволяет удостовериться в том, что ПО корректно устанавливается и настраивается, накат новых версий происходит без ошибок, а также есть возможность деинсталлировать и удалить данное ПО. Тестирование инсталляции необходимо проводить при создании ПО, после появления новой версии, а также при изменении конфигурации стенда.
Инсталляционное тестирование ПО рекомендуется проводить на разных платформах, ручным методом или с помощью автоматизации. На данный тип работ по тестированию влияют следующие факторы:
⦁ Какие платформы и операционные системы поддерживаются?
⦁ Каким образом будет распространяться программное обеспечение?
⦁ Кто будет устанавливать программное обеспечение?

Ключевые преимущества

Тестирование установки позволяет избежать таких проблем при установке ПО в промышленную среду, как:
⦁ Невозможность установить ПО
⦁ Потеря данных после установки новой версии
⦁ Невозможность откатиться до предыдущей версии

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

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

Тестирование удобства использования

Функциональное тестирование программного обеспечения

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

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

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

Основные задачи

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

В рамках данной задачи оценивается:

⦁ Сколько шагов нужно сделать для выполнения задачи?
⦁ Сколько времени требуется на выполнение задачи?
⦁ Сколько ошибок делает пользователь-новичок при выполнении задачи?
⦁ Какое впечатление осталось у пользователя от работы с программой?
⦁ Эмоции пользователя во время выполнения задачи.

Конфигурационное тестирование

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

Ключевые преимущества

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

Основные этапы конфигурационного тестирования

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

Что такое функциональное программирование

? Функциональное — это про функции?

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

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

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

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

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

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

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

Что такое функциональное программирование

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

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

Императивное программирование

Примеры языков: C, С++, Go, Pascal, Java, Python, Ruby

Императивное программирование устроено так:

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

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

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

Получается, что в разные дни функция получает на вход 1000 ₽, но возвращает разные значения — так работает императивное программирование, когда всё зависит от других переменных.

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

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

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

Звучит логично, и большинство программистов привыкли именно к такому поведению кода. Но функциональное программирование работает совершенно иначе.

Функциональное программирование

Примеры языков: Haskell, Lisp, Erlang, Clojure, F#

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

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

Функциональное программирование здесь идёт ещё дальше. В нём весь код — это правила работы с данными. Вы просто задаёте нужные правила, а код сам разбирается, как их применять.

Если мы сравним принципы функционального подхода с императивным, то единственное, что совпадёт, — и там, и там есть команды, которые язык может выполнять. Всё остальное — разное.

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

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

Функции всегда возвращают одно и то же значение, если на вход поступают одни и те же данные. Если в прошлом примере мы отдавали в функцию сумму в 1000 ₽, а на выходе получали скидку в зависимости от дня недели, то в функциональном программировании если функция получит в качестве параметра 1000 ₽, то она всегда вернёт одну и ту же скидку независимо от других переменных.

Можно провести аналогию с математикой и синусами: синус 90 градусов всегда равен единице, в какой бы момент мы его ни посчитали или какие бы углы у нас ещё ни были в задаче. То же самое и здесь — всё предсказуемо и зависит только от входных параметров.

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

В русском языке всё работает точно так же: есть правила правописания и грамматики. Нам неважно, в каком порядке мы их изучили, главное — чтобы мы их вовремя применяли при написании текста или в устной речи. Например, мы можем сначала пройти правило «жи-ши», а потом правило про «не с глаголами», но применять мы их будем в том порядке, какой требуется в тексте.

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

Источники:

https://proglib. io/p/debugging/

https://daglab. ru/funkcionalnoe-testirovanie-programmnogo-obespechenija/

https://thecode. media/func/

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: