-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
348 lines (335 loc) · 16.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>Типы без границ: фронтенд-разработка с GraphQL и умным компилятором</title>
<meta name="description" content="">
<meta name="author" content="Andrey Miskov">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="stylesheet" href="../reveal/css/reveal.css">
<link rel="stylesheet" href="../reveal/css/theme/white.css" id="theme">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="../reveal/lib/css/github.css">
<!-- Printing and PDF exports -->
<script>
const link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match(/print-pdf/gi) ? '../reveal/css/print/pdf.css' : '../reveal/css/print/paper.css';
document.getElementsByTagName('head')[0].appendChild(link);
</script>
<style>
section img {
max-height: 40vh !important;
border: none !important;
}
</style>
</head>
<body>
<div class="reveal">
<div class="slides">
<section>
<h1>Типы без границ</h1>
<h2>фронтенд-разработка с GraphQL и умным компилятором</h2>
<div>
<img height="42" src="img/graphql_logo.svg" alt="">
<img height="42" src="img/elm_logo.svg" alt="">
</div>
</section>
<section>
<h3>О чём доклад?</h3>
<p>Вроде про GraphQL и Elm...</p>
</section>
<section>
<h3>О чём доклад?</h3>
<p>На самом деле...</p>
<ul>
<li class="fragment">Сложность.</li>
<li class="fragment">Ограничения.</li>
<li class="fragment">Developer Experience.</li>
<li class="fragment">Trade-offs.</li>
</ul>
</section>
<section>
<h3>План</h3>
<ol>
<li>Кратко про GraphQL.
<li>Кратко про Elm.
<li>GraphQL-типы в IDE разработчика: как рассказать компилятору, что ждёт БД от фронта.
<li>Выводы и впечатления от работы с таким стэком.
<li>Рекомендации желающим разобраться подробнее.
</ol>
</section>
<section>
<h3>GraphQl</h3>
<ul>
<li class="fragment">Гибкое API: фронтенду хорошо, бэкенду тоже неплохо</li>
<li class="fragment">Типизировано, документировано</li>
<li class="fragment">Спецификация: реализуй сам</li>
<li class="fragment">Запросы, мутации, подписки</li>
<li class="fragment"><i>Хорошо для агрегирования данных</i></li>
</ul>
</section>
<section>
<h3>Почему компилируют в JS?</h3>
<ul>
<li class="fragment">Что такое программирование?</li>
<li class="fragment">Управление сложностью.</li>
<li class="fragment">It's all about predictability.</li>
<li class="fragment"><em>В JS сложно управлять сложностью.</em></li>
</ul>
</section>
<section>
<blockquote style="text-align: left">
Managing complexity is the most important technical topic in software development. In my view, it's so
important that Software's Primary Technical Imperative has to be managing complexity. Complexity is not
a new feature of software development.
<p style="text-align: right">― Steve McConnell, Code Complete</p>
</blockquote>
</section>
<section>
<h3>JS, the bad parts</h3>
<p>Слово создателю</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/DUYQ9AZrHWc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</section>
<section>
<h3>JS, the bad parts</h3>
<ul>
<li>Нельзя просто взять и исправить язык — сломается Веб.</li>
<li>Много языковых возможностей — много возможностей делать плохо.</li>
</ul>
</section>
<section>
<h3>Что можно убрать из языка?</h3>
<ul style="font-size: 85%">
<li class="fragment">Циклы</li>
<li class="fragment">Присваивание</li>
<li class="fragment">Мутации</li>
<li class="fragment">Инструкции (statements)</li>
<li class="fragment">Объекты</li>
<li class="fragment">Классы</li>
<li class="fragment"><code>return</code> и множественный возврат</li>
<li class="fragment">Сайд-эффекты</li>
</ul>
</section>
<section data-background="#000" data-background-image="../ogon/img/fire.gif" data-background-repeat="no-repeat" data-background-size="cover" data-background-position="center bottom">
<h3>Что можно убрать из языка?</h3>
<ul>
<li><code>null</code></li>
<li><code>undefined</code></li>
<li><code>NaN</code></li>
</ul>
</section>
<section>
<h3>Как так? 😱</h3>
<ul style="font-size: 75%">
<li class="fragment">Циклы → Функции (рекурсия, HoF)</li>
<li class="fragment">Присваивание → Связывание</li>
<li class="fragment">Мутации → Иммутабельные структуры данных</li>
<li class="fragment">Инструкции (statements) → Выражения (expressions)</li>
<li class="fragment">Объекты → Модули, замыкания</li>
<li class="fragment">Классы → Типы, хэш-мапы</li>
<li class="fragment"><code>return</code> и множественный возврат → Единичный возврат без return</li>
<li class="fragment">Сайд-эффекты → Управляемые (managed) эффекты</li>
<li class="fragment"><code>null</code>, <code>undefined</code>, <code>NaN</code> → Явная обработка (<code>Maybe</code>/<code>Option</code>)</li>
</ul>
</section>
<section>
<img style="height: 100px" src="img/elm_logo.svg" alt="">
<h4><a target="_blank" href="https://elm-lang.org/">Elm</a></h4>
<p>A delightful language for reliable web applications.</p>
</section>
<section>
<h3>Типы</h3>
<p>Для моделирование предметной области.</p>
</section>
<section>
<h3>Типы</h3>
<p>Пример: да-нет.</p>
<pre data-trim class="elm"><code data-trim data-noescape>
type Bool = True | False
if isReady then go() else stop()
</code></pre>
</section>
<section>
<h3>Типы</h3>
<p>Пример: светофор.</p>
<pre class="elm"><code data-trim data-noescape>
type TrafficLights = Red | Yellow | Green
tlAction tl =
case tl of
Red -> "Stop"
Yellow -> "Prepare"
Green -> "Go"
</code></pre>
</section>
<section>
<h3>Типы</h3>
<p>Пример: загрузка данных</p>
<img src="img/http-request-states.svg" alt="">
<p><small><a href="https://elmprogramming.com/remote-data.html">источник</a></small></p>
</section>
<section>
<h3>Типы</h3>
<p>Пример: загрузка данных</p>
<pre><code data-trim class="elm">
type RemoteData error value
= NotAsked
| Loading
| Failure error
| Success value
</code></pre>
<p><small><a href="http://blog.jenkster.com/2016/06/how-elm-slays-a-ui-antipattern.html">How Elm Slays a UI Antipattern</a></small></p>
</section>
<section>
<h3>Типы</h3>
<p>Пример: загрузка данных</p>
<pre><code class="elm" data-trim>
viewPostsOrError model =
case model.posts of
RemoteData.NotAsked ->
text ""
RemoteData.Loading ->
h3 [] [ text "Loading..." ]
RemoteData.Success posts ->
viewPosts posts
RemoteData.Failure httpError ->
viewError (buildErrorMessage httpError)
</code></pre>
</section>
<section>
<h3>Типы</h3>
<p>Пример: GraphQL</p>
<pre><code class="elm" data-trim>
type alias User =
{ name : Maybe String
, account : Eos.Name
, avatar : Avatar
}
selectionSet =
SelectionSet.succeed User
|> with User.name
|> with User.account
|> with (Avatar.selectionSet User.avatar)
</code></pre>
</section>
<section>
<h3>Типы</h3>
<p>из бэкенда в <a href="https://github.com/klazuka/intellij-elm">IDE у фронтенда</a></p>
<ul>
<li>Экспортируем <a href="https://graphql.org/graphql-js/utilities/#introspection">схему</a> из GraphQl.</li>
<li><a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest">Генерируем</a> из неё Elm-модули.</li>
<li>Теперь компилятор знает, что нужно серверу.</li>
<li>Код получается production ready [почти] без тестов.</li>
</ul>
</section>
<section>
<h3>GraphQL + Elm</h3>
<p>Подробнее в этом докладе.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/memIRXFSNkU"
title="YouTube video player" frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen></iframe>
<p><small>Библиотека <a href="https://package.elm-lang.org/packages/dillonkearns/elm-graphql/latest">elm-graphql</a>.</small>
</p>
</section>
<section>
<h3>Когда пригодится GraphQL?</h3>
<ul>
<li class="fragment">Много источников данных.</li>
<li class="fragment">Много разных клиентов (веб, мобилы, внешнее API, ...).</li>
<li class="fragment">Когда задолбались создавать REST-эндпойнты.</li>
</ul>
</section>
<section>
<h3>Когда уходить от JS?</h3>
<p class="fragment">Когда есть разработчики, которые могут это обосновать.</p>
<p class="fragment">Когда нет уже никаких сил поддерживать кодовую базу на JS.</p>
</section>
<section>
<p>— Что наша жизнь?.. 🤔</p>
<p class="fragment">— Trade-off 🤷🏻♂️</p>
</section>
<section>
<h3>Контрольный вопрос</h3>
<ul>
<li class="fragment">Есть один бэкенд и одна БД.</li>
<li class="fragment">Есть один фронтенд — веб-сайт.</li>
<li class="fragment">На сайте, в основном, формы.</li>
<li class="fragment">Заказчик хочет использовать Elm и GraphQl.</li>
<li class="fragment">Ваши действия?</li>
</ul>
</section>
<section>
<h3>Simple is not Easy</h3>
<div style="display: flex">
<img src="img/taxi.jpg" alt="">
<ul style="margin-left: 4rem; font-size: 85%">
<li>Простое надёжнее лёгкого.</li>
<li>Конкретное надёжнее обобщённого.</li>
<li>Абстракции — хорошо, но в меру.</li>
</ul>
</div>
</section>
<section>
<h3>Чем интересно ФП?</h3>
<div style="display: flex;" class="fragment">
<img src="img/lomonosov.jpg" alt="">
<blockquote>
<p>А функциональное программирование уже затем учить следует, что оно ум в порядок приводит.</p>
<p>— М.В. Ломоносов</p>
</blockquote>
</div>
</section>
<section>
<h3>Почему Elm стоит внимания?</h3>
<ul>
<li class="fragment">Чтобы понять, что значит «не всрато».</li>
<li class="fragment">Разобрать идеи Redux, Vuex и пр. в первоисточнике*.</li>
<li class="fragment">Строгий, но справедливый и дружелюбный компилятор прививает хорошие привычки.</li>
<li class="fragment">Просто и приятно программировать.</li>
</ul>
<p class="fragment"><small>*это всё уже было, только не в вебе</small></p>
</section>
<section>
<blockquote>
<p style="text-align: left; padding: 0 1rem">Лучшие технологии — те, которые экономят время, силы и деньги.
<span style="display: block; text-align: right;">— Капитан</span></p>
<img src="img/kapitan.jpg" alt="">
</blockquote>
</section>
<section>
<h2>Конец</h2>
<p>Спасибо</p>
<ul>
<li><a href="https://amiskov.github.io/keynotes/">amiskov.github.io/keynotes</a></li>
<li><a href="https://elm-lang.org/">elm-lang.org</a></li>
<li><a href="https://graphql.org/">graphql.org</a></li>
</ul>
</section>
</div>
</div>
<script src="../reveal/lib/js/head.min.js"></script>
<script src="../reveal/js/reveal.js"></script>
<script>
// More info https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
transition: 'none', // none/fade/slide/convex/concave/zoom
// More info https://github.com/hakimel/reveal.js#dependencies
dependencies: [
{
src: '../reveal/plugin/highlight/highlight.js', async: true, callback: function () {
hljs.initHighlightingOnLoad();
}
}
]
});
</script>
</body>
</html>