Как стать автором
Обновить

Краткий справочник информатики

Программирование *Совершенный код *Проектирование и рефакторинг *Haskell *ООП *

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


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


Тип — это то, над чем компьютер умеет рассуждать. Рассуждать в смысле привычной человеческой или формальной логики, то есть по правилам строить некоторые заключения из исходных посылок. Хорошая новость в том, что компьютер делает это автоматически. Бывают разные системы типов: одни упраздняют определённый вид ошибок, таких как несоответствие типов, утечка ресурсов (Rust Borrow Checking); другие автоматически генерируют реализацию (Haskell Type Class, Scala & Rust Trait). Когда типы легко воспринимается человеком, то служат документацией. Сильные системы типов могут за вас делать больше работы, чем слабые. А статическая обработка типов сделает эту работу раньше, при компиляции, а не позже, при выполнении, как динамическая.


Класс в ООП — это одна из систем типов, которая позволяет рассуждать о внутренней структуре, какие внутри есть поля и методы. Аналоги: запись, кортеж, тип-произведение.


Наследование в ООП смешивает как минимум 4 идеи, которые стоит реализовывать отдельными способами:


  1. Наследование данных, довольно бесполезное после того, как они обернуты в getter/setter и превратились в методы с наследованием реализации. А пример прозрачного оборачивания — Elm Records и Haskell Records.
  2. Наследование реализации для повторного использования, рекомендуется заменять на делегирование.
  3. Наследование интерфейса (Ad hoc полиморфизм) перегружает метод, то есть позволяет по одному имени получить разную реализацию для каждого типа. Аналоги: Java Interface, Scala & Rust Trait, Haskell Type Class; алгебра как тип данных и набор операций на этом типе.
  4. Объединение типов аналогично Java Enum, Scala Case Class, Elm & Haskell Algebraic Data Type, тип-сумма.

Pattern Matching деконструирует алгебраический тип-сумму или тип-произведение, то есть это обратная конструктору операция.


Объект в ООП — замыкание, где свободные переменные являются полями, желательно приватными.


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


Полиморфизм бывает разным.


Типаж, интерфейс — тип-произведение, состоящее, в основном, из функций.


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


Visitor — шаблон проектирования, реализующий Pattern Matching.


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


Dependency Injection — шаблон проектирования, реализующий функцию высшего порядка, которая принимает зависимости и выдаёт продукт. Изоморфен шаблону Builder с поправкой на то, что зависимости, обычно, являются функциями.


Клиентская Web разработка — востребованный исторически сложившийся, но не уникальный набор идей, основанный на монопольном положении JavaScript.


MVC, MVP, MVVC — чистая функция и абстрактный автомат для обработки внешних событий.


Event Loop (Node.js, Rust tokio) — абстрактный автомат для обработки внешних событий.


Программирование — инженерная наука о композиция кода.


Теория категорий — фундаментальная теория о композиции чего угодно.


Изоморфизм — превращение или замена чего-либо во что-то другое и обратно, то есть суть изоморфных вещей одна.


Рефакторинг — изоморфизм, выполняемый людьми.


Оптимизация — изоморфизм, выполняемый компьютером.


(Чистая) функция — превращение одного в другое всегда одинаково.


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


Монада превращает один тип в другой, да так, что можно компоновать функции с побочным эффектом. Например, монада "ожидание" (Future, Promice) имеет побочным эффектом ожидание завершения длительной операции и преобразует тип "массив байт" в тип "ожидание массива байт", а тип "подтверждение" в тип "ожидание подтверждения". Передадим функции чтения имя файла и подождёт массив байт с диска. Затем передадим полученный массив байт функции отправки по сети и подождём, когда клиент подтвердит получение. А можно заменить пару ожиданий на одно составное (комбинатором (>>=), bind, and_then), которая сначала подождёт массив байт с диска, а потом подождёт подтверждения от клиента по сети, но главное, пропадёт явное промежуточное ожидание, позволив среде исполнения в это время заниматься другими полезными делами.


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


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


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



Квантовые вычисления работают не с битами, а с кубитами. Например, вместо шариков в Marble adding machine можно кидать Котов Шрёдингера. Например, пара котов даст 4 варианта: оба живых, первый живой, второй живой, нет выживших. В итоге за один запуск машины мы получим суммы всех возможных чисел. Проблема только в том, как превратить Котов Шрёдингера внизу машины в обычных котов, полезных в хозяйстве.


Зависимые типы — работа с типами и оптимизациями кода тем же способом (Pattern Matching и вычисления), что и со значениями. Зависимые типы позволяют переложить на компьютер работу с вычислимыми шаблонами и даже саму математику. Например, можно указать, что тип "множество элементов", когда элементов не более 64, можно заменить на тип u64, который поместится в регистр. Или компилятор может удостовериться, что размеры складываемых векторов одинаковы.


Дополнения и исправления принимаются.

Теги:
Хабы:
Всего голосов 19: ↑8 и ↓11 -3
Просмотры 5K
Комментарии 64
Комментарии Комментарии 64

Истории