YouTube2Text

Static Types Finally Come to the BEAM | Annette Bieniusa & Guillaume Duboc — Transcript

by BEAM There, Done That · 9,655 words · 1,644 segments · language en · Watch on YouTube

Full transcript

  1. 0:00So, hello. Welcome to the episode of
  2. 0:02Beam There, Done That. I'm your host,
  3. 0:03Alan Wyman. Today, we have, of course,
  4. 0:06my other host, Francesco Cesarini.
  5. 0:09>> Hi, I'm Francesco. I'm also co-host.
  6. 0:11Welcome to the show. Today, we will be
  7. 0:13tackling the question of how we bring
  8. 0:16your static types
  9. 0:17to Erlang and Elixir. It's It's a quest
  10. 0:21which, you know, I tend to joke is
  11. 0:22almost as old as Erlang itself. And
  12. 0:25joining us are Annette Bieniusa and
  13. 0:28Guillaume Duboc. But, you know, before
  14. 0:30introducing me,
  15. 0:31let me go in and give you some some
  16. 0:33background of the topic. You know, when
  17. 0:35I was at the Computer Science Lab, you
  18. 0:36know, back in 1995,
  19. 0:38so, I can't believe it was over 30 years
  20. 0:40ago, I was working on my master thesis.
  21. 0:42Anders Lingren, who you know, studied
  22. 0:43computer science with me at Uppsala
  23. 0:45University, that as part of his thesis
  24. 0:47went in and proposed a soft type system
  25. 0:50you know, for Erlang. Simon Marlow, so,
  26. 0:52the Glasgow Haskell Compiler maintainer,
  27. 0:54was working on his PhD thesis at the
  28. 0:56University of Glasgow together with
  29. 0:59Philip Wadler.
  30. 1:00And they were looking at a subtyping
  31. 1:03based system. And what the system did is
  32. 1:05it trade did ex- expressive power, you
  33. 1:07know, for simplicity. So, they were
  34. 1:10going in and trying to understand, you
  35. 1:12know, how do we get stronger typing in
  36. 1:15in Erlang. Both Anders and you know,
  37. 1:17Simon met at conferences, you know, they
  38. 1:19shared a lot of notes and ideas, what
  39. 1:22worked and what didn't work, but you
  40. 1:24know, what they what what they achieved
  41. 1:27did not go far and and never really made
  42. 1:29it into production. You know, to quote
  43. 1:30Joe Armstrong at the time, you know,
  44. 1:32anyone can write a type system which
  45. 1:34covers 90% of Erlang, but the remaining
  46. 1:3610% is really, really hard. And even the
  47. 1:38brightest mind in computer science and
  48. 1:40here
  49. 1:41he was referring to Phil Wadler have
  50. 1:42struggled. And you know, as a side note,
  51. 1:46this is because of some of the design
  52. 1:47choices they made with the Erlang
  53. 1:49semantics very, very early on. So,
  54. 1:53the the the tension we were wrestling
  55. 1:55with, you know, back then is the same
  56. 1:57tension that we're wrestling with today.
  57. 1:59So, decades might have passed,
  58. 2:01but those challenges and tensions
  59. 2:03continued, you know, with Thomas Arts
  60. 2:05and Joe Armstrong's practical type
  61. 2:06system, you know, Sven Olof Nyström's
  62. 2:08polyvariance of typing, and Kostis
  63. 2:10Sagonas' Dialyzer. Dialyzer was a
  64. 2:13pragmatic compromise that admitted it
  65. 2:16couldn't prove your code was correct,
  66. 2:18but could reliably tell you when
  67. 2:20something was definitely wrong. It seems
  68. 2:22like today, we're reaching an inflection
  69. 2:24point. So, Elixir 1.
  70. 2:272 is is shipping with a gradual type
  71. 2:30with gradual set theoretic type system.
  72. 2:32It's built on the
  73. 2:34on years of research by Guillaume, who's
  74. 2:36on the show with us today.
  75. 2:38And our second guest, Annette, has been
  76. 2:40building, you know, the parallel
  77. 2:41Equalizer project for Erlang with her
  78. 2:44team and collaborators.
  79. 2:46And you know, between them and other
  80. 2:48projects such as WhatsApp Equalizer,
  81. 2:50it genuinely feels like the beam is is
  82. 2:53converging on an answer after nearly 30
  83. 2:56years. And yeah, and that's what we're
  84. 2:57here to dig into today. It's a bit of a
  85. 2:59long introduction,
  86. 3:00but you know, there's a lot of history
  87. 3:02behind us, and it's important to
  88. 3:03understand the history to understand
  89. 3:05where we're heading to. So, Annette,
  90. 3:06Guillaume, why don't you introduce
  91. 3:08yourselves? Welcome to the show.
  92. 3:10>> Hi Francesco. Great to have us, and
  93. 3:12we're very we are very happy to be here.
  94. 3:14Um my name is Annette Vinusa. I'm a
  95. 3:16professor for software technology at the
  96. 3:19uh RPTU in Southwest Germany, um
  97. 3:22university,
  98. 3:23and I've been doing research on
  99. 3:25programming languages, type systems,
  100. 3:27distributed systems for almost two
  101. 3:29decades now, and Erlang and Elixir and
  102. 3:33the beam is uh one of the core aspects
  103. 3:37that we uh that we deal with in our
  104. 3:39research, and we also introduce a lot of
  105. 3:41students to it. So, growing the
  106. 3:42community this way.
  107. 3:44>> Hi Francesco, Helen, uh
  108. 3:47Annette.
  109. 3:47I'm um
  110. 3:49Guillaume Duboc. I'm um
  111. 3:51a PhD currently at Dashbit. I did my PhD
  112. 3:56in Paris at the I Reef, Institute for
  113. 4:00research research in theoretical
  114. 4:03computer science. And I defended it in
  115. 4:06in January of this year. The name title
  116. 4:09is typing dynamic languages with set
  117. 4:12theoretic types the case of Elixir.
  118. 4:14And um
  119. 4:15I've been
  120. 4:17working on
  121. 4:18type systems since my masters. I did my
  122. 4:22internship with Jose Valim Castagna at I
  123. 4:25Reef
  124. 4:26on the theory of set theoretic types.
  125. 4:29So, this uh
  126. 4:30PhD was an
  127. 4:32occasion to apply them to
  128. 4:34real industrial language. And um
  129. 4:38I'm yeah, of course, I'm I'm really
  130. 4:40interested in to
  131. 4:42bringing research to to practice.
  132. 4:44And I was really charmed by this this
  133. 4:47theory of semantics of typing set
  134. 4:49theoretic types. And
  135. 4:50really pleased to really pleased to be
  136. 4:53able to
  137. 4:54to bring it
  138. 4:55into practice.
  139. 4:57>> Now, Guillaume, just to kind of start to
  140. 4:58break the ice and warm you up to the
  141. 5:00podcast. I'm kind of curious, right? I'm
  142. 5:02sure you've programmed before. Do you
  143. 5:04have a have has there ever been a bug
  144. 5:06that you've introduced to a production
  145. 5:08system that no type system would have
  146. 5:10caught?
  147. 5:11>> I I don't really have a crispy personal
  148. 5:14story of a bug, but type systems I'll
  149. 5:16I'll take the question the more general
  150. 5:18answer to that question is that type
  151. 5:20systems they catch a certain given class
  152. 5:24of bugs, but there are other class of
  153. 5:25bugs that they just have nothing to tell
  154. 5:28you about.
  155. 5:29Thinking about in most cases
  156. 5:33non-termination
  157. 5:34errors. Often the property that we can
  158. 5:38say after having typed the program is
  159. 5:40that
  160. 5:41it's not going to crash and you know
  161. 5:44what is the type of value that is going
  162. 5:47to compute, but the
  163. 5:50third second thing is that it may
  164. 5:52diverge, and in that case you cannot say
  165. 5:54anything. So,
  166. 5:57it's a bit of a of a
  167. 6:00an escape, but I've I've I've shipped
  168. 6:03some some program that looked because of
  169. 6:06badly evaluating the
  170. 6:08where where it was going to run out.
  171. 6:11And otherwise, uh
  172. 6:15the the
  173. 6:16to to take the the question more
  174. 6:19seriously, I think it boils down to how
  175. 6:22far you're able or willing to go with
  176. 6:25the complexity of the type system and uh
  177. 6:28amount of work that the programmer is
  178. 6:31going to have to do, because a lot of
  179. 6:34type errors that you don't catch are
  180. 6:35because the type system has limitations
  181. 6:39in the expressivity that uh
  182. 6:42that
  183. 6:43it is able to describe, or either that
  184. 6:46or uh
  185. 6:48uh
  186. 6:48the designers of the type system they
  187. 6:50want you to spend
  188. 6:52a lot of time
  189. 6:54writing a proof about why your uh uh
  190. 6:57functions are correct.
  191. 6:59So, um
  192. 7:01uh
  193. 7:03I would say that
  194. 7:05I don't wish that I had been able at I
  195. 7:08don't wish that I had been given the
  196. 7:10opportunity to prove that my program was
  197. 7:13correct every every time, because that
  198. 7:15that that means sometimes that I would
  199. 7:17have just spent a lot of time proving
  200. 7:20that something is correct when I just
  201. 7:21wanted to scrap up scrap it and do do
  202. 7:24things differently in a more simple way.
  203. 7:27>> Now, Annette,
  204. 7:28what was the first programming language
  205. 7:30with a type system that you know, made
  206. 7:33you either fall in love with or you
  207. 7:35know, have a real maybe disdain for?
  208. 7:37>> So, when I learned programming in in
  209. 7:40high school, we started with type
  210. 7:43languages and even the first university
  211. 7:46courses, you know, it was Java
  212. 7:48and Haskell. It was always kind of clear
  213. 7:50that these languages would have a type
  214. 7:52system and that types were something
  215. 7:54that you need to deal with somehow.
  216. 7:55First time I realized that type systems
  217. 7:57can actually bring something very very
  218. 7:59powerful to the to the table and help me
  219. 8:02refine my programs and make them better
  220. 8:04maintainable and so on was actually a
  221. 8:06master level seminar where I had to
  222. 8:10report on the new addition to Java 1.3,
  223. 8:14namely type variables and parametric
  224. 8:17polymorphism. And there was, you know,
  225. 8:20the wild cards and the the sub sub and
  226. 8:23supertype constraints, I realized that
  227. 8:25type systems can be actually very very
  228. 8:27expressive, but it took me a while to
  229. 8:29wrap my head around it and, yeah, make
  230. 8:31use of this expressivity in a in a good
  231. 8:34way.
  232. 8:34>> Now, coming back to to types, right? I
  233. 8:37want to start from the absolute bottom,
  234. 8:38Anette. If one of our listeners has only
  235. 8:40ever used a dynamic language such as
  236. 8:42Python or Elixir, of course Erlang,
  237. 8:45how do you explain what a type actually
  238. 8:46is to them?
  239. 8:47Uh without using the word class and
  240. 8:48without kind of getting deep and quoting
  241. 8:50what a textbook would say.
  242. 8:52And in in that in going on top of that,
  243. 8:55in Erlang, if you say that a function
  244. 8:58takes an integer,
  245. 8:59what is it actually promising uh when we
  246. 9:01talk about types within what you're
  247. 9:03working on?
  248. 9:04>> So, from my perspective, types
  249. 9:06characterize um values that are um given
  250. 9:10in a in a programming language. And uh
  251. 9:12if I know that some form of value has a
  252. 9:15specific type, I know what I can do with
  253. 9:18this value. So, and
  254. 9:20this this means that when in Elang
  255. 9:22Elixir, I have a function that takes an
  256. 9:24integer, I know that or I hope that the
  257. 9:27function will be well-behaving uh
  258. 9:29whenever I pass an integer to it. And I
  259. 9:31should not assume that it works
  260. 9:32correctly if I would pass a boolean
  261. 9:34value or another function or, you know,
  262. 9:36something of a different type.
  263. 9:39And depending on how the type checking
  264. 9:42is actually done and what the guarantees
  265. 9:44are that a specific type system gives
  266. 9:47you, there are certain things that you
  267. 9:49may assume and that you might not
  268. 9:51assume. So, types, in particular when it
  269. 9:53comes to functions, can be seen as
  270. 9:54contracts. As a
  271. 9:57caller of a function, I can assume a
  272. 10:00specific behavior if I pass the values
  273. 10:03according to the the type specification,
  274. 10:07and I can make assumptions again on the
  275. 10:09values that would be returned.
  276. 10:11>> Erlang and Elixir have always been
  277. 10:12dynamically typed. Java, Rust, Haskell
  278. 10:16are statically typed.
  279. 10:18And people say static catches the bugs
  280. 10:22before your program runs. Can you tell
  281. 10:25us what the difference is between your
  282. 10:27static and dynamic typing and what part
  283. 10:29of the sentence I just mentioned
  284. 10:32basically static catches the bug before
  285. 10:34they run
  286. 10:35is generally true and what part of that
  287. 10:37is oversold?
  288. 10:38>> So, static and dynamic first of all
  289. 10:40refer to the time when the type check
  290. 10:43happens, right? Static means it happens
  291. 10:46before the program gets compiled and
  292. 10:47before it's executed. Dynamic refers to
  293. 10:50type checks that happen at runtime while
  294. 10:53the program is executing. Both Both Both
  295. 10:56approaches catch bugs. For the dynamic,
  296. 10:59it feels different because very often
  297. 11:01the program resorts to aborting the
  298. 11:04execution if uh if the type check kind
  299. 11:06of fails, and most often this is very
  300. 11:08annoying, right? So, you run your
  301. 11:09program and then boom, it it kind of
  302. 11:11crashes and you're wondering what's
  303. 11:12happening and if the reason is where
  304. 11:14type kind of goes goes wrong,
  305. 11:17then that's that's really problematic,
  306. 11:19yeah? So, what you get with static
  307. 11:22typing is the is the bugs that actually
  308. 11:25are the bugs that that you can
  309. 11:26anticipate and yeah, prevent them from
  310. 11:29happening at runtime.
  311. 11:32What type of bugs can be can be checked
  312. 11:34really depends on the type system. So,
  313. 11:37even C that has has aspects of a So, so
  314. 11:41C has aspects of a static type system,
  315. 11:44of course. It doesn't do a lot of
  316. 11:45dynamic checks. Dynamic checks are
  317. 11:48somewhat more expensive, right? If
  318. 11:50you're If you're doing a lot of checks
  319. 11:52while your program is executing, this
  320. 11:53will will slow the program down. If you
  321. 11:56compare this to languages that try to
  322. 11:58provide better guarantees like Java,
  323. 12:01Java would still do checks at run time.
  324. 12:04Like also dynamically check for some
  325. 12:05aspects that it won't wouldn't be able
  326. 12:07to catch
  327. 12:08during during the the compilation phase
  328. 12:11as as part of the as part of the
  329. 12:12compilation phase. So, checks like null
  330. 12:16pointer exceptions are actually to some
  331. 12:18degree can also be considered type
  332. 12:20checks.
  333. 12:21And most languages actually use a mix of
  334. 12:24both. I would I would kind of claim in
  335. 12:26particular those that have static types
  336. 12:29will also make use of the types at run
  337. 12:30at run time somehow.
  338. 12:32>> And a a lot of developers think static
  339. 12:34and strong mean the same thing.
  340. 12:36And they don't. Yeah, can you untangle
  341. 12:38them? Where do Erlang and Elixir
  342. 12:41actually sit on both axes?
  343. 12:43>> With Erlang, right? Erlang is not
  344. 12:46statically typed unless you use an
  345. 12:48external tool like an additional tool
  346. 12:50like Dialyzer, say for example, then you
  347. 12:52don't get specific guarantees at compile
  348. 12:56time
  349. 12:57or prior to execution. It does checks at
  350. 13:00dynamically at at run time.
  351. 13:02Whether you consider the the type system
  352. 13:05strong or weak depends a bit on what
  353. 13:08your expectations are. Erlang actually
  354. 13:10has dynamic type checks and they give
  355. 13:12you some guarantees you can't
  356. 13:14accidentally wreck up your memory.
  357. 13:16>> And then a lot of developers think that
  358. 13:18static and strong mean the same thing
  359. 13:19when actually they don't. Can you
  360. 13:22actually start to kind of describe the
  361. 13:23the differences and maybe the positives
  362. 13:25and negatives of each one?
  363. 13:27>> So, static refers actually just to the
  364. 13:29to the point in time when the type check
  365. 13:31is happening. Whether the type system is
  366. 13:34strong or weak depends on the amount of
  367. 13:37guarantees or the type of guarantees
  368. 13:38that you would get with a with a type
  369. 13:40checker. All right? You can have very
  370. 13:42strong dynamic typing, you can have weak
  371. 13:45static typing, and everything in
  372. 13:46between. So, one thing is not per se
  373. 13:49better than the other. Even strong type
  374. 13:51systems can have aspects that
  375. 13:55make them not nice to use because a
  376. 13:58stronger guarantees typically mean that
  377. 14:00you need to be more careful in how you
  378. 14:02write types and how the types look look
  379. 14:04like. Like, be more precise, for
  380. 14:05example.
  381. 14:06>> Guillaume, the phrase that ties this
  382. 14:08whole episode together is gradual
  383. 14:09typing. You know, what is it?
  384. 14:12And why is it the thing that makes
  385. 14:14typing Elixir possible at all?
  386. 14:17>> I would say that gradual typing
  387. 14:20is allowing
  388. 14:22yourself or allowing the type checker to
  389. 14:25operate with uncertainty about the
  390. 14:28types. This is the dynamic type or any
  391. 14:32unknown that you have. And um in the
  392. 14:36case of Elixir, it's quite important
  393. 14:39because it has been a
  394. 14:41dynamic language, untyped language for
  395. 14:44its uh whole life. So, there are
  396. 14:47entire code bases that exist
  397. 14:50and that needed to work with the new
  398. 14:53system. You cannot just expect that
  399. 14:56those code bases are going to be to have
  400. 14:59to be entirely annotated with a static
  401. 15:02types before being used again after a
  402. 15:05version 1.21 of uh
  403. 15:08of Elixir. And uh so, gradual typing
  404. 15:11allows the type checker to function
  405. 15:13with the knowledge that, well,
  406. 15:16this function here, all that we know
  407. 15:19about it is that when you give it an
  408. 15:22integer,
  409. 15:23it returns you something dynamic.
  410. 15:26Value that you don't know about at
  411. 15:30compile time.
  412. 15:31So, from a very practical point of view,
  413. 15:35this is what makes the
  414. 15:39work possible in in the first place.
  415. 15:43Now, there's
  416. 15:43there's another um
  417. 15:46a theoretical reason why we also want a
  418. 15:49gradual system, which is and it is that
  419. 15:53in the type system that I've designed
  420. 15:55with BP and
  421. 15:56just to say BP and
  422. 15:58with Jose.
  423. 15:59Uh we are treating the functional aspect
  424. 16:03of Elixir. That is we are typing
  425. 16:06functions
  426. 16:08in a very precise way and uh
  427. 16:11case pattern matching
  428. 16:14all of this. And there are some aspects
  429. 16:16that we have not treated, for instance,
  430. 16:19typing the messages that are sent.
  431. 16:21And that means that we need an escape
  432. 16:25hatch when the type system is not going
  433. 16:29to be able to give static types to those
  434. 16:33um
  435. 16:34uh to those to those uh
  436. 16:36expressions. And this this escape hatch
  437. 16:40is baked into a gradual system in in the
  438. 16:43form of a the dynamic type.
  439. 16:45>> Why is Elixir team's version of gradual
  440. 16:48typing different from what TypeScript or
  441. 16:50Python does today?
  442. 16:51>> The difference is that it is part of its
  443. 16:56foundation. To design the type system of
  444. 17:01Elixir,
  445. 17:02uh we started from theory of types that
  446. 17:06are set theoretic,
  447. 17:08uh meaning that you can express union of
  448. 17:12types,
  449. 17:13intersection. An intersection of two
  450. 17:16types is going to be all the values that
  451. 17:18are both that are in both types.
  452. 17:21Negations as well. All the values that
  453. 17:23are not in a given static type. So, if
  454. 17:26you get the type the type not integer is
  455. 17:29every every double value, list value,
  456. 17:32etc. And the dynamic type is also part
  457. 17:36of that structure. If you do the union
  458. 17:39of a dynamic type and static type, what
  459. 17:42you have is a
  460. 17:44gradual type. So, for instance, you have
  461. 17:46the type integer or dynamic boolean.
  462. 17:49That that type is is interesting because
  463. 17:52it tells you how the type checker is
  464. 17:54going to treat that. It's it's going to
  465. 17:56consider that the integer part is a
  466. 17:59static, so it needs to you know, be
  467. 18:01handled by a
  468. 18:04function if if you pass this arg as
  469. 18:06argument to a function, but the dynamic
  470. 18:09boolean part is more is less strict less
  471. 18:14restrictive. So, if the function does
  472. 18:16not handle this boolean part, then the
  473. 18:19program
  474. 18:20may
  475. 18:22may accept this program. That allows
  476. 18:25that allows us to bake a lot of
  477. 18:27flexibility into the type system. And I
  478. 18:30think this is the difference with the
  479. 18:32way that
  480. 18:34TypeScript for instance was built is
  481. 18:37that at first they introduced
  482. 18:40the
  483. 18:41So, I I don't
  484. 18:43they they have they have two dynamic
  485. 18:45types. Uh
  486. 18:47I think it was any. At first they
  487. 18:49introduced any as this dynamic unsafe
  488. 18:53escape hatch. And then they realized
  489. 18:55that because of the way that they
  490. 18:57designed the system around it, it was um
  491. 19:01it was
  492. 19:02too too unsafe and
  493. 19:04disliked by the programmers who wanted a
  494. 19:06way to say, "Okay, I put an escape
  495. 19:08dynamic escape hatch, but I want you to
  496. 19:10remind me that I need to refine it and
  497. 19:13check in and this is why I have to
  498. 19:15introduce the unknown.
  499. 19:17And the the reason is the reason is that
  500. 19:20in those cases
  501. 19:21the dynamic type is
  502. 19:24an extra thing on top of type system and
  503. 19:28it it makes the things a difficult. I
  504. 19:30mean
  505. 19:32at least it it makes the design around
  506. 19:34the how it's going to be used
  507. 19:36non-trivial and
  508. 19:38I think
  509. 19:40that's that's the main difference.
  510. 19:41>> I mean the beam has has been around for
  511. 19:43quite some time, right? Why does it
  512. 19:45actually need a type system at all?
  513. 19:47Guillaume.
  514. 19:48>> The
  515. 19:49in our case the type system is not going
  516. 19:52to improve of on the run time
  517. 19:55cuz it's it's already a fantastic run
  518. 19:57time. What
  519. 20:00the
  520. 20:02what we bring I think to the table is an
  521. 20:05improvement on the process of writing a
  522. 20:09code base or of maintaining a code base.
  523. 20:12Elixir and Erlang scale to users but
  524. 20:16the does the
  525. 20:18code does Erlang and Elixir code scale
  526. 20:21to
  527. 20:23millions of lines of code?
  528. 20:25And
  529. 20:27I think that
  530. 20:28the type system helps helps with this
  531. 20:31this process because it's going to
  532. 20:34enable programmers senior programmers to
  533. 20:39define
  534. 20:40what the code base is about and have
  535. 20:42this
  536. 20:44mechanically checked documentation
  537. 20:47and it's going to improve collaboration
  538. 20:50around the code base. So, I would say
  539. 20:52this is
  540. 20:54there is there is an aspect of
  541. 20:58type system that
  542. 21:00maybe can
  543. 21:02improve the technical the technical
  544. 21:05aspect of the code like
  545. 21:06perhaps improve the quality of the code.
  546. 21:09Perhaps because the type system is going
  547. 21:11to to guide
  548. 21:13programmer towards um
  549. 21:15avoiding some
  550. 21:17some bad patterns or
  551. 21:20making sure that for instance um
  552. 21:24exceptions are completely
  553. 21:26handled in the in the whole code.
  554. 21:29Uh
  555. 21:29but
  556. 21:31like good software that has already been
  557. 21:33written in
  558. 21:35longer is not going to get better.
  559. 21:37However, maybe it's going to help
  560. 21:40writing um
  561. 21:42more of those.
  562. 21:44>> I'd love an X's view here because again,
  563. 21:46Erlang's run telecoms you know for 25
  564. 21:50years without static types. You know,
  565. 21:53we're talking GPRS, 3G, 4G, 5G.
  566. 21:56And Ericsson at Code Beam Stockholm
  567. 21:58announced you know that they're doing
  568. 22:00all of the 6G with Erlang.
  569. 22:03As you can actually work with Erlang,
  570. 22:05you know, you've got pattern matching,
  571. 22:06you've got supervision tree,
  572. 22:08embracing the whole let it crash
  573. 22:09approach, you know, and let it crash
  574. 22:11happens regardless
  575. 22:13of a
  576. 22:15of a type system. So,
  577. 22:18and so without
  578. 22:20static types, you know, the beam shipped
  579. 22:22some of the most reliable software ever
  580. 22:24written. And we're talking a few seconds
  581. 22:25of downtime per year including upgrades
  582. 22:29and maintenance. You know, I want to ask
  583. 22:31you the obvious question I think, what
  584. 22:33problems are we actually solving now
  585. 22:36that we weren't solving in 1995?
  586. 22:39>> So, one of the aspects here is that
  587. 22:42actually type systems catch bugs that
  588. 22:46are due to programmers uh
  589. 22:50and that that are that are introduced by
  590. 22:52programmers, not necessarily by
  591. 22:53situations that occur at runtime.
  592. 22:55So, let's assume you have a bug that
  593. 22:58could have been caught by a type system.
  594. 23:02It might be that you implemented all the
  595. 23:04supervision trees and everything kind of
  596. 23:05correctly. So, when you hit the specific
  597. 23:08path, the specific execution path, then
  598. 23:11your program will, you know,
  599. 23:14make use of the of the of the restart
  600. 23:15and everything, and it won't necessarily
  601. 23:18kind of go down immediately, but you
  602. 23:20have a lot of overhead, and you need to
  603. 23:22kind of keep in mind that you need to
  604. 23:23provide supervision trees, etc., and
  605. 23:26there might be parts in the code where
  606. 23:27this is not necessarily the case. You
  607. 23:29don't want to spawn a new process just
  608. 23:33for executing a function call, making
  609. 23:35sure that if this function call has a
  610. 23:37type error, that you can kind of catch
  611. 23:38it somehow. It's also not totally
  612. 23:40obvious how to deal with this problem at
  613. 23:43runtime, so you would need to kind of
  614. 23:44patch the code and so on. And this is
  615. 23:46all very expensive. And even if a type
  616. 23:49system just catches, say, 5% of all
  617. 23:52issues in your code base that happen
  618. 23:54over the course of of the runtime of a
  619. 23:56system, it's still 5%, right? And this
  620. 23:59directly reflects in in overheads, also
  621. 24:03on on latencies, and better machines
  622. 24:06that you need, and and so on, because
  623. 24:07you need to over-provision for these
  624. 24:09situations. And if it's just a bug that
  625. 24:12a type system could have caught, why not
  626. 24:14use a type system to prevent it?
  627. 24:16>> If you tried to build the type system
  628. 24:18you're building now, so this is for
  629. 24:20Guillaume, in 2005, what would have made
  630. 24:23it impossible
  631. 24:25or just not worth the effort?
  632. 24:27>> I think that
  633. 24:29the
  634. 24:30So,
  635. 24:32the
  636. 24:34immediate difficulty when typing uh
  637. 24:37Erlang
  638. 24:40is that
  639. 24:42because of the way it is structured
  640. 24:45around the pattern matching
  641. 24:47with no no need to
  642. 24:49satisfy a static type checker, you can
  643. 24:53have
  644. 24:54you can freely have a function that
  645. 24:55returns
  646. 24:57an integer or
  647. 24:59a boolean.
  648. 25:00And you don't want to build or rather
  649. 25:04you've not been asked to build special
  650. 25:07type
  651. 25:08that would
  652. 25:09encapsulate that like in the
  653. 25:12ML family of languages
  654. 25:15for instance where you're going to build
  655. 25:17some type saying
  656. 25:19or I can have a constructor with an
  657. 25:22integer under or another constructor
  658. 25:26boolean under.
  659. 25:27And so you need your type system to
  660. 25:30freely represent union of types.
  661. 25:35Integer or boolean.
  662. 25:37So you need
  663. 25:39fully developed type system that that
  664. 25:42has this property.
  665. 25:44Another thing is that because you have
  666. 25:47functions that
  667. 25:49are able to return those
  668. 25:51completely different
  669. 25:53type of values. Now it's possible that
  670. 25:56you're going to do overloading and that
  671. 25:58you're going to expect your function
  672. 26:00to return an integer when given an
  673. 26:03integer and return a boolean when given
  674. 26:05a boolean.
  675. 26:06And that's why you need overloading
  676. 26:09function overloading.
  677. 26:11And you want to bake it into your type
  678. 26:13theory as well because you want
  679. 26:14something that is that is
  680. 26:17that follows closely the the semantic of
  681. 26:20the language and the
  682. 26:22around the 2005 the
  683. 26:25there was the
  684. 26:26thesis of Anna Frisch on the
  685. 26:29on the CDuce which showed that you could
  686. 26:32do this in in a language have a
  687. 26:36function overloading via intersection
  688. 26:38types and the
  689. 26:40union of types
  690. 26:42and the
  691. 26:44other other very precise features. The
  692. 26:47theory called the semantics of typing
  693. 26:48but this theory was
  694. 26:51still missing a lot of things that were
  695. 26:53developed 10 years after. That is
  696. 26:56polymorphism.
  697. 26:58Being able to do
  698. 27:00parametric polymorphism
  699. 27:02in
  700. 27:03context in the context of sub 30 types
  701. 27:06was in
  702. 27:072015.
  703. 27:08And then the ability to integrate
  704. 27:12dynamic into that was from
  705. 27:162019.
  706. 27:18So the
  707. 27:21if you wanted to um
  708. 27:24have a theory that
  709. 27:26easily expresses those um
  710. 27:28those um
  711. 27:30free patterns that those
  712. 27:32this very free way of programming that
  713. 27:34Aaron uses, you couldn't use
  714. 27:38sub 30 types in 2005. So you would have
  715. 27:41to do some very complex
  716. 27:45inference, some so some very complex
  717. 27:49constraint solving. But the way that you
  718. 27:52present this to the programmer would
  719. 27:54maybe a bit difficult because
  720. 27:57I think that there are two
  721. 27:59there are two aspects to type system.
  722. 28:02There's the aspect is the type system
  723. 28:05able to
  724. 28:07represent
  725. 28:08all the types that you need. Like is its
  726. 28:11model
  727. 28:13complex enough?
  728. 28:15And is the type system
  729. 28:17adapted to
  730. 28:20the way the programmer thinks about the
  731. 28:23language. And then is the type system or
  732. 28:26maybe the type language sufficiently
  733. 28:30Is it is it easy to understand, right?
  734. 28:33And
  735. 28:34I think those are This is what the
  736. 28:37sub 30 types bring to the table there.
  737. 28:39Is that we have both way to technically
  738. 28:41solve the challenge and we have a way to
  739. 28:43present them
  740. 28:44in
  741. 28:45in an interesting
  742. 28:47in
  743. 28:48a sufficiently easy way for the
  744. 28:50programmers.
  745. 28:50>> And
  746. 28:51you were workshop chair when I believe
  747. 28:54this is pronounced Kostis Sagontas gave
  748. 28:56his 15 years of dialyzing retrospective.
  749. 28:59Now dialyzer has been a very good
  750. 29:01practical answer when we don't have
  751. 29:03types, right? That it can kind of run
  752. 29:04through and see if there's any kinds of
  753. 29:06type issues. I mean, it's it's really
  754. 29:08great. It's probably underutilized in
  755. 29:10terms of not many people using Elixir at
  756. 29:12least are using it. Even people who are
  757. 29:14using Erlang are probably I mean
  758. 29:15definitely not all using it. And it's
  759. 29:17air messages are
  760. 29:18you know, infamous in being very very
  761. 29:20cryptic. Do you think that dialyzer was
  762. 29:23definitely a great step forward in in
  763. 29:25working with a type system and in kind
  764. 29:27of like a good base to to to work at?
  765. 29:29Have you used it when you're working on
  766. 29:31the Elixir project? Or what do you kind
  767. 29:33of feel about the about dialyzer?
  768. 29:35>> I typically like to use use dialyzer in
  769. 29:39my projects and we always tell the
  770. 29:41students also to use dialyzer in their
  771. 29:42project projects. There is a catch with
  772. 29:45dialyzer. So from my experience, if you
  773. 29:48use it without knowing what it provides,
  774. 29:52um you get sometimes too high
  775. 29:53expectations. So being used to static
  776. 29:57types um in the in the way that say Java
  777. 30:00for example provides them, there is a
  778. 30:02certain class of type errors that I
  779. 30:03would expect a tool like dialyzer to
  780. 30:05catch, but just because dialyzer um has
  781. 30:08this specific approach of success
  782. 30:10typing, it will not flag these issues.
  783. 30:13So this is where people very often get
  784. 30:15get confused. Dialyzer did one decision
  785. 30:20very great, namely reducing the amount
  786. 30:23of false positives to zero. So when
  787. 30:26dialyzer is complaining, you can be
  788. 30:28pretty sure that actually there is
  789. 30:30something wrong with the code. It's not
  790. 30:32so easy to to debug once in a while if
  791. 30:34you get like several lines of debug
  792. 30:36output and need to compare very long
  793. 30:39type annotations or or type types for
  794. 30:42for function say to figure out in which
  795. 30:44of the parameter which option is
  796. 30:47actually the wrong one. There's been a
  797. 30:48lot of very nice work from the community
  798. 30:51and from the OTP team to highlight
  799. 30:53things and and make this more
  800. 30:54approachable. So this this is this is
  801. 30:56great. Then as the error messages are
  802. 30:59going into the right direction.
  803. 31:01If we can keep the idea of success
  804. 31:03typing only flagging not
  805. 31:05not flagging false positives, then we
  806. 31:07learn something from Dialyzer.
  807. 31:09>> From the Elixir side, is the new type
  808. 31:10system replacing like Dialyzer's
  809. 31:12philosophy or building on top of it? And
  810. 31:14also, where do success typing and
  811. 31:17gradual set theoretic typing actually
  812. 31:19agree and where do they actually start
  813. 31:20to diverge?
  814. 31:21>> Yeah, the Elixir type system is a
  815. 31:23replacement to Dialyzer. I would say
  816. 31:26that previously I was saying there are
  817. 31:28two aspects to type system. One is the
  818. 31:32technical ability of the system to find
  819. 31:34the bugs,
  820. 31:36all right. And
  821. 31:37Dialyzer does that
  822. 31:39very well. And
  823. 31:41this is
  824. 31:43something that
  825. 31:44we've we've done as well and I think we
  826. 31:47are on on par with the Dialyzer in in
  827. 31:49terms of bug finding.
  828. 31:51But the second aspect is the type
  829. 31:54language and the ability for the
  830. 31:55programmer to direct the
  831. 31:59the type the the type checker to to
  832. 32:03for the programmer to specify contracts
  833. 32:05on top of functions and for those
  834. 32:08contracts to be enforced in a strict
  835. 32:10way. And this is this is where Dialyzer
  836. 32:12is is not uh
  837. 32:16as a convenient as a as a normal type
  838. 32:18system because the way it has been
  839. 32:20designed is that it
  840. 32:23it sits in the middle of
  841. 32:25of
  842. 32:26of the programs and it builds this
  843. 32:29graph of
  844. 32:32dependency between between all the
  845. 32:34variables and then it looks at all the
  846. 32:36checks, the checks
  847. 32:38that are giving some type information
  848. 32:41like is integer is going to make
  849. 32:43variable integer and then it goes to
  850. 32:45look for in consti- inconsistencies
  851. 32:48between those.
  852. 32:50And
  853. 32:51with the
  854. 32:53with the system that we have designed,
  855. 32:55we are able to have
  856. 32:57also a top-down approach led by
  857. 33:00programmers that when they write a
  858. 33:02contract integer to integer on top of
  859. 33:04their function
  860. 33:06this this the body of this function is
  861. 33:09going to be um
  862. 33:11the type checker is going to go through
  863. 33:12it with the assumption that arguments
  864. 33:14are integers and it's going to enforce
  865. 33:17this
  866. 33:18in a more strict way. So, in in terms of
  867. 33:21um
  868. 33:22user of the design, it's um
  869. 33:25it's quite
  870. 33:27quite different.
  871. 33:28Uh
  872. 33:29I'd say that the the ability of Dialyzer
  873. 33:33to find bugs is something we've we've
  874. 33:36wanted to conserve. That
  875. 33:39and uh
  876. 33:41so, right now we haven't added the
  877. 33:44type annotations on top of functions, so
  878. 33:46we've been working on this type system
  879. 33:49in
  880. 33:51uh complete inference mode or dynamic
  881. 33:54mode.
  882. 33:55And
  883. 33:57so, that means that we've not we've not
  884. 34:00really allowed the type checker to
  885. 34:03reject programs uh instead we've made it
  886. 34:06give give out type warnings.
  887. 34:09And those type warnings they're
  888. 34:12the philosophy of
  889. 34:14of the current type warnings is that
  890. 34:16when you get a warning, 90% of the times
  891. 34:18it is because there is a bug that is
  892. 34:20definitely going to happen. In in the
  893. 34:23same same way that Dialyzer does. Um but
  894. 34:26yeah, in in the future we want to also
  895. 34:28have the the ability to for the type
  896. 34:32checker to say, well, this program
  897. 34:34doesn't uh compile or
  898. 34:36well, because you told me about its type
  899. 34:39and and those types are not are not
  900. 34:42working out.
  901. 34:42>> Anette, you've worked on CRDTs, you've
  902. 34:46worked actually we've worked on CRDTs
  903. 34:48together, you've worked on replication
  904. 34:50in distributed systems, formal
  905. 34:51verifications. Types are just one tool
  906. 34:54in your toolbox, not the whole answer,
  907. 34:56you know, so taking a step back from
  908. 34:58that broader vantage point,
  909. 35:01where do types sit in in this stack of
  910. 35:03things which make the beam software
  911. 35:06trust trustworthy, you know, are they a
  912. 35:08floor of a taller building or are they
  913. 35:10actually the foundation of that
  914. 35:11building? Doing much more than what it's
  915. 35:14daily users actually realize.
  916. 35:17>> I think there are two aspects to that.
  917. 35:18So, first of all,
  918. 35:21types help sometimes to restrict
  919. 35:24behaviors. So, if we assume for example
  920. 35:26that a function is only supposed to be
  921. 35:28working correctly if an integer is
  922. 35:29passed, then that's an assumption we can
  923. 35:31make and we can build arguments and
  924. 35:34verification tool chains based on these
  925. 35:37type of, yeah,
  926. 35:39guarantees that we get.
  927. 35:41So, my personal take is that we probably
  928. 35:45with with having with having the ability
  929. 35:47to type things, we will enable future
  930. 35:51verification works that can then build
  931. 35:54on top of that. And then there's a
  932. 35:56second aspect, namely that types are
  933. 35:58really not just for the programmer and
  934. 36:00for the documentation and so on, but
  935. 36:02they also have an effect on the runtime.
  936. 36:06Right now, the type annotations, if I if
  937. 36:09I recall correctly, that programmers add
  938. 36:12to their Erlang code will not and also
  939. 36:16for for the Elixir code, as far as I
  940. 36:17know, will not have influence on the on
  941. 36:20the execution engine, but in certain
  942. 36:23parts of the execution engine, types are
  943. 36:26actually derived and assumed to enable
  944. 36:29certain optimizations. So, these runtime
  945. 36:33optimizations could be done at a much
  946. 36:35more greater level if static type
  947. 36:38information was available because then
  948. 36:40we can kind of propagate this
  949. 36:41information from the code into the into
  950. 36:43the compiled version and then the
  951. 36:45runtime can make use of it, for example,
  952. 36:47when allocating space for things or when
  953. 36:50trying to parallelize things and so on.
  954. 36:51So, they might enable more than the
  955. 36:54community assumes.
  956. 36:57>> Uh Jose
  957. 36:58said it plainly at his Elixir Conf
  958. 37:00Europe talk in Malaga, the type systems
  959. 37:03do not mean error-free.
  960. 37:05But there's a real risk here. Developers
  961. 37:07see static types appearing their
  962. 37:09language, they get lulled into a false
  963. 37:11sense of confidence.
  964. 37:13They start writing less defensive code,
  965. 37:15fewer supervision trees, and less
  966. 37:18paranoia about failure. Even scarier,
  967. 37:21no recovery strategy. You know, these
  968. 37:24are the very things
  969. 37:26that make the programming model in the
  970. 37:28being reliable in the first place. Is
  971. 37:30there a concern that this could quietly
  972. 37:33erode? You know, how do you guard
  973. 37:35against that culturally and not just
  974. 37:38technically?
  975. 37:39>> I guess the fear is that programmers
  976. 37:41will start um
  977. 37:42writing a thousand line PRs and um
  978. 37:46uh accept that because it type checks
  979. 37:48that they can just send it or merge it
  980. 37:51and that but that's also the what what
  981. 37:54you want from a uh good good type
  982. 37:56system. You know, this sense of
  983. 37:58confidence that
  984. 37:59all the
  985. 38:01all the obvious errors have been have
  986. 38:03been tackled. But
  987. 38:05I think that
  988. 38:07this problem is
  989. 38:09in in in
  990. 38:11in the case of Elixir and Erlang,
  991. 38:13supervision trees, the the let it crash
  992. 38:16uh philosophy, and and all those
  993. 38:18recovery strategies that make give this
  994. 38:21fantastic up time. They they are not
  995. 38:24here to guard against type errors
  996. 38:27really. They are here to guard against
  997. 38:29the
  998. 38:30uh different kind of errors like
  999. 38:34conflicts or
  1000. 38:36synchronization problems and um
  1001. 38:39static types are are not going to
  1002. 38:43are not going to make uh
  1003. 38:45people get rid of these.
  1004. 38:47I don't think so. So,
  1005. 38:49I think per- perhaps it does not It's
  1006. 38:51not the biggest
  1007. 38:52the biggest danger there.
  1008. 38:54>> We've basically established why, you
  1009. 38:56know, this this can this why this work
  1010. 38:58matters, what it's not trying to do, of
  1011. 39:01course, what it's trying to do, but
  1012. 39:03let's actually get into the the system
  1013. 39:04that Guillaume and and his team is
  1014. 39:06working on. What does it look like when
  1015. 39:08it does work and where do you see like a
  1016. 39:10lot of the strain when it's starting to
  1017. 39:13work?
  1018. 39:14>> When the type system starts working,
  1019. 39:17you gain a level of control on your code
  1020. 39:21which is
  1021. 39:23very satisfying but but also has
  1022. 39:27practical benefits because uh
  1023. 39:30you become able to enforce those complex
  1024. 39:33contracts over your code
  1025. 39:35and
  1026. 39:37it's going to um
  1027. 39:39enable you to have uh uh
  1028. 39:42for instance longer factoring, to have
  1029. 39:45this this this power at your
  1030. 39:47the tip of your fingers
  1031. 39:49to know that actually you've
  1032. 39:51successfully mutated the way a function
  1033. 39:55call or function
  1034. 39:58of
  1035. 39:59of the logic of your program was working
  1036. 40:01and
  1037. 40:03that's uh
  1038. 40:05that's on top of finding obvious bugs,
  1039. 40:07right?
  1040. 40:09Time where this can become
  1041. 40:12a bit difficult is Uh,
  1042. 40:15when the type system is not able to find
  1043. 40:19uh
  1044. 40:20why
  1045. 40:21your program is
  1046. 40:23actually correct. In a gradual
  1047. 40:26type system, this is
  1048. 40:28this is
  1049. 40:29this is a problem. Or rather,
  1050. 40:31when you're retrofitting a type system
  1051. 40:33on top of dynamic language, it's um
  1052. 40:36it's a danger because
  1053. 40:38you're going to write, you know, good
  1054. 40:40annotation on top of your function and
  1055. 40:43uh unfortunately, the type system does
  1056. 40:45not manage to find that in one branch of
  1057. 40:49your program, one of your variables
  1058. 40:52has a type integer instead and instead
  1059. 40:55it thinks it has still has type integer
  1060. 40:57or boolean.
  1061. 40:59And so then you apply this you do I
  1062. 41:02don't know plus one on this and it gives
  1063. 41:04you a
  1064. 41:06a warning. So this is the lack of
  1065. 41:09precision of the system is that's why
  1066. 41:12it's extremely important in what we're
  1067. 41:15doing.
  1068. 41:16Uh, because um
  1069. 41:19if if this happens,
  1070. 41:21then this means that
  1071. 41:24the programmer
  1072. 41:25is going to have to relax the safety
  1073. 41:29that
  1074. 41:29is expected of this function. For
  1075. 41:32instance, you can wrap the input of your
  1076. 41:35function in a dynamic. So you say
  1077. 41:38okay, I was a
  1078. 41:41uh writing the annotation that
  1079. 41:44my function receives an integer or
  1080. 41:46boolean and then does whatever. Instead,
  1081. 41:49they can wrap it and say this is
  1082. 41:52dynamic integer or boolean. Uh,
  1083. 41:56both of those are dynamic. And this is
  1084. 41:58going to relax the the system. So that
  1085. 42:00now if this input is used as a list, you
  1086. 42:03get an error, but
  1087. 42:05now if it's used
  1088. 42:07only as an
  1089. 42:09as an integer, then uh
  1090. 42:11the system is going to load this because
  1091. 42:14it sees that it could be an integer at
  1092. 42:16some point.
  1093. 42:17So,
  1094. 42:18I think when you start having to play
  1095. 42:21with the
  1096. 42:23limits of what the type system can
  1097. 42:26express, this this is the difficulty.
  1098. 42:28And
  1099. 42:29in that case, um
  1100. 42:31we're going to have to either provide
  1101. 42:34clear warnings explaining, "Oh, well,
  1102. 42:38this is a known um
  1103. 42:40limitation of the system. You could
  1104. 42:42perhaps try to
  1105. 42:44rewrite this in this way, rewrite it in
  1106. 42:46that way." But
  1107. 42:48it's it's not obvious that we can think
  1108. 42:50of all the possible cases in which this
  1109. 42:52could fail. And otherwise, this is the
  1110. 42:55reason why the the the way the type
  1111. 42:57system works has to be uh well explained
  1112. 43:00and understood by the programmer so that
  1113. 43:03they can they can understand what's
  1114. 43:05going wrong in a given situation. And it
  1115. 43:08is better that
  1116. 43:10the system is easy to understand so that
  1117. 43:12they can think, "Oh, well, the system
  1118. 43:15works that way and that way, so in this
  1119. 43:16case it's not it's not going to be able
  1120. 43:18to type my
  1121. 43:20program, so
  1122. 43:22I'm going to have to do it another way
  1123. 43:24because
  1124. 43:25because because of those those reasons.
  1125. 43:28I I hope we've minimized those those
  1126. 43:30instances, but they're they're going to
  1127. 43:32they're going to exist."
  1128. 43:33>> I'd like to go over one of the examples
  1129. 43:35that Jose uses used in his talk before.
  1130. 43:38It's a very simple function, basically
  1131. 43:39it it's
  1132. 43:40a function that takes in a string that
  1133. 43:42splits on commas and then, you know,
  1134. 43:44have basically a list with, you know,
  1135. 43:46different size strings.
  1136. 43:48And it returns the the largest string of
  1137. 43:51those.
  1138. 43:52Now,
  1139. 43:53can we talk a little bit more about
  1140. 43:54about this with regards to the type
  1141. 43:55system? Because if you think about it,
  1142. 43:57what happens when you pass in an empty
  1143. 43:58list? What happens when you pass in,
  1144. 44:00you know, like a string that doesn't
  1145. 44:02have any commas? If you just pass in,
  1146. 44:03you know, something that does have lots
  1147. 44:05of commas, but maybe like nothing in
  1148. 44:06between. How would the type system kind
  1149. 44:09of help with this problem or
  1150. 44:11do we have to kind of use your you
  1151. 44:12talked about kind of like an escape
  1152. 44:13hatch with dynamic, right? Would we need
  1153. 44:15to rely on something like that?
  1154. 44:17>> When it comes to very precise behavior,
  1155. 44:21I don't know, for instance, imagine a
  1156. 44:23program that works all lists except
  1157. 44:26lists of size three.
  1158. 44:29Uh and in that case it's going to crash.
  1159. 44:32Well, there there are two two ways.
  1160. 44:34Either you want your type system to be
  1161. 44:37able to do this precise reasoning about
  1162. 44:39the size of lists or you don't. And if
  1163. 44:42you don't, then an easy way is that
  1164. 44:46indeed you're going to work with dynamic
  1165. 44:48lists.
  1166. 44:49And all you're going to want from your
  1167. 44:51type system is that you want it to check
  1168. 44:53that, okay,
  1169. 44:55I'm passing a list through my programs
  1170. 44:57and not a
  1171. 44:58tuple or and not a
  1172. 45:01uh
  1173. 45:02some not a
  1174. 45:04struct
  1175. 45:05And that's what you're expecting from
  1176. 45:07your type system. You're
  1177. 45:09You're not expecting your system to
  1178. 45:10count the size of lists for you and uh
  1179. 45:13uh
  1180. 45:14you're not you're not expecting it to do
  1181. 45:16all of this. And if you actually do want
  1182. 45:20the type system to handle these kind of
  1183. 45:22things, then sometimes it can mean that
  1184. 45:25you're going to have to do a lot of lot
  1185. 45:27of work. It's not necessarily that we
  1186. 45:30can't express those things. We can
  1187. 45:32actually uh
  1188. 45:34in the theory of dependent types express
  1189. 45:36a
  1190. 45:38list of a given size
  1191. 45:40or
  1192. 45:42you know, express
  1193. 45:44very precise integers uh
  1194. 45:46the the the type of integers uh
  1195. 45:49that are between two and five.
  1196. 45:51Uh but the thing is that if you have
  1197. 45:54this precision and you want to use it,
  1198. 45:56then
  1199. 45:58uh you
  1200. 45:59you're starting not to write types,
  1201. 46:01you're starting to write
  1202. 46:03equations. Like you want to ensure that
  1203. 46:07after this plus operation then your
  1204. 46:10function is going to indeed have the the
  1205. 46:12list of size of three and the
  1206. 46:15type checker can help you but
  1207. 46:18I think it stops at some point when you
  1208. 46:21think that perhaps if you're doing this
  1209. 46:24very precise thing you're not writing
  1210. 46:27it's not
  1211. 46:29it's not something that's important to
  1212. 46:31the to the core logic of your program.
  1213. 46:33>> Jose's talk laid out an argument that I
  1214. 46:35want to test with both of you you know
  1215. 46:37simple type systems are easy easy to
  1216. 46:40learn
  1217. 46:41easy to write signatures for they're
  1218. 46:43fast to compile
  1219. 46:45but they force you to push invariants to
  1220. 46:48run time. Expressive type systems will
  1221. 46:50catch more but the signatures explode in
  1222. 46:53complexity error messages get worse and
  1223. 46:56compile time suffer. He called it an
  1224. 46:59inherent trade-off with no silver
  1225. 47:01bullet. Dio, where did the Elixir team
  1226. 47:04choose to sit on that spectrum and what
  1227. 47:07and what made that the right point you
  1228. 47:10have the right approach?
  1229. 47:12>> I think that um
  1230. 47:14the the big challenge in this work is
  1231. 47:17that we're trying to answer the question
  1232. 47:19is
  1233. 47:21is a type system based on semantics of
  1234. 47:23typing set the types or
  1235. 47:27which is founded on that theory is it
  1236. 47:30correct is it the right point in the
  1237. 47:33design space for for programmers?
  1238. 47:36And
  1239. 47:37this is the the exact thing that is is a
  1240. 47:40danger is that
  1241. 47:42we are so precise that um
  1242. 47:44the errors that are given or the
  1243. 47:48the types that are inferred for
  1244. 47:49functions
  1245. 47:51they become too hard to handle. And I
  1246. 47:53think we are sitting right at the
  1247. 47:56at the
  1248. 47:58right at the point where it it's it's
  1249. 48:01good to understand. It's easy to
  1250. 48:02understand. I think the notion that
  1251. 48:05a type is either one or the other or
  1252. 48:08both
  1253. 48:10is
  1254. 48:11is enough to present.
  1255. 48:12And in order to reduce the complexity
  1256. 48:15we've made some
  1257. 48:16choices to limit
  1258. 48:19representation of types.
  1259. 48:22Those are choices that have been done
  1260. 48:24for now. So they could
  1261. 48:26potentially be changed. But for
  1262. 48:28instance, we're we're not having a
  1263. 48:30precise singleton integers
  1264. 48:33because then you could express
  1265. 48:35union of the integers between minus 10
  1266. 48:38and minus five and
  1267. 48:40five and 15 and have this whole
  1268. 48:43machinery on on
  1269. 48:45integers.
  1270. 48:46And this may be not
  1271. 48:49part of the language that
  1272. 48:53that is required. You have we have atom
  1273. 48:56singletons. So they are able to express
  1274. 48:58the
  1275. 48:59the way in which Elixir really uses
  1276. 49:01those a lot to to have tagged tuples.
  1277. 49:04So we we're trying to find
  1278. 49:06the correct
  1279. 49:09the simple enough place where we can we
  1280. 49:11can say that the
  1281. 49:13the system is both precise and still
  1282. 49:15understandable by programmers. But this
  1283. 49:17is a this is a constant effort, I think.
  1284. 49:20There are some bug
  1285. 49:22There there have been some bug
  1286. 49:24bugs reported as issues in the
  1287. 49:27in the type check in the in the compiler
  1288. 49:29before that where it was just a giant
  1289. 49:32union
  1290. 49:34this was
  1291. 49:36because we weren't
  1292. 49:37simplifying of course, but
  1293. 49:40seeing the type checker produce a giant
  1294. 49:43giant type is is a
  1295. 49:45is
  1296. 49:47one of my personal fears, I would say.
  1297. 49:49>> And you're building Dialyzer on
  1298. 49:53for Erlang on the same theoretical
  1299. 49:54foundation, but with different design
  1300. 49:57priorities. Do you land at the same
  1301. 49:59point on that spectrum or or somewhere
  1302. 50:01different? And if different, why?
  1303. 50:03>> We land at a slightly related point, but
  1304. 50:05not exactly the same point. When
  1305. 50:08designing Etilizer, we made a very
  1306. 50:10conscious decision to keep the type
  1307. 50:13specs as Erlang code and also Elixir
  1308. 50:16code and still has, right? So, our
  1309. 50:19assumption was that programmers can use
  1310. 50:22with the type language with the type
  1311. 50:25specification annotations that come with
  1312. 50:27the Erlang standard. That these are the
  1313. 50:29tools that allow them already nowadays
  1314. 50:32to express what their functions, for
  1315. 50:34example, are supposed to do. And we
  1316. 50:37didn't want to have too many moving
  1317. 50:38parts, so this was kind of the
  1318. 50:39assumptions. Let's try to take code with
  1319. 50:42its type annotations as it is and see
  1320. 50:43how far we get. It turned out that
  1321. 50:45unions, intersections are pretty
  1322. 50:48important,
  1323. 50:49but even numbers, like the the union uh
  1324. 50:52the singleton types that Jim just
  1325. 50:53mentioned, um do occur. So, like in the
  1326. 50:56standard library, there are, I think, um
  1327. 51:00something like a couple of hundred
  1328. 51:02annotations where we rely on these
  1329. 51:05singleton types. And the question is, do
  1330. 51:07we want to uh deviate from that or not?
  1331. 51:10Our decision was uh was to stay with it.
  1332. 51:13Um other than that, the set theoretic
  1333. 51:14types turned out to be, I think, the the
  1334. 51:16the right theoretic foundation for
  1335. 51:19approaching this type checking for the
  1336. 51:21beam languages.
  1337. 51:22>> Both type checkers have gradual typing
  1338. 51:24on top.
  1339. 51:25Why does set theoretic typing buy you
  1340. 51:29You know, what what what does set
  1341. 51:30theoretic typing buy you
  1342. 51:33that you couldn't have gotten here from
  1343. 51:35a more traditional type system?
  1344. 51:37>> So, for me, it's really this this
  1345. 51:38combination of these different this
  1346. 51:40different expressiveness that you get
  1347. 51:42with union type, with intersection
  1348. 51:44types, and also with singleton types for
  1349. 51:46for example for the atoms. Gradual
  1350. 51:48typing is as as Guillaume mentioned is
  1351. 51:51is required to help
  1352. 51:54programmers and not require them to
  1353. 51:57annotate every single line or every
  1354. 52:00single function in a module with a type
  1355. 52:02and be overly precise when it's not
  1356. 52:05needed, right? So, gradual typing is is
  1357. 52:08for practical reasons I think
  1358. 52:09unavoidable. The combination of
  1359. 52:11different aspects that you can have with
  1360. 52:13set theoretic types makes makes them
  1361. 52:15very, very powerful and they're also
  1362. 52:16good mental model for describing values
  1363. 52:19in the language.
  1364. 52:20>> Intersection and unions they are the
  1365. 52:21user-facing types, but there is also
  1366. 52:24differences
  1367. 52:26that are
  1368. 52:28expressible using set theoretic types
  1369. 52:30and they have
  1370. 52:31particularly important value on the
  1371. 52:33technical aspect of
  1372. 52:36checking programs because they allow you
  1373. 52:38to precisely analyze pattern matching.
  1374. 52:42So, you have different clauses and they
  1375. 52:45do pattern matching and uh
  1376. 52:47you're able to compute the type of the
  1377. 52:50first clause and in the second clause,
  1378. 52:53you know that the type of values that
  1379. 52:55enter this second clause, it's all the
  1380. 52:57ones accepted by the pattern minus the
  1381. 53:00ones accepted by the first clause. And
  1382. 53:04this difference we're able to express it
  1383. 53:06at the type level and this
  1384. 53:09this gives us a lot of precision. It
  1385. 53:11allows us to give exhaustiveness
  1386. 53:13exhaustivity warning or it allows us to
  1387. 53:16detect branches that are never going to
  1388. 53:17run because all the values were already
  1389. 53:20caught by previous clauses. And so it is
  1390. 53:23not necessarily
  1391. 53:25very present in annotations although
  1392. 53:28although it can it can definitely, but
  1393. 53:30from the technical
  1394. 53:31point of thing it's it's really
  1395. 53:33important
  1396. 53:34and uh
  1397. 53:35it's I think it's uh
  1398. 53:38also one of the less uh,
  1399. 53:41it's something that does not exist in
  1400. 53:44other languages that have introduced
  1401. 53:46ways to do unions and sometimes
  1402. 53:49intersections in in in a bit of an ad
  1403. 53:52hoc way.
  1404. 53:53>> So, you both mentioned process
  1405. 53:55boundaries as one of the hard problems.
  1406. 53:57And and that's where I want to take the
  1407. 53:58conversation next that's where Alan and
  1408. 54:00I want to take the conversation next
  1409. 54:02because the Beam's whole identity is
  1410. 54:04built on process and message passing.
  1411. 54:07And and and that yeah I suspect that is
  1412. 54:09your territory.
  1413. 54:11>> Everything we've talked about so far
  1414. 54:13happens inside of a single process. Now,
  1415. 54:15the moment that a message crosses a
  1416. 54:16process boundary or worse a network
  1417. 54:19boundary to another node, what changes
  1418. 54:21for the type system and what does it
  1419. 54:23stop being able to to tell you?
  1420. 54:26>> So, this is for us typically the the
  1421. 54:28boundary where you have to switch or
  1422. 54:31where you typically would switch to
  1423. 54:32dynamic because you don't exactly know
  1424. 54:34what type of message to expect. There
  1425. 54:36are type there are type systems that
  1426. 54:38deal with these aspects that try to
  1427. 54:41approach typing of
  1428. 54:46line of work on on mailbox types that
  1429. 54:48one of our students here is is is
  1430. 54:50looking at. There are session types that
  1431. 54:52help in dealing with understanding what
  1432. 54:54type of messages are passed between
  1433. 54:56processes in as part of a of a protocol.
  1434. 54:59We started integrating some of the these
  1435. 55:03ideas so kind of a poor man's approach
  1436. 55:05for mailbox types if you want to wanted
  1437. 55:07to say so. This is ongoing work and we
  1438. 55:09are able to kind of make some progress
  1439. 55:12on that but there are inherently some
  1440. 55:15some limitations. Yeah, so if if your if
  1441. 55:17your message can deal sorry if your
  1442. 55:20receive can deal with a lot of different
  1443. 55:21type of messages and you don't know what
  1444. 55:24you get, you lose preciseness at some
  1445. 55:26point.
  1446. 55:27>> Let's set aside what's pragmatic to ship
  1447. 55:29this year. You know, 10 years out, what
  1448. 55:31do you personally hope the Beam looks
  1449. 55:32like? So, effect session types,
  1450. 55:35dependent types, you know, deeper
  1451. 55:37verification or something new you which
  1452. 55:40has not been named yet.
  1453. 55:43Which of these if any do you actually
  1454. 55:45expect to arrive?
  1455. 55:46So let's start with Annette first.
  1456. 55:48>> My personal guess is that we will see
  1457. 55:50more work towards deeper verification
  1458. 55:53approaches just because generating code
  1459. 55:58becomes much simpler. We can have a
  1460. 56:00large number of modules you know
  1461. 56:02generated without completely
  1462. 56:03understanding what they do. So
  1463. 56:06programmer supporting programmers in
  1464. 56:08getting confident about their code is I
  1465. 56:11think the the most important thing that
  1466. 56:13we need to address in programming
  1467. 56:15languages in the in the next couple of
  1468. 56:17years and verification is in its very
  1469. 56:20many different forms
  1470. 56:22will be exactly this. If we have good
  1471. 56:24tools that help us verify behavior, we
  1472. 56:27can be sure that the code actually does
  1473. 56:31accordingly.
  1474. 56:32>> My [snorts]
  1475. 56:33answer is similar to
  1476. 56:35Annette's. I think that um
  1477. 56:38a fantastic uh
  1478. 56:40uh state would be
  1479. 56:42that uh the type system
  1480. 56:45evolves
  1481. 56:46and
  1482. 56:48becomes able to be to serve as
  1483. 56:50infrastructures for more complex
  1484. 56:53techniques.
  1485. 56:54So I could imagine for instance that you
  1486. 56:58have a
  1487. 56:59light
  1488. 57:00typing mode for a program that finds a
  1489. 57:04common type errors and then and that
  1490. 57:07you can
  1491. 57:09at some point mark that there is going
  1492. 57:12to that the
  1493. 57:14the proof for some function for instance
  1494. 57:16that this function's logic is correct
  1495. 57:18because it's implementing a sorting and
  1496. 57:22you want to
  1497. 57:23to know that the sorting is going to be
  1498. 57:25correct that this is then delegated to
  1499. 57:27to some other tool that provides deeper
  1500. 57:30verification. Ideally, I think that um
  1501. 57:34uh type system is made to be uh nice to
  1502. 57:38deal with from the programmer's point of
  1503. 57:41view. So, ideally, you would you would
  1504. 57:43use the type system and then and then um
  1505. 57:46delegate, but your main interface would
  1506. 57:48be would be the type system for those
  1507. 57:50for those deeper processes. I think
  1508. 57:53also, one very interesting question for
  1509. 57:56me is uh what is the good
  1510. 58:00way to um
  1511. 58:03bring these uh more complex
  1512. 58:07uh ways
  1513. 58:08to deal with um sending messages and and
  1514. 58:11all of these. For instance, uh session
  1515. 58:13types are a thing in the in the theory
  1516. 58:16of typing concurrency. And the question
  1517. 58:19is how
  1518. 58:21what form would it take to bring these
  1519. 58:23these verification techniques to to uh
  1520. 58:26language as Elixir, which is which which
  1521. 58:32like uh would it take the form of
  1522. 58:34annotations? Would it be simple enough
  1523. 58:36to understand? And would it bring would
  1524. 58:39it cover the use case that that people
  1525. 58:40need? Right?
  1526. 58:41>> Very quickly, right? If we were to kind
  1527. 58:43of sum up this whole conversation and
  1528. 58:44what you've learned, what's one thing
  1529. 58:46that you wished every Beam developer
  1530. 58:48understood about types? And one thing
  1531. 58:51you you wished every type system
  1532. 58:53researcher could understand about the
  1533. 58:54Beam. Uh let's go to Annette first.
  1534. 58:57>> Uh types don't hurt. There is a certain
  1535. 58:59learning curve, but there's a lot of
  1536. 59:00things that you actually get from it.
  1537. 59:02So, trying to hit the sweet spot between
  1538. 59:05too much work on the type annotations
  1539. 59:08and yeah, the nice guarantees and the
  1540. 59:10confidence in the in the work that you
  1541. 59:12get. I think this is something that I
  1542. 59:13would hope for many programmers that are
  1543. 59:16now refraining from use types from using
  1544. 59:18types because they seem too complex or
  1545. 59:21complicated. It's not as bad as it as it
  1546. 59:23might seem might seem to be. Right?
  1547. 59:25>> That uh
  1548. 59:28the point of a static type system for
  1549. 59:31for for the beam is to catch the
  1550. 59:34the one path out of a hundred that is
  1551. 59:38going to
  1552. 59:39uh fail because the destruct at at this
  1553. 59:42point or at this map at this point
  1554. 59:45doesn't have does not have the given
  1555. 59:47field anymore. And so, what we're
  1556. 59:49helping with this the the the really
  1557. 59:51edge cases those uh things that even a
  1558. 59:55very well-designed library and a very
  1559. 59:58well-designed
  1560. 1:00:00project
  1561. 1:00:01is going to have struggles with. And uh
  1562. 1:00:05this is
  1563. 1:00:06rather than
  1564. 1:00:08promising a
  1565. 1:00:09fight against a
  1566. 1:00:10very complex logic design that to
  1567. 1:00:14uh to make sure you don't write bad
  1568. 1:00:15code. I think
  1569. 1:00:17this
  1570. 1:00:18this is a
  1571. 1:00:20interest
  1572. 1:00:21of types for the beam. And you said, I
  1573. 1:00:23think, what should researchers
  1574. 1:00:25understand about the beam? For me, what
  1575. 1:00:27I understood is that the the beam is a
  1576. 1:00:29is is stronger than me and uh the the
  1577. 1:00:32runtime at
  1578. 1:00:35uh
  1579. 1:00:36the the importance of the
  1580. 1:00:38of the quality of the runtime is a
  1581. 1:00:40something that is
  1582. 1:00:42that is a
  1583. 1:00:44it's it's the first it's the main point
  1584. 1:00:46of a of a language. And
  1585. 1:00:48the role of a type system is to support
  1586. 1:00:51that
  1587. 1:00:52uh
  1588. 1:00:53rather than
  1589. 1:00:55restrict it. And if you have a
  1590. 1:00:57runtime that is so excellent that you
  1591. 1:01:00can afford to program in a dynamic way
  1592. 1:01:03with a pattern matching
  1593. 1:01:05or by um
  1594. 1:01:07uh having message passing and or having
  1595. 1:01:10all those extremely dynamic, very hard
  1596. 1:01:13to type features that Elixir or Erlang
  1597. 1:01:15have, then the role of the type system
  1598. 1:01:17is going to get on their get on their
  1599. 1:01:19level.
  1600. 1:01:20>> The The beam ecosystem is actually great
  1601. 1:01:22for research. Yeah, we have real world
  1602. 1:01:24problems that have been high impact. We
  1603. 1:01:26have a a long-standing community and the
  1604. 1:01:30languages are very active, right? So,
  1605. 1:01:32the community is active, the languages
  1606. 1:01:34are evolving. There is no need to assume
  1607. 1:01:37that the beam is obsolete in any way. I
  1608. 1:01:40would I would rather claim it's getting
  1609. 1:01:42more and more important with with every
  1610. 1:01:45cloud server that runs some some Erlang
  1611. 1:01:48or Elixir code, right? And there is a
  1612. 1:01:50great opportunity to um make a point and
  1613. 1:01:52have impact with the research that you
  1614. 1:01:54do.
  1615. 1:01:54>> So, Adnan and Guillaume, you know, thank
  1616. 1:01:56you both. Yeah, this has been exactly
  1617. 1:01:58the conversation I was hoping for. You
  1618. 1:01:59know, we've got two amazing researchers
  1619. 1:02:01from sister projects who spent years
  1620. 1:02:03thinking hard about the same problem,
  1621. 1:02:05but you know, from different angles. And
  1622. 1:02:08what I'm personally taking away from the
  1623. 1:02:11last hour, I hope the listeners too, is
  1624. 1:02:13that the type system arriving in Elixir
  1625. 1:02:161.2
  1626. 1:02:17isn't the end of a 30-year argument
  1627. 1:02:19about typing on the beam. It's actually
  1628. 1:02:22the moment that argument finally has a
  1629. 1:02:24theoretical foundations and the
  1630. 1:02:25engineering pragmatism to move forward
  1631. 1:02:28together. So,
  1632. 1:02:30if you want to be part of where this
  1633. 1:02:31goes next, the most useful thing you can
  1634. 1:02:34do this week is to try Elixir 1.2
  1635. 1:02:36release candidate, you know, read
  1636. 1:02:37Adnan's, you know, same same but
  1637. 1:02:39different paper to understand the
  1638. 1:02:41broader landscape, and report back what
  1639. 1:02:44works and what doesn't.
  1640. 1:02:46You know, I think both teams generally
  1641. 1:02:48want the feedback. So, yep, thank you
  1642. 1:02:50for so much for listening. Don't forget
  1643. 1:02:53to subscribe. And for the record, this
  1644. 1:02:55podcast was recorded on May 28th, 2026.

About this transcript

This page contains the full transcript of Static Types Finally Come to the BEAM | Annette Bieniusa & Guillaume Duboc by BEAM There, Done That, generated from the public captions YouTube serves with the video. The transcript has 9,655 words across 1,644 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.