Шрифт:
То, что я придумал, пришло ко мне скорее в виде образа, чем чего-то другого: это было похоже на колесо. Если посмотреть на источник, цель и границы слова, то кажется, что колесо забирает целые слова здесь и переносит их туда, так что требуется только один перенос, — вот такая картина мне и явилась. Теперь оставалось только переложить это на язык кода.
Таким образом, в центре операции BitBlt находится один длинный процесс сдвига, который забирает слова в источнике и переносит их к цели. Над этим уже следовало подумать. Но как только понимаешь, что можно таким образом хранить константы, становится ясно, что так можно размещать текст, брать образы символа из шрифта и помещать их в любое место экрана.
Сейбел: Вернемся к варианту Smalltalk на Бейсике: получается, это был предтеча Smalltalk, даже еще до Smalltalk-72?
Ингаллс: Именно так. Как только он заработал, я тут же начал делать практически полную версию на языке ассемблера, который у меня был на Nova. Мы использовали ее для отладки, а параллельно создавался компьютер Alto. Как только он стал доступен, мы переключились на него. Так и появился Smalltalk-72.
Сейбел: Итак, Smalltalk-72 был написан на ассемблере — когда же, в таком случае, он стал самодостаточным? Часто можно услышать, что лучшее в Smalltalk — то, что многое в нем написано на нем самом.
Ингаллс: Это было уже намного позже. Smalltalk-72 содержал большое количество кода на ассемблере. Как, собственно говоря, и Smalltalk-76. Основная разница между Smalltalk-72 и Smalltalk-76 заключалась в том, что я предложил идею движка байт-кода для Smalltalk, у которого был синтаксис на основе ключевых слов и который компилировался. Так что классы и даже стековые фреймы были реальными объектами — это к вашему замечанию о самодостаточности.
Сейбел: Когда вы пришли к идее написать интерпретатор байт-кода?
Ингаллс: Меня захватила такая идея: синтаксический анализ (парсинг) Smalltalk-72 выполняется на лету, и как минимум по двум причинам нам нужно было уметь компилировать нечто с той же семантикой, но не требующее моментального парсинга.
И я предложил синтаксис Smalltalk-76, который во многом был близок синтаксису Smalltalk-80. Затем встал другой вопрос: как компилировать, чтобы эффективно заработало с новым синтаксисом? Впрочем, единственным моментом, с которым возникли сложности, были так называемые удаленные вычисления — переменные, которые вы объявляете в одном месте, вычисляются в другом. Так в Smalltalk появились блоки — эквиваленты замыканий в других системах.
Сейбел: А почему просто не компилировать в машинный код?
Ингаллс: Мы по-прежнему экономили память, и наш вариант выходил исключительно компактным по сравнению с любым другим. И он должен был быть компактным, потому что запускать это все равно предстояло на Alto с 96 Кбайт памяти. Потом вышли более объемные разновидности — 128 Кбайт. То есть была важна компактность.
Сейбел: Значит, порожденный код был меньше, потому что байт-код был богаче, чем машинные инструкции?
Ингаллс: Да. Я был в восторге от идеи, навеянной работой Питера Дойча над движком байт-кода для Лиспа. Это взаимодействие очень повлияло на меня: появилось еще одно ядро, которое могло поместиться в микрокод. С самого начала работы я старался уместить ее в микрокоде для Alto.
Сейбел: Микрокод был в памяти, так что вы могли бы внедрить туда ядро Smalltalk, а затем переключиться на Лисп и встроить туда интерпретатор байт-кода на Лиспе.
Ингаллс: Да.
Сейбел: Что стало следующим шагом?
Ингаллс: Smalltalk-76 унаследовал тот же графический багаж: много специального кода для отрисовки линий, вывода текста и так далее. Но в то же время я уже сделал BitBlt, так что я переписал ядро, чтобы вся графика использовалась только BitBlt и Smalltalk, в итоге ядро стало значительно меньше. Это был Smalltalk-78 — первый, который мы запустили на микропроцессоре — на 8086.
Но это по-прежнему не был Smalltalk на Smalltalk. Smalltalk на Smalltalk не существовал до появления Squeak. Для Smalltalk-80 были спецификации виртуальной машины — они были опубликованы в виде книги, но все реализации были на Си или на ассемблере.
Сейбел: А компилятор?
Ингаллс: Компилятор был написан на Smalltalk. Собственно, когда мы писали книги о Smalltalk-80, мы с Дэйвом Робсоном — в основном, впрочем, он — написали на Smalltalk эмуляцию интерпретатора байт-кода. Это должно было стать частью Smalltalk-80: мы хотели помочь людям создать собственные виртуальные машины. Мы обнаружили, что очень полезно знать, какие именно байт-коды и в каком порядке выполняются при первом запуске системы.
Итак, он написал эмулятор на Smalltalk, потому что наш Smalltalk становился все быстрее, так что вполне подходил для этой цели, и создал все необходимые инструменты слежения, которые помогали пользователям при отладке.