Ссылки для упрощенного доступа

logo-print

Эволюция языков программирования


На вопросы Александра Костинского отвечают Владимир Губайловский и Александр Сергеев

Александр Костинский: Параметры компьютеров растут в геометрической прогрессии, то есть по законам взрыва. Эта мысль стала надоедливым штампом - тем не менее, рост продолжается в том же темпе. Поразительно усложняющаяся цифровая техника охватывает все новые и новые области, при этом в той же геометрической прогрессии растет сложность программ, которые этой техникой управляют. Если первые программы были длиной в сотни команд, то сегодня существуют программные комплексы, которые содержат миллионы строк кода. Как люди могут составить без критических ошибок такие длинные инструкции машине? Как вообще компьютер может часами работать при такой сложности инструкций? Оказалось, что подобные программы должны быть написаны на специальных языках. Это языки общения человека с машиной. Как возникли, развивались и чего достигли создатели языков программирования, расскажут сегодня профессиональные программисты Владимир Губайловский и Александр Сергеев.

Александр Костинский: Как могло прийти в голову человеку, что для того, чтобы общаться с машиной ему нужен язык?

Александр Сергеев: На самом деле в такой постановке вопрос не выглядит совсем уж удивительным. Для общения мы все используем язык. Другое дело, как могла возникнуть идея общения с машиной, мы же не общаемся с пылесосом? Всерьез стоит проблема управления машиной, то есть отдачи ей определенных команд, целых, достаточно протяженных инструкций, то есть программ. И программы эти пишутся в начале в виде механических деталей, которые встраиваются в машину, например в музыкальных шкатулках или автоматах.

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

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

Александр Костинский: У вас история получилась непрерывной, а непрерывного-то развития и не было. Непрерывным развитие кажется, когда мы смотрим назад и, конечно, мы там находим то, что можем подгрести под свою идею. Но все-таки началом был момент окончания Второй мировой войны, когда возникли машины вроде ENIAC в США, возникли машины, на которых в Англии считали криптозадачи, и все эти машины были в интересах военно-промышленного комплекса, причем они были продолжателями дела людей-вычислителей и, наконец, были построены такие большие машины, где возникла проблема программирования, создания инструкций. Это, на мой взгляд, и был водораздел.

Александр Сергеев: Я бы не сказал, что был такой уж серьезный водораздел. Был очень быстрый количественный рост, особенно в военных условиях. При этом возникла ситуация, когда схемы управления машинами стали настолько сложными, что их невозможно было настраивать, отлаживать прямо в самой машине. Нужно было как-то вот эту самую программу отделить от машины и работать с ней отдельно. Проблема в чрезвычайной сложности тех программ, которые надо задавать машине, причем эти программы меняются раз от раза, и менять их нужно тоже быстро, и встал вопрос, в виде чего хранить программы в тот момент, когда они не вставлены в машину. Возникла задача введения некой нотации, способа записи тех самых команд, которые отдаются машине. Поначалу эта запись была очень простой. Это были те самые машинные коды, которые вводились в машину тем или иным способом.

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

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

Александр Костинский: И, вообще, выделилась профессия программист.

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

Александр Костинский: Более того, машины менялись, и возникла идея, чтобы написанная для одной машины программа могла быть реализована на других.

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

Александр Костинский: Грубо говоря, программисты стали мыслить более крупными блоками. Чтобы ориентироваться во времени, скажите, какие это были годы.

Александр Сергеев: Программирование в кодах - это 40-е годы и самое начало 50-х. Уже 50-е - это эпоха Ассемблера или по-русски автокода (в это время не было единства терминологии у нас и на Западе). В конце 50-х появляются первые языки высокого уровня - ФОРТРАН (FORTRAN), LISP. В 60-м году появляется АЛГОЛ и дальше, примерно за десять лет, к концу 60-х формируется все разнообразие концепций, положенных в основу различных типов языков программирования. 70-е годы это совершенствование этих концепций и появление над ними более сложных надстроек.

Александр Костинский: Владимир, скажите, что потом происходило с языками? Многие не понимают, что за эти годы произошло несколько качественных скачков. Программы, которые были длиною в несколько тысяч операторов сейчас превратились в программы длинною в миллионы операторов и на этом пути было несколько важных этапов. Давайте кратко о них скажем.

Владимир Губайловский: Здесь, наверное, надо сказать, что в первый момент, действительно революционный, когда появились языки высокого уровня ФОРТРАН и LISP (группы Бэкуса и Маккарти в IBM, конец 50-х годов), они возникли одновременно с первой операционной системой.

Александр Костинский: Слово ФОРТРАН переводится "переводчик формул". Нужно было решать физические, счетные задачи, и появился такой язык, который упрощал введение в компьютер формул.

Александр Сергеев: На самом деле мы не охарактеризовали, что это были за языки. Язык машинных кодов - это те самые числа, которые вводятся в компьютер и прямо там в таком числовом виде работают. Следующий уровень - язык Ассемблер. Мы отвлекаемся только от запоминания кодов. Вместо кодов мы пишем некоторые буквенные обозначения, а специальная программа подменяет их кодами для машины. Вместо ссылок на адреса ячеек памяти мы пишем их имена, а специальная программа просматривает, какой номер ячейки будет соответствовать этому имени, и везде по программе его подставляет. По сути дела это может сделать и человек, но человек наделает ошибок, а машина сделает все надежно, и поэтому работа убыстряется. А вот переход к языкам высокого уровня это принципиальный скачок. В чем он? Когда я записываю несложную формулу, скажем "a в квадрате плюс b в квадрате", то на машинных языках я должен писать по очереди каждую команду: взять число из ячейки с номером таким-то, взять это число еще раз и занести в другой регистр, перемножить эти два регистра - это все отдельные команды, длинные и очень подробные записи, которые неудобны для восприятия. Прочитать с листа такой текст невозможно. Было обнаружено, что если я запишу эту самую строчку в виде последовательности "a стрелочка вверх 2 плюс b стрелочка вверх 2", то такая запись вполне понятна машине, если написать специальную программу, которая переводит из этой формы записи в более развернутую, близкую к машинной. Оказалось, что такие программы-переводчики можно написать, и их стали собственно и называть трансляторами. Вот с этого момента программирование резко упростилось. Вместо написания десятка машинных команд я мог написать одну строчку, похожую на математическую формулу.

Владимир Губайловский: Я не знаю, начали ли мы двигаться быстрее, но у нас очень сильно менялись задачи. Если в 50-е годы наши задачи с сегодняшней точки зрения были крайне простыми, то на ФОРТРАНе мы уже могли писать, например, решения уравнений в частных производных, это уже довольно большие программы. Но задачи, которые мы ставили перед компьютером, все время росли, и росли наши программы и качественно менялись. И оказалось, что даже используя языки высокого уровня, такие как ФОРТРАН, человек все равно может контролировать весьма ограниченное количество строк, хотя, конечно на языке высокого уровня от может контролировать, отслеживать, сопровождать, передавать гораздо больше кода, чем на Ассемблере и, конечно, гораздо больше, чем в машинных кодах. Но все равно наступило ограничение, и в этот момент возникли следующие проблемы. Это проблема, которую Питер Брукс в свое время назвал "мифический человеко-месяц". Это проблемы не только межпрограммных, но и межчеловеческих интерфейсов.

Александр Костинский: Между программистами в команде разработчиков.

Владимир Губайловский: Да, да. Оказалось, что сам язык ФОРТРАН просто не обеспечивает условий, не дает возможности аккуратно поделить работу между всеми программистами.

Александр Костинский: Возникают ошибки и программы плохо работают?

Владимир Губайловский: Они может и хорошо работают, но их медленно разрабатывают. Просто приведу пример. Если условно один программист пишет за неделю сто строк кода, то три программиста пишут только двести строк кода, а четыре программиста двести пятьдесят. И увеличение количества пишущих в какой-то момент перестает приводить к ускорению процесса. Новые люди тратят все время на согласование и отладку интерфейсов взаимодействия друг с другом. И вот здесь появились такие идеи, как модульность программирования, системные библиотеки, которые выполняют какие-то стандартные функции. То есть, сами программы надо было делить на части, и видимо самым революционным шагом было (конец 60-х), когда Эдсгер Дейкстра предложил отказаться от оператора безусловного перехода GO TO. Тогда практически любая программа представляла собой линейную цепочку, но оказалось, что в этой линейной структуре необходимо иногда возвращаться далеко назад и прыгать далеко вперед. Вот этот переход по метке (GO TO "метка, номер строки") делал достаточно большие коды просто нечитаемыми.

Александр Костинский: Если программа передавалась другому человеку, то он не мог в ней разобраться. Более того, сам человек написавший программу, если он не работал с ней год, то ему было трудно восстановить структуру программы.

Александр Сергеев: Тут можно вот так объяснить. Характерная, не очень большая по современным меркам программа может иметь несколько тысяч строк, и между ними может быть при таком неструктурном методе несколько сотен переходов вперед, назад по разным номерам строк. Такую программу даже специалист, который всю жизнь занимается только составлением инструкций, не может удержать в голове и написать безошибочно. А тут требуется абсолютная безошибочность, потому что, если человек в инструкции по сборке шкафа, наткнувшись на ошибку, может догадаться, как действовать на самом деле правильно, у него есть интуиция, то машина не о чем не догадается. Она тупо сделает так, как написано и все претензии предъявляйте сами себе.

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

Владимир Губайловский: Структурность, прослеженная сверху донизу, позволяла очень хорошо и аккуратно разводить переменные так, чтобы модули друг другу не мешали. Мы выстраивали аккуратное дерево сверху донизу, и нам удавалось хорошо согласовывать внутри программы вот эти внутрипрограммные интерфейсы взаимодействия.

Александр Костинский: Получается, что развитие языков программирования это - паровоз для машиниста. Машинисты-программисты создавали для себя все более хороший паровоз для езды.

Владимир Губайловский: В общем-то, им все время приходилось водить все более сложные составы.

Александр Костинский: И по все более сложным железнодорожным путям.

Александр Сергеев: Тут главная проблема вот в чем: есть некоторый предел сложности программы, которая обозрима для человека. В неестественных для человека машинных кодах предел обозримости несколько сотен, в крайнем случае, несколько тысяч строчек. На Ассемблере можно контролировать несколько тысяч строк. Каждый следующий этап развития языков программирования позволял контролировать программы примерно на порядок-полтора большие. То есть, на неструктурных языках высокого уровня можно было написать программу в несколько тысяч строк того самого ФОРТРАНа, которые, допустим, превращались в несколько десятков тысяч машинных команд и эта система работала. Когда были введены конструкции структурного программирования, когда отказались от беспорядочных переходов вперед-назад и программистов обязали структурировать и разбивать программы на модули обозримого размера с четко оговоренными связями, то один программист хорошей квалификации стал контролировать код объемом несколько десятков тысяч строк на языке программирования (вплоть до ста тысяч строк). Такой объем может держать под контролем один программист. Для сравнения скажем, что операционные системы класса Windows - это миллионы строк, следовательно, держать под контролем такую систему, пользуясь только структурными языками, почти невозможно.

Александр Костинский: Более того, изменился и сам характер программирования. Если в начале программисты были похожи на людей, которые изготовляют штучные изделия ручной работы, то со временем они получали все более сложные подсобные инструменты. Реально они превращались из людей, которые строили дом с помощью топора, в людей, которые получали кирпичи, потом они становились прорабами, а потом инженерами, которые управляли механизмами, сделанными для них, да?

Владимир Губайловский: Да. Насколько я понимаю, сейчас надо сказать об объектном подходе. При переходе к объектному программированию мы переходим к тому, что начинаем работать с библиотеками объектов. Работа с объектами все дело очень упростила. Мы опять сделали по сложности шаг вверх.

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

Александр Костинский: Чтобы было видно, что в начале котлован, потом фундамент и так далее.

Александр Сергеев: Компьютеры, с которыми мы на самом деле работаем, насыщены в первую очередь объектами, которые представляют собой те или иные элементы операционной системы и среды, на которой мы работаем. Например, есть объект, отвечающий за окно, которое мы видим на экране монитора. Есть обязательно объект, который отвечает за каждую кнопку, есть объект, который отвечает за меню в целом, и есть объекты, которые отвечают за каждый пункт меню по отдельности, и у всех этих объектов есть определенные свойства, которые можно изменять, есть определенные методы, которыми можно на них воздействовать, заставляя, например, окно изменяться по размерам или кнопку нажиматься или отпускаться. Таких объектов в современных операционных системах тысячи и, соответственно, многие тысячи методов, которыми можно к ним обращаться. Вот это и есть те объекты, иероглифы, на которых пишут современные программисты. Нужно знать всю эту мастерскую инструментов, с помощью которых мы можем программировать, и это ставит современное программирование в очень неудобное положение, потому что упомнить тысячи инструментов, тысячи иероглифов на грани человеческих возможностей, и многие программисты их, собственно, и не знают, а знают только некоторый сектор, в котором они работают.

Александр Костинский: Что будет дальше?

Александр Сергеев: В данный момент мы находимся в своего рода тупике. Есть исследования, как можно попробовать двигаться дальше, но они еще пока не до конца подтвердили, что идти нужно именно туда. Но это всегда так бывает. Все что можно сделать текущими средствами, будет сделано, дальше мы упираемся в определенную стенку, которая мешает нам двигаться вперед, и начинам долбиться в нее, чтобы можно пройти дальше. Есть, например, так называемые кейс-системы (CASE - Computer Aided Software Engineering). Расшифровывается - разработка программного обеспечения с компьютерной автоматизированной поддержкой. Речь идет о том, чтобы разрабатывать специальные языки, уже не те, на которых мы пишем инструкции - сделай то, проверь это, перейди туда, выполни то, а делаются специальные языки, на которых мы описываем только требования к программам и модулям, которые мы собираемся создавать.

Александр Костинский: А машина во многом сама пишет программы, такая самопишущая программа?

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

Владимир Губайловский: Я просто хотел сказать буквально два слова в защиту программистов. Все не так безрадостно, как на картине, которую нарисовал Саша Сергеев. Дело в том, что касается задач вполне стандартизованных, таких как оконный интерфейс, доступ к реляционным данным, тут да, действительно, реализуется такой подход. Это задачи, которые в целом охватывают, как правило, офисные, банковские нужды. Здесь все более или менее стандартно и все так и есть, но дело в том, что программирование все время разбухает, оно все время касается новых областей, соответственно, когда появляется новое приложение, когда появляется новая область, там, конечно, никаких объектов нет.

Александр Костинский: В передаче участвовали профессиональные программисты Владимир Губайловский и Александр Сергеев

Все ссылки в тексте программ ведут на страницы лиц и организаций, не связанных с радио "Свобода"; редакция не несет ответственности за содержание этих страниц.

XS
SM
MD
LG