Это текстовая версия видеоэссе, которое я опубликовал на своем канале. На YouTube, в VK. А еще для моих текстов есть telegram-канал, куда я вас с удовольствием приглашаю. Там интересно.
Почему языки программирования называются языками? Есть ли у них что-то общее с естественными языками, на которых говорят люди? В практическом смысле действительно есть — и те и эти языки нужно учить, причем способы учения часто похожи друг на друга, а главное и там, и там — настойчивая практика. Чем больше и регулярнее тренируешься, тем лучше получается. Ну ок, сейчас уже не так нужно учить, есть онлайн-переводчики и ChatGPT. Но еще недавно нужно было учить.
А еще? Есть ли что-то общее в самих языках, если посмотреть на то, как они устроены?
Языки существуют, чтобы передавать информацию. Не только для этого, у них есть еще куча функций, но эта самая очевидная и самая востребованная. Когда-то давно, десятки тысяч лет назад появился человеческий язык, про то, как так получилось, есть увлекательная книга Светланы Анатольевны Бурлак.
Выяснилось, что язык — это громадное эволюционное преимущество. С его помощью можно организовывать особей в коллектив, а коллектив способен на большие свершения. А потом, много позже появился компьютер, то есть в переводе — вычислитель. Задачи, которые ставились перед компьютером, и способы их решения были настолько сложными, что для их описания нужно было сложно устроенное и гибкое средство. То есть язык. Потому что главное свойство языка именно в гибкости: с его помощью можно выразить кучу всяких вещей, про которые сразу и не подумаешь. Более того, каких-то вещей еще нет на свете, а язык есть уже сейчас, и он даст возможность о них говорить, как только они появятся. Вот межзвездных перелетов в реальности не бывает, а с помощью языка говорить о них уже можно, и даже романы про них писать. Русский язык появился несколько столетий назад, когда и в околоземное космическое пространство летать еще не умели, а язык уже давал возможность об этом говорить.
Правда, желающих было сначала мало, но зато, когда желающие появились, выяснилось, что язык уже готов их обеспечивать.
Компьютеры не думают на языках программирования. У них все вычислительные операции происходят с помощью очень формализованных инструкций процессора, которые называются машинным кодом. Это не язык программирования. Для компьютера они удобны и в своем строении максимально приближены к тому, что в реальности происходит внутри этой электронной коробочки. Что значит «максимально приближены»? Ну вот при работе компьютера происходят арифметические операции с числами: что-то нужно сложить, что-то перемножить. Мы про это уже забыли, если у нас на экране открыт Ворд, мы считаем, что работаем с текстом, а не с числами. Но это обманчивое впечатление. Скрытая от нас машинерия внутренностей компьютера все равно, и даже сейчас, основана на том, что процессор оперирует чиселками. И машинный код говорит: возьми это число, возьми это число, теперь сложи их и положи результат вот сюда.
А насколько естественный язык приближен к тому, что в реальности происходит в жизни? Прямо скажем, не всегда и не очень. Вот русский язык сообщает: «идет дождь». То есть вкладывает в эту фразу идею, что есть какой-то активный деятель (дождь) и он предпринимает какое-то действие, да еще и не просто какое-то, а такое, которое у нас ассоциируется с движением: идет. Но ведь на самом деле нет никого такого, кто бы совершал какое-то действие или тем более куда-то шел. Просто капельки падают с неба на землю. То есть язык подстраивает под себя, под свои привычки, то, как устроен мир вокруг. И не все языки это делают одинаково. Немного более правдив, хотя и не до конца, английский, он говорит: it rains, то есть «оно дождит». Уже лучше, никто никуда не идет. Хотя и вот это сомнительное «оно» тут тоже — некоторый компромисс языка и реальности. Ведь никакого «оно» тоже нет. Аналогично во французском: Il pleut, переводится так же. С этим устройством языка могут играть поэты, например, Верлен берет эту фразу и соединяет ее с глаголом pleurer, «плакать», похоже звучит, и изобретает фразу Il pleure dans mon cœur.
Il pleure dans mon cœur Comme il pleut sur la ville; Quelle est cette langueur Qui pénètre mon cœur ?
То есть не «я плачу», а «плачется» в моем сердце. Такое еще поди переведи. Вот поэтому говорят, что поэзию нужно читать в оригинале.
Так вот машинный код от всего этого избавлен, там все четко, по-пацански. Но есть проблема: если программу записать машинным кодом, то это будет хорошо для компьютера и совершенно непонятно для человека.
BB 11 01 B9 0D 00 B4 0E 8A 07 43 CD 10 E2 F9 CD 20 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21
Казалось бы, при чем тут удобство человека? Пусть подстраивается! Но нет, в реальной жизни все же приходится немного заботиться и о человеке тоже. Ведь это он управляет компьютером, и если ему придется писать инструкции для машины в таком виде, который ему плохо понятен, он, во-первых, будет это делать медленно, а, во-вторых, будет ошибаться. А как исправить ошибку, если ничего непонятно? Нет, конечно, были и есть такие уникумы, которые изучили машинный код в совершенстве и умеют на нем разговаривать как на родном. Но таких мало, и даже им все равно тяжело.
Поэтому придумали, что можно создать промежуточную форму коммуникации между человеком и компьютером, такую, чтобы она была понятна человеку, и которую можно было бы легко перевести в машинный код. Эта промежуточная форма и есть язык программирования.
subroutine check_file_exists(file)
implicit none
character(len=*),intent(in) :: file
! the file to look for
if(.not.file_exists(file)) then
call error("check_file_exists","File does not exist : "//trim(file))
end if
end subroutine check_file_exists
Начали они появляться в конце 1950-х годов, и их появление существенно упростило и ускорило программирование. После того, как придумали языки программирования, стали делать так: человек пишет программу (которая представляет собой текст) на языке программирования, а затем автоматически этот текст переводится в единственную понятную компьютеру форму: машинный код. А почему язык программирования в отличие от машинного кода понятен человеку? Он использует не непонятные циферки и индексы, а слова из привычного естественного языка, чаще всего английского: run, if, replace, end и т.д.
def clk(button):
while True:
coord = pyautogui.locateOnScreen('{}/{}'.format(buttons_img, button))
if coord:
break
print('waiting '+button)
time.sleep(3)
click_simple(coord)
Языков программирования много и они все разные. Например, есть такие, которые называются языками низкого уровня и которые называются языками высокого уровня. Это не значит, что одни для крестьян, а другие для аристократов. За этим стоит самовлюбленное представление человека о том, что он находится наверху пищевой цепи, а компьютер — прах и раб его, внизу. А язык между ними. Если язык в этой схеме ближе к компьютеру, ориентируется на схемы описания задачи по-компьютерному, требует детализации каждого шага — откуда взять число, как его сложить с другим числом, то язык такой внизу, низкого уровня. А если язык ориентирован на человека, не закапывается в мелочах и человек с помощью этого языка может просто написать что-то вроде «сделай мне красиво, а как ты это сделаешь, меня не волнует», то язык этот там же, где и человек, наверху, язык высокого уровня.
То есть языки программирования, как и естественные языки, нужны для коммуникации, в которой участвует человек. Правда, коммуникация эта односторонняя, только в сторону компьютера: компьютер не отвечает человеку на языке программирования. Это отличие.
А что общего? В языках программирования тоже есть аналог слов, причем это не только имена переменных, это и операторы, и числа. То есть знак плюс, больше или равно тоже слова. В языках обоих типов есть грамматика, то есть правила соединения слов вместе. Но если мы начнем рассматривать конкретные высказывания на разных языках, мы выясним, что высказывания эти очень сильно отличаются по цели. И это накладывает свою специфику. Скажем, что мы чаще всего делаем с нашим естественным языком? Мы что-то кому-то рассказываем. Самый частый способ использования естественного языка — это повествование. Вот я сейчас вам рассказываю про языки. Верлен рассказывает про то, что в его сердце идет дождь. Вы сами наверняка пять минут назад что-то кому-то рассказывали. Какая погода на улице, какие впечатления от последней прочитанной книги, как пройти в библиотеку. На языках программирования таких высказываний почти нет. Почти целиком тексты на них состоят из того, что в естественных языках называется повелительным наклонением. Это как если бы люди вместо романов в свободное время читали инструкции к холодильникам: вставьте вилку в розетку, откройте дверцу морозильной камеры и т.д. Ну ладно, немножко повествования в языках программирования тоже бывает. Но здесь возможности пишущего на этих языках серьезно ограничены. Смотрите, как разнообразно можно рассказать историю на естественном языке:
Я проснулся одетым в кресле, В своей квартире средь знакомых стен, Я ждал тебя до утра, Интересно, где ты Провела эту ночь, Моя сладкая N.
А на языке программирования все, что у тебя есть, это утверждения типа что-то является чем-то. Попробуйте перевести на такой язык историю про проснувшегося в своей квартире человека. «Я являюсь одетым. Я являюсь проснувшимся. Мое местоположение является местоположением в кресле». Получается неуклюже, потому что язык такого типа не предназначен для таких высказываний, и у него для этого всего недостаточно выразительности. Выразительность — это то, по чему языки можно сравнивать. А еще тут очень трудно отразить идею времени. Это же не сейчас я одетый, а в прошлом, в момент, когда проснулся. А как это передать языком программирования? Никак, но потому что это не нужно. Имеет значение то, что сейчас, а зачем компьютеру знать, как оно было в прошлом?
Поэтому то, что легче легкого выразить на естественном языке: описание события, произошедшего в прошлом, очень трудно сказать на языке программирования.
Духовной жаждою томим, В пустыне мрачной я влачился, — И шестикрылый серафим На перепутье мне явился.
Немного проще будет там, где желание говорящего тоже связано с выражением идеи повеления:
Прими, прими, святый Евгений, Дань благодарную певца, И слово пламенных хвалений, И слезы, катящи с лица.
Но и тут не все просто: если создателями языка не описано, как можно принять дань, то у говорящего все равно будут сложности.
То есть в языке программирования, несмотря на всю его гибкость, нет такого большого запаса слов для описания нашего мира. Возьмите учебник Python или JavaScript. Ни «духовной», ни «жажды» вы там не найдете. Как всё это сказать? Первое желание — использовать переменные. Даже если вы не программировали, явление переменных вам знакомо из школьной математики. Пусть x
будет равен 3
… Но даже если завести в программе вместо x
переменную zhazhda
zhazhda = 0
компьютер вас не поймет. Для него это будет просто пустышка, контейнер для неназначенного значения, «жажда» не будет ничем отличаться от «насыщения». То есть переменная zhzhda не будет полноценным эквивалентом слова «жажда» в естественном языке, потому что не будет означать того же самого.
А еще помните требование к языкам программирования? Они должны легко переводиться в четкий машинный код. То есть это языки, в которых максимально затруднено создание неоднозначностей, образов, метафор.
Но, несмотря на это, люди пытаются писать стихи на языках программирования. У меня про это есть статья. Такие стихи могут быть массовыми и элитарными, то есть понятными всем или только избранным.
А еще бывают эзотерические языки программирования. Они принципиально не должны делать ничего полезного, но код на них должен выглядеть особенным образом. И про это у меня тоже есть статья прямо на Системном Блоке. Например, есть язык программирования, который называется Шекспир, там программный код (не путайте с машинным кодом, это разное) — это имитация пьесы Шекспира.
Так что общее у естественных языков и языков программирования есть, но и различий хватает. И там, и там есть слова и грамматика, но покрывают они в разных случаях разное. Грамматика естественного языка универсальна, а у языка программирования они узко специализирована, и заточена под то, чтобы отдавать приказы. Все это потому что естественные языки используются нами, чтобы что-то рассказать, а языки программирования — чтобы что-то приказать. Отсюда и особенности.
На обложке: Wes Cockx & Google DeepMind / Better Images of AI / AI large language models / CC-BY 4.0