Возьми? это как "Droppin Dimes", но... ладно, что угодно
Вы, наверное, слышали фразу «Есть несколько способов содрать шкуру с кошки». Если нет, то мне очень жаль, и, чтобы было ясно, ни одна кошка не пострадала при создании этой статьи. Также я не одобряю снятие шкуры с кошек. Но я отвлекся.
Вы, наверное, слышали — нет, *перезапустить* слово «парадигма» может сбивать с толку в контексте программирования. Парадигма — это просто способ смотреть на мир. И в нашей конкретной ситуации мир — это проблема, которую мы пытаемся решить с помощью нашей программы. Итак, я решил пройтись по разным парадигмам и дать вам несколько примеров и краткое объяснение каждой. TLDR внизу.
1/5 — Императивное программирование
Вероятно, вы начали с императивного программирования. Кто-то показывает вам, как написать сценарий для чего-то. Вы написали программу для своего 101 класса. Большинство из нас узнают, как работает программирование, составляя список инструкций и позволяя компьютеру следовать им. Это кажется несколько ограниченным, и я думаю, что только понимание программирования из этой парадигмы похоже на жизнь в 2D-мире.
Это самый простой способ начать программировать, но зачастую это самый сложный способ добиться цели.
Императивное программирование — это перечисление набора инструкций, которым должен следовать компьютер, а затем нажатие кнопки «Пуск». Вот пример C++ с операторами goto:
if (!doA())
goto exit;
if (!doB())
goto cleanupA;
if (!doC())
goto cleanupB;
/* everything has succeeded */
return;
cleanupB:
undoB();
cleanupA:
undoA();
exit:
return;
Это простой фрагмент кода, который берет текст из файла и меняет порядок символов в каждой строке, но сохраняет порядок строк. Он запустится один раз и завершится. Это может иметь побочные эффекты. Вы можете разбить весь код на что-то вроде этого, так как он будет скомпилирован в последовательные гудки и буп для вашего компьютера.
Поместите это в одну повторно используемую функцию с вводом имени файла, и она может быть функциональной, но идея состоит в том, что вы явно определяете и управляете вещами, выходящими за пределы вашей текущей области. Императивное программирование имеет множество хороших вариантов использования, но лучше всего его использовать в сочетании с другими парадигмами.
2/5 — Декларативное программирование
Для тех из вас, кто считает HTML, XML и другие языки разметки программированием, то это в основном и есть декларативное программирование. Вы объявляете фиксированное состояние. Языки запросов также считаются декларативными, и здесь все становится интереснее. Такие языки, как Prolog, основаны на состояниях и запросах, поэтому вы, по сути, создаете набор правил, которые должны выполняться, а реализация делает все остальное.
Я приведу вам пример PSQL, потому что я сделал это недавно, и я хочу сохранить Prolog для раздела логического программирования.
SELECT id, name, age FROM people WHERE age > 21 AND hair_color = 'brunette' ORDER BY age DESC;
Мы объявили некоторые квалификации, а механизм запросов сделает все остальное. Наслаждаться.
3/5 — Функциональное программирование
Функциональное программирование можно описать как машину, в которой один и тот же ввод всегда дает один и тот же результат. Важно вынести из функционального программирования отсутствие побочных эффектов. Функциональное программирование не манипулирует состоянием и не полагается ни на что за пределами своей области для выполнения задачи.
Вот пример javascript:
//this function returns the same thing regardless of the input const multiplyMe = (input) => { const multiplier = 2; return input * multiplier; } multiplyMe(2); //returns 4 multiplyMe(2); //still returns 4 multiplyMe(2); //I think you get the picture. //This function is not pure and changes each time we run it. let multiplicand = 1; const mutliplyChange = (input) => { multiplicand += 1; //multiplicand gets modified return input * multiplicand; } multiplyChange(2); //returns 4 multiplyChange(2); //returns 6 multiplyChange(2); //returns 8
Итак, вы видите, что во второй функции мы просто не можем доверять результату, и он считается «нечистым». Lisp — это язык программирования, который был разработан, чтобы быть функциональным, так что изучайте C-Lisp. Обещаю, будет весело ((((((((((())))))))))
4/5 — Объектно-ориентированное программирование
Объектно-ориентированное программирование (ООП) — это парадигма, в которой объекты, в отличие от функций, управляют потоком ваших программ. Объектно-ориентированное программирование фокусируется на соединении состояния со связанными функциями (называемыми мутаторами). Побочным продуктом этого является разделение вашего кода на полезные строительные блоки для более крупных и сложных систем. Для получения дополнительной информации о том, как это полезно, прочитайте о шаблонах проектирования от Gang of Four (статья об этом скоро появится). Такие языки, как C++, C#, Java, Python, Ruby, Rust и т. д., в основном построены на объектно-ориентированном программировании.
Вот пример класса JavaScript*:
class Person { constructor(name, age, weight, height, eyeColor, hairColor) { this.name = name; this.age = age; this.weight = weight; this.height = height; this.eyeColor = eyeColor; this.hairColor = hairColor; } description() { return `This is ${this.name}. He's ${this.age} years old, weighs ${this.weight}lbs, stands at ${this.height}, has ${this.eyeColor} eyes, and ${this.hairColor} hair.`; } birthday() { this.age += 1; } //I wish this worked this way workout() { this.weight -= .5; } } //So now I can use this in an imperative manner for demonstration purposes const michael = new Person('Michael', 23, 200, '6\'3"', 'brown', 'brown'); //200lbs lol goals console.log(michael.description()); michael.birthday(); michael.workout(); console.log(michael.description(); // now I'm 24 and I only weigh 199.5lbs!
Надеюсь, вы видите, что мой класс Person — это объект, содержащий состояние, которое изменяется с помощью мутаторов, которые я определил для класса. Объектно-ориентированное программирование — это именно то, что по своей сути. Для получения дополнительной информации посмотрите, наследование, инкапсуляция и блоки [jk, это должно быть программирование черного ящика или белого ящика и т. д. Я просто хотел запутать людей, и теперь я просто странно звучу, ка.]
5/5 — Логическое программирование
Логическое программирование превратит вас в волшебника! Это очень похоже на формальную логику. Идея состоит в том, что вы можете определять отношения, факты и правила и создавать запросы на основе этих фактов. Я нахожу это действительно приятным, потому что это делает программирование на Прологе похожим на волшебство. Вы создаете набор правил, а Prolog предлагает решение.
Я не занимался Прологом уже несколько десятилетий (или около 6 лет), так что это довольно простой пример.
//here's some relationship-defining stuff likes(michael,food). likes(michael,whisky). ?- likes(michael,food). yes. ?- likes(michael,whisky). no.
Здесь мы определяем факты и отношения. Мы можем абстрагироваться от этого в более сложную задачу, такую как решатель судоку. Вы создаете правила того, как должна выглядеть строка или столбец, а затем просите Prolog дать вам результат, соответствующий ограничениям. Другая забавная часть заключается в том, что вы можете заставить его продолжать выплевывать решения.
Прости. Это касательная больше сфокусирована на Прологе. Это должно дать вам представление о том, как мы мыслим в логическом программировании. Это парадигма, которая более специфична для языка.
6/5 — Процедурное программирование
Я обозначил процедурное программирование как 6/5, потому что оно очень похоже на императивное программирование. По сути, процедурное программирование — это реализация императивного программирования. PP (хе-хе) дополняет императивное программирование, потому что он в основном полагается на блоки и область видимости для управления потоком.
Итак, вот фрагмент javascript
let output = ''; const appendString = (input) => { output += input; } const fileFunction = () => { // file is limited to the scope of this function. const file = //get a bunch of text from a file. const lines = file.split('\n'); //separate the file into its lines for (var i = 0; i < lines.length; i++) { for (var j = lines[i].length - 1; j >= 0 ; j--) { appendString(j); } appendString('\n'); } console.log(output); // or writefile => output; } fileFunction(); //output now has been affected by this function without any obvious assignment
7/5
TLDR: прочтите статью :P
Парадигма — это всего лишь способ подхода к проблеме. Общие парадигмы:
- Императив — ваш традиционный javascript и то, как большинство людей учатся программировать. Вы просто выкладываете список инструкций, а у него есть побочные эффекты.
- Декларативная — вы определяете модель, и она происходит. Пролог подходит. Если вы считаете разметку (HTML, XML и т. д.) программированием, это тоже работает. React.js также поддерживает форму декларативного программирования.
- Функциональный — это отсутствие побочных эффектов, один и тот же вход превращается в тот же тип мысли на выходе. Так мы думаем, когда определяем «чистые» функции.
- Объектно-ориентированный — большинство языков, которые вы используете или использовали, будут совместимы**. Мы представляем мир/состояние нашей программы в объектах со структурой, методами и типами. Это имеет очень широкое определение.
- Логика — Пролог юсссссс. Вы определяете синтаксис и правила, модель исполнения и происходит волшебство.
- Процедурный — основанный на подпрограммах и подобных группировках функций. Go — недавний пример процедурного языка.
*(Поскольку язык слабо типизирован, вы можете вызвать некоторые ошибки во время выполнения, если не проверите типы должным образом. Но я не пытаюсь придираться)
**Я говорю совместимые, но на самом деле вы можете более или менее использовать любой из них вместе. Некоторые из них вам просто нужно приложить больше усилий, чтобы заставить их работать.