Напишите лучшие функции, приняв этот стиль программирования

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

Эта и мои предыдущие статьи основаны на книге Кристины Видейры Лопес Упражнения в стиле программирования.

Определенный стиль трубопровода

Лучшая аналогия стиля Pipeline - это заводские конвейеры, такие как те, что используются в автомобильной промышленности. Автомобили собираются по частям на «конвейерной ленте», где есть станции, выполняющие индивидуальные задачи, такие как установка двигателя, установка дверей, установка капота и багажника и т. Д.

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

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

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

Пример стиля конвейера: конвейеры Unix

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

Концепция программных конвейеров была разработана в ранних версиях Unix, но просуществовала гораздо дольше. Один из сотрудников Bell Labs, который был на заре Unix в качестве главы отдела, курировавшего команду разработчиков Unix, Дуг Макилрой в 1964 году написал меморандум с изложением своей концепции конвейерной системы. Способ соединения программных продуктов, очень похожий на садовые шланги, которые соединяются вместе, чтобы образовать более длинный шланг. Так родилась концепция программных труб.

Команда Unix для канала - это полоса (|). Сначала использовался символ >, но было решено, что этот символ лучше использовать для перенаправления вывода, поэтому вместо него был выбран символ |.

Вот пример использования конвейеров в Unix. Допустим, вы хотите подсчитать все записи каталога, в которых есть слово system. Отдельные команды: ls для перечисления записей каталога, grep “system” для сопоставления строк, в которых есть system, и wc для подсчета количества строк.

Вот команда для этого:

ls | grep “system” | wc -l

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

В оболочке Windows DOS вы можете передавать команды DOS по конвейеру, но только команды DOS, а не вывод конкретных программ. Например, я могу перечислить каталог папки и передать этот вывод команде more, чтобы количество отображаемых файлов было ограничено. Вот пример:

C:\Windows\System32>dir | more
Volume in drive C has no label.
|Volume Serial Number is 1290-1953
Directory of C:\Windows\System32
02/27/2021  01:50 PM    <DIR>          .
02/27/2021  01:50 PM    <DIR>          ..
12/07/2019  03:49 AM    <DIR>          0409
01/14/2021  01:38 PM    <DIR>          1028
01/14/2021  01:38 PM    <DIR>          1031
01/14/2021  01:38 PM    <DIR>          1033
01/14/2021  01:38 PM    <DIR>          1036
01/14/2021  01:38 PM    <DIR>          1040
01/14/2021  01:38 PM    <DIR>          1041
01/14/2021  01:38 PM    <DIR>          1042
01/14/2021  01:38 PM    <DIR>          1045
01/14/2021  01:38 PM    <DIR>          1046
01/14/2021  01:38 PM    <DIR>          1049
01/14/2021  01:38 PM    <DIR>          1055
01/14/2021  01:38 PM    <DIR>          2052
-- More  --

Вот еще один пример, в котором используется текст, который я использую для подсчета частотности слов, - эссе Джонатана Свифта Скромное предложение. В этом примере текст из эссе передается по конвейеру команде DOHere’s the и команде output:S find, которая выполняет поиск слова children, а затем сортирует строки, содержащие children, в алфавитном порядке на основе первого слова в строке текста с помощью команды sort.

Вот команда и результат:

C:\js>type text.txt | find "children" | sort
children in the arms, or on the backs, or at the heels of their
children sound and useful members of the commonwealth, would deserve sodyet, there are more children born in Roman Catholick countries 
for those women who miscarry, or whose children die by accident or
four, or six children, all in rags, and importuning every passenger 
giving some pleasure to the rich. I have no children, by which I can
hundred and twenty thousand children, already computed, twenty 
murdering their bastard children, alas! too frequent among us,
not be wanting; although I rather recommend buying the children 
reason is, that these children are seldom the fruits of marriage, a
sterling per annum by the sale of their children, will be rid of the
the children of professed beggars: it is of a much greater extent,
their children, when they were sure of a settlement for life to the
Thirdly, Whereas the maintainance of a hundred thousand children, 
thirty thousand couple, who are able to maintain their own children,
thousand children of poor parents annually born. The question 
to have the best title to the children.
with their wives and children, who are beggars in effect; I desire

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

Конвейерная программа подсчета частоты слов

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

Вот результат этой программы:

children: 18
kingdom: 15
thousand: 15
country: 11
own: 10
child: 10
hundred: 8
parents: 7
little: 7
shillings: 7

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

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

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

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

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