И это круто. Вот еще одна стратегия распараллеливания, больше похожая на первую: инициализируем какой-нибудь регистр нулем, а потом процессоры борются за то, чтобы взять следующее число и прибавить его к этому регистру. Встает вопрос о синхронизации, но ответ-то будет тот же самый. Ведь сложение не только ассоциативно, но и коммутативно. То есть не имеет значения не только порядок группировки чисел, но и порядок их обработки.
У математиков для описания всего этого есть громоздкие устрашающие слова — «нейтральный элемент», «ассоциативность», «коммутативность». Я попытался растолковать понятнее. Программистам надо просто знать, что порядок операций не имеет значения и что можно перегруппировывать объекты. То есть в какой-то мере математические понятия, я считаю, важны для программистов.
Сейбел: Да, это хороший пример, потому что его поймет каждый, кто знает арифметику. Но не считаете ли вы, что таким же образом в программирование входят и понятия более высокого уровня?
Стил: Предположим, я генерирую отчет. Типичная ситуация: я делаю сколько-то выводов на печать, они должны быть выведены в определенном порядке. В многоядерном мире я, возможно, захочу делать это не в линейном порядке, а разложить на разные процессоры. Как мне связать все воедино? Можно ли использовать те же методы, что при сложении чисел? Выясняется, что здесь есть ассоциативность, но нет коммутативности, — тогда я знаю, какие приемы будут работать для строк, а какие не будут. Как разработчик языков программирования, имеющий дело с созданием параллельных языков, я нахожу эти понятия и прилагающийся к ним словарь очень полезными.
Сейбел: Кстати о создании языков: как менялся ваш подход с течением времени?
Стил: Главную перемену я описал в своем докладе «Growing a Language» (Выращивание языка) на конференции по объектно-ориентированному программированию OOPSLA 1998 года. В 1970-е годы создатель языка готовил для него проект, реализовывал его и на этом всё. Или не всё; но вы оставались с мыслью, что язык завершен.
Возьмем Паскаль. Что-то по каким-то причинам туда вошло, что-то не вошло, но проектирование языка был завершено. Если бы выяснилось, что чего-то не хватает, что работа со строками никуда не годится, что ж, не повезло. Вирт создал такой язык. ПЛ/1 и Ада были спроектированы таким же образом. Возможно, Ада и C++ стали едва ли не последними языками такого рода. В меньшей степени C++ — он все-таки развивался с течением времени.
Затем языки становились все сложнее, было уже невозможно проектировать их за один раз, и эти языки уже эволюционировали с течением времени, потому что они были слишком велики, чтобы их спроектировать или реализовать за один раз. Вот это и определило смену моего подхода к проектированию языков.
Сейбел: Значит, по-вашему, Java проектировался уже по-другому?
Стил: Наверное, нет. Хотя должен был бы. Java менялся благодаря Java Community Process. Это касалось больше API, чем ядра. Последние 12-13 лет к языку добавлялись все новые свойства, но, наверное, его создатели в начале 1990-х думали, что создают совершенный язык для конкретных ограниченных целей. Вы знаете, их целью были ресиверы для телевизоров.
Сейбел: Верно.
Стил: Они не рассчитывали на Интернет или на такую широкую пользовательскую базу, как сейчас. По-моему, они хотели создать компактный, автономный базовый язык, над которым можно было бы надстраивать API для разных целей. Мой доклад «Выращивание языка» отчасти был посвящен этому процессу: тому, как Java оказался слишком маленьким, а пользователям нужно было больше свойств для их целей.
Особенно требовалось нечто вроде итерации с помощью цикла for путем перечисления. И это добавили в язык. Ученые, которые занимались высокопроизводительными научными вычислениями, требовали большей поддержки операций с плавающей запятой и тому подобного. Но участники Java Community Process это в целом отвергли — по причинам не столько техническим, сколько социальным, мне кажется.
Так или иначе, существовала потребность что-то добавлять к языку, и это вылилось в многоплановый социальный процесс. Думаю, для создания действительно успешного языка нужно планировать такой — социальный — процесс в той же мере, в какой и технические особенности языка. Нужно думать о взаимодействии этих двух вещей. Fortress стал нашим — по крайней мере, моим — первым экспериментом подобного рода. И он еще не закончен, мы пока что на середине пути.
Сейбел: A Common Lisp, в создании которого вы участвовали, может служить в этом смысле примером?
Стил: Да, это еще один из «ранних» языков, который, будучи противопоставленным языкам вроде Java, заставил меня задуматься о «выращивании языка». Я хорошо знаю историю Лиспа, знаю, как возможности его макросов помогли ему безболезненно эволюционировать, помогли людям участвовать в добавлении новых свойств.