Завершающая часть перевода интервью (первая часть, вторая часть), взятого у создателя Стандартной библиотеки шаблонов Алекса Степанова в 1995 году. Здесь Алекс рассказывает о том, почему в шаблонах не включена поддержка персистентности и серилазизации, о будущем библиотеки и о связи ООП и обобщённого программирования.
Алекс, STL не реализует объектную модель персистентности (постоянного хранения) объектов. Map и Multimap являются особенно хорошими кандидатами для постоянного хранения контейнеров как инвертированных индексов в базах данных постоянного хранения объектов. Скажите, работали ли Вы в этом направлении или же Вы можете хотя бы прокомментировать реализации этой идеи?
Это обстоятельство отмечалось многими. STL не реализует персистентность по уважительной причине. STL настолько велика, насколько можно было себе представить в то время. Я не думаю, что любой больший набор компонентов прошёл бы через Комитет по стандартам. Но персистентность является тем, о чём думали некоторые люди тогда. При проектировании STL и особенно во время проектирования компонента-распределителя, Бьярн отметил, что распределители, которые инкапсулируют памяти модели, могут быть использованы для инкапсуляции модели постоянной памяти. Прозрение принадлежит Бьярну, и это важное и интересное прозрение. Несколько компаний, разрабатывающие объектные базы данных, рассматривают эту идею. В октябре 1994 года я посетил встречу Группы по системам управления объектными базами данных. Я выступил с докладом по STL, и после был большой интерес к тому, чтобы сделать контейнеры с их развивающимся интерфейсом соответствующими STL. Они не рассматривали распределители как таковые. Некоторые из членов группы, однако, пытались выяснить, могут ли распределители быть использованы для реализации персистентности. Я ожидаю, что в течение следующего года появятся хранилища объектов с STL-совместимыми интерфейсами, которые будут вписываться в рамки STL.
Set, Multiset, Map и Multimap реализуются красно-черными деревьями. Вы экспериментировали с другими структурами, такими как B*-деревья?
Я не думаю, что это будет достаточно верным для структур данных в памяти, но это то, что должно быть сделано. Те же интерфейсы, определенные STL, должны быть реализованы и другими структурами данных — списками пропусков, полу-сбалансированными деревьями и т.д. Это серьёзная научно-исследовательская деятельность, которая должна быть выполнена, т.к. STL предоставляет нам фреймворк (основу), в котором мы можем сравнивать производительность этих структур. Интерфейс фиксирован. Основные требования сложности фиксированы. Теперь мы можем проводить значимые эксперименты для сравнения различных структур данных друг с другом. Известны представители сообщества, связанного со структурами данных, которые придумывали все возможные виды структур данных для подобных интерфейсов. Я надеюсь, что они будут реализовывать их как обобщённые структуры данных в рамках STL.
Взаимодействуют ли с вами разработчики компиляторов для реализации STL в их продуктах?
Да. Я получаю много звонков от поставщиков компиляторов. Пит Беккер из Borland был чрезвычайно полезным. Он помог путём написания кода, так что мы смогли реализовать распределители для всех моделей памяти компиляторов Borland. Symantec собирается выпустить реализацию STL для их компилятора под Macintosh. Edison Design Group была очень полезной. У нас была хорошая поддержка от большинства поставщиков компиляторов.
STL включает шаблоны, которые поддерживают модель памяти 16-битных компиляторов MS-DOS. С нынешним акцентом на 32-разрядных архитектурах, плоская модель компиляторов и операционных систем, как вы думаете, останется ли верной текущий уклон модели памяти?
Независимо от архитектуры Intel, модель памяти есть объект, который инкапсулирует информацию о том, что такое указатель, что такое размер целого числа и тип разности указателей, что такое ссылочный тип, связанный с этим указателем, и так далее. Абстрагирование важно́, если мы введём другие виды памяти, такие как постоянная память, разделяемая память и т. д. Приятной особенностью STL является то, что единственное место, где в STL упоминаются машинные типы — то, что относится к реальному указателю, реальной ссылке и т.д. — заключен в примерно 16 строках кода. Всё остальное, все контейнеры, все алгоритмы, построены абстрактно, без упоминания чего-либо, относящегося к машине. С точки зрения переносимости, все вещи, касающиеся конкретных устройств и связанные с понятиями адреса, указателя, и так далее, инкапсулированы в небольшом и хорошо понимаемом механизме. Распределители, однако, не являются необходимыми для STL, вернее, не так важны, как декомпозиция фундаментальных структур данных и алгоритмов.
Стандарты комитета ANSI/ISO C рассматривали платформо-зависимые вопросы, такие как модели памяти, детали реализации, и не пытались их систематизировать. Примет ли комитет по C++ другой взгляд на эти вопросы? Если да, то почему?
Я думаю, что STL опережает стандарт С++ с точки зрения моделей памяти. Но есть существенное различие между C и C++. C++ имеет конструкторы и оператор new, которые имеют дело с моделью памяти и которые являются частью языка. Сейчас может быть важным посмотреть на такие обобщающие вещи, как оператор new, чтобы иметь возможность принимать распределители тем же путём, как это делают контейнеры STL. Это не так важно сейчас, как это было до принятия STL, потому что структуры данных STL устранят большинство потребностей в использовании new. Большинство людей не должны аллоцировать массивы, поскольку STL эффективно в этой задаче. Мне никогда не придётся использовать new в своём коде, и я уделяю большое внимание эффективности. Коду свойственно быть более эффективным без использования new. С принятием STL new станет исчезающим видом. STL также решает проблему удаления, поскольку, например, в случае вектора, деструктор уничтожит его на выходе из блока. Вам не нужно беспокоиться об очистке хранилища, как вы делаете при использовании new. STL может существенно сократить потребность в сборке мусора. Дисциплинированное использование контейнеров позволяет вам делать всё, что вам нужно сделать, без автоматического управления памятью. STL конструкторы и деструкторы выполняют распределение правильно.
Подкомитет C++ по Стандартной библиотеке определяет стандартные пространства имен и соглашения об обработке исключений. Будет ли STL классы иметь пространства имён и исключения?
Да, будут. Члены Комитета работают с этим, и делают отличную работу.
Как сильно будет отличаться возможный стандарт от текущего определения STL? Будет ли комитет влиять изменения или дизайн с большей степенью контроля?
Похоже, есть консенсус в том, что не должно быть существенных изменений в STL.
Как программисты могут получить первый опыт с STL в ожидании её стандартизации?
Они могут скачать заголовочные файлы STL butler.hpl.hp.com в / STL и использовать его с компилятором Borland или IBM, или с любым другим компилятором, достаточно мощным, чтобы иметь дело с STL. Единственный способ освоить определённый стиль программирования — это непосредственное программирование в этом стиле. Они должны посмотреть на примеры и писать программы в этом стиле.
Вы сотрудничаете с P.J. (Биллом) Пладжером, чтобы написать книгу о STL. В чём будет состоять основная идея книги, и когда она запланирована к публикации?
Это запланировано на лето 1995 года и станет аннотированной реализацией STL. Это будет похоже на книги Билла по стандарту C и проект стандарта Библиотеки C++. Он шефствует над книгой, поэтому книга послужит справочником по стандарту и использованию STL. Я надеюсь написать статью с Бьярном, в которой будет обсуждаться взаимодействие языка и Библиотеки в контексте C++ и STL. А это может привести к другой книге.
Намного больше работы предстоит сделать. Для STL, чтобы стать успешным, требуется, чтобы люди исследовали и экспериментировали с этим стилем программирования. Должно быть написано больше книг и статей, объясняющих, как программировать в этом стиле. Должны быть разработаны курсы, написаны учебники. Должны быть созданы инструменты, помогающие людям ориентироваться в Библиотеках. STL является фреймворком (рабочей средой), и было бы неплохо иметь инструмент, позволяющий обозревать эту среду.
Какова связь между обобщённым и объектно-ориентированным программированием?
В каком-то смысле, обобщенное программирование является естественным продолжением фундаментальных идей объектно-ориентированного программирования — разделение интерфейса и реализации и полиморфное поведение компонентов. Однако, существует принципиальное различие. Объектно-ориентированного программирование подчеркивает синтаксис языковых элементов при конструировании программ. Вы должны использовать наследование, вы должны использовать классы, вы должны использовать объекты, объекты отправляют сообщения. Обобщенное программирование не начинается с определения того, используете ли вы наследование или нет. Оно начинается с попытки выявить или породить таксономии, какие в них объекты и как они себя ведут. То есть, что значит — две вещи идентичны? Какой путь верен для определения идентичности? Дело не только в том, каково поведение идентичных объектов. Вы можете проанализировать идентичность глубже и обнаружить, что есть общее понятие равенства, в котором два объекта равны, если их части, или, по крайней мере, их основные части равны. Мы можем получить общий рецепт для операции равенства. Мы можем обсудить, какие есть виды объектов. Существуют последовательности. Есть операции над последовательностями. Какова семантика этих операций? Какие типы последовательностей с точки зрения сложностных компромиссов мы должны предложить пользователю? Какие есть алгоритмы на последовательностях? Какие различные функции сортировки нам нужны? И только после того как мы определим это, и получим концептуальную таксономию компонентов, мы решаем вопрос о том, как их реализовать. Будем ли мы использовать шаблоны? Используем ли мы наследование? Используем ли макросы? Какую языковую технологию мы используем? Основная идея обобщенного программирования состоит в классификации абстрактных программных компонентов и их поведения и создании стандартной таксономии. Отправной точкой являются реальные, эффективные алгоритмы и структуры данных, а не язык. Конечно, это всегда воплощается на определённом языке. Вы не можете иметь обобщённое программирование вне языка. STL написан на C++. Вы могли бы реализовать его на Ada. Вы могли бы реализовать его в других языках. Они будут немного отличаться, но есть некоторые фундаментальные вещи, которые будут там. Бинарный поиск должен быть везде. Сортировка должна быть везде. Это то, что обычно делают люди. Там будут какие-то изменения в семантике контейнеров, незначительные изменения, определяемые языком. В некоторых языках вы можете использовать наследование в большей степени, в некоторых языках вы должны использовать шаблоны. Но принципиальное отличие в том, что обобщенное программирование начинается именно с семантики и семантической декомпозиции. Например, мы решим, что нам нужен компонент, называемый swap. Тогда мы выясняем, как данный компонент будет работать в разных языках. Акцент делается на семантике и семантической классификации, в то время как в объектно-ориентированном программировании, особенно если вспомнить, как оно развивалось, гораздо больше внимания, и, я думаю, слишком много внимания, уделяется именно тому, как создавать вещи, то есть с использованием иерархии классов. ООП говорит вам, как строить иерархии классов, но не говорит вам, что должно быть внутри этих иерархий классов.
Как вы представляете себе будущее STL и обобщённого программирования?
Я уже говорил о том, что мечта программистов — это стандартные репозитории абстрактных компонентов с интерфейсами, которые хорошо понятны и следуют общим парадигмам. Для осуществления этого должно быть намного больше усилий по разработке научных основ этого стиля программирования. STL запускает это в определённой степени, классифицируя семантику некоторых базовых компонентов. Нам нужно больше работать над этим. Цель состоит в превращении разработки программного обеспечения из ремесла в инженерную дисциплину. Она нуждается в таксономии основных понятий и некоторых законов, которые регулируют эти понятия, которые хорошо понятны, которым можно научить, которые каждый программист знает, даже если он не состоянии их правильно сформулировать. Многие люди знают арифметику, даже если они никогда не слышали о коммутативности. Все, кто окончил школу, знает, что 2+5 равно 5+2. Не все из них знают, что это свойство коммутативности сложения. Я надеюсь, что большинство программистов знает фундаментальные семантические свойства основных операций. Что означает присваивание? Что означает равенство? Как конструировать структуры данных.
В настоящее время С++ является лучшим средством для этого стиля программирования. Я пробовал разные языки, и думаю, что C++ предоставляет то самое замечательное сочетание абстрактности и эффективности. Однако, я думаю, что можно разработать язык, основанный на C и многих идеях, что принёс C++, но язык, более подходящий для этого стиля программирования, в котором отсутствуют некоторые недостатки C++, в особенности его огромный размер. STL имеет дело с понятиями. Что такое итератор? Не класс. Не тип. Это понятие. (Или, если мы хотим быть более формальным, это то, что Бурбаки называет структурным типом, что логики называют теории, или то, что люди области теории типов называют видом). Это то, что не имеют языкового воплощения в C++. Но могло бы. Вы могли бы иметь языке, где вы могли бы формулировать концепции, уточнить их, и, наконец, превращать их в классы определённым образом. (Есть, конечно, языки, которые касаются видов, но они не имеют особого смысла, если вы хотите просто сортировать.) Мы могли бы иметь язык с возможностью определить нечто под названием forward-итератор, который определён в STL просто как концепция — и в C++ этому нет воплощения. Далее мы можем уточнить forward-итератор до двунаправленного итератора. Затем случайный итератор может быть уточнен из двунаправленного. Можно разработать язык, который позволил бы даже с гораздо большей легкостью программировать в таком стиле. Я полностью убежден, что он должен быть эффективным и настолько же близким к машине, как и C и C++. И я верю, что можно построить язык, который позволяет близко приблизиться к машине, с одной стороны и способен иметь дело с очень абстрактными объектами, с другой стороны. Я думаю, что абстрактности может быть даже больше, чем в C++ без разрыва между машинами, положенными в основу. Я думаю, обобщенное программирование может повлиять на исследования в области языков, и мы будем иметь практические языки, которые просты в использовании и хорошо подходят для этого стиля программирования. Из этого вы можете понять, над чем я далее планирую работать.
Автор: excoder