Smalltalk ([ˈsmɔːltɔːk]) — объектно-ориентированный язык программирования с динамической типизацией, основанный на идее посылки сообщений, разработанный в Xerox PARC Аланом Кэем, Дэном Ингаллсом, Тедом Кэглером, Адель Голдберг, и другими в 1970-х годах. Представляет собой интегрированную среду разработки и исполнения, объекты которой доступны для модификации через неё саму, и программирование в которой в итоге сводится к модификации её собственного поведения. Язык был представлен как Smalltalk-80.
Smalltalk | |
---|---|
Семантика | объектно-ориентированная |
Класс языка | язык программирования |
Появился в | Разработка начата в 1969 г., стал доступен для широкого использования в 1980 |
Автор | Алан Кэй, Адель Голдберг, Дэн Ингаллс, Xerox PARC |
Разработчик | Кэй, Алан Кёртис, Адель Голдберг[1], Дэниэл Генри Холмс Ингаллс[d] и Diana Merry[d] |
Выпуск | Smalltalk-80 version 2 |
Тестовая версия | 1980; 42 года назад (1980) |
Система типов | динамическая |
Основные реализации | Pharo, Squeak, VisualWorks, GNU Smalltalk |
Испытал влияние | Simula, Sketchpad, Lisp, Logo |
Повлиял на | Objective-C, AppleScript, C#, Dylan, Groovy, Io, Java, Lisaac, NewtonScript, Python, Ruby, Scala, Self, C++ |
Smalltalk является одним из многих объектно-ориентированных языков, основанных на языке Симула[2], который сам оказал большое влияние на развитие таких объектно-ориентированных языков, как: Objective-C, Actor, Java, Erlang[3], Groovy, Ruby и многих других. Многие идеи 1980-х и 1990-х по написанию программ появились в сообществе Smalltalk. К ним можно отнести рефакторинг, шаблоны проектирования (применительно к ПО), карты «класс — обязанности — взаимодействие» и экстремальное программирование в целом. Основатель концепции вики Уорд Каннингем также входит в сообщество Smalltalk.
Основными идеями Smalltalk являются:
Smalltalk также использует другие современные идеи:
Одной из особенностей Smalltalk является то, что даже такие традиционные конструкции, как if-then-else, for, while, и т. д. не являются частью языка. Все они реализованы с помощью объектов. Например, решение принимается с помощью посылки сообщения ifTrue:
логическому объекту, и передаёт управление фрагменту текста, если логическое значение истинно.
Собственно встроенных синтаксических конструкций в языке немного:
и несколько синтаксических конструкций для определения объектов-литералов и временных переменных.
Аналогом механизма обмена сообщениями Smalltalk является сеть интернет: можно представить каждый объект как веб-сервер, отвечающий на запросы. При этом, сервер на запросы может просто выдавать заранее предопределённый ответ, например веб-страницу, расположенную по определённому пути; может перенаправить запрос-сообщение другому объекту, аналог — прокси-сервер; может изменить запрос по определённым правилам, аналог — техника url rewriting, и конечно же, может сформировать абсолютно новую страницу, соответствующую данным, переданным с сообщением. Если для реакции на сообщение у объекта нет предопределённого метода, то среда вызывает у получателя метод #doesNotUnderstand:, так же, как веб-сервер возвращает страницу с сообщением об ошибке, если задан несуществующий путь к веб-странице.
Краткий обзор синтаксических элементов:
Отдельно стоящей парой символов |
окружается список имён переменных, которые будут временными. Символ :
при передаче сообщения ставится после имени сообщения или его аргумента, перед передаваемым с ним значением, а символы [
и ]
ограничивают блок команд, а точнее — литерал анонимной функции. Но их можно, для начала, воспринимать их как аналог фигурных скобок {
и }
в Си-подобных языках. В начале такой анонимной функции до символа |
можно перечислить требуемые ею аргументы. Её результатом будет последнее вычисленное ею выражение. Символ .
завершает отдельную команду, символ ;
— разделяет сообщения, которые нужно последовательно передать одному и тому же объекту. Пара символов :=
обозначает присваивание в переменную, имя которой расположено перед ней, объекта-литерала или объекта-ответа на сообщение, расположенного после неё.
Следующий пример, показывающий нахождение гласных в строке, иллюстрирует стиль Smalltalk.
| aString vowels |
aString := 'This is a string'.
vowels := aString select: [:aCharacter | aCharacter isVowel].
В последней строке примера объекту-строке посылается сообщение select:
с аргументом — анонимным блоком кода, принимающим один аргумент, и возвращающим то, что вернёт обработчик события isVowel переданного этим аргументом объекта. При обработке сообщения select вызывается метод select:
из класса Collection
(одного из предков класса String
, к которому относится объект, создаваемый строковым литералом во второй строке примера). Текст этого метода показан ниже:
select: aBlock
| newCollection |
newCollection := self species new.
self do: [:each |
(aBlock value: each)
ifTrue: [newCollection add: each]].
^newCollection
Он осуществляет принимает на вход анонимную функцию aBlock, создаёт новую коллекцию, аналогичную себе, и вызывает перебор своих элементов (это метод do:
), выполняя переданный ему блок aBlock
для каждого элемента; когда блок выполняется (в примере — aCharacter isVowel
), он создаёт логическое значение, которому затем посылается сообщение ifTrue:
. Если это значение true
, то буква добавляется в возвращаемую строку. В конце созданная коллекция возвращается ответом на сообщение, на что указывает символ возвращения в качестве ответа ^
. Из-за того что select:
определён в абстрактном классе Collection
, мы также можем использовать его ещё и так:
| rectangles aPoint|
rectangles := OrderedCollection
with: (Rectangle left: 0 right: 10 top: 100 bottom: 200)
with: (Rectangle left: 10 right: 10 top: 110 bottom: 210).
aPoint := Point x: 20 y: 20.
collisions := rectangles select: [:aRect | aRect containsPoint: aPoint].
Smalltalk был создан группой исследователей, возглавляемой Аланом Кэем, в исследовательском центре Xerox PARC. Первая реализация, известная как Smalltalk-71, была создана за несколько месяцев как результат спора о том, что язык программирования, основанный на идее посылки сообщений, подсказанной Симулой, должен реализовываться на «странице кода». Более поздняя версия, действительно использованная для исследовательской работы, известна сейчас как Smalltalk-72. Его синтаксис и модель исполнения сильно отличались от современного Smalltalk, настолько, что его надо рассматривать как другой язык.
После существенных переработок, которые зафиксировали несколько сторон семантики выполнения для увеличения эффективности, была создана версия, известная как Smalltalk-76. В этой версии добавились наследование, синтаксис, более близкий к Smalltalk-80, и среда разработки, включающая большинство инструментов, знакомых современным Smalltalk-разработчикам.
В Smalltalk-80 были добавлены метаклассы, что делало фразу «всё — объекты» истинной путём связывания с индивидуальными классами свойств и поведения (например, поддержки различных способов создания экземпляров). Smalltalk-80 был первой версией, доступной за пределами PARC — сначала как Smalltalk-80 Version 1, розданный небольшому количеству компаний и университетов для «экспертной оценки». Позже, в 1983 году, были выпущены общедоступная реализация, известная как Smalltalk-80 Version 2 — в виде образа (независимый от платформы файл, содержащий объекты) и спецификации виртуальной машины.
Сейчас существует две реализации Smalltalk, являющиеся прямыми потомками Smalltalk-80 — Squeak и VisualWorks.[4] Образ Smalltalk-80 version 2 запущен на Hobbes, виртуальной машине ST-80, реализованной на VisualWorks.
Transcript show: 'Hello, world!'
Этот пример показывает две стороны Smalltalk.
Во-первых, посылка сообщения: в Smalltalk все действия производятся путём посылки сообщений объектам. В данном случае сообщение это show: 'Hello, world!'
, и оно посылается объекту Transcript
. Для обработки этого сообщения будет вызван метод Transcript show:
, который должен рассмотреть свой аргумент (строку 'Hello, world!') и отобразить этот аргумент на transcript (заметьте, что у вас должно быть открыто окно Transcript, чтобы увидеть результат).
Во-вторых, этот пример показывает основной синтаксис посылки сообщения в Smalltalk: <получатель сообщения> <пробел> <сообщение>. В отличие от C++, нет точек после получателя, и нет скобок вокруг аргументов.
Object subclass: #MessagePublisher
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: ''
category: 'Smalltalk Examples'
Это простое определение класса с определением имени и категории. Обычно среда разработки предоставляет заготовку с большей частью текста этого примера.
publish
Transcript show: 'Hello, world!'
Это определение метода с именем publish
. Тело метода такое же, как в простом примере.
MessagePublisher new publish
В данном примере создаётся экземпляр класса MessagePublisher
(MessagePublisher new
), затем ему посылается сообщение publish
. Обратите внимание, что для создания объекта не используется ключевое слово языка (как в C++, Java, C#), а посылается обычное сообщение new
классу MessagePublisher
. Сообщения для создания объектов иногда переопределяют. Например, некий абстрактный класс может в ответ на new
возвращать экземпляр одного из своих конкретных подклассов.
![]() | Список примеров в этой статье не основывается на авторитетных источниках, посвящённых непосредственно предмету статьи. |
![]() |
Имеется викиучебник по теме «Smalltalk в примерах» |
---|
![]() ![]() | |
---|---|
В библиографических каталогах |
|
![]() | Для улучшения этой статьи желательно: |
![]() Языки программирования | |
---|---|
| |
|
![]() Объектно-ориентированные языки | |
---|---|
Компилируемые | |
Скриптовые |
|
Оба исполнения |