Читать нас в Telegram

Что самого гуманитарного есть в программировании?

Если считать лингвистику гуманитарной наукой (на самом деле, она скорее ближе к естественным, вроде биологии), то можно, например, порассуждать о внутреннем устройстве программных языков. В C++, Perl и Python тоже есть слова, синтаксис, приемы выразительности, а выразительность — категория гуманитарная. Как на любом естественном языке можно выразить любую идею, так и компьютер можно заставить выполнить любое действие, описав его на любом языке программирования. Разница будет только в том, как много слов для этого потребуется и каким количеством дополнительных смыслов это выражение будет отягощено. Это когда мы фокусируемся на естественных языках. А если говорить о программировании, то разница между языками в том, как много кода нужно будет написать и какие лишние действия при этом машине придется совершить. Чем выражение лаконичнее и свободнее от всего постороннего, тем красивее и выразительнее.

Знаток и латинской, и русской поэзии М. Л. Гаспаров подмечал, что «по-латыни можно сказать не только “дети, которые хуже, чем отцы”, но и “дети, худшие, чем отцы”; по-русски это звучит очень тяжело. По-латыни можно сказать не только “породивший” или “порождающий”, но и в будущем времени: “породящий”; по-русски это вовсе невозможно. У Горация цикл “римских од” кончается знаменитой фразой о вырождении римского народа; вот его дословный перевод: “Поколение отцов, худшее дедовского, породило порочнейших нас, породящих стократ негодное потомство”. По-латыни это великолепная по сжатости и силе фраза, по-русски — безграмотное косноязычие».

Сгенерированная с помощью DALL-E mini картинка по запросу «язык программирования»

У языков программирования тоже есть свои особенности. Например, операция присваивания обычно записывается справа налево: в левой части выражения объявляется переменная, а в правой — то значение, которое мы этой переменной назначаем. В языке Python это выглядит так:

x = 5

x здесь — это имя переменной, а 5 присвоенное ей значение. То есть мы как бы мысленно берем объект справа и кладем его в «емкость», которая располагается слева.

В языке R есть нетипичная для этой логики конструкция, где переменная и значение меняются местами:

5 -> x

Занятно, что «лаконичнее» в программировании вовсе не значит «свободнее от всего постороннего». Assembler требует от программиста прописывать самые мельчайшие действия, включая перекладывание битов данных из одного регистра процессора в другой, в результате программа получается длинной, но зато работает она быстро, потому что не делает ничего лишнего. А вот Python или PHP, чтобы выполнить даже самое простое действие, вынужден запускать множество сторонних процессов, подгружать дополнительные переменные и библиотеки, так что за лаконичным кодом может стоять не совсем очевидная лишняя деятельность.

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

Из нее видно, что такие опыты уже получили свою институционализацию в виде конкурсов и публичных выступлений.

Сгенерированная с помощью DALL-E mini картинка по запросу «поэзия на языке программирования»

В уже довольно древнем интервью писатель Виктор Пелевин признавался, что увлекся поэтическим творчеством, используя в качестве материала язык Assembler:

<Pelevin> Parker: … Я пытался писать на нем стихи, но не получалось… Может быть, это был не 8086, а тот, который был до этого — я помню, там было три уровня питания. 85 год… перестройка…

<fiz_i_len> Пелевин: Если у вас на Ассемблере плохо пишется, я могу вам сделать переводы с BASICa на Assebler ваших стихов :)))

<Pelevin> fizik: Я предпочитаю в двоичном коде. Гораздо меньше проблем с рифмовкой.

Шутка в последней реплике довольно остроумная: учитывая, что двоичный код содержит всего два символа: 0 и 1, в самом деле, не нужно особенно стараться подобрать «созвучное» окончание строки, ведь вариантов мало. В то же время даже литератор Пелевин здесь воспроизводит такой живучий именно среди русскоязычных технарей стереотип, что рифма для стихов обязательна (на самом деле, рифму использовали в русской поэзии золотого века, а современные поэты от нее все чаще отказываются, японская, древнегреческая и римская поэзии рифмы не знали совсем). Жаль, что Пелевин не опубликовал своих опытов: трудно себе представить, как именно должны были выглядеть такие стихи с содержательной точки зрения. Например, хотелось бы посмотреть, как автор реализует на ассемблере метафору.

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

Сгенерированная с помощью DALL-E mini картинка по запросу «эзотерический язык программирования»

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

Вот пример программы на этом языке:

>>>>>,+[>>>,+]<<<[<<<
[>>>[-<<<-<+>[>]>>]<<<[<]>>
[>>>+<<<-]<[>+>>>+<<<<-]
<<]>>>[-.[-]]>>>[>>>]<<<]

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

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

Первоначальным импульсом, который привел к появлению этого языка программирования, стала мысль о том, что в традиционных языках синтаксис представляет собой жесткую структуру, которая определяет следование элементов. Сначала переменная, потом оператор, потом значение. Так же и в английском The boy gave the dog the food — одно значение, а The food gave the boy the dog — уже другое. Вряд ли это сходство появилось потому что языки программирования поначалу создавались носителями английского (а они действительно создавались носителями английского, так Fortran — более-менее первый язык программирования, был разработан в американской компании IBM), скорее всего разработчики опирались на традиции формальных языков математической логики. Но традиция здесь довольно явная.

Если есть традиция, то обязательно найдется тот, кто захочет ее нарушить. За горизонт традиционной английской грамматики можно заглянуть, если ты учишь такие языки, в которых есть склонение имен. В латинском и Puer cani escam dedit, и Escam dedit puer cani формально значат одно и то же ‛Мальчик дает собаке еду’, хотя и стилистически, и в плане тонкой расстановки акцентов, конечно, отличаются. Но различаются не настолько, насколько английские The boy gave the dog the food и The food gave the boy the dog.

Эти размышления привели Дамиана Конвея мысли создать язык программирования на основе латинского языка. В нем переменная и значение определяется не порядком следования в коде, а наличием латинских падежных окончаний. Существительное в форме датива — переменная, которой присваивается значение. Существительное в форме аккузатива — переменная, значение которой используется. Стоять в строке они могут в любом порядке. Вот пример кода и справа после знака комментария «перевод» на язык Perl:

nexto stringum reperimentum da.     # $next = pos $string;
nextum stringo reperimento da.      # pos $string = $next;

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

Сгенерированная с помощью DALL-E mini картинка по запросу «римский философ пишет программный код»

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

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

Сгенерированная с помощью DALL-E mini картинка по запросу «Шекспир в Матрице»

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

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

Primes
(This is the contents of the file primes.spl.)


Prime Number Computation in Copenhagen.

Romeo, a young man of Verona.
Juliet, a young woman.
Hamlet, a temporary variable from Denmark.
The Ghost, a limiting factor (and by a remarkable coincidence also
        Hamlet's father).


                    Act I: Interview with the other side.

                    Scene I: At the last hour before dawn.

[Enter the Ghost and Juliet]

The Ghost:
 You pretty little warm thing! Thou art as prompt as the difference
 between the square of thyself and your golden hair. Speak your mind.

Juliet:
 Listen to your heart!

[Exit the Ghost]

[Enter Romeo]

Juliet:
 Thou art as sweet as a sunny summer's day!


                    Act II: Determining divisibility.

                    Scene I: A private conversation.

Juliet:
 Art thou more cunning than the Ghost?

Romeo:
 If so, let us proceed to scene V.

[Exit Romeo]

[Enter Hamlet]

Juliet:
 You are as villainous as the square root of Romeo!

Hamlet:
 You are as lovely as a red rose.

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

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

Зачем всё это нужно? Повторим ответ создателя Перлигаты: If you have to ask «Why?», then the answer probably won’t make any sense to you either.