Smalltalk - язык объектно-ориентированного программирования
Перед Smalltalk имеет смысл пройти парадигмы и уровни абстракции и ООП — о разделе (зачем объекты, введение, абстракция, инкапсуляция, наследование, полиморфизм).
Затем — практика в ООП-модели Smalltalk.
Play ITЗагрузка интерактивного демо…
Smalltalk
Что такое Smalltalk?
Smalltalk — это язык программирования со следующими особенностями:
- Типизация — динамическая, сильная; вывода типов нет; тип определяется объектом, на который ссылается переменная, а не объявлением.
- Парадигма — чистый объектно-ориентированный: всё — объект, вычисления — посылка сообщений; рефлексия и метапрограммирование (классы и методы изменяются на лету).
- Уровень — высокоуровневый.
- Выполнение — интерпретируемый на виртуальной машине: исходник компилируется в байт-код при сохранении метода; современные VM (Pharo, VisualWorks) добавляют JIT-компиляцию в нативный код.
- Память — автоматическая: сборщик мусора (generational GC), прозрачен для программиста.
- Платформа — кроссплатформенный (Windows, macOS, Linux через VM); управляемый runtime (образ image + VM); не транспилируется в другой высокоуровневый язык; интеграция с C через FFI.
- Формат разработки — не скриптовый и не "файлы + сборка": работа внутри image (живая среда); код организуют пакетами (Pharo, Tonel), но нет классической модели "проект → exe".
- Направление — универсальный с акцентом на обучение ООП, прототипирование и исследовательскую разработку; исторически — корпоративные GUI-системы (VisualWorks); сильное влияние на Java, Ruby, Objective-C и практики разработки.
- REPL — есть и это основа среды: Workspace и Playground в Pharo/Squeak; выражения выполняются интерактивно, результат можно инспектировать сразу.
- Поколение — классический (Smalltalk-80, 1980-е), экосистема поддерживается (Pharo, Squeak, GNU Smalltalk).
- Параллелизм и асинхронность — нативно на уровне VM — лёгкие Process (green threads), Semaphore, планировщик внутри образа; нет
async/awaitкак в современных языках — фоновую работу выносят в отдельный процесс (forkв Pharo). - Безопасность — относительно "безопасный" для памяти (GC, нет указателей как в C); полная рефлексия и изменение классов на лету делают систему гибкой, но уязвимой к произвольным изменениям кода внутри образа.
Если какой-то пункт из списка непонятен — подробные определения и примеры в Язык программирования.
Кому и зачем
После ООП в разделе "Код" Smalltalk показывает чистую объектную модель — image, сообщения, живая среда. Практика — в Pharo и первой программе.
Мы с вами изучили основы кода, и особенно важным было изучение ООП — объектно-ориентированного программирования. Когда речь идёт об ООП, логично поговорить о Smalltalk: это один из самых последовательных ООП-языков — без примитивов и без отдельного синтаксиса для if/for. Язык старый, но даёт сильное понимание того, как устроены сообщения, классы и "живая" среда разработки. В Java, C#, Python и Ruby ООП часто смешано с процедурным кодом, статической типизацией или файловой моделью — это компромиссы, а не "ошибка проектирования".
Smalltalk ([ˈsmɔːltɔːk]) — объектно-ориентированный язык с динамической типизацией, построенный на идее посылки сообщений. Его разрабатывали в Xerox PARC (Алан Кэй, Дэн Ингаллс, Тед Кэглер, Адель Голдберг и др.) в 1970-х; широкую известность принесла версия Smalltalk-80. Исходники и фрагменты кода часто сохраняют в файлах с расширением .st.
Среда Smalltalk — интегрированная — разработка, исполнение и сами объекты системы доступны для изменения изнутри, без обязательной остановки и полной пересборки. Программирование здесь часто сводится к настройке поведения уже работающей среды.
Это первый широко известный "чистый" ООП-язык; на него опирались Java, Objective-C, Ruby и идеи многих IDE. Для обучения в разделе ориентируемся на открытую реализацию Pharo (термины package, Playground, Tonel).
Место среди языков
Smalltalk относится к семейству ООП-языков, восходящих к Simula (классы, наследование, моделирование). Simula повлияла на Smalltalk; Smalltalk, в свою очередь, повлиял на Objective-C, Java, Ruby, Python, C#, Groovy, Scala, Self и другие.
| Направление | Примеры |
|---|---|
| Предшественники | Simula, Sketchpad, Lisp, Logo |
| Языки, перенявшие идеи | Objective-C, AppleScript, Java, Ruby, Python, C#, Groovy, Dylan, Io, Scala, Self |
Подробная хронология — в статье История языка Smalltalk.
Практики из сообщества Smalltalk
Многие приёмы разработки ПО сформировались в экосистеме Smalltalk 1980–1990-х и позже стали общей нормой:
- рефакторинг (Кент Бек и др.);
- шаблоны проектирования применительно к ПО;
- CRC-карты (класс — обязанности — взаимодействие);
- экстремальное программирование (XP);
- SUnit — первый фреймворк модульных тестов (прообраз JUnit и NUnit).
Уорд Каннингем, автор концепции вики, также работал в этом сообществе. Развёрнуто о философии — в Философия и принципы.
Интерактивная схема — класс и объект (псевдокод; в Smalltalk "всё — объект"). Полный разбор принципов: ООП в разделе "Код и разработка".
Play ITЗагрузка интерактивного демо…
Особенности работы
Smalltalk:
- объектно-ориентированный;
- динамический;
- интерпретируемый;
- рефлексивный (может исследовать и модифицировать себя);
- интерактивный - программирование в режиме диалога с системой.
Он относится к семейству языков с высокой степенью мета-возможностей, наряду с Lisp, Self и современными динамическими языками.
Smalltalk - один из самых влиятельных проектов в истории вычислений, потому что он впервые реализовал идеи, которые сегодня кажутся нам естественными:
- Всё в программе - объект;
- Программирование - взаимодействие с живой системой;
- Среда разработки - часть самой программы.
Технически, принципы ООП здесь доведены до логического предела. Здесь нет примитивных типов, операторов или статических конструкций. Только объекты и сообщения, которыми они обмениваются.
В отличие от большинства языков, где код пишется в редакторе, компилируется и запускается отдельным процессом, Smalltalk работает иначе.
Работа с программой здесь представляет собой своего рода "жизнь" внутри неё, ведь всё состояние системы - код, объекты, переменные, окна интерфейса - всё сохраняется в образе. Это образ системы (Система Image), бинарный файл, содержащий полную копию работающей среды.
Вы можете изменить код, отлаживать, создавать объекты - и всё это сохранится при следующем запуске. Нет понятия "перезапуск приложения" - есть продолжение работы с того же места. Это как если бы ваша IDE, запущенные процессы и данные были бы одним целым. К примеру, вы исправили баг в отладчике, сохранили исправление, закрыли систему — а через неделю, открыв её снова, продолжаете с того же момента.
Smalltalk работает на виртуальной машине - VM, это программа, которая интерпретирует байт-код и управляет образом. VM отвечает за выполнение кода, управление памятью, графический интерфейс и взаимодействие с ОС. Это, кстати единственная часть системы, не написанная на самом Smalltalk (обычно на C/C++, традиционных системных языках). Всё остальное - включая сам компилятор, отладчик и редактор, написано на Smalltalk и работает внутри образа.
Smalltalk - язык с полной динамической типизацией, где типы проверяются во время выполнения, а не на этапе компиляции. Переменная не имеет типа — тип определяется по объекту, на который она ссылается. Это позволяет писать гибкий, адаптивный код, но требует от программиста большей ответственности.
Бывают языки строго типизированные, которые требуют указать тип, выделят память согласно правилам, и в случае несоответствия типов будут "ругаться". А динамически типизированные языки подразумевают, что платформа "сама разберётся", что за тип данных, главное их ей дать.
Smalltalk здесь реализуют концепцию интересным образом. Все типы данных здесь - числа, строки, классы, методы, блоки кода - всё является объектом, даже true, false. Имеется полная интроспекция - любой объект может рассказать о себе, кто его класс, какие его переменные, какие методы он поддерживает.
И самое необычное - здесь почти нет ключевых слов (всего их около шести).
В большинстве языков мы, как программисты, говорим "вызвать метод", что даёт команду и обращается к соответствующему блоку кода. В Smalltalk немного иначе - здесь "посылается сообщение". Любому объекту может быть послано любое сообщение. Что будет дальше — зависит от того, понимает ли объект это сообщение.
Давайте наконец посмотрим как выглядит язык:
42 factorial "отправляем сообщение 'factorial' объекту 42"
'hello' size "отправляем 'size' строке"
(3 > 5) ifTrue: [ 'yes' ] ifFalse: [ 'no' ] "отправляем условное сообщение"
Если вы знаете или работали хоть с одним современным языком, то заметите сильную разницу в стиле и синтаксисе. Представьте что всё здесь - сообщения и объекты. Мы указываем объект и указываем сообщения. Если объект не понимает сообщение, он получает специальное сообщение doesNotUnderstand:, и вы можете перехватить его — это основа для динамического поведения, проксирования, DSL.
Smalltalk кроссплатформенный, и современные реализации работают как на Windows, так на macOS и Linux. VM обеспечивает абстракцию от операционной системы. Образы переносятся между платформами без изменений.
Совместимости с современными программами напрямую нет, ведь Smalltalk не компилируется допустим в .exe. Но есть интеграция с C через FFI (Foreign Function Interface), можно запускать внешние процессы.
В Smalltalk нет внешней IDE. Всё, что нужно, встроено.
Компоненты
Компоненты языка:
- Браузер классов (Class Browser) позволяет просматривать и редактировать классы, методы, пакеты. Иерархия классов здесь визуальная, а навигация мгновенная. Можно открыть любой метод в системе — включая код самого отладчика.
- Отладчик (Debugger) работает при возникновении ошибок. Там можно увидеть стек вызовов, изменить код "на лету" и продолжить выполнение. Можно вставить новые переменные, изменить значения и продолжить. Словом, позволяет "вмешаться" в процесс.
- Инспектор объектов (Inspector) позволяет заглянуть внутрь любого объекта, просмотреть переменные экземпляра, изменить их, вызвать методы, что полезно для отладки и экспериментов.
Сборка мусора (Garbage Collection) здесь автоматическая, на основе поколений (generational GC), освобождает память от объектов, на которые больше никто не ссылается, и является прозрачной для программиста.
Код компилируется в байт-код виртуальной машины, а компиляция происходит на лету, при сохранении метода. Здесь нет отдельного этапа "сборки проекта". Современные VM (например, в Pharo) используют JIT-компиляцию (Just-In-Time) для ускорения. Часто исполняемый код переводится в нативный машинный код.
Современными реализациями языка являются:
- Pharo - открытая реализация, имеет отличную IDE, поддерживает веб-разработку и анализ кода, подходит для обучения и прототипирования.
- Squeak — открытый потомок Smalltalk-80; используется в образовании (Etoys; Scratch 1.x строился на Squeak).
- VisualWorks — коммерческая реализация от Cincom, применяется в промышленных системах (финансы, телеком).
- GNU Smalltalk - реализация от проекта GNU.
Существуют и иные реализации, но для изучения рекомендуется обычно Pharo.