Всем привет!

Я сделал перевод и набил субтитры на доклад Рича Хикки — Effective Programs (10 Years of Clojure) — Эффективные программы (10 лет Clojure). Впервые на русском языке.

Доклад был представлен в 2017 году на конференции Clojure Conj.




О докладе:

Рич Хикки подробно рассказывает о том, как создавать действительно эффективные программы, о том, как он создавал Clojure, что лежит в основе правильной архитектуры языка и почему типы не то, чем кажутся.


Рич Хикки — создатель языка программирования Clojure, независимый разработчик ПО и консультант с 20-летним опытом работы в различных областях разработки ПО. Примерно 2,5 года в одиночку работал над Clojure, прежде чем кому-либо его показать.



Посмотреть на Ютубе

Полный текст субтитров
1
00:00:01,000 --> 00:00:07,146
Эффективные программы

2
00:00:07,146 --> 00:00:10,528
Каждый раз на таких выступлениях
чувствую себя заезженной пластинкой

3
00:00:10,552 --> 00:00:11,697
когда благодарю всех.

4
00:00:11,721 --> 00:00:14,168
Поэтому хочу начать этот разговор
по-другому, сказав:

5
00:00:14,192 --> 00:00:19,070
Мой сын женится сегодня

6
00:00:23,821 --> 00:00:26,398
В другом штате

7
00:00:26,422 --> 00:00:31,151
Итак, сразу после этого выступления я собираюсь
сесть на самолет, и отправиться на свадьбу.

8
00:00:31,175 --> 00:00:33,911
Я вернусь завтра утром.
Так что я не исчезаю.

9
00:00:33,935 --> 00:00:37,619
Я с нетерпением жду последующих обсуждений
и всего остального,

10
00:00:37,643 --> 00:00:39,861
но я буду некоторое время отсутствовать.

11
00:00:39,885 --> 00:00:44,128
Продолжая пустословие. Спасибо всем, что пришли.

12
00:00:44,152 --> 00:00:51,493
Десять лет назад Clojure был выпущен, и ни за что на свете…

13
00:00:55,605 --> 00:00:57,548
я не мог представить такое.

14
00:00:57,572 --> 00:01:05,346
Я сказал своей жене Стефе: «Если бы им пользовались
100 человек, это было бы фантастически много».

15
00:01:07,491 --> 00:01:14,162
Но получилось иначе. И то, что получилось, занятно.

16
00:01:14,186 --> 00:01:16,336
Не думаю, что полностью понятно почему.

17
00:01:18,577 --> 00:01:25,644
Но сегодня я хотел немного оглянуться и взглянуть
на движущую силу, которая стоит за Clojure.

18
00:01:25,668 --> 00:01:30,993
Когда выходит новый язык программирования,
вначале вы не можете понять причины.

19
00:01:31,017 --> 00:01:33,827
Я думаю первая в том:
дело не в хорошем маркетинге

20
00:01:33,851 --> 00:01:39,217
и вторая: если вы действительно честны,
вы, вероятно, не знаете в чём причина успеха.

21
00:01:39,241 --> 00:01:46,035
Требуется время, чтобы понять, что произошло,
и почему, и о чём вы на самом деле думали.

22
00:01:46,059 --> 00:01:50,619
И я не буду притворяться, что у меня был
грандиозный план, который включал в себя всё,

23
00:01:50,619 --> 00:01:52,129
что в итоге было включено в Clojure.

24
00:01:52,153 --> 00:01:55,755
Конечно было много взаимодействия с людьми в комьюнити.

25
00:01:58,670 --> 00:02:05,291
Но так произошло. «Clojure стал самодостаточным».
Мы слышим это.

26
00:02:07,004 --> 00:02:09,568
И я думаю, что интересно подумать о двух аспектах.

27
00:02:09,592 --> 00:02:14,065
Во-первых, в чем это выражается?
И что значит для языка быть самодостаточным?

28
00:02:14,089 --> 00:02:18,527
Я думаю, что в случае c Clojure
люди приходят в язык, и они такие:

29
00:02:18,551 --> 00:02:23,988
«Вау. Он заставляет меня, куда бы я ни повернулся,
делать что-то определённым образом».

30
00:02:25,915 --> 00:02:30,261
И я думаю, что хороший способ сказать:
есть всего несколько сильно поддерживаемых идиом,

31
00:02:30,285 --> 00:02:33,802
и большая поддержка вокруг них.

32
00:02:33,826 --> 00:02:39,418
Так что, если вы используете вещи, которые
идут с языком, у вас будет сильная поддержка.

33
00:02:39,442 --> 00:02:43,315
Но если вы хотите бороться с ними,
у нас ничего не получится.

34
00:02:43,339 --> 00:02:49,505
Алекс спрашивал меня, какие очки
лучше подходят, и ответ «ни одни».

35
00:02:49,529 --> 00:02:52,427
Но архитектура — это когда делаешь выбор.

36
00:02:52,451 --> 00:02:57,417
В Clojure есть множество вариантов выбора. В частности,
есть сложный выбор из того, что нужно убрать.

37
00:02:57,441 --> 00:03:00,985
И часть этого выступления будет
затрагивать те вещи, которые были убраны.

38
00:03:01,009 --> 00:03:06,519
Другая сторона самодостаточности в том, «Как стать самодостаточным?» Звучит будто я самодостаточен.

39
00:03:10,219 --> 00:03:13,791
Конечно, я самодостаточен, и это приходит с опытом.

40
00:03:14,553 --> 00:03:22,491
Когда я начал создавать Clojure в 2005 году,
я программировал уже 18 лет.

41
00:03:22,515 --> 00:03:26,633
Так что я уже таким был. Я был сыт по горло.
Я устал от этого.

42
00:03:27,633 --> 00:03:31,127
Но я сделал несколько действительно
интересных вещей с языками,

43
00:03:31,151 --> 00:03:34,728
которые использовали профессиональные
программисты в то время.

44
00:03:34,752 --> 00:03:41,376
В основном я работал над системами расписания на C++.
Системы расписания для дикторов.

45
00:03:41,400 --> 00:03:45,435
Радиостанции используют системы расписания, чтобы определить, какую музыку они играют.

46
00:03:45,459 --> 00:03:48,202
И они довольно сложно устроены.

47
00:03:48,226 --> 00:03:52,189
Вы думаете о том, что «в течение дня не хотите
повторять одну и ту же песню».

48
00:03:52,213 --> 00:03:58,959
На самом деле вы должны думать о людях,
которые слушают радио один час утром и один час днем.

49
00:03:58,983 --> 00:04:05,482
И вы создаете своего рода альтернативное
временное пространство для каждого часа в пути.

50
00:04:05,506 --> 00:04:06,569
Вроде того.

51
00:04:06,651 --> 00:04:08,287
Итак, существует многомерное планирование,

52
00:04:08,391 --> 00:04:16,000
и мы использовали эволюционную программу
оптимизации для оптимизации расписания.

53
00:04:16,024 --> 00:04:19,440
Автоматизация трансляций — это воспроизведение звука.

54
00:04:19,464 --> 00:04:21,064
И в то время, когда мы этим занимались,

55
00:04:21,088 --> 00:04:24,897
воспроизведение аудио на компьютерах
было сложной задачей.

56
00:04:24,921 --> 00:04:30,084
Для работы DSP (процессор цифровой обработки
аудиосигнала) требовались выделенные карты.

57
00:04:30,108 --> 00:04:33,359
Я работал над аудио фингерпринтингом.

58
00:04:33,383 --> 00:04:41,431
Мы сделали системы, которые сидели в шкафах,
слушали радио и записывали то, что они слышали.

59
00:04:42,697 --> 00:04:46,769
И они одновременно использовались для
отслеживания плейлиста радиостанции,

60
00:04:46,793 --> 00:04:50,056
а затем, в конечном счете, для отслеживания
рекламы, на что и были выделены деньги.

61
00:04:50,080 --> 00:04:55,448
Они включали в себя выяснение того,
как эффективно распознавать и очищать звук,

62
00:04:55,448 --> 00:04:58,033
что-то вроде сравнения нового с прошлым.

63
00:04:59,514 --> 00:05:01,655
Я работал над системами управления доходностью.

64
00:05:02,840 --> 00:05:05,513
Все ли знают, что такое «управление доходностью»?
Возможно нет.

65
00:05:05,537 --> 00:05:11,166
Итак, что общего у отелей,
авиакомпаний и радиостанций?

66
00:05:13,225 --> 00:05:16,048
Их запасы со временем исчезают.

67
00:05:17,152 --> 00:05:21,282
«О, у меня есть свободная комната.
В моем расписании есть место.

68
00:05:21,306 --> 00:05:23,087
У меня есть место в этом самолете».

69
00:05:23,111 --> 00:05:26,738
А потом проходит время, их никто
не купил, а теперь — их нет.

70
00:05:27,952 --> 00:05:33,594
Таким образом, управление доходностью — это наука и практика попыток выяснить,

71
00:05:33,618 --> 00:05:38,043
как оптимизировать стоимость
ваших запасов, когда они исчезают.

72
00:05:38,067 --> 00:05:43,825
И о том, чтобы посмотреть на прошлое
и на предыдущие продажи, и это не так просто.

73
00:05:43,849 --> 00:05:48,174
Например, цель не в том, чтобы
продать все ваши запасы.

74
00:05:48,198 --> 00:05:52,709
Цель в том, чтобы максимизировать сумму дохода,
которую вы получаете от них,

75
00:05:52,709 --> 00:05:55,332
что означает в большинстве случаев
не продавать все запасы.

76
00:05:56,852 --> 00:05:59,789
Софт не был написан на C++.

77
00:05:59,813 --> 00:06:02,117
Это было примерно в то время,
когда я открыл для себя Common Lisp,

78
00:06:02,141 --> 00:06:05,597
то есть примерно через 8 лет
из этих 15 лет.

79
00:06:05,621 --> 00:06:10,983
И заказчик ни за что не стал бы
использовать Common Lisp,

80
00:06:10,983 --> 00:06:16,093
поэтому я написал программу на Common Lisp, которая
снова записывала все алгоритмы управления доходностью

81
00:06:16,117 --> 00:06:23,591
в виде хранимых процедур SQL и предоставляла
ему базу данных, которая являлась программой.

82
00:06:24,989 --> 00:06:29,685
В конце концов я вернулся к планированию
и снова написал новый вариант системы планирования

83
00:06:29,709 --> 00:06:33,433
на Common Lisp, которую они снова
не хотели запускать в продакшен.

84
00:06:34,850 --> 00:06:36,919
Затем я переписал её на C++.

85
00:06:36,943 --> 00:06:45,734
К этому моменту я был экспертом в C++
и очень любил C++, особой любовью

86
00:06:45,758 --> 00:06:49,157
не предполагающей никакого удовлетворения.

87
00:06:49,181 --> 00:06:55,766
Но, как мы увидим позже,
мне нравятся головоломки C++.

88
00:06:55,790 --> 00:06:58,007
Мне нужно было переписать её на C++,

89
00:06:58,031 --> 00:07:02,398
и на переписывание потребовалось в четыре раза
больше времени, чем на первоначальную версию.

90
00:07:02,422 --> 00:07:06,299
Она стала в пять раз больше по объему кода
и не была быстрее.

91
00:07:06,323 --> 00:07:08,869
И тогда я понял, что делаю что-то неправильно.

92
00:07:10,047 --> 00:07:14,364
Я продолжал помогать своему другу
Эрику написать новую версию

93
00:07:14,364 --> 00:07:17,219
Национальной системы экзитполов
для правительства США,

94
00:07:17,219 --> 00:07:19,924
которая также включает систему
прогнозирования результатов выборов.

95
00:07:19,924 --> 00:07:25,833
Мы сделали это в своего рода
добровольном функциональном стиле C#.

96
00:07:27,485 --> 00:07:29,220
А затем, примерно в 2005 году,

97
00:07:29,244 --> 00:07:33,804
я начал одновременно заниматься Clojure
и этим проектом машинного прослушивания.

98
00:07:33,828 --> 00:07:37,490
И я взял двухлетний творческий отпуск,
чтобы поработать над этими вещами,

99
00:07:37,514 --> 00:07:41,092
не зная, какая из них куда меня заведет.

100
00:07:41,116 --> 00:07:44,074
И позволяя себе делать то,
что я считаю правильным.

101
00:07:44,098 --> 00:07:48,241
Так что у меня не было коммерческих целей,
не было критериев приемки.

102
00:07:48,265 --> 00:07:52,473
Два года пытался себя ублажить.
Я просто купил себе отдых.

103
00:07:52,497 --> 00:07:58,984
Тогда же я ??понял, что успею
закончить только один проект.

104
00:07:59,008 --> 00:08:03,547
И я знал, как закончить Clojure, а машинное
прослушивание — это тема для исследования.

105
00:08:03,571 --> 00:08:05,957
Я не знал через сколько закончу её — через два года или через пять.

106
00:08:07,343 --> 00:08:11,157
Итак, Clojure написан на Java, и в конечном
итоге библиотека написана на Clojure.

107
00:08:11,181 --> 00:08:16,687
И работа над машинным прослушиванием включала
создание искусственной улитки внутреннего уха,

108
00:08:16,711 --> 00:08:21,850
и я сделал это, используя Common Lisp,
математику и C++.

109
00:08:21,874 --> 00:08:26,312
И в последние годы, отряхнув пыль,
я смог сделать это на Clojure,

110
00:08:26,336 --> 00:08:28,157
и это в некотором роде самая захватывающая вещь.

111
00:08:28,181 --> 00:08:34,195
Раньше мне нужны были три языка, а теперь нужен только Clojure.

112
00:08:35,577 --> 00:08:38,030
А потом я сделал Datomic (база данных), который тоже был Clojure.

113
00:08:41,156 --> 00:08:43,924
Почти во всех этих проектах использовалась
база данных.

114
00:08:43,948 --> 00:08:48,606
Все типы баз данных, начиная с баз данных
ISAM (индексно-последовательный метод доступа),

115
00:08:48,630 --> 00:08:54,490
много SQL, много попыток, но не много интеграций
RDF (среда описания ресурса).

116
00:08:54,514 --> 00:09:00,346
Базы данных являются неотъемлемой частью
решения подобных проблем. Это то, что мы делаем.

117
00:09:00,370 --> 00:09:07,004
Сколько людей используют базу данных в
повседневной работе? Сколько людей нет? OK.

118
00:09:09,075 --> 00:09:11,426
Итак, последнее [LWW] не является
аббревиатурой для баз данных.

119
00:09:11,450 --> 00:09:14,692
Это напоминание мне рассказать этот анекдот.

120
00:09:14,716 --> 00:09:16,716
Я ходил на Light-Weight Languages воркшоп.

121
00:09:16,740 --> 00:09:21,674
Это был однодневный воркшоп, проводившийся в
Массачусетском технологическом институте,

122
00:09:21,698 --> 00:09:25,255
на котором люди, работающие над
небольшими языками, проприетарными

123
00:09:25,279 --> 00:09:27,879
или просто DSL-языками
(предметно-ориентированный язык),

124
00:09:27,879 --> 00:09:29,218
DARPA или чем-то подобным

125
00:09:29,242 --> 00:09:33,079
говорили о своих маленьких языках
и о том, что они делают с небольшими языками.

126
00:09:33,079 --> 00:09:34,653
Это было очень круто и очень увлекательно.

127
00:09:34,677 --> 00:09:39,205
В одной комнате собралась куча
языковых гиков, а потом была пицца.

128
00:09:39,229 --> 00:09:42,316
Итак, я помню, я просто приехал один
или со своим другом.

129
00:09:42,340 --> 00:09:46,598
Я не был частью комьюнити, которое
этим занималось. Меня просто впустили.

130
00:09:47,076 --> 00:09:48,837
Но в конце у них была пицца.

131
00:09:48,861 --> 00:09:52,402
Итак, я сел с пиццей и двумя людьми, которых
я не знал, и я до сих пор не знаю их имен.

132
00:09:52,426 --> 00:09:55,606
И хорошо, что не знаю, потому что
сейчас я собираюсь унизить их.

133
00:09:55,630 --> 00:10:01,639
Они оба были исследователями
в области компьютерных языков.

134
00:10:01,663 --> 00:10:07,378
Говорили пренебрежительно о своем приятеле,

135
00:10:07,378 --> 00:10:12,121
который каким-то образом занялся
базами данных и сбился с истинного пути.

136
00:10:12,145 --> 00:10:16,173
И один из них насмешливо подошел
к другому и сказал:

137
00:10:16,197 --> 00:10:19,188
«Ой, Дэвид, когда ты в последний
раз пользовался базой данных?».

138
00:10:19,188 --> 00:10:21,982
И тот ответил: «Я не знаю, использовал ли я
когда-либо базы данных».

139
00:10:22,006 --> 00:10:30,681
И я почти подавился пиццей, потому что гипотетически
они разрабатывают языки программирования.

140
00:10:30,705 --> 00:10:33,852
И ещё они программируют, но никогда
не используют базы данных

141
00:10:33,876 --> 00:10:36,431
Я не знал, как такое может быть.

142
00:10:36,455 --> 00:10:38,979
Но частично это вдохновило сделать Clojure,

143
00:10:39,003 --> 00:10:42,971
потому что если люди, не занимающиеся базами
данных, могут писать языки программирования,

144
00:10:42,995 --> 00:10:44,853
то это может делать кто угодно.

145
00:10:47,891 --> 00:10:50,464
Итак, есть разные виды программ.

146
00:10:50,488 --> 00:10:53,948
И одна из вещей, которые я попытался показать
на этом слайде это рассказать о том,

147
00:10:53,972 --> 00:10:56,595
над какими программами я работал.

148
00:10:56,619 --> 00:11:00,113
И слово, которое я придумал, было
«размещаемые» программы.

149
00:11:01,221 --> 00:11:05,673
Другими словами, стоит различать такие
программы, которые размещены в мире от тех,

150
00:11:05,697 --> 00:11:07,622
которые как бы связаны с миром.

151
00:11:07,646 --> 00:11:09,973
У них есть множество характеристик.

152
00:11:09,997 --> 00:11:13,961
Одна из них: они выполняются в течение
длительного периода времени.

153
00:11:13,985 --> 00:11:16,893
Не просто вычисляют результат
и выплевывают наружу.

154
00:11:16,917 --> 00:11:19,643
Они не похожи на лямбда-функцию в AWS.

155
00:11:19,667 --> 00:11:23,880
Эти программы работают на постоянной основе
и как бы связаны с миром.

156
00:11:23,904 --> 00:11:28,058
И большинство из этих систем
работают непрерывно, 24/7.

157
00:11:28,082 --> 00:11:32,619
Меня очень пугает, что сейчас эти
системы, которым 30 лет,

158
00:11:32,643 --> 00:11:38,434
почти наверняка все еще где-то работают
круглосуточно и без выходных, если их не заменили.

159
00:11:38,458 --> 00:11:45,320
Итак, первое понятие длительных периодов времени
означает непрерывность, а не просто разовый всплеск.

160
00:11:45,344 --> 00:11:50,290
Они почти всегда имеют дело с информацией.
О чем я говорил?

161
00:11:50,314 --> 00:11:53,016
Планирование. При составлении расписания вы
смотрите на то, что вы сделали в прошлом.

162
00:11:53,016 --> 00:11:54,793
Вы смотрите на данные своего исследования.

163
00:11:54,817 --> 00:11:59,206
Что ваша аудитория говорит о том, что ей нравится,
или чем она интересуется, или что не нравится?

164
00:11:59,230 --> 00:12:03,987
И вы объединяете эти знания,
чтобы составить расписание.

165
00:12:04,011 --> 00:12:05,979
Управление доходностью рассматривает
прошлые продажи

166
00:12:06,003 --> 00:12:09,396
и продажи, относящиеся к конкретным периодам времени, и факты о них,

167
00:12:09,420 --> 00:12:13,354
а также предоставляет информацию о ценах.

168
00:12:13,378 --> 00:12:17,119
Избирательная система учитывает
предыдущие результаты голосования.

169
00:12:17,143 --> 00:12:21,329
Как люди голосовали раньше? Это важный показатель
того, как они будут голосовать снова.

170
00:12:21,353 --> 00:12:24,747
Конечно, стоящие за этим алгоритмы
намного сложнее.

171
00:12:24,771 --> 00:12:29,734
Но упрощенно можно сказать, что все эти
системы потребляли информацию.

172
00:12:29,758 --> 00:12:33,272
И для них это было жизненно необходимо.
И некоторые из них производили информацию.

173
00:12:33,296 --> 00:12:35,309
Они отслеживали записи того, что делали.

174
00:12:35,309 --> 00:12:38,579
И это следующий момент, заключающийся в том,
что у большинства из этих систем

175
00:12:38,603 --> 00:12:40,729
есть что-то вроде долговременной памяти.

176
00:12:40,753 --> 00:12:45,016
Эта база данных — не то, что было
заранее подключено к системе.

177
00:12:45,542 --> 00:12:48,764
Она добавляется по мере работы системы.

178
00:12:48,788 --> 00:12:54,833
Итак, эти системы помнят, что они сделали.

179
00:12:54,857 --> 00:12:59,947
Причем довольно часто делают это как для собственного
потребления, так и для потребления другими программами.

180
00:12:59,971 --> 00:13:03,594
И они имеют дело с неравномерностями реального мира.

181
00:13:03,618 --> 00:13:09,018
Это еще одна вещь, которая, на мой взгляд, очень
важна в этом ситуативном мире программирования.

182
00:13:09,042 --> 00:13:14,016
Реальный мир никогда не бывает
таким элегантным, как вы думаете.

183
00:13:14,040 --> 00:13:16,735
И я говорил об этой проблеме планирования:

184
00:13:16,759 --> 00:13:23,528
есть линейное время, кто-то слушает весь день, а есть те,
кто слушает только во время вождения утром и вечером.

185
00:13:23,552 --> 00:13:27,695
На протяжении восьми часов есть
одна группа людей, а в следующем часу

186
00:13:27,719 --> 00:13:31,163
— другая группа людей и еще одна группа.
Вы должны думать о всех этих группах.

187
00:13:31,187 --> 00:13:35,074
Вы придумываете это элегантное понятие
многомерного времени и думаете:

188
00:13:35,098 --> 00:13:39,682
«О, я в полном порядке… кроме вторника».
Почему?

189
00:13:41,936 --> 00:13:48,035
Что ж, в США на радио определенных жанров есть
такое понятие, как «две подряд по вторникам».

190
00:13:48,059 --> 00:13:51,067
Итак, вы создали эту систему расписания,

191
00:13:51,067 --> 00:13:55,341
и ее основная цель — никогда не проигрывать
одну и ту же песню дважды подряд

192
00:13:55,365 --> 00:13:58,109
или даже через небольшой промежуток
времени от последнего раза.

193
00:13:58,133 --> 00:14:01,835
И даже не ставить одного и того же исполнителя
подряд, иначе кто-то скажет:

194
00:14:01,835 --> 00:14:04,955
«Все, что вы делаете, это играете Элтона Джона.
Я ненавижу эту станцию».

195
00:14:04,979 --> 00:14:07,980
Но во вторник всё иначе.

196
00:14:08,004 --> 00:14:11,772
«Две по вторникам» означает, что
в каждом слоте, в котором мы играем песню,

197
00:14:11,772 --> 00:14:13,953
мы собираемся сыграть две песни
этого исполнителя,

198
00:14:13,977 --> 00:14:19,246
нарушая все драгоценные элегантные правила,
которые вы ввели в систему.

199
00:14:19,270 --> 00:14:25,720
И у меня никогда не было реальной системы,
в которой бы не было таких нарушений.

200
00:14:25,744 --> 00:14:27,684
И где они были не важны.

201
00:14:28,981 --> 00:14:31,180
Другие аспекты размещаемых программ.

202
00:14:31,204 --> 00:14:35,272
Они редко представляют собой своего рода
маленькую вселенную, где они могут решать,

203
00:14:35,296 --> 00:14:40,244
как обстоят дела, и им не нужно взаимодействовать
с кем-либо еще или соглашаться с кем-либо еще.

204
00:14:40,268 --> 00:14:43,211
Почти все эти системы взаимодействовали
с другими системами.

205
00:14:43,235 --> 00:14:46,405
Практически все эти системы
взаимодействовали с людьми.

206
00:14:46,429 --> 00:14:50,385
Кто-то сидел и говорил: «начни играть эту
песню прямо сейчас» или «пропусти эту песню»,

207
00:14:50,409 --> 00:14:54,165
и мы такие: «я запланировал эту песню,
и я сбалансировал все вокруг,

208
00:14:54,189 --> 00:14:57,030
и теперь твой ди-джей просто сказал:
«не делай так».

209
00:14:57,054 --> 00:15:02,754
Система прогнозирования выборов имеет множество
экранов, на которых пользователи могут видеть данные,

210
00:15:02,778 --> 00:15:06,970
составлять перекрестные таблицы и принимать
решения, используя все, что вы видите по телевизору,

211
00:15:06,994 --> 00:15:09,724
чтобы люди могли объяснять прогнозы другим людям.

212
00:15:09,748 --> 00:15:13,312
Итак, люди и общение с людьми — важная часть этих программ.

213
00:15:13,336 --> 00:15:18,457
Ими пользуются в течение длительного времени.
Как я уже сказал, это не одноразовые программы.

214
00:15:19,460 --> 00:15:25,887
Не думаю, что большая часть написанного мной
софта перестала кем-то использоваться.

215
00:15:25,911 --> 00:15:28,082
Люди до сих пор им пользуются.

216
00:15:28,106 --> 00:15:31,559
И они также ситуативны в мире, который меняется.

217
00:15:31,583 --> 00:15:36,038
Итак, опять же, ваши наилучшие планы существуют
в тот день, когда вы впервые их напишете,

218
00:15:36,062 --> 00:15:37,857
но затем правила меняются.

219
00:15:37,881 --> 00:15:39,637
Может появится, «три по четвергам».

220
00:15:39,661 --> 00:15:45,792
Я не знаю, но когда это произойдет,
поменяйте все, чтобы с этим справиться.

221
00:15:45,816 --> 00:15:51,057
Другой аспект ситуативности, о котором
я много думал в последнее время,

222
00:15:51,081 --> 00:15:55,473
это ситаутивность в
программной среде и сообществе.

223
00:15:55,473 --> 00:16:02,726
Ваша программа редко пишется с нуля, со всем кодом,
который вы написали только для целей программы.

224
00:16:02,750 --> 00:16:05,127
Неизменно вы собираетесь использовать
некоторые библиотеки.

225
00:16:05,151 --> 00:16:10,853
И когда вы это делаете, вы попадаете в экосистему
этой библиотеки. А это ещё одна история.

226
00:16:11,970 --> 00:16:16,659
Итак, когда я говорю о ситаутивных
программах, и вы смотрите на программы,

227
00:16:16,683 --> 00:16:21,206
которые я писал за свою карьеру, одна из них
действительно выделяется, верно? Какая?

228
00:16:21,230 --> 00:16:22,898
Clojure

229
00:16:22,922 --> 00:16:27,889
Компиляторы, они другие.
У них нет и части этих проблем.

230
00:16:27,913 --> 00:16:31,691
Они берут какие-то данные прямо с диска.
Они ведь определяют весь мир, верно?

231
00:16:31,715 --> 00:16:33,739
Когда вы пишете язык, что вы делаете?

232
00:16:33,763 --> 00:16:38,973
Первое, что вы делаете, когда пишете язык,
вы избавляетесь от любых «два по вторникам».

233
00:16:38,997 --> 00:16:44,415
Так ведь? Вы можете просто запретить это.
Вы стараетесь делать самые обычные дела.

234
00:16:44,439 --> 00:16:46,912
И тогда ваше программирование просто…

235
00:16:46,912 --> 00:16:49,686
ну, теперь я должен обеспечить соблюдение
правил, которые я для себя придумал.

236
00:16:49,710 --> 00:16:53,148
Что может быть проще, чем это?

237
00:16:53,172 --> 00:16:56,492
И так действительно намного проще.

238
00:16:57,605 --> 00:17:01,192
Обычно они не используют базу данных.
Хотя думаю, наверное, следует.

239
00:17:01,216 --> 00:17:04,215
Они редко общаются по сети и так далее.

240
00:17:04,239 --> 00:17:08,297
Так что компиляторы, средства доказательства
теорем и тому подобное не похожи на эти программы.

241
00:17:09,419 --> 00:17:11,115
Итак, название этого выступления — «Эффективные программы».

242
00:17:11,139 --> 00:17:12,630
А что значит «эффективный»?

243
00:17:13,419 --> 00:17:15,425
Оно означает «получение желаемого результата».

244
00:17:15,449 --> 00:17:20,164
И я очень хочу, чтобы это слово стало важным,
потому что я очень устал от слова «корректность»,

245
00:17:20,188 --> 00:17:24,455
где «корректный» означает, я не знаю,
«сделать type checker счастливым».

246
00:17:24,479 --> 00:17:32,002
Ни один из моих заказчиков этих программ, которыми
я профессионально занимался, не заботился об этом.

247
00:17:32,026 --> 00:17:35,808
Их заботит, что программа работает,
по их определению «работает».

248
00:17:37,766 --> 00:17:44,984
С другой стороны, я не хочу, чтобы это воспринималось
как «это способ хака» или «делай что-нибудь подобное».

249
00:17:45,008 --> 00:17:48,305
Итак, мы должны поговорить о том,
что означает «работает».

250
00:17:48,329 --> 00:17:51,149
Что на самом деле значит
выполнять работу эффективно.

251
00:17:51,173 --> 00:17:56,439
И именно здесь я хочу восстановить
понятие «программирование».

252
00:17:56,463 --> 00:17:59,518
Или, по крайней мере, убедиться,
что у нас есть широкое определение,

253
00:17:59,542 --> 00:18:03,410
включающее такие языки, как Clojure,
и подходы, которые он использует.

254
00:18:03,434 --> 00:18:05,478
Потому что я думаю, что эти
проблемы имеют значение.

255
00:18:05,502 --> 00:18:07,033
Так что же такое программирование?

256
00:18:07,057 --> 00:18:11,759
Я собираюсь сказать, что для меня «программирование
— это сделать компьютеры эффективными в мире».

257
00:18:11,783 --> 00:18:15,567
И я имею в виду «эффективный» так же,
как мы говорим об эффективных людях в мире.

258
00:18:15,591 --> 00:18:19,782
Либо сами программы эффективны,
либо они помогают людям быть эффективными.

259
00:18:19,806 --> 00:18:26,874
Насколько мы эффективны? Что ж, иногда мы
эффективны, потому что очень хорошо вычисляем.

260
00:18:26,898 --> 00:18:32,834
Например, когда мы пытаемся вычислить
траектории ракет или что-то в этом роде.

261
00:18:32,858 --> 00:18:38,164
Но в основном — нет. Почти во всех
областях человеческой деятельности.

262
00:18:38,188 --> 00:18:41,861
Мы эффективны, потому что
извлекли уроки из своего опыта

263
00:18:41,885 --> 00:18:47,713
и можем превратить этот опыт
в предсказательную силу.

264
00:18:47,737 --> 00:18:51,686
Будь то знание того, что нельзя ступать
в гигантскую нору или падать с обрыва,

265
00:18:51,710 --> 00:18:57,400
или идти к рычащему льву,
или как продавать товары,

266
00:18:57,424 --> 00:19:01,934
или как правильно проводить хирургические операции,
или правильно оценивать проблемы.

267
00:19:03,558 --> 00:19:08,135
Люди эффективны, потому что они учатся,
учатся на опыте и используют его.

268
00:19:08,159 --> 00:19:14,106
Итак, я собираюсь сказать, что «эффективность
в основном не в умении вычислять,

269
00:19:14,130 --> 00:19:18,268
а в создании предсказательной
силы на основе информации».

270
00:19:18,292 --> 00:19:22,641
И вы слышали, как я говорил об информации.
Она про факты. Про то, что произошло.

271
00:19:22,665 --> 00:19:29,144
Опыт, особенно когда мы начинаем внедрять его
в мир программирования, опыт равен информации,

272
00:19:29,168 --> 00:19:31,342
он равен фактам о том, что
действительно произошло.

273
00:19:31,366 --> 00:19:37,834
Это основа успеха.
В нашем мире он о людях.

274
00:19:37,858 --> 00:19:41,097
Должны быть программы, которые либо
поддерживают людей, либо заменяют людей,

275
00:19:42,206 --> 00:19:44,197
чтобы люди могли делать
более интересные вещи.

276
00:19:44,221 --> 00:19:50,902
Я также скажу: «чем не является программирование?»
Дело не в нем самом.

277
00:19:50,926 --> 00:19:55,423
Программирование — это не доказательство
теорий о соответствии типов

278
00:19:55,447 --> 00:19:59,322
вашим первоначальным предположениям.

279
00:19:59,346 --> 00:20:03,166
Оно не про это.
Это само по себе интересное начинание.

280
00:20:03,190 --> 00:20:08,165
Но я говорил не об этом.
Я не этим занимался в своей карьере.

281
00:20:08,189 --> 00:20:11,138
Для меня программирование не в этом,
и я не из-за этого люблю программирование.

282
00:20:11,162 --> 00:20:14,429
Мне нравится совершенствовать что-то в этом мире.

283
00:20:14,453 --> 00:20:18,026
Бертран Рассел сделал по этому поводу
хороший язвительный комментарий.

284
00:20:18,050 --> 00:20:19,707
На самом деле он не язвит.

285
00:20:19,731 --> 00:20:25,075
Он хочет возвысить математику и сказать:
«Очень важно, чтобы математика была вещью в себе».

286
00:20:25,099 --> 00:20:30,875
По словам Бертрана Рассела, если вы начинаете
их перекрещивать, стоять на сцене и говорить:

287
00:20:30,899 --> 00:20:36,436
«Математика безопасна, ведь безопасность типов
равняется безопасности сердечно-легочного аппарата»

288
00:20:36,460 --> 00:20:38,780
вы неправильно понимаете математику.

289
00:20:41,194 --> 00:20:43,088
И дело не только в алгоритмах и вычислениях.

290
00:20:43,112 --> 00:20:46,350
Они важны, но они являются лишь
частью того, что мы делаем.

291
00:20:47,784 --> 00:20:50,166
Так что не поймите меня неправильно.
Мне нравится логика.

292
00:20:50,190 --> 00:20:53,923
Я писал системы планирования.
Я писал алгоритмы управления доходностью.

293
00:20:53,947 --> 00:20:56,693
Я написал движок Datalog.
Мне нравится логика.

294
00:20:56,717 --> 00:21:00,170
Мне нравится писать эту часть системы.
Обычно я работаю над этой частью системы.

295
00:21:00,194 --> 00:21:02,017
Это действительно круто.

296
00:21:02,041 --> 00:21:08,221
Но даже программе доказательства теорем или
компилятору рано или поздно нужно

297
00:21:08,245 --> 00:21:12,301
что-то прочитать с диска или
что-то выплюнуть назад или что-то напечатать.

298
00:21:12,325 --> 00:21:16,081
Так что есть некоторая прокладка
чего-то еще, кроме логики.

299
00:21:16,105 --> 00:21:20,826
В мире размещаемых программ и
тех видов программирования, которыми я занимался,

300
00:21:20,850 --> 00:21:27,588
и того, что делают программисты на Clojure,
это небольшая часть программы.

301
00:21:27,612 --> 00:21:32,196
В программах преобладает обработка информации.

302
00:21:32,220 --> 00:21:34,220
До тех пор, пока у вас не появится
пользовательский интерфейс,

303
00:21:34,244 --> 00:21:38,733
тогда вокруг этого будет гигантский круг,
а обработка информации будет выглядеть как точка.

304
00:21:42,047 --> 00:21:44,271
Но я не собираюсь это обсуждать.

305
00:21:44,295 --> 00:21:47,653
Собственно, потому что я
не занимаюсь этой частью.

306
00:21:48,902 --> 00:21:52,845
Но обработка информации на самом деле
доминирует над программами в попытках…

307
00:21:52,869 --> 00:21:55,390
… беспорядочность часто присутствует.

308
00:21:55,414 --> 00:21:59,013
Это та часть информации, которая
устраняет всю беспорядочность,

309
00:21:59,037 --> 00:22:01,763
так что у моего движка Datalog
может быть легкий день,

310
00:22:01,787 --> 00:22:04,466
потому что теперь все идеально,
потому что теперь все прекрасно,

311
00:22:04,490 --> 00:22:06,525
ведь кто-то исправил всё,
прежде чем оно попало ко мне.

312
00:22:06,549 --> 00:22:10,813
Не хочу игнорировать это.
Я считаю это сверхважным.

313
00:22:10,837 --> 00:22:15,878
Ваш лучший и самый крутой
поисковый алгоритм Google,

314
00:22:15,902 --> 00:22:18,971
если бы они не смогли заставить его появиться
на веб-странице, а сделать что-то разумное,

315
00:22:18,995 --> 00:22:23,358
когда вы что-то набираете и нажимаете Enter,
никто бы этого не заметил.

316
00:22:23,382 --> 00:22:29,490
Вот где достигается ценность алгоритмов.
Это очень важно.

317
00:22:29,514 --> 00:22:37,719
Но по моему опыту, вот таким соотношение должно быть,
чтобы решить проблему [вернулся на предыдущий слайд]

318
00:22:37,743 --> 00:22:42,666
но по-факту это соотношение бывает таким
[перешел вперед, где круг — большая часть всего]

319
00:22:42,690 --> 00:22:46,439
На самом деле, всё еще хуже.
Квадрат был бы скорее точкой.

320
00:22:46,463 --> 00:22:51,290
Информационная часть наших программ
намного больше, чем должна быть,

321
00:22:51,314 --> 00:22:53,783
потому что языки программирования,
которые у нас были тогда

322
00:22:54,254 --> 00:22:56,963
и все еще есть в большинстве своем,
ужасны в этом плане.

323
00:22:56,987 --> 00:23:01,155
И нам приходится писать целую тонну кода,
чтобы выполнить эту работу.

324
00:23:01,179 --> 00:23:05,223
Потому что это не то, чем разработчики
этих языков занимались.

325
00:23:05,247 --> 00:23:06,827
И, конечно, мы еще не закончили.

326
00:23:06,851 --> 00:23:10,144
Мы не пишем программы с нуля,
поэтому надо добавлять библиотеки.

327
00:23:11,097 --> 00:23:16,239
Когда мы это сделаем, мы можем вычеркнуть
пункт «мы должны все определить».

328
00:23:16,263 --> 00:23:19,102
Теперь у нас есть соотношения.

329
00:23:19,126 --> 00:23:22,796
И мы должны определить, как мы будем
взаимодействовать с библиотеками,

330
00:23:22,820 --> 00:23:25,113
и как они могут взаимодействовать с нами,
но в основном мы взаимодействуем с ними.

331
00:23:25,137 --> 00:23:26,264
Итак, теперь есть линии.

332
00:23:26,288 --> 00:23:29,235
Есть некоторый протокол того, как вы
взаимодействуете с этой библиотекой.

333
00:23:29,259 --> 00:23:30,957
И мы все еще не закончили.

334
00:23:30,981 --> 00:23:34,485
Поскольку мы сказали, что эти размещаемые
программы, они используют базы данных.

335
00:23:34,509 --> 00:23:41,504
Теперь, обработка информации, логика и библиотеки
могут иметь общий язык программирования — 336
00:23:41,528 --> 00:23:47,631
или, по крайней мере иметь одну JVM, что-то вроде
JVM, среды выполнения — теперь мы избавились от этого.

337
00:23:47,655 --> 00:23:50,165
Теперь у нас есть база данных,
которая явно рядом.

338
00:23:50,189 --> 00:23:56,248
Она написана на другом языке. Она не размещена в
памяти, поэтому нужно ее связать с программой.

339
00:23:56,272 --> 00:24:00,876
У нее свой взгляд на мир, и есть какой-то
протокол для общения с ней.

340
00:24:00,900 --> 00:24:05,072
И неизменно, каким бы ни был этот протокол,
мы хотим его исправить.

341
00:24:05,096 --> 00:24:13,199
А почему так? Ну, это то, о чем я собираюсь
поговорить позже, под названием «местничество».

342
00:24:13,223 --> 00:24:16,649
Мы приняли взгляд на мир, который нам дал
наш язык программирования,

343
00:24:16,673 --> 00:24:22,407
и он не соответствует тому,
как база данных думает о вещах.

344
00:24:22,431 --> 00:24:26,538
И вместо того, чтобы говорить:
«Интересно, ошибаемся ли мы со своей стороны?»

345
00:24:26,562 --> 00:24:29,387
мы такие:
«О нет, мы должны это исправить.

346
00:24:30,882 --> 00:24:35,179
Эта реляционная алгебра,
она не может быть хорошей идеей».

347
00:24:37,606 --> 00:24:42,158
Хорошо, но мы еще не закончили. Как я сказал эти
программы не существуют сами по себе.

348
00:24:42,182 --> 00:24:43,491
Они общаются с другими программами.

349
00:24:43,515 --> 00:24:46,965
Итак, теперь у нас есть
три или более таких вещи.

350
00:24:46,989 --> 00:24:50,406
И теперь они могут быть написаны
на разных языках программирования.

351
00:24:50,606 --> 00:24:54,668
У всех них есть свое представление о том,
как должна работать логика.

352
00:24:54,692 --> 00:24:58,023
У всех них есть свое представление о том, как они хотят
общаться с библиотеками или использовать библиотеки.

353
00:24:58,047 --> 00:25:01,448
И получаем больше связей и больше протоколов.

354
00:25:01,472 --> 00:25:05,453
Мы не получаем от поставщика базы данных
хотя бы какой-то протокол связи для начала,

355
00:25:05,477 --> 00:25:08,060
который мы исправим с помощью ORM.

356
00:25:08,084 --> 00:25:11,808
Мы должны создать свои собственные протоколы.
И мы это делаем.

357
00:25:11,808 --> 00:25:17,646
И что у нас получается? JSON, верно?
Это не хорошо.

358
00:25:19,064 --> 00:25:21,079
Ну хотя бы у нас что-то есть…

359
00:25:21,103 --> 00:25:28,297
Итак, когда я программирую, я программирую
именно это. Для меня это программа.

360
00:25:28,321 --> 00:25:33,419
Это решит проблему, и никакая часть
этого не решит проблему.

361
00:25:33,443 --> 00:25:38,480
Это первое, с чего вы начинаете решать проблему.
Но с проблемами не покончено…

362
00:25:38,504 --> 00:25:45,824
Потому что у нас не одноразовая,
не одномоментная, не одна отличная идея,

363
00:25:45,848 --> 00:25:49,793
типа нажал кнопку, доставил фичу, пошел дальше,
что-то вроде такого мира, нет ведь?

364
00:25:49,817 --> 00:25:56,648
Каждый аспект этого со временем видоизменяется.
Правила меняются.

365
00:25:56,672 --> 00:26:02,475
Требования меняются. Сети меняются.
Вычислительная мощность меняется.

366
00:26:02,499 --> 00:26:05,628
Библиотеки, которые вы используете, изменяются.

367
00:26:05,652 --> 00:26:08,284
К счастью, протоколы не меняются,
но иногда и они меняются.

368
00:26:08,308 --> 00:26:11,567
Так что со временем нам придется
и с этим столкнуться.

369
00:26:11,591 --> 00:26:16,198
И для меня эффективное программирование в том,
чтобы делать это хорошо, на протяжении времени.

370
00:26:16,957 --> 00:26:20,677
Поэтому я не пытаюсь сказать:

371
00:26:20,677 --> 00:26:24,212
«Есть правильный и неправильный путь,
Clojure — хорошо, а все остальное — плохо».

372
00:26:24,236 --> 00:26:28,550
Но это должно быть очевидным,
а может и нет, потому что я думаю,

373
00:26:28,574 --> 00:26:32,760
что все мы стремимся писать языки
программирования общего назначения.

374
00:26:32,784 --> 00:26:35,890
Вероятно, вы могли бы написать средство
доказательства теорем на Clojure.

375
00:26:35,914 --> 00:26:37,851
На самом деле, я уверен, что смогли бы.

376
00:26:38,952 --> 00:26:42,220
Но вы наверняка получили бы другой язык,
если бы вашей целью были

377
00:26:42,244 --> 00:26:44,435
компиляторы и средства доказательства теорем,

378
00:26:44,459 --> 00:26:48,504
или вашей целью были драйверы устройств
или коммутаторы телефонов.

379
00:26:48,528 --> 00:26:55,391
Целью Clojure являются ориентированные на информацию
программы. Для этого нет броской фразы.

380
00:26:55,415 --> 00:27:00,433
Но это то, что я делал.
Все мои друзья так делали.

381
00:27:00,457 --> 00:27:04,648
Сколько людей в этой комнате так делают?
Да.

382
00:27:04,672 --> 00:27:08,632
Итак, когда вы смотрите на языки программирования,
вам действительно стоит задуматься:

383
00:27:10,526 --> 00:27:12,991
для чего они нужны?

384
00:27:13,966 --> 00:27:19,417
Нет врожденной полезности.
Есть ограничения пригодности.

385
00:27:19,441 --> 00:27:23,466
Итак, прежде чем я начал создавать Clojure,
я нарисовал эту диаграмму

386
00:27:25,711 --> 00:27:31,213
На самом деле — нет.
Это было бы удивительным подвигом предвидения.

387
00:27:32,546 --> 00:27:36,867
Но пока я пытаюсь выделить,
о чем был Clojure — потому что я думаю,

388
00:27:36,891 --> 00:27:39,678
что нет причин писать новый
язык программирования, если вы не собираетесь

389
00:27:39,702 --> 00:27:41,334
пытаться решать некоторые проблемы.

390
00:27:41,358 --> 00:27:43,102
Вы должны посмотреть,
в чем суть проблемы.

391
00:27:43,102 --> 00:27:46,122
Я имею в виду, почему я был недоволен
как программист после 18 лет и сказать:

392
00:27:46,146 --> 00:27:52,443
«Если я не могу переключиться на что-то вроде
Common Lisp, я собираюсь сменить карьеру».

393
00:27:52,467 --> 00:27:54,243
Почему я это говорю?

394
00:27:54,267 --> 00:27:59,574
Я говорю так, потому что разочарован множеством
ограничений в тех вещах, которые я использовал.

395
00:27:59,598 --> 00:28:03,873
Вы можете называть их проблемами, а я буду
называть их проблемами программирования.

396
00:28:03,897 --> 00:28:12,340
Я распределил их здесь по степени серьезности.

397
00:28:12,364 --> 00:28:17,910
И серьезность проявляется по-разному.
Самое главное — цена.

398
00:28:17,934 --> 00:28:20,486
Какова цена ошибки?

399
00:28:22,021 --> 00:28:26,801
На самом верху у вас есть доменная сложность,
с которой вы ничего не можете поделать.

400
00:28:26,825 --> 00:28:31,217
Таков мир. Какой есть — такой есть.

401
00:28:31,241 --> 00:28:34,885
Но на следующем уровне
мы начинаем программировать.

402
00:28:34,909 --> 00:28:38,025
Мы смотрим на мир и говорим:
«У меня есть представление о том,

403
00:28:38,049 --> 00:28:42,176
как он устроен, и каким он должен быть,
и каким образом моя программа может быть

404
00:28:42,200 --> 00:28:43,808
эффективной для решения этой проблемы».

405
00:28:43,832 --> 00:28:48,773
И проблема в том, что если у вас нет хорошего
представления о том, как устроен мир,

406
00:28:48,797 --> 00:28:56,258
или вы не можете сопоставить его с решением,
все, что ниже по течению, потерпит неудачу.

407
00:28:56,282 --> 00:29:03,457
С этой проблемой недопонимания не выжить.
А цена устранения недопонимания невероятно высока.

408
00:29:04,613 --> 00:29:09,565
Итак перед вами полный список проблем по
уменьшению степени тяжести,

409
00:29:09,589 --> 00:29:14,483
прежде чем мы перейдем к этому списку проблем,
которые, я думаю, больше связаны с тем,

410
00:29:14,507 --> 00:29:17,172
с чем могут помочь языки программирования.

411
00:29:17,196 --> 00:29:22,416
И поскольку вы можете их сами прочитать,
они все появятся через секунду,

412
00:29:22,440 --> 00:29:27,637
когда я буду показывать каждую из них на слайдах,
поэтому я не собираюсь зачитывать их все прямо сейчас.

413
00:29:27,661 --> 00:29:33,622
Но, что важно, есть еще один прорыв, когда мы
переходим к тривиальности проблем в программировании.

414
00:29:33,646 --> 00:29:37,159
Типа опечаток и просто неконсистентность.

415
00:29:37,183 --> 00:29:41,335
Например, вы думали, что у вас будет
список строк, но поместили туда число.

416
00:29:41,359 --> 00:29:47,539
Такое бывает. Люди совершают такие ошибки.
Они довольно недорогие.

417
00:29:49,077 --> 00:29:52,945
Так, какие проблемы взял на себя Clojure?
Помеченные зеленым.

418
00:29:52,969 --> 00:29:55,907
И снова через мгновение я пройдусь
по всем зеленым, но я бы сказал,

419
00:29:55,931 --> 00:30:00,104
что среди тех, что посередине, я не думаю,

420
00:30:00,128 --> 00:30:06,055
что Clojure пытался сделать что-то отличное от
использования ресурсов, чем это сделала Java.

421
00:30:06,079 --> 00:30:08,656
Он как бы принял ту среду исполнения
и ее модель затрат.

422
00:30:10,567 --> 00:30:13,553
Я хотел, чтобы Clojure был
хорошим библиотечным языком,

423
00:30:13,577 --> 00:30:17,667
но я не думал о проблемах библиотечной
экосистемы как части Clojure.

424
00:30:17,691 --> 00:30:22,098
И мой прошлогодний доклад
о библиотеках подразумевает,

425
00:30:22,122 --> 00:30:25,873
что я все еще думаю, что это большая
проблема для программ.

426
00:30:25,897 --> 00:30:28,616
Это одна из тех, что ещё не решены, верно?

427
00:30:28,640 --> 00:30:32,213
Что нужно исправить после того,
как вы создали Clojure и Datomic?

428
00:30:34,922 --> 00:30:42,005
И библиотеки есть. Но непоследовательностей
и опечаток не так уж и много.

429
00:30:42,029 --> 00:30:44,089
Я имею в виду, что мы знаем,
что такое может произойти в Clojure.

430
00:30:44,113 --> 00:30:47,146
На самом деле здорово,
что он позволяет делать опечатки.

431
00:30:49,231 --> 00:30:53,526
Итак, в чем суть Clojure? Можем ли мы делать
программы из более простых вещей?

432
00:30:53,550 --> 00:30:59,953
Я имею в виду, что это проблема.
После 18 лет использования C++ и Java вы измотаны.

433
00:30:59,977 --> 00:31:04,332
Сколько людей занимаются
программированием 18 лет? OK.

434
00:31:04,356 --> 00:31:14,555
Сколько более 20 лет? Больше 25? Меньше 5?
Очень интересно.

435
00:31:15,591 --> 00:31:20,330
Можно сказать, что Clojure используется как язык
для начинающих, или может быть, что Clojure — 436
00:31:20,354 --> 00:31:26,165
это язык для расшатанных, усталых,
старых программистов.

437
00:31:31,164 --> 00:31:36,483
И знаете, что? Я бы не смутился, если бы это было так.
Меня это устраивает.

438
00:31:36,507 --> 00:31:41,569
Потому что я сделал его для себя, что,
на мой взгляд, правильно.

439
00:31:41,593 --> 00:31:47,672
Пытаться решить проблемы других людей и думать,
что вы понимаете, в чем они состоят, — это сложно.

440
00:31:47,696 --> 00:31:52,894
Поэтому, когда я открыл для себя Common Lisp,
использовав C++, я сказал,

441
00:31:52,918 --> 00:31:58,438
что «я почти уверен, что ответ на этот первый
вопрос — «да, безусловно».

442
00:31:59,838 --> 00:32:04,525
И можем ли мы сделать это при более низкой
когнитивной нагрузке? Я тоже думаю «да, безусловно».

443
00:32:04,549 --> 00:32:08,583
И тогда возникает вопрос: «Могу ли я создать Лисп,
который я смогу использовать вместо Java или C#?»

444
00:32:08,607 --> 00:32:12,089
Потому что вы только что услышали мою историю,
и я пару раз использовал Common Lisp,

445
00:32:12,113 --> 00:32:15,429
и каждый раз его убирали из продакшена.

446
00:32:15,453 --> 00:32:19,539
Или просто исключали из продакшена,
но толком это не удавалось.

447
00:32:19,563 --> 00:32:24,845
Итак, я знал, что мне нужно выбрать
среду выполнения, которую примут люди.

448
00:32:24,869 --> 00:32:26,529
Итак, есть эти мета-проблемы.

449
00:32:26,529 --> 00:32:28,714
Вы можете попробовать решить некоторые
проблемы с программированием,

450
00:32:28,738 --> 00:32:31,066
но всегда возникают проблемы
с принятием языка.

451
00:32:31,090 --> 00:32:35,597
Я не думал, что Clojure будет принят.
Правда, честно.

452
00:32:35,621 --> 00:32:40,393
Но я знал, что если бы я захотел, чтобы мой друг,
который думал, что я сумасшедший, когда создавал язык,

453
00:32:40,417 --> 00:32:45,756
он первый, кроме меня, попробовал его, я должен
был бы получить надежный ответ

454
00:32:45,780 --> 00:32:50,370
на проблемы приемлемости и проблемы
с производительностью.

455
00:32:50,394 --> 00:32:52,184
Потому что иначе он просто непрактичен.

456
00:32:52,208 --> 00:32:55,489
Он что-то вроде: «Это круто, Рич,
но у нас есть над чем поработать».

457
00:32:56,789 --> 00:33:00,852
Если мы не можем использовать его профессионально,
на самом деле это просто хобби.

458
00:33:00,876 --> 00:33:04,376
Так что у нас есть критерии приемки, я думаю,
это связано с производительностью,

459
00:33:04,400 --> 00:33:07,023
и для меня, я решил, что это также связано
с платформой для развертывания.

460
00:33:07,047 --> 00:33:10,811
Есть проблема производительности,
с которой вам придется столкнуться

461
00:33:10,835 --> 00:33:14,013
и она связана с эффективностью,
и я расскажу об этом позже.

462
00:33:14,037 --> 00:33:18,084
А также совместимость.
Опять же, это часть применимости.

463
00:33:18,108 --> 00:33:23,497
Но способность Clojure сказать «это просто
библиотека Java» была важной.

464
00:33:23,521 --> 00:33:32,690
Сколько людей тайком пронесли Clojure
в свою компанию? Хорошо. Это успех!

465
00:33:32,714 --> 00:33:39,400
А потом были и другие вещи, которые
я считал абсолютно не важными.

466
00:33:39,424 --> 00:33:41,437
И первая из них — круглые скобки.

467
00:33:41,461 --> 00:33:46,338
Сколько людей… в этом не стыдно признаться?
У каждого есть своя история.

468
00:33:46,338 --> 00:33:51,185
Сколько людей думали, что круглые скобки будут
проблемой, а теперь думают, что это было безумием?

469
00:33:51,209 --> 00:33:54,873
Это нормально, я думаю,
что через это проходят все.

470
00:33:54,897 --> 00:33:59,117
Все смотрят на Lisp и думают:
«Это круто, но я собираюсь исправить эту часть,

471
00:33:59,141 --> 00:34:00,443
прежде чем приступить к работе.

472
00:34:00,467 --> 00:34:05,449
Прежде чем я начну, прежде чем я вообще пойму
его преимущества, я собираюсь исправить это»,

473
00:34:06,039 --> 00:34:10,104
и это что-то говорит о программистах.
Я не знаю точно, что именно.

474
00:34:11,714 --> 00:34:15,909
Но я не считаю, что это проблема, и на самом деле,
когда мы дойдем до середины этого выступления,

475
00:34:15,933 --> 00:34:18,941
вы увидите, что я думаю,
что это противоположно проблеме.

476
00:34:18,965 --> 00:34:21,233
Это основное преимущество Clojure.

477
00:34:21,257 --> 00:34:28,352
И я думаю, что такие вещи, как «par-make-go-away»,
что бы это ни было, это ужасная идея.

478
00:34:28,376 --> 00:34:34,033
И новичкам это вредно, пытаться решить проблему,
которая является фичей.

479
00:34:35,335 --> 00:34:38,474
Еще одна вещь, которую я не считал проблемой, — это его динамичность.

480
00:34:38,498 --> 00:34:42,563
Я писал на C++.
У нас была фраза про C++,

481
00:34:42,587 --> 00:34:44,917
что «если он компилируется, он,
вероятно, будет работать».

482
00:34:44,941 --> 00:34:50,574
Также говорят о Haskell.
И тогда это было так же верно, как и сейчас.

483
00:34:52,846 --> 00:34:57,952
Но мы действительно в это верили!
Мы абсолютно в это верили.

484
00:34:57,976 --> 00:35:04,521
Но это не помогает. Это действительно
не помогает при больших проблемах.

485
00:35:04,545 --> 00:35:06,801
Самых сложных проблемах.

486
00:35:06,825 --> 00:35:11,218
Итак, проблема номер один в этом списке — это позиционно-ориентированное программирование.

487
00:35:11,242 --> 00:35:17,531
Безусловно, это проблема. Почти все программы,
которые я написал, были многопоточными.

488
00:35:19,552 --> 00:35:22,304
Это безумно трудно в C++.

489
00:35:22,328 --> 00:35:29,151
Просто невозможно сделать правильно, когда вы применяете
нормальный подход к изменчивости, изменяемые объекты.

490
00:35:29,175 --> 00:35:32,821
Итак, это проблема программирования номер один,
созданная самостоятельно.

491
00:35:32,845 --> 00:35:37,416
Мне казалось очевидным, что ответ
заключался в том, чтобы использовать

492
00:35:37,440 --> 00:35:42,570
функциональное программирование и
иммутабельные данные идиомой по умолчанию.

493
00:35:42,594 --> 00:35:47,981
Итак, передо мной стояла задача: существуют ли
структуры данных, которые будут достаточно

494
00:35:48,005 --> 00:35:50,878
быстрыми, чтобы сказать:
«Мы могли бы поменять это на это»?

495
00:35:50,902 --> 00:35:57,616
И моя цель заключалась в том, чтобы уложиться
в 2x для чтения и 4x для записи.

496
00:35:57,640 --> 00:36:01,805
И я много над этим поработал. Фактически, это
была основная исследовательская работа,

497
00:36:01,829 --> 00:36:04,723
кроме Clojure, посвященная этим
персистентным структурам данных.

498
00:36:04,747 --> 00:36:06,447
И в конце концов я обнаружил…

499
00:36:06,471 --> 00:36:10,342
Я посмотрел на труды Окасаки (Крис Окасаки)
и на полностью функциональный подход,

500
00:36:10,366 --> 00:36:12,609
и ничего из этого не подошло.

501
00:36:12,633 --> 00:36:16,718
А потом я обнаружил структуры Бэгвелла (Фил Бэгвелл),
которые не были персистентными,

502
00:36:16,742 --> 00:36:19,171
но я понял, что они могут быть такими.

503
00:36:19,195 --> 00:36:22,560
И у них просто совершенно
замечательные характеристики,

504
00:36:22,584 --> 00:36:26,674
сочетающие персистентность с тем,
как работает память.

505
00:36:27,779 --> 00:36:28,608
У них получилось.

506
00:36:28,780 --> 00:36:34,166
Они заложили основы, и я смог уговорить друга
попробовать мой язык программирования.

507
00:36:35,377 --> 00:36:39,220
И у нас есть большая библиотека
чистых функций для поддержки этого

508
00:36:39,244 --> 00:36:42,813
и иммутабельное локальное связывание.

509
00:36:42,837 --> 00:36:46,649
По сути, если вы попадаете в Clojure, ваше первое
препятствие — не круглые скобки, верно?

510
00:36:46,673 --> 00:36:51,061
А функциональная парадигма.
Больше ничего нет.

511
00:36:51,085 --> 00:36:57,593
Нет изменяемых переменных. Нет состояния.
Нет изменяемых коллекций и всего остального.

512
00:36:57,617 --> 00:37:00,770
Но есть большая поддержка.
Есть большая библиотека.

513
00:37:00,794 --> 00:37:05,302
Вам просто нужно выучить идиомы.
Так что я думаю, что это не представляет труда.

514
00:37:05,326 --> 00:37:10,347
Важнейшая особенность Clojure заключается в том,
что к тому времени, когда я работал над Clojure,

515
00:37:10,371 --> 00:37:14,825
люди, которые изобрели эти вещи,
заимствовали гораздо больше.

516
00:37:14,849 --> 00:37:19,831
Я думаю, что большинство приверженцев
функционального программирования считали,

517
00:37:19,855 --> 00:37:22,968
что функциональное программирование — это типизированное функциональное программирование.

518
00:37:22,968 --> 00:37:26,803
Статически типизированное функциональное
программирование — это функциональное программирование.

519
00:37:26,827 --> 00:37:32,160
А я так не думаю. Я думаю, что это точно
соответствует правилу 80/20.

520
00:37:32,184 --> 00:37:35,453
И я думаю, что раскол здесь
больше похож на 99/1.

521
00:37:35,477 --> 00:37:41,953
Все ценности находятся на этой стороне, и я думаю,
что пользователи Clojure это понимают.

522
00:37:41,977 --> 00:37:45,973
Они это чувствуют. Это то,
что позволяет вам спать по ночам.

523
00:37:47,647 --> 00:37:51,104
Хорошо, проблема номер два — и это самая тонкая проблема.

524
00:37:51,128 --> 00:37:55,410
Это то, что меня больше всего раздражает
в языках со статической типизацией,

525
00:37:55,434 --> 00:37:57,334
это то, что они плохо
справляются с информацией.

526
00:37:57,358 --> 00:37:59,152
Итак, давайте посмотрим,
что такое информация.

527
00:37:59,176 --> 00:38:01,288
По сути, информация разбросана.

528
00:38:01,312 --> 00:38:03,938
Это то, что вы знаете.
Это то, что происходит в мире.

529
00:38:03,962 --> 00:38:08,242
Заполняет ли мир формы
и заполняет их за вас?

530
00:38:08,266 --> 00:38:14,503
Все, что вы хотели бы знать?
Нет! Он так не делает.

531
00:38:14,527 --> 00:38:19,549
Это не так, и, наверное, правильнее сказать
«так никогда не будет».

532
00:38:19,573 --> 00:38:28,988
Другой вопрос: «Что вы можете знать?»
Что вам разрешено знать? На это нет хороших ответов.

533
00:38:29,012 --> 00:38:34,424
Все, что хотите, правда? Запрета нет.
Что еще там? Что нужно знать?

534
00:38:34,448 --> 00:38:36,558
Ну я имею в виду, который час, верно?

535
00:38:36,582 --> 00:38:40,270
Потому что с каждой секундой во вселенной
происходит больше вещей,

536
00:38:40,294 --> 00:38:43,141
происходит больше событий, больше фактов,
больше вещей происходит.

537
00:38:43,165 --> 00:38:47,365
Итак, информация увеличивается,
она просто накапливается.

538
00:38:48,405 --> 00:38:50,153
Что еще мы знаем об информации?

539
00:38:50,177 --> 00:38:57,235
На самом деле у нас нет хороших способов
справиться с ней, кроме как с помощью имен.

540
00:38:57,259 --> 00:39:01,957
Когда мы, люди, имеем дело с информацией,
имена очень важны.

541
00:39:01,981 --> 00:39:07,892
Если я просто скажу «47»,
то еще никакого общения нет.

542
00:39:07,916 --> 00:39:09,802
Мы должны это связать.

543
00:39:09,826 --> 00:39:15,089
А потом еще одна важная вещь, с которой
я так часто борюсь. У меня есть система.

544
00:39:15,113 --> 00:39:21,882
Я создал класс или тип с какими-то данными.
Здесь я знаю немного больше данных, чем там.

545
00:39:21,906 --> 00:39:24,596
Могу ли я сделать что-нибудь «другое»,
но подобное?

546
00:39:24,620 --> 00:39:28,494
Если у меня есть производный тип,
могу ли я сделать вот это «другое»?

547
00:39:28,518 --> 00:39:33,497
Что, если я сейчас в другом контексте и
знаю что-то об одной части, а что-то о другой.

548
00:39:33,521 --> 00:39:39,017
Какой тип имеет одна часть,
а какой — другая? А потом следует взрыв.

549
00:39:39,041 --> 00:39:45,287
Но, конечно, эти языки делают это неправильно.
У них нет композиционных информационных конструкций.

550
00:39:45,311 --> 00:39:50,870
Так в чем же проблема программирования,
совместимого с информацией?

551
00:39:50,894 --> 00:40:00,612
Дело в том, что мы поднимаем информационный
контейнер, чтобы стать семантическим проводником.

552
00:40:00,636 --> 00:40:05,950
Мы говорим: «Это человек, и у человека есть имя,
и у человека есть электронная почта,

553
00:40:05,974 --> 00:40:07,422
и у человека есть номер
социального страхования»,

554
00:40:07,446 --> 00:40:15,382
и для этих трех вещей нет семантики,
кроме контекста класса person или какого-то типа.

555
00:40:16,245 --> 00:40:22,543
И часто, в зависимости от языка
программирования, даже имен нет.

556
00:40:22,567 --> 00:40:24,916
Если у вас есть такие кортежи типов:

557
00:40:24,940 --> 00:40:32,899
«человек — это строка x, x — строка, x — int, x — строка,
x — строка, x — int, x — float, x — float»

558
00:40:32,899 --> 00:40:41,151
Вроде, полное бездушное пренебрежение
к людям, именам, человеческому мышлению. Безумие.

559
00:40:41,175 --> 00:40:46,119
Или у вашего языка программирования могут быть имена,
но они компилируются отдельно.

560
00:40:46,143 --> 00:40:49,227
Они не первого класса.
Вы не можете использовать их в качестве аргументов.

561
00:40:49,251 --> 00:40:52,080
Вы не можете использовать их в качестве
векторов поиска.

562
00:40:52,104 --> 00:40:54,820
Вы не можете использовать их как функции
по отношению к самим себе.

563
00:40:56,488 --> 00:41:00,350
В информационных языках программирования
нет композиционной алгебры.

564
00:41:00,374 --> 00:41:05,085
Итак, мы берем эти конструкции, которые,
я думаю, нужны для других целей.

565
00:41:05,109 --> 00:41:10,084
Мы должны использовать их, потому что это все,
что нам дали, и так будет идиоматично.

566
00:41:10,108 --> 00:41:14,050
Возьмите класс, возьмите тип и сделайте так.

567
00:41:14,074 --> 00:41:18,483
Но самое главное, что агрегирование определяет
семантику, что совершенно неверно.

568
00:41:18,507 --> 00:41:23,000
Если вы заполняете форму, никакая информация,
которую вы помещаете в эту форму,

569
00:41:23,024 --> 00:41:28,534
семантически не зависит от формы,
которую вы заполняете.

570
00:41:28,558 --> 00:41:34,324
Это сборное устройство. Это не семантическое
устройство, но таким оно становится.

571
00:41:34,348 --> 00:41:41,197
И что произойдет, если вы возьмете
эти гигантские наборы конкреций.

572
00:41:41,221 --> 00:41:45,638
Люди, которые пишут библиотеки Java,
посмотрите на Java Framework. Это круто.

573
00:41:45,662 --> 00:41:52,845
Он относительно небольшой, и все дело в механике.
Java хороша в механических вещах — ну, в механизмах.

574
00:41:52,869 --> 00:41:56,679
Но затем вы передаете этот же язык
бедным прикладным программистам,

575
00:41:56,703 --> 00:42:03,550
которые пытаются решить эту проблему с информацией
в размещаемой программе, и это все, что у них есть.

576
00:42:03,574 --> 00:42:07,178
И они достают класс, содержащий всё,
что только можно, каждую часть,

577
00:42:07,202 --> 00:42:09,317
каждый небольшой набор информации,
который у них есть.

578
00:42:09,341 --> 00:42:17,506
Сколько людей хоть раз видели Java-библиотеку
на полторы тысячи классов? Да все.

579
00:42:17,530 --> 00:42:23,215
И таков мой опыт. По моему опыту,
не имеет значения, какой язык вы используете.

580
00:42:23,239 --> 00:42:31,100
Если у вас есть эти типы и вы имеете дело с информацией,
у вас будет быстрое увеличение некомпонуемых типов,

581
00:42:31,124 --> 00:42:36,502
каждый из которых представляет собой небольшую обобщенность
вокруг крошечного фрагмента данных, которые не компонуются.

582
00:42:36,526 --> 00:42:42,325
И меня это действительно не устраивает.

583
00:42:42,349 --> 00:42:47,593
В литературе по программированию слово
«абстракция» используется двояко.

584
00:42:47,617 --> 00:42:51,773
Первое значение — «абстрагирование — это давать чему-либо имя».

585
00:42:51,797 --> 00:42:53,701
Я не согласен с этим.

586
00:42:53,725 --> 00:42:59,458
Абстрагирование действительно должно заключаться
в извлечении из набора образцов чего-то существенного.

587
00:43:00,446 --> 00:43:02,098
А не просто давать имя чему-либо.

588
00:43:02,122 --> 00:43:08,073
И я думаю, что на самом деле здесь происходит то,
что мы получаем не абстракции данных, а конкреции данных.

589
00:43:08,097 --> 00:43:16,286
Реляционная алгебра — это абстракция данных. Datalog — это абстракция данных. RDF — это абстракция данных.

590
00:43:16,310 --> 00:43:23,700
Ваш класс person, ваш класс product — это не абстракции данных. Это конкреции.

591
00:43:25,254 --> 00:43:28,575
Итак, мы знаем на практике, Clojure говорит:
«просто используйте мапы (maps)».

592
00:43:28,599 --> 00:43:32,747
На самом деле это означает: «Clojure не дает
вам ничего другого», верно?

593
00:43:32,771 --> 00:43:40,646
Больше нечего использовать. Классов нет.
Ни к чему не применить deftype. Типов нет.

594
00:43:40,670 --> 00:43:43,729
Нет алгебраических типов данных
или чего-то подобного.

595
00:43:43,753 --> 00:43:51,708
Были эти мапы и огромная библиотека функций для
их поддержки. Для этого была синтаксическая поддержка.

596
00:43:51,732 --> 00:43:55,360
Так что работа с этими ассоциативными
структурами данных была осязаемой,

597
00:43:55,384 --> 00:43:59,648
хорошо поддерживаемой, функциональной
и высокопроизводительной деятельностью.

598
00:44:00,812 --> 00:44:02,185
И они обобщенные.

599
00:44:02,209 --> 00:44:06,273
Что мы будем делать в Clojure, если у нас есть только
часть информации здесь и только часть информации там,

600
00:44:06,297 --> 00:44:08,331
и нам нужны обе эти части тут?

601
00:44:08,355 --> 00:44:11,631
Мы говорим «в чем проблема?»
Нет проблем.

602
00:44:11,655 --> 00:44:18,257
Я беру эту информацию, ту информацию, их объединяю,
передаю вместе. Если мне нужно подмножество, я беру его.

603
00:44:18,281 --> 00:44:23,725
Я вызываю «взять ключи» и получаю подмножество.
Я могу комбинировать все, что захочу.

604
00:44:23,749 --> 00:44:26,805
Есть алгебра, связанная с ассоциативными данными.

605
00:44:26,829 --> 00:44:34,813
Имена первого класса. Ключевые слова и символы — это
функции. Они являются функциями ассоциативных контейнеров.

606
00:44:34,813 --> 00:44:36,520
Они умеют искать самих себя.

607
00:44:36,544 --> 00:44:39,842
И они овеществлены, так что вы можете ощутимо
распределить их по своей программе и сказать:

608
00:44:39,866 --> 00:44:45,166
«выберите эти три вещи» без написания
программы, которая знает,

609
00:44:45,190 --> 00:44:50,203
как написать сопоставление с образцом (pattern matching)
на Java или Haskell, чтобы найти эти три вещи.

610
00:44:50,227 --> 00:44:55,450
Они не зависят от языка программы.
Это просто аргументы.

611
00:44:55,474 --> 00:44:59,348
Это просто фрагменты данных.
Но у них есть такая возможность.

612
00:44:59,372 --> 00:45:06,384
И еще одна вещь, которая, как мне кажется, является
потенциалом Clojure — она ??реализована в разной степени,

613
00:45:06,408 --> 00:45:14,310
но основа для этого есть — это то, что мы можем
связывать семантику с атрибутами, а не с агрегатами.

614
00:45:14,334 --> 00:45:19,264
Потому что у нас есть полностью
квалифицированные символы и ключевые слова.

615
00:45:19,288 --> 00:45:22,366
И, очевидно, spec (clojure.spec — набор функций и макросов)
как раз про это.

616
00:45:22,390 --> 00:45:26,735
Ладно, хрупкость и связность (coupling). Это еще
одна вещь, о которой я знаю на собственном опыте:

617
00:45:26,759 --> 00:45:30,632
системы со статическими типами дают
гораздо более сильно связанные системы.

618
00:45:30,656 --> 00:45:34,175
И когда вы сопровождаете код,
то большая часть времени,

619
00:45:34,175 --> 00:45:39,862
которое мы тратим,
определяется связностью в программе.

620
00:45:39,886 --> 00:45:44,639
Информация о текущем типе является
основным источником связности в программах.

621
00:45:44,663 --> 00:45:53,254
Сопоставление с образцом структурного представления
в сотне мест в вашей программе дает связность.

622
00:45:53,278 --> 00:45:58,261
Вроде, я застреваю, когда вижу это.

623
00:45:58,285 --> 00:46:03,104
Ваши чувства, после 20 лет программирования,
такие, что вы ненавидите связность.

624
00:46:03,128 --> 00:46:11,058
Хуже связности ничего нет и, когда чувствуешь его запах,
ты не хочешь быть частью этого. И это большая проблема.

625
00:46:11,082 --> 00:46:15,714
Другая вещь, на мой взгляд, более тонкая,
но я помещаю ее здесь, и смотрите

626
00:46:15,738 --> 00:46:19,852
— позиционная семантика не масштабируется.

627
00:46:19,876 --> 00:46:23,781
Какой пример позиционной семантики?
Списки аргументов.

628
00:46:23,805 --> 00:46:26,488
Они есть в большинстве языков,
и в Clojure они тоже есть.

629
00:46:26,512 --> 00:46:31,697
Кто хочет вызывать функцию
с 17 аргументами? Неа. [Один человек поднял руку]

630
00:46:31,721 --> 00:46:36,885
В каждой комнате такой человек найдется.

631
00:46:36,909 --> 00:46:39,683
Никто не хочет. Все мы знаем, что код ломается.

632
00:46:39,707 --> 00:46:45,609
Где ломается? Пять, шесть, семь?
В какой-то момент мы больше не счастливы.

633
00:46:45,633 --> 00:46:49,272
Но если это все, что у вас есть, если у вас есть
только кортежи типов,

634
00:46:49,296 --> 00:46:52,040
они будут ломаться каждый раз,
когда вы достигнете этого предела.

635
00:46:52,064 --> 00:46:58,175
Сколько людей любят ходить к врачу и заполнять анкеты.
Разве вы не ненавидите это?

636
00:46:58,199 --> 00:47:04,777
Вы получаете большой пустой лист линованной бумаги.
Затем вы получаете набор правил, который гласит:

637
00:47:04,801 --> 00:47:10,036
«укажите свой номер социального страхования
в строке 42, а свое имя — в строке 17».

638
00:47:10,060 --> 00:47:13,932
Вот как это работает, правда?
Так устроен мир.

639
00:47:13,932 --> 00:47:16,865
Так мы разговариваем с другими людьми?
Нет!

640
00:47:16,889 --> 00:47:19,193
Оно не масштабируется.
Это не то, чем мы занимаемся.

641
00:47:19,217 --> 00:47:22,717
Мы всегда ставим ярлыки рядом с вещами,
и ярлыки имеют значение.

642
00:47:22,741 --> 00:47:25,415
Но с позиционной семантикой мы говорим:
«Нет, ярлыки не важны.

643
00:47:25,439 --> 00:47:28,745
Просто помните, что третье значение означает
это, а седьмое означает то».

644
00:47:29,670 --> 00:47:35,353
И типы не помогают. Они на самом деле не различают
такое: float x, float x, float x, float x, float…

645
00:47:35,377 --> 00:47:38,596
В определенный момент
они вам ничего не говорят.

646
00:47:38,620 --> 00:47:43,019
Итак, они не масштабируются, но они — это происходит
в других местах, поэтому у нас есть списки аргументов.

647
00:47:43,043 --> 00:47:49,308
У нас есть кортежи типов. Что еще?
Параметризация.

648
00:47:50,763 --> 00:47:59,957
Кто видел обобщенный тип с более чем семью
типами аргументов в C++ или Java?

649
00:47:59,981 --> 00:48:05,492
Да, мы обычно не видим такого в Java,
потому что люди отказываются от параметризации.

650
00:48:06,855 --> 00:48:09,620
А на что они переходят?

651
00:48:09,620 --> 00:48:11,665
А на что они переходят?
На Spring!

652
00:48:11,689 --> 00:48:21,108
Нет, я имею ввиду, это не шутка. Это факт.
Они перешли на более динамичную систему инъекций.

653
00:48:21,132 --> 00:48:23,587
Потому что параметризация не масштабируется.

654
00:48:23,611 --> 00:48:28,123
И одна из причин, по которой она не масштабируется,
заключается в том, что на этих параметрах нет меток.

655
00:48:28,147 --> 00:48:32,306
Они могут получать имена по соглашению,
но они не названы должным образом.

656
00:48:32,330 --> 00:48:38,031
Если вы хотите повторно использовать тип с
параметрами, вам нужно дать им имена опять таки.

657
00:48:38,055 --> 00:48:44,806
Как и при сопоставлении с образцом. Это ужасно.
Это ужасная идея. И она не масштабируется.

658
00:48:44,830 --> 00:48:54,093
Так что везде, где у вас есть только
позиционирование, вы рано или поздно выдохнетесь.

659
00:48:54,117 --> 00:48:58,293
Вы потеряете способность разговаривать с людьми,
или они потеряют способность понимать, что вы делаете.

660
00:49:01,165 --> 00:49:07,681
Поэтому я считаю, что типы — это анти-паттерн
для поддержки программ и для расширяемости,

661
00:49:07,705 --> 00:49:13,723
потому что они добавляют связность, она
затрудняет поддержку программ,

662
00:49:13,747 --> 00:49:16,121
но, в первую очередь, затрудняет понимание.

663
00:49:16,145 --> 00:49:19,828
Итак, Clojure динамически типизирован.
У вас нет бремени доказывания.

664
00:49:19,852 --> 00:49:24,403
Вам не нужно это доказывать, из-за того, что
я сделал что-то здесь, и кто-то заботится об этом там,

665
00:49:24,427 --> 00:49:28,470
каждый человек в середине не возится с этим.

666
00:49:29,630 --> 00:49:31,392
В основном они с этим не связываются.

667
00:49:31,416 --> 00:49:37,155
Я не знаю, от чего мы защищаемся, но теперь мы можем
доказать, что они все еще имеют тип string вон там.

668
00:49:37,179 --> 00:49:39,075
Конструкции открытые.

669
00:49:39,099 --> 00:49:44,042
Мы скорее предпочтем динамический полиморфизм или с
использованием мультиметодов, или протоколов,

670
00:49:44,066 --> 00:49:47,725
чем switch-утверждения и
сопоставления с образцом и тому подобное.

671
00:49:47,749 --> 00:49:49,775
Мапы открыты.
По принципу минимальной осведомленности.

672
00:49:49,799 --> 00:49:53,974
Что мы делаем в Clojure, если мы чего-то не знаем?
Мы просто оставляем это в стороне.

673
00:49:53,998 --> 00:49:57,972
Мы этого не знаем.
Нет такого как: «может такой тип, а может такой».

674
00:49:57,996 --> 00:50:02,053
Если бы вы действительно параметризовали
информационную систему, она имела бы любой тип.

675
00:50:03,294 --> 00:50:08,275
Любой тип уже не информативен.
Это так.

676
00:50:08,299 --> 00:50:15,326
И «ничего» это тип «может что-то». Если ваш
номер социального страхования — строка, то это строка.

677
00:50:15,350 --> 00:50:20,765
Вы либо знаете это, либо нет.
Смешивать эти две вещи вместе не имеет смысла.

678
00:50:20,789 --> 00:50:22,499
Это не тип сущности.

679
00:50:22,523 --> 00:50:29,882
Это может быть частью вашего входного протокола,
тогда может вам это нужно или нет. Это не тип сущности.

680
00:50:29,906 --> 00:50:32,546
Итак, мапы открыты.

681
00:50:32,570 --> 00:50:34,965
Мы имеем дело с ними по
принципу минимальной осведомленности,

682
00:50:34,989 --> 00:50:37,524
а вы приобретаете привычку
распространять остальное.

683
00:50:37,548 --> 00:50:42,508
Может, ты передал мне лишнее.
Должен ли я переживать? Нет.

684
00:50:42,532 --> 00:50:47,060
Приезжает грузовик UPS,
и мой телевизор стоит на нем.

685
00:50:47,084 --> 00:50:54,474
Меня волнует, что еще в грузовике? Нет, я не хочу знать.
Но это нормально, что в нем и другие вещи.

686
00:50:57,996 --> 00:51:00,523
Итак, другая проблема — сложность языковой модели.

687
00:51:00,547 --> 00:51:06,962
C++ — очень сложный язык,
как и Haskell, и Java, и большинство из них.

688
00:51:08,839 --> 00:51:15,472
Clojure очень маленький. Не такой маленький
как Scheme, но по сравнению с другими он маленький.

689
00:51:15,496 --> 00:51:23,621
И это просто базовое лямбда-исчисление
с иммутабельным функциональным ядром.

690
00:51:23,645 --> 00:51:28,718
Есть функции. Есть значения. Вы можете вызывать
функции для значений и получать другие значения.

691
00:51:28,742 --> 00:51:32,846
Вот и все. Нет никакой иерархии.
Параметризации нет.

692
00:51:32,870 --> 00:51:36,981
Нет предопределённых типов,
бла-бла-бла-бла-бла.

693
00:51:38,118 --> 00:51:40,110
И модель исполнения — еще одна хитрость.

694
00:51:40,134 --> 00:51:45,153
Мы подходим к сути, даже в Java, где становится
все труднее и труднее рассуждать

695
00:51:45,177 --> 00:51:49,550
о производительности наших
программ из-за ресурсов.

696
00:51:51,430 --> 00:51:52,727
И это прискорбно.

697
00:51:52,751 --> 00:51:56,107
По крайней мере, одна из приятных особенностей C
заключалась в том, что вы знали,

698
00:51:56,131 --> 00:51:58,154
что если ваша программа упадет,
это будет ваша проблема.

699
00:51:58,178 --> 00:51:59,253
И вы просто разберетесь.

700
00:51:59,277 --> 00:52:04,790
Но вы знали, что она заняла всю ОЗУ, и вы могли
провести расчеты, и это было довольно легко решаемо.

701
00:52:04,814 --> 00:52:09,481
И это важно для программистов.
Программирование — это не математика.

702
00:52:09,505 --> 00:52:16,358
В математике любой изоморфизм можно заменить
любым другим. В программировании за это увольняют.

703
00:52:17,225 --> 00:52:23,544
У нас по-другому. Производительность имеет значение.
Это часть программирования. Она важна.

704
00:52:23,568 --> 00:52:29,777
Так что, сделав так, по крайней мере, я мог бы
сказать: «Это похоже на Java, и винить их».

705
00:52:29,801 --> 00:52:34,072
Но это также означает, что
нам помогали все инструменты.

706
00:52:34,072 --> 00:52:37,507
Все инструменты Java работают с Clojure.

707
00:52:37,531 --> 00:52:41,045
Сколько людей используют YourKit и
подобные профилировщики на Clojure?

708
00:52:41,069 --> 00:52:43,622
Это здорово, что есть такая возможность.

709
00:52:44,804 --> 00:52:50,297
Теперь мы говорим о рутинных вещах, которые
мне не нравились, и поэтому я убрал их.

710
00:52:50,321 --> 00:52:53,768
Это типичная вещь, она везде.

711
00:52:53,792 --> 00:52:56,893
И название, которое я придумал, — «узость».

712
00:52:56,917 --> 00:53:01,311
Эта идея о том, что «У меня есть такой язык,
и у него есть классная идея о том,

713
00:53:01,311 --> 00:53:05,046
как вы должны думать о вещах.
Вы должны думать, используя алгебраические типы данных.

714
00:53:05,046 --> 00:53:07,840
Или вы должны думать о вещах,
используя наследование».

715
00:53:09,207 --> 00:53:12,299
Это приводит к сильной узости.

716
00:53:12,323 --> 00:53:20,061
У вас появляются представления о вещах,
проявления представлений об информации,

717
00:53:20,085 --> 00:53:25,470
которые имеют смысл только
в контексте правил этого языка.

718
00:53:25,494 --> 00:53:31,318
И они не сочетаются с чужими идеями.
Вы разбиваетесь о базу данных.

719
00:53:31,342 --> 00:53:35,058
Вы разбиваетесь о сети.
Вы разбиваетесь о другой язык программирования,

720
00:53:35,082 --> 00:53:41,819
потому что у вас есть своеобразное,
локальное представление о том, как думать о вещах.

721
00:53:41,843 --> 00:53:47,963
В RDF сделано правильно. И у них получилось,
потому что была цель. Они пытались чего-то добиться.

722
00:53:47,987 --> 00:53:50,800
Мы хотим иметь возможность объединять
данные из разных источников.

723
00:53:50,824 --> 00:53:54,881
Мы не хотим, чтобы схемы
преобладали над семантикой.

724
00:53:55,862 --> 00:54:00,515
Сколько людей когда-либо получали ещё одно и то же
письмо от одной и той же компании и спрашивали:

725
00:54:00,539 --> 00:54:05,793
«Что не так с вашими базами данных, чуваки?»
Да. Что не так?

726
00:54:05,817 --> 00:54:11,429
Не так то, что одна компания купила другую.
Теперь они одна и та же компания.

727
00:54:11,453 --> 00:54:13,683
Теперь у них есть эти две базы данных.

728
00:54:13,707 --> 00:54:18,078
В одной базе данных ваше имя
находится в таблице людей,

729
00:54:18,102 --> 00:54:25,546
а в другой базе данных ваше имя находится
в таблице списка рассылки.

730
00:54:27,905 --> 00:54:34,798
Кто знает, что имя в списке рассылки и имя человека — это на самом деле одна и та же информация? Никто.

731
00:54:34,798 --> 00:54:39,707
У них должны быть собрания. Я имею в виду,
что это дорого обойдется — это большая проблема.

732
00:54:39,731 --> 00:54:43,264
Это не мелочь… Мне же не до смеха, правда?

733
00:54:43,288 --> 00:54:48,501
У крупных компаний есть огромное количество сотрудников,
пытающихся объединить эти системы,

734
00:54:48,525 --> 00:54:55,064
потому что ограниченность таблиц, это то же самое,
что классы и алгебраические типы данных.

735
00:54:55,088 --> 00:54:57,211
Это та же проблема.
Это не другая проблема.

736
00:54:57,235 --> 00:55:02,234
Это все похоже на то, что у меня был такой взгляд на мир,
и в тот день, когда я решил, каков мир,

737
00:55:02,258 --> 00:55:07,881
я решил, что имена являются частями класса person,
а вы решили, что имена являются частью списков рассылки.

738
00:55:07,905 --> 00:55:11,611
И теперь нам нужно это исправить.
И вы знаете, как многие из этих компаний это исправляют?

739
00:55:11,635 --> 00:55:16,641
Они вводят третью базу данных, обычно базу данных RDF,
в качестве точки объединения,

740
00:55:16,665 --> 00:55:20,186
так что теперь они могут понять,
что эти две вещи одинаковы.

741
00:55:20,210 --> 00:55:23,495
И в конце концов они перестанут отправлять
вам одно и то же письмо дважды.

742
00:55:25,790 --> 00:55:30,698
Итак, есть субъект, предикат, объект, и, очевидно,
вы можете увидеть влияние этого на Datomic.

743
00:55:30,722 --> 00:55:37,372
Но все ещё хуже. Я бы сказал, что чем более сложна
ваша система типов, тем более ограниченнее ваши типы.

744
00:55:37,396 --> 00:55:43,670
Чем они менее универсальны, тем они менее транспортабельны,
тем менее понятны для других систем,

745
00:55:43,694 --> 00:55:49,564
менее пригодны для повторного использования,
менее гибки, менее удобны для отправки по сети,

746
00:55:50,496 --> 00:55:54,647
менее подвержены общим манипуляциям.

747
00:55:54,671 --> 00:56:02,202
Почти каждый другой язык, имеющий дело с типами, поощряет
эту тиранию контейнера, о которой я говорил ранее.

748
00:56:02,226 --> 00:56:06,100
У нас есть выбор в Clojure, я думаю,
люди идут в обоих направлениях.

749
00:56:06,124 --> 00:56:11,221
Есть две вещи: одна — контейнер доминирует,
другая — просто своего рода понятие контекста,

750
00:56:11,245 --> 00:56:16,722
доминирующего над смыслом, например, «потому что я
вызвал это в этом контексте, это означает то».

751
00:56:16,746 --> 00:56:23,927
Но у нас есть рецепт в Clojure, чтобы добиться большего,
вы используете ключи, определяемые пространством имен.

752
00:56:23,951 --> 00:56:29,098
С помощью ключей с указанием пространства имен
теперь мы можем объединять данные и знать,

753
00:56:29,122 --> 00:56:31,984
что они означают, независимо от контекста,
в котором они используются.

754
00:56:32,008 --> 00:56:35,666
И это всё мешает композиции,
о которой я говорил раньше.

755
00:56:35,690 --> 00:56:40,336
И, в частности, поскольку мы указываем на
программу-манипулирующую-программой,

756
00:56:40,360 --> 00:56:42,958
как вы увидите позже,
это усложняет задачу.

757
00:56:42,982 --> 00:56:48,239
Итак, Clojure имеет имена первого класса.
Это то, что было в Лиспе.

758
00:56:48,263 --> 00:56:55,759
Они просто доминируют сильнее, потому что
по ним можно обращаться к ассоциативным типам данных.

759
00:56:55,783 --> 00:57:01,458
Они являются функциями для самих себя. Ключевые
слова, являющиеся функциями, — это важная вешь.

760
00:57:01,482 --> 00:57:06,572
Они не исчезают. Они не компилируются с отклонениями.
Мы можем передать их. Мы можем их записать.

761
00:57:06,596 --> 00:57:11,577
Пользователь, не знакомый с Clojure, может
ввести их в текстовый файл и сохранить его,

762
00:57:11,601 --> 00:57:15,106
а также сделать что-нибудь значимое
с нашей программой, не изучая Clojure.

763
00:57:17,217 --> 00:57:19,405
У нас есть квалифицированное пространство имен.

764
00:57:19,429 --> 00:57:24,852
Если вы следуете соглашениям — которых, к сожалению,
многие библиотеки Clojure еще не придерживаются — 765
00:57:24,876 --> 00:57:28,972
этой системы обратных доменных имен,
которая такая же, как и в Java,

766
00:57:28,996 --> 00:57:34,147
все имена Clojure не конфликтуют не только с другими
именами Clojure, но и с другими именами в Java.

767
00:57:34,171 --> 00:57:42,169
Это фантастически хорошая идея, и она похожа
на идею в RDF об использовании URI для имен.

768
00:57:42,169 --> 00:57:45,605
И псевдонимы помогают сделать
это менее обременительным.

769
00:57:45,629 --> 00:57:48,536
И совсем недавно мы сделали кое-что,
чтобы стало лучше.

770
00:57:48,560 --> 00:57:50,539
Есть проблема с поставкой.

771
00:57:50,563 --> 00:57:55,781
И здесь я начинаю говорить: «Создавать архитектуру
программы опираясь на специфику языка

772
00:57:55,805 --> 00:57:58,896
ужасная ошибка», потому что вы
находитесь в этой маленькой коробочке.

773
00:57:58,920 --> 00:58:00,904
Вы игнорируете главное.

774
00:58:00,928 --> 00:58:06,082
Как только вы отойдете на шаг назад, вы
увидите проблемы. Вы должны работать с сетью.

775
00:58:06,106 --> 00:58:12,769
Сколько людей используют вызов
удаленных методов? Мне очень жаль.

776
00:58:13,885 --> 00:58:16,586
Потому что это жестоко.
Это очень жестоко.

777
00:58:16,610 --> 00:58:23,420
Невероятно нестабильно, хрупко, сложно,
подвержено ошибкам и ограниченно.

778
00:58:23,444 --> 00:58:30,042
Сколько людей используют такие технологии,
чтобы общаться с людьми, не работающими с ними вместе?

779
00:58:30,066 --> 00:58:34,911
Нет, так не работает. Интернет работает не так.
Удаленные объекты неудачны.

780
00:58:34,935 --> 00:58:38,134
Интернет — это отправка простых данных по сети.

781
00:58:38,158 --> 00:58:42,753
И почти все, что когда-либо касалось сети,
удавалось только тогда, когда все упрощалось.

782
00:58:42,777 --> 00:58:44,814
И это здорово.

783
00:58:45,674 --> 00:58:49,577
Почему мы должны программировать
так ограниченно,

784
00:58:49,601 --> 00:58:55,501
если нам нужно только представить
некоторое подмножество программы

785
00:58:55,525 --> 00:59:00,311
возможно, подмножество, которое
мы не знали заранее — по сети.

786
00:59:00,335 --> 00:59:06,089
Если мы все время программируем таким образом,
мы программируем внутреннюю часть наших программ как

787
00:59:06,113 --> 00:59:08,833
«давайте передавать структуры данных»,
а затем кто-то говорит:

788
00:59:08,857 --> 00:59:13,164
«О, я бы хотел передать половину вашей программы
по сети или распределить её на шесть машин»,

789
00:59:13,188 --> 00:59:18,534
что мы говорим в Clojure? Отлично.
Я пошлю немного EDN через сокет, и все готово.

790
00:59:18,558 --> 00:59:22,448
В противном случае,
вам нужно все делать заново.

791
00:59:24,570 --> 00:59:28,670
Так что у меня было много
вдохновения и примеров.

792
00:59:28,694 --> 00:59:31,722
Осознаваемость времени выполнения — одна из вещей,
которые меня по-настоящему ободрили,

793
00:59:31,746 --> 00:59:34,645
когда я изучил Common Lisp после C++.

794
00:59:35,767 --> 00:59:44,456
Smalltalk и Common Lisp — языки, которые были написаны
людьми, которые пытались писать программы для людей.

795
00:59:44,480 --> 00:59:51,263
Это не теоретики языка. Это точно.
Они писали графические интерфейсы.

796
00:59:51,287 --> 00:59:55,364
Они писали базы данных.
Они писали логические программы, а также языки.

797
00:59:55,388 --> 01:00:02,800
Но есть неоспоримая чувствительность системы,
которая проходит через Smalltalk и Common Lisp.

798
01:00:03,272 --> 01:00:08,477
И когда вы впервые обнаруживаете её, особенно если вы
обнаруживаете её поздно, как я, это потрясающе.

799
01:00:14,198 --> 01:00:19,547
И я думаю, что это традиция, которая в значительной
степени утрачена в академических кругах.

800
01:00:19,571 --> 01:00:26,382
Я просто не вижу таких же людей, создающих
системы и языки вместе. Они вроде как разделились.

801
01:00:26,406 --> 01:00:33,751
И это действительно досадно, потому что у этих
языков еще очень много чего можно стянуть.

802
01:00:33,775 --> 01:00:36,187
Они были в высшей степени осязаемыми.

803
01:00:36,211 --> 01:00:39,500
У них была овеществленная среда: все имена, которые
вы могли видеть, вы могли вернуться и найти код.

804
01:00:39,524 --> 01:00:44,638
Пространства имен были осязаемыми. Вы можете загружать
код во время выполнения. То есть один за другим и за другим.

805
01:00:44,662 --> 01:00:47,559
И старая шутка Алана Перлиса
(перепутал с Филипом Гринспаном) о том,

806
01:00:47,583 --> 01:00:54,373
что «Любая достаточно большая программа на C или C++
имеет плохо реализованный Common Lisp», является верной.

807
01:00:54,373 --> 01:00:57,475
И опять Spring, правда?

808
01:00:57,499 --> 01:01:02,195
По мере того, как вы получаете более крупную систему,
которую хотите поддерживать с течением времени,

809
01:01:02,219 --> 01:01:08,998
и справляетесь со всеми теми сложностями,
которые я показал ранее, вам нужен динамизм.

810
01:01:09,022 --> 01:01:13,564
Без него не обойтись. Это не что-то необязательное.
Он необходим.

811
01:01:13,588 --> 01:01:16,872
Но что было особенно интересно для меня
при создании Clojure, так это то,

812
01:01:16,896 --> 01:01:24,136
насколько осязаем рантайм и ситуативная
чувствительность в архитектуре JVM.

813
01:01:24,160 --> 01:01:27,665
JVM на самом деле очень динамичная вещь.

814
01:01:27,689 --> 01:01:34,472
Несмотря на то, что Java выглядит как, скажем,
C# или C++, JVM была написана с идеей:

815
01:01:34,496 --> 01:01:39,405
«Мы собираемся встраивать эти программы в
телевизионные приставки и объединять их в сеть,

816
01:01:39,429 --> 01:01:43,010
и передавать код для обновления их возможностей".

817
01:01:43,034 --> 01:01:49,454
То есть он везде, куда ни глянь.
И рантайм получил массу отличной поддержки для этого.

818
01:01:49,478 --> 01:01:53,854
Это делает JVM отличной платформой
для таких языков как Clojure.

819
01:01:53,878 --> 01:02:03,664
И слава богу, что работа, которую люди проделали над Self
не умерла, она действительно была пронесена сквозь время.

820
01:02:03,688 --> 01:02:08,226
Не все получилось. Но это очень важно.

821
01:02:08,250 --> 01:02:11,353
И это будет печальный день, когда кто-то скажет:

822
01:02:11,377 --> 01:02:15,339
«Что ж, давайте просто заменим JVM какой-нибудь
технологией статической компиляции».

823
01:02:15,363 --> 01:02:20,680
И я скажу вам, что, глядя на JVM и CLR, очевидно:

824
01:02:20,704 --> 01:02:25,551
CLR — это статическое мышление, а
JVM — это динамическое мышление.

825
01:02:25,575 --> 01:02:27,908
Итак, во всем этом есть
размещаемая чувствительность.

826
01:02:27,932 --> 01:02:31,973
Последней проблемой на моем начальном слайде
была параллелизм, и я думаю, что в основном проблемы

827
01:02:31,997 --> 01:02:36,454
параллелизма решаются за счет функционального подхода
и иммутабельности по умолчанию.

828
01:02:36,478 --> 01:02:44,911
Еще вам понадобится некоторый язык
для работы с переходами между состояниями.

829
01:02:44,935 --> 01:02:48,391
И это epochal time model.
Я, конечно, не собираюсь здесь вдаваться в подробности,

830
01:02:48,415 --> 01:02:50,467
но я уже говорил об этом раньше.

831
01:02:50,491 --> 01:02:51,909
Итак, у Clojure есть это.

832
01:02:51,933 --> 01:02:54,407
И это была комбинация таких вещей,
которые позволяют мне сказать:

833
01:02:54,431 --> 01:02:57,191
«Думаю, у меня есть разумный
ответ для моего друга».

834
01:02:57,215 --> 01:02:59,665
Если он спросит:
«Как я могу написать настоящую программу?»,

835
01:02:59,689 --> 01:03:05,696
Я могу ответить: «Вот как ты можешь написать настоящую
программу, в том числе многопоточную, и не сойти с ума».

836
01:03:05,720 --> 01:03:09,942
Итак, есть много вещей, которые я хотел позаимствовать
из Lisp, и я думаю, что говорил о многих из них.

837
01:03:09,966 --> 01:03:13,166
Он динамичен. Он малого размера.
У него имена первого класса. Он очень осязаем.

838
01:03:13,190 --> 01:03:17,240
Код как данные, чтение/печать,
и я собираюсь поговорить об этом немного подробнее.

839
01:03:17,264 --> 01:03:22,255
Но есть REPL. И я думаю, что люди до сих пор говорят:
«REPL — это круто, потому что я могу что-то попробовать».

840
01:03:22,279 --> 01:03:28,239
И это правда, но REPL намного круче этого.
Он круче, потому что это аббревиатура.

841
01:03:28,263 --> 01:03:32,418
И он круче, потому что чтение — это отдельная вещь.

842
01:03:32,442 --> 01:03:41,417
Добавив более богатый набор структур данных,
Clojure превратил чтение/печать в суперсилу.

843
01:03:41,441 --> 01:03:45,137
Это было не просто ради удобства.
Это не просто способ взаимодействия с людьми.

844
01:03:45,161 --> 01:03:50,277
Это не просто способ упростить потоковую
передачу программ или фрагментов программ.

845
01:03:50,301 --> 01:03:55,235
Теперь это похоже на «Вот ваш бесплатный
проводной протокол для реальных вещей».

846
01:03:55,259 --> 01:04:00,612
Сколько людей когда-либо отправляли edn по сети?
Да.

847
01:04:00,636 --> 01:04:04,696
Скольким нравится тот факт, что им не нужно думать,
что это возможно. Они могут просто это сделать?

848
01:04:04,720 --> 01:04:10,257
А если они захотят переключиться на
что-то другое — пожалуйста. Это очень важно.

849
01:04:10,281 --> 01:04:15,684
Eval, нам очевидно, что он позволяет
нам переходить от данных к коду.

850
01:04:15,708 --> 01:04:22,678
И это источник макросов, но я снова думаю,
что это намного больше, чем приложение к макросам.

851
01:04:22,702 --> 01:04:25,691
И, наконец, печать, а это как раз другое направление.

852
01:04:25,715 --> 01:04:32,331
Но, на мой взгляд, в Лиспе было много вещей, которые
нужно было исправить. Он построен на конкрециях.

853
01:04:32,355 --> 01:04:39,811
Большая часть архитектуры дополнительных абстракций, CLOS
и тому подобное пришли после того, как была заложена основа.

854
01:04:39,835 --> 01:04:47,071
В основе этого не было, поэтому, если вам нужен
полиморфизм в основе, вы должны его модифицировать.

855
01:04:47,095 --> 01:04:52,323
Если вам нужна иммутабельность в основе,
вам нужно что-то другое с нуля.

856
01:04:52,347 --> 01:04:58,469
Вот почему стоило создать Clojure, а не пытаться
создать Clojure как библиотеку для Common Lisp.

857
01:04:58,493 --> 01:05:06,331
Списки были функциональными, в основном по соглашению.
Но других структур данных не было.

858
01:05:06,355 --> 01:05:11,420
Вам приходилось переключаться, чтобы перейти
от ассоциативных листов к правильной хэш-таблице.

859
01:05:11,444 --> 01:05:16,725
А списки — это дерьмовые структуры данных.
Извините, так и есть. Они очень слабые.

860
01:05:16,749 --> 01:05:20,518
И нет причин использовать их в качестве
главных примитивов для программирования.

861
01:05:20,542 --> 01:05:23,942
К тому же пакеты и интернирование
были очень сложными.

862
01:05:23,966 --> 01:05:29,011
Другая важная часть Clojure —
это усилие рычага (leverage).

863
01:05:29,035 --> 01:05:31,850
О, у меня мало времени.
Я не буду об этом говорить.

864
01:05:31,874 --> 01:05:33,663
Или об этом.

865
01:05:33,687 --> 01:05:38,599
Таким образом, модель данных edn не небольшая часть Clojure.
Это своего рода сердце Clojure.

866
01:05:38,623 --> 01:05:45,995
Это ответ на многие из этих проблем. Она ощутима.
Работает по сети. Она совместима с остальным миром.

867
01:05:46,019 --> 01:05:52,306
Есть ли мапы в других языках?
Ассоциативные структуры данных, векторы, строки и числа?

868
01:05:52,330 --> 01:05:56,438
Так что это похоже на удачный лингва франка
(язык межэтнического общения).

869
01:05:56,462 --> 01:05:58,993
И почему бы нам не использовать
лингва франка в нашей программе?

870
01:05:59,017 --> 01:06:01,723
Почему у нас должен быть другой язык?

871
01:06:01,747 --> 01:06:04,646
На самом деле такая ситуация не намного лучше,
и вам нужно продолжать переводить.

872
01:06:04,670 --> 01:06:07,815
Итак. Напоследок.

873
01:06:07,839 --> 01:06:15,485
Саймон Пейтон Джонс в прекрасной серии
выступлений перечислил эти преимущества типов.

874
01:06:15,509 --> 01:06:18,210
Потому что это самое важное,
что осталось за пределами Clojure. В Clojure типов нет.

875
01:06:18,234 --> 01:06:22,702
Они гарантируют отсутствие тех или иных ошибок,
и это действительно так.

876
01:06:22,726 --> 01:06:28,198
И он сказал бы — он действительно сказал —
«Это наименьшее преимущество статической типизации».

877
01:06:28,222 --> 01:06:35,522
Они служат спецификации частичной машинной проверки,
и здесь ключевое слово «частичной». Очень частичной.

878
01:06:35,546 --> 01:06:38,491
Они определяют архитектуру языка.
Они помогают вам думать.

879
01:06:38,515 --> 01:06:41,577
У вас есть фреймворк, в котором
вы можете думать о своих проблемах.

880
01:06:41,601 --> 01:06:44,460
Они поддерживают интерактивную разработку,
такую ??как IntelliSense.

881
01:06:44,484 --> 01:06:48,510
Но самая большая заслуга, по его словам,
заключается в обслуживании программного обеспечения.

882
01:06:48,534 --> 01:06:53,950
И я действительно не согласен со многими утверждениями.
Не по своему опыту.

883
01:06:53,974 --> 01:06:56,467
Эти системы типов не улавливают самые большие ошибки.

884
01:06:56,491 --> 01:07:02,062
Чтобы проверить эффективность в реальных условиях,
вам потребуется обширное тестирование.

885
01:07:02,086 --> 01:07:04,948
Имена доминируют над семантикой.

886
01:07:04,972 --> 01:07:07,472
Привести А к А [a -> a],
список из А в список из А [[a] -> [a]].

887
01:07:07,496 --> 01:07:10,025
Ничего не понятно.
Такая запись ни о чем не говорит.

888
01:07:10,049 --> 01:07:15,037
Если убрать слово «reverse», то вы ничего не знаете.
Вы действительно не знаете.

889
01:07:15,061 --> 01:07:18,945
И чтобы усилить это мы говорим:
«О, это важно. У нас есть все эти свойства».

890
01:07:18,969 --> 01:07:21,653
Это неправда. Это просто неправда.

891
01:07:21,677 --> 01:07:25,040
Существуют тысячи функций, которые принимают
список из А и возвращают список из А.

892
01:07:25,064 --> 01:07:27,683
Что это значит?
Ничего не значит.

893
01:07:27,707 --> 01:07:30,105
И проверка типов это…

894
01:07:30,105 --> 01:07:34,047
Я имею в виду, если бы у вас был только список А,
где вы собираетесь взять что-нибудь еще, чтобы вернуть?

895
01:07:34,047 --> 01:07:38,256
Я имею в виду, очевидно, вы собираетесь вернуть список А,
если только вы не получаете что-то откуда-то еще.

896
01:07:38,256 --> 01:07:40,900
А если вы пишете функционально,
то вы так не делаете.

897
01:07:41,845 --> 01:07:46,797
Скольким людям нравится UML? Сколько людей когда-либо
использовали инструмент для построения диаграмм UML?

898
01:07:48,136 --> 01:07:49,608
Это не весело, правда?

899
01:07:49,608 --> 01:07:53,201
Это похоже на «Нет, вы не можете связать это с этим».
«О нет, ты должен использовать такую ??стрелку».

900
01:07:53,201 --> 01:07:55,869
«Нет, ты не можешь этого сделать». «Нет, ты не можешь...».
Это ужасно.

901
01:07:55,893 --> 01:07:59,798
OmniGraffle намного лучше. Нарисуйте все, что хотите.
О чем вы думаете? Нарисуйте это.

902
01:07:59,822 --> 01:08:04,241
Что важно? Запишите это.
Вот как это должно работать.

903
01:08:05,558 --> 01:08:08,751
Да, в IntelliSense очень помогают статические типы.

904
01:08:08,775 --> 01:08:13,425
И оптимизация производительности, которую он не перечислил,
но я думаю, что это одно из самых больших преимуществ.

905
01:08:13,449 --> 01:08:15,626
Нам это нравится в C++.

906
01:08:15,650 --> 01:08:18,519
И техническое обслуживание, как мне кажется,
не соответствует действительности.

907
01:08:18,543 --> 01:08:22,745
Я думаю, что они создали проблемы,
для решения которых теперь используют типы.

908
01:08:22,769 --> 01:08:27,773
О, я сопоставил эту штуку с образцом в 500 местах,
и я хочу добавить еще одну вещь посередине.

909
01:08:27,797 --> 01:08:31,687
Что ж, слава богу, у меня есть типы,
чтобы найти эти 500 мест.

910
01:08:31,711 --> 01:08:37,636
Но суть в том: вещь, которую я добавил, никого не должна была
волновать, кроме нового кода, который её использовал.

911
01:08:37,636 --> 01:08:42,498
И если бы я сделал по-другому, мне бы не пришлось
ничего менять, кроме producer'а и consumer'а,

912
01:08:42,522 --> 01:08:48,187
а не всех подряд, кто может об этой вещи и не знает, так?
Это же новая вещь.

913
01:08:50,580 --> 01:08:56,350
Я имею в виду, что для молодых программистов,
если вы устали и стары, это уже не имеет значения.

914
01:08:56,374 --> 01:09:05,624
Но когда вы молоды, у вас много свободного места.
Раньше я говорил «пустая голова», но это неправильно.

915
01:09:05,648 --> 01:09:10,035
У вас много свободного места,
и вы можете заполнить его чем угодно.

916
01:09:10,059 --> 01:09:17,996
И эти системы типов довольно забавны,
потому что с точки зрения выработки эндорфинов

917
01:09:18,020 --> 01:09:20,662
решение головоломок и решение проблем —
одно и то же.

918
01:09:20,686 --> 01:09:24,279
Они дают вам одинаковый всплеск.
Решать головоломки действительно круто.

919
01:09:29,030 --> 01:09:34,727
Я думаю, что такая проверка и все такое, это невероятно
важно, но это должно быть на заказ (a la carte).

920
01:09:34,751 --> 01:09:39,115
В зависимости от того, что вам нужно сделать,
в зависимости от суммы денег, которую вы можете потратить,

921
01:09:39,139 --> 01:09:46,973
в зависимости от того, что вы хотите выразить, вы сможете
извлечь с полки различные виды технологий проверки и применить их.

922
01:09:46,997 --> 01:09:53,758
Их не следует встраивать. Разные потребности.
Разные подходы и разные затраты.

923
01:09:53,782 --> 01:09:58,734
Кроме того, я думаю, что в той мере, в какой эти инструменты
могут быть направлены на проблему системного уровня,

924
01:09:58,758 --> 01:10:02,587
а не на некоторую ограниченность языка, вы
получите больше отдачи от вложенных средств.

925
01:10:02,611 --> 01:10:08,218
Сколько людей использовали spec для определения
проводного протокола? Да. А будете еще чаще.

926
01:10:10,553 --> 01:10:14,720
И я не буду больше говорить о spec,
но следующая версия улучшит программируемость.

927
01:10:14,744 --> 01:10:21,548
Итак, наконец, информация против логики.
Суть в том, «Куда мы идем в программировании?»

928
01:10:21,572 --> 01:10:28,695
Дело в том, что мы фактически не умеем водить машину.
Мы не можем объяснить, как водить машину.

929
01:10:28,719 --> 01:10:31,618
Мы не можем объяснить, как играть в Го.

930
01:10:31,642 --> 01:10:39,400
И, следовательно, мы не можем применить традиционную логику
для кодирования и создать программу, которая будет успешна.

931
01:10:39,424 --> 01:10:40,933
Мы просто не можем этого сделать.

932
01:10:40,957 --> 01:10:45,131
Сейчас мы приближаемся к проблемам в программировании,
которые не умеем решать.

933
01:10:45,155 --> 01:10:50,191
Мы не знаем, как объяснить, как их решить. Мы умеем водить
машину, но не знаем как объяснить, как водить машину.

934
01:10:50,215 --> 01:10:54,206
Итак, мы переходим к мозгам натренированным информацией.

935
01:10:54,230 --> 01:10:58,115
Глубокое обучение и машинное обучение,
статистические модели и тому подобное.

936
01:10:58,139 --> 01:11:06,404
Вы используете информацию для управления моделью,
которая полна неточностей и предположений,

937
01:11:06,428 --> 01:11:10,149
но она по-прежнему эффективна
из-за количества данных,

938
01:11:10,173 --> 01:11:13,589
которые использовались для обучения
ее принятию достойных решений,

939
01:11:13,613 --> 01:11:17,092
хотя она также не может объяснить,
как она работает.

940
01:11:17,116 --> 01:11:21,810
Однако этим программам потребуются
руки, ноги и глаза.

941
01:11:21,834 --> 01:11:27,097
Когда вы тренируете большую сеть глубокого обучения,
получает ли она свои собственные данные?

942
01:11:27,121 --> 01:11:30,216
Есть ли у нее собственный ETL? Нет.

943
01:11:30,240 --> 01:11:35,804
Ничего из этого не происходит. Когда она приняла
решение о том, что делать, как она это будет делать?

944
01:11:36,920 --> 01:11:41,225
Что ж, когда у нас будет Скайнет,
это больше не будет нашей проблемой.

945
01:11:42,598 --> 01:11:44,029
Но на данный момент это так.

946
01:11:44,053 --> 01:11:50,087
И я думаю, что довольно рискованно работать на языке
программирования, который сам является программируемым,

947
01:11:50,111 --> 01:11:54,000
которым можно манипулировать
другими программами.

948
01:11:54,024 --> 01:11:58,429
Будет весело использовать
Clojure для построения мозга.

949
01:11:58,453 --> 01:12:03,396
Но также будет полезно иметь возможность использовать
Clojure для обработки и подготовки информации,

950
01:12:03,420 --> 01:12:11,751
а также использовать программы и программные
компоненты Clojure для принятия решений.

951
01:12:15,742 --> 01:12:19,803
В конце концов, безопасность в реальном мире
будет зависеть от опыта. А не от доказательства.

952
01:12:19,827 --> 01:12:25,316
Любой, кто выходит на сцену и делает заявление о том,
что системы типов дают безопасные системы,

953
01:12:25,340 --> 01:12:29,531
где «безопасный» означает реальный мир?
Это неправда.

954
01:12:30,647 --> 01:12:39,667
Вот что действительно интересно. Глубокое обучение и подобные
технологии указаные выше черты, они выше этих верхних 10x.

955
01:12:39,691 --> 01:12:43,903
Они указывают на проблему недопонимания.
Они говорят: «Знаете что? Вы правы.

956
01:12:43,927 --> 01:12:47,820
Мы не знаем как играть в Го.
Мы не знаем как водить машину.

957
01:12:47,844 --> 01:12:51,203
Давайте создадим систему,
которая могла бы понять, как это сделать,

958
01:12:51,227 --> 01:12:56,776
и научиться этому, потому что в противном случае
мы просто непонимаем как правильно".

959
01:12:56,800 --> 01:13:02,662
Итак, я хочу подчеркнуть, что мы пишем программируемые
программы, и Clojure хорошо для этого подходит.

960
01:13:02,686 --> 01:13:07,034
У нас есть обобщенный способ представления
информации и акцентов.

961
01:13:07,058 --> 01:13:12,171
У нас есть обобщенный способ композиции
аргументов без применения системы типов.

962
01:13:12,195 --> 01:13:21,417
Достаточно тяжело водить машину. С пониманием
монад легче не станет, это так не работает.

963
01:13:21,441 --> 01:13:25,490
Овеществленная система подвержена
динамическому раскрытию,

964
01:13:25,514 --> 01:13:29,937
и я думаю, что spec в сочетании с
овеществленной остальной частью Clojure — 965
01:13:29,961 --> 01:13:35,904
отличный способ сделать системы, о которых другие системы
могут узнать и, следовательно, научиться использовать.

966
01:13:35,928 --> 01:13:39,711
И, конечно же, у нас есть такая же возможность
со временем улучшать наши программы.

967
01:13:39,735 --> 01:13:46,444
Итак, я бы посоветовал вам всем принять тот факт,
что Clojure отличается от других.

968
01:13:46,468 --> 01:13:51,658
Не пугайтесь людей доказывающих типы.

969
01:13:51,682 --> 01:13:59,458
Программирование — это не решенная проблема.
Логика должна вам служить. А не вы ей.

970
01:13:59,482 --> 01:14:04,673
Вы не должны подчиняться логической системе. Вы должны
применять логическую систему, когда она вам подходит.

971
01:14:04,697 --> 01:14:10,411
Я призываю вас проектировать на системном уровне.
Дело не только в вашем языке программирования.

972
01:14:10,435 --> 01:14:13,145
Все мы увлечены нашими языками программирования.
Но вы знаете, что?

973
01:14:13,169 --> 01:14:18,189
На самом деле я довольно скептически отношусь к тому, что
языки программирования являются ключом к программированию.

974
01:14:18,213 --> 01:14:19,812
Я так не думаю.

975
01:14:19,836 --> 01:14:25,362
Это небольшая часть программирования.
Они не являются движущей силой программирования.

976
01:14:25,362 --> 01:14:29,828
И воспользуйтесь этими новыми возможностями.
Во время конференции будет много

977
01:14:29,946 --> 01:14:33,256
разговоров о глубоком обучении, послушайте их.

978
01:14:33,280 --> 01:14:38,160
Создавайте программируемые программы
и решайте проблемы, а не головоломки.

979
01:14:38,184 --> 01:14:40,355
Спасибо.

980
01:14:40,379 --> 01:14:49,287
Автор перевода и субтитров:
Константин Проскурня — t.me/ProsWeb