Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Изучай Erlang во имя добра!

Покупка
Артикул: 712461.01.99
К покупке доступен более свежий выпуск Перейти
Усеянная беспечными иллюстрациями и смесью развлекательных и практических примеров программ, книга «Изучай Erlang во имя добра!» является отличным пунктом отправления в иногда безумный, но всегда восхитительный мир Erlang. Вероятно, вас привело к Erlang обещание конкурентности или параллелизма. Возможно, это аспект языка, касающийся распределённых вычислений, а может быть, необычный подход к устойчивости против сбоев. Одним из величайших препятствий на пути изучения Erlang является не столько то, что идеям его свойственна сложность, но и то, что они сильно отличаются от идей большинства других языков, которые вам встречались. Переменные в Erlang не переменны. Вам не следует программировать в ожидании ошибки. Процессы действительно очень дёшевы, и вы можете иметь тысячи их одновременно, даже миллионы, если вам так захочется. Ох, и потом этот странный синтаксис. Erlang совершенно не похож на Java; нет ни методов, ни классов, ни объектов. И, обождите... знак равенства вовсе не означает «равно»... Издание предназначено как для начинающих изучать Erlang, так и для более опытных разработчиков. Даже в том случае, если читатель очень хорошо знаком с Erlang, книга сможет стать справочником и даже научить чему-то новому.
Хеберт, Ф. Изучай Erlang во имя добра! / Фред Хеберт ; пер. с англ. Д. Литовченко. — Москва : ДМК Пресс, 2015. - 688 с. - ISB 978-5-97060-086-3. - ISBN 978-5-97060-086-3. - Текст : электронный. - URL: https://znanium.ru/catalog/product/1028040 (дата обращения: 06.10.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов
Фред Хеберт

Изучай Erlang во имя добра! !!

Learn You Some
Erlang for Great

Good!

San Francisco

Fred Hebert

Изучай Erlang во

имя добра!

Москва, 2015

Фред Хеберт

У ДК 004.432.42Erlang
ББК 32.973.28-018.1

Фред Х еберт

Изучай Erlang во имя добра! / Пер. с англ. Литовченко Д. — М.:
– 688 с.: ил.

ISBN
978-5-97060-086-3

Усеянная беспечными иллюстрациями и смесью развлекательных и практических

примеров программ, книга «Изучай Erlang во имя добра!» является отличным пунктом
отправления в иногда безумный, но всегда восхитительный мир Erlang.

Издание предназначено как для начинающих изучать Erlang, так и для более

опытных разработчиков. Даже в том случае, если читатель очень хорошо знаком с
Erlang, книга сможет стать справочником и даже научить чему-то новому.

Вероятно, вас привело к Erlang обещание конкурентности или параллелизма.

Возможно, это аспект языка, касающийся распределённых вычислений, а может быть,
необычный подход к устойчивости против сбоев.

Одним из величайших препятствий на пути изучения Erlang является не столько

то, что идеям его свойственна сложность, но и то, что они сильно отличаются от
идей большинства других языков, которые вам встречались. Переменные в Erlang
не переменны. Вам не следует программировать в ожидании ошибки. Процессы
действительно очень дёшевы, и вы можете иметь тысячи их одновременно, даже
миллионы, если вам так захочется. Ох, и потом этот странный синтаксис. Erlang
совершенно не похож на Java; нет ни методов, ни классов, ни объектов. И, обождите...
знак равенства вовсе не означает «равно»...

УДК 004.432.42Erlang

ББК 32.973.28-018.1

Original English language edition published by No Starch Press, Inc. 38 Ringold Street,

San Francisco, CA 94103. Copyright ©
2013 by No Starch Press, Inc. Russian-language edition

copyright ©
2014 by DMK Press. All rights reserved.

Все права защищены. Любая часть этой книги не может быть воспроизведена в какой бы то

ни было форме и какими бы то ни было средствами без письменного разрешения владельцев
авторских прав.

Материал, изложенный в данной книге, многократно проверен. Но, поскольку вероятность

технических ошибок все равно существует, издательство не может гарантировать абсолютную
точность и правильность приводимых сведений. В связи с этим издательство не несет ответственности за возможные ошибки, связанные с использованием книги.

ISBN 978-1-59327-435-1 (англ.)
©
Fred Hebert, No Starch Press, Inc.

ISBN 978-5-97060-086-3
©
Оформление, перевод на русский язык,

ДМК Пресс, 2014

ДМК Пресс, 2015.

Х 35

Х35

Оглавление

Об авторе
17

Предисловие от Джо Армстронга, одного из создателей языка
19

Предисловие
21

Благодарности
23

Вступление
25

Об этом уроке . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25

Что такое Erlang? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
25

Что вам потребуется, чтобы начать . . . . . . . . . . . . . . . . . . . . . . .
29

Где получить помощь
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
31

1
Давайте начнём
33

Интерактивная консоль . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
33

Ввод команд интерпретатора . . . . . . . . . . . . . . . . . . . . . . .
34

Выход из интерпретатора . . . . . . . . . . . . . . . . . . . . . . . . .
34

Некоторые основы Erlang . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35

Числа . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36

Неизменные переменные . . . . . . . . . . . . . . . . . . . . . . . . .
37

Атомы
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39

Булева алгебра и сравнение . . . . . . . . . . . . . . . . . . . . . . . .
40

Кортежи . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
43

Списки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
45

Генераторы списков . . . . . . . . . . . . . . . . . . . . . . . . . . . .
48

Работа с двоичными данными . . . . . . . . . . . . . . . . . . . . . .
51

Двоичные строки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56

Двоичные генераторы . . . . . . . . . . . . . . . . . . . . . . . . . . .
56

2
Модули
59

Что такое модули?
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
59

Объявление модуля . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60

Компилируем код . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
64

Параметры компилятора . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
66

5

ОГЛАВЛЕНИЕ

Макросы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
67

Больше о модулях . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68

Метаданные . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
68

Циклические зависимости
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
70

3
Cинтаксис функций
71

Сопоставление с образцом
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
71

Более сложные образцы . . . . . . . . . . . . . . . . . . . . . . . . . .
73

Переменные в связке . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
74

Охрана! Охрана!
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
76

Что за Если? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79

В случае… если (case …of)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . .
82

Что же лучше? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83

4
Типы (вернее, их отсутствие)
85

Типизация сильная, как динамит
. . . . . . . . . . . . . . . . . . . . . . . .
85

Преобразование типов
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
87

Охрана типов данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
88

Для типозависимых
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
90

5
Привет, рекурсия
91

Длина списка
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
92

Длина хвостовой рекурсии . . . . . . . . . . . . . . . . . . . . . . . . . . . .
94

Больше рекурсивных функций . . . . . . . . . . . . . . . . . . . . . . . . . .
95

Функция дублирования duplicate . . . . . . . . . . . . . . . . . . . . .
96

Функция переворота reverse
. . . . . . . . . . . . . . . . . . . . . . .
97

Функция отрезания sublist . . . . . . . . . . . . . . . . . . . . . . . .
98

Функция склеивания пар zip . . . . . . . . . . . . . . . . . . . . . . .
99

Быстро! Сортируй! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Думаем рекурсивно . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

6
Функции высшего порядка
109

Становимся функциональными
. . . . . . . . . . . . . . . . . . . . . . . . . 109

Анонимные функции . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111

Больше анонимных функций . . . . . . . . . . . . . . . . . . . . . . . 112

Область видимости функции и замыкания . . . . . . . . . . . . . . . . . . . 113
Отображения, фильтры, свёртки и так далее
. . . . . . . . . . . . . . . . . 115

Фильтры . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Сворачиваемся (fold)
. . . . . . . . . . . . . . . . . . . . . . . . . . . 117

Больше абстракций
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 119

6

ОГЛАВЛЕНИЕ

7
Ошибки и исключения
121

Коллекция ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

Ошибки компиляции
. . . . . . . . . . . . . . . . . . . . . . . . . . . 122

Нет, ТВОЯ логика ошибочна!
. . . . . . . . . . . . . . . . . . . . . . 124

Ошибки времени выполнения . . . . . . . . . . . . . . . . . . . . . . 124

Создание исключений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128

Исключения-ошибки error
. . . . . . . . . . . . . . . . . . . . . . . . 128

Выходы процессов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
Броски исключений throw . . . . . . . . . . . . . . . . . . . . . . . . . 130

Обработка исключений . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

Обработка разных типов исключений
. . . . . . . . . . . . . . . . . 132

После catch
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

Попытка выполнить несколько выражений . . . . . . . . . . . . . . 135

Обождите, это ещё не всё!
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 136

Попробуйте try в дереве . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

8
Функциональный подход к решению проблем
143

Калькулятор в обратной польской записи
. . . . . . . . . . . . . . . . . . . 143

Как работают RPN-калькуляторы
. . . . . . . . . . . . . . . . . . . . 144

Создаём RPN-калькулятор . . . . . . . . . . . . . . . . . . . . . . . . . 145

Тестируем код . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
Из Хитроу в Лондон . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150

Рекурсивное решение проблемы
. . . . . . . . . . . . . . . . . . . . 151

Пишем код (из Хитроу в Лондон) . . . . . . . . . . . . . . . . . . . . 153

Запуск программы без интерпретатора Erlang . . . . . . . . . . . . . . . . . 158

9
Короткий экскурс в структуры данных
161

Записи . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161

Объявление записей . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Чтение значений из записей . . . . . . . . . . . . . . . . . . . . . . . 164
Совместное использование записей . . . . . . . . . . . . . . . . . . . 166

Хранилища данных ключ/значение . . . . . . . . . . . . . . . . . . . . . . . 167

Для небольших объёмов данных . . . . . . . . . . . . . . . . . . . . . 167
Большие хранилища: словари и общие сбалансированные деревья 169

Множество множеств
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171

Упорядоченные множества ordsets
. . . . . . . . . . . . . . . . . . . 172

Множества sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Общие сбалансированные множества gb_sets . . . . . . . . . . . . . 172
Множества множеств sofs . . . . . . . . . . . . . . . . . . . . . . . . . 172

Ориентированные графы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Очереди . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
Конец недолгой прогулки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175

7

ОГЛАВЛЕНИЕ

10 Автостопом по параллельным вычислениям
177

Не паникуйте . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
Концепции конкурентности
. . . . . . . . . . . . . . . . . . . . . . . . . . . 179

Масштабируемость . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Устойчивость к сбоям . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Реализация конкурентности . . . . . . . . . . . . . . . . . . . . . . . 182

Не совсем непохоже на линейный рост . . . . . . . . . . . . . . . . . . . . . 183
Всего хорошего, и спасибо за рыбу! . . . . . . . . . . . . . . . . . . . . . . . 185

Порождение процессов . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Отправка сообщений
. . . . . . . . . . . . . . . . . . . . . . . . . . . 188

Получение сообщений
. . . . . . . . . . . . . . . . . . . . . . . . . . 189

11 Ещё о параллельной обработке
193

Утверждайте ваше состояние . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Мы обожаем сообщения, но держим их в секрете . . . . . . . . . . . . . . . 195
Тайм-аут
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197

Избирательное получение
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 200

Подводные камни выборочного приёма сообщений . . . . . . . . . 201
Больше подводных граблей . . . . . . . . . . . . . . . . . . . . . . . . 203

12 Ошибки и процессы
205

Связи . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205

Это ловушка!
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208

Старые исключения, новые идеи
. . . . . . . . . . . . . . . . . . . . 209

Всё меняет exit/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
Убивая меня (не очень) нежно... . . . . . . . . . . . . . . . . . . . . . 213

Мониторы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Именование процессов
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215

13 Проектирование параллельного приложения
221

Понимание проблемы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
Определяем протокол . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Построим фундамент
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226

Модуль событий
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227

События и циклы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
Добавляем интерфейс . . . . . . . . . . . . . . . . . . . . . . . . . . . 231

Сервер событий . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233

Обработка сообщений . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
Горячая любовь к коду . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Я сказал, спрячьте ваши сообщения . . . . . . . . . . . . . . . . . . . 240

Пробный запуск . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
Добавляем надзор
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243

8

ОГЛАВЛЕНИЕ

Пространства имён (вернее, их отсутствие) . . . . . . . . . . . . . . . . . . 245

14 Представляем OTP
247

Общий вид процесса, абстрактно
. . . . . . . . . . . . . . . . . . . . . . . . 248

Простейший сервер . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249

Представляем сервер котят . . . . . . . . . . . . . . . . . . . . . . . . 249
Обобщаем вызовы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Обобщаем внутренний цикл сервера . . . . . . . . . . . . . . . . . . 253
Функции для старта
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 254

Обобщаем сервер котят . . . . . . . . . . . . . . . . . . . . . . . . . . 255

Конкретная реализация против обобщения . . . . . . . . . . . . . . . . . . 257
Обратный вызов в будущее . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258

Функция init
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259

Функция handle_call
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

Функция handle_cast
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

Функция handle_info
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

Функция terminate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

.BEAM Me Up, Scotty! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262

15 Ярость против конечных автоматов
267

Что такое конечный автомат?
. . . . . . . . . . . . . . . . . . . . . . . . . . 267

Обобщённые конечные автоматы . . . . . . . . . . . . . . . . . . . . . . . . 271

Функция инициализации . . . . . . . . . . . . . . . . . . . . . . . . . 271
Функция ИмяСостояния . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
Функция handle_event . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
Функция handle_sync_event . . . . . . . . . . . . . . . . . . . . . . . . . 273
Функции code_change и terminate . . . . . . . . . . . . . . . . . . . . . . 274

Спецификация торговой системы . . . . . . . . . . . . . . . . . . . . . . . . 274

Покажи мне свои движения
. . . . . . . . . . . . . . . . . . . . . . . 274

Определяем диаграммы состояний и переходы . . . . . . . . . . . . 276

Игровой обмен между двумя игроками . . . . . . . . . . . . . . . . . . . . . 283

Общедоступный интерфейс
. . . . . . . . . . . . . . . . . . . . . . . 283

Функции общения между КА . . . . . . . . . . . . . . . . . . . . . . . 284

Функции обратного вызова gen_fsm . . . . . . . . . . . . . . . . . . . . . . . . 286
Это было что-то . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
Готовы к реальному миру? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297

16 Обработчики событий
299

Справься-ка с этим! *перезаряжает ружьё* . . . . . . . . . . . . . . . . . . . . 299
Обобщённые обработчики событий . . . . . . . . . . . . . . . . . . . . . . . 300

Функции init и terminate . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Функция handle_event . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302

9

ОГЛАВЛЕНИЕ

Функция handle_call
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 303

Функция handle_info
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 303

Функция code_change
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 303

Пришло время кёрлинга! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303

Табло со счётом . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
Игровые события
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

Уведомите прессу! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309

17 Кто присмотрит за наблюдателями?
315

Принципы работы наблюдателей . . . . . . . . . . . . . . . . . . . . . . . . 316
Использование наблюдателей
. . . . . . . . . . . . . . . . . . . . . . . . . . 318

Стратегии перезапуска
. . . . . . . . . . . . . . . . . . . . . . . . . . 319

Ограничения перезапуска
. . . . . . . . . . . . . . . . . . . . . . . . 321

Спецификации на детей . . . . . . . . . . . . . . . . . . . . . . . . . . 321

Репетиция музыкальной группы . . . . . . . . . . . . . . . . . . . . . . . . . 324

Музыканты
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324

Наблюдатель за группой
. . . . . . . . . . . . . . . . . . . . . . . . . 328

Динамические процессы-наблюдатели . . . . . . . . . . . . . . . . . . . . . 331

Динамическое использование стандартных наблюдателей . . . . . 331
Использование наблюдателя simple_one_for_one . . . . . . . . . . . . 333

18 Строим приложение
335

Пул процессов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335

Теория луковых слоёв . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Дерево для пула . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339

Реализация наблюдателей . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
Работаем с работниками . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
Пишем рабочий процесс
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352

Беги, пул, беги . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Чистим бассейн . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356

19 Строим приложение в стиле OTP
359

Пул — мой второй автомобиль
. . . . . . . . . . . . . . . . . . . . . . . . . . 360

Файл ресурсов приложения . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Преображение пула
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364

Поведение приложения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
Из хаоса к приложению . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
Библиотечные приложения . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371

10

К покупке доступен более свежий выпуск Перейти