Morning Keynote: Embracing an Error-Prone Reality
Cunningham, Emma
Emma is a Senior Software Engineer at Second Spectrum, where she gets to solve all kinds of fun problems around how to build compelling data visualization and analytics apps for clients like the NBA and the LA Clippers. She is actively involved in various STEAM education equity initiatives in low-income communities across Los Angeles, including co-organizing YouthBuild Charter School of California’s CODEChella, serving on the Advisory Board at the Critical Design and Gaming School, teaching robotics and programming at Heart of Los Angeles, and co-directing Code Hawk Camp, an inclusive and free summer computer science camp for students in South LA.
 Hi everyone. I am super thrilled to be here. I'm especially thrilled to be talking about Elixir in LA and to end like such a cool venue also. This is probably the coolest venue setting that I've ever been in. I don't know if I've ever given a talk under a disco ball. So thank you, first like thank you to all the organizers. I think they've organized like a really great day for us. So yeah, very exciting stuff. But yes, hi, I'm Emma as Desin said. I am based in Los Angeles. I work at a startup, a sports tech startup based in LA at Second Spectrum. It's called Second Spectrum. It's very close to here. It's in little Tokyo just up the street a few blocks. And so what we do at Second Spectrum is we do a lot of work around both capturing data and then also passing the video capture through machine learning and computer vision layers to be able to derive certain insights from that video capture. We're currently the official optical tracking and analytics provider for the MBA. And in addition to that, we build full stack data visualization platforms that bring our advanced analytics data to life for coaches, leagues, and media broadcasters. A lot of the work that we do on the full stack apps team requires our products to have like reliable uptime, be able to serve a lot of users, and also be able to process a lot of data. So we've been using Elixir and some of my products for the past couple of years and we really come to love the language for a lot of reasons. A few of those reasons at a high level. So the language features themselves, the tooling that comes with Elixir, and the legacy that it inherits as a descendant of Erlang. And so I should pause here and say that as I was putting together this talk, initially I was prepared to just talk about these things in greater detail and kind of give you the pitch of like why Elixir. And I think it's important as a community that we continue to reflect on why we love this language, what the benefits are so we can share this with other people. And so I think that is a perfectly fine talk. But as I started to think more about some of these things in greater detail, I realized that for both me and the team that I work on, one of the reasons why we've come to love Elixir so much, and a common trend across some of the details of these individual details, was that the language really reflects the realities of the world we live in, rather than say an idealized version of it. And in particular what I mean is both Elixir and Erlang deliberately provide a language that accepts as a fact that sometimes things will fail. And to live in a world like this means that we have to design systems that can account for these failures without everything kind of like halting to a crash. And so being able to design these kinds of systems will require a language that prioritizes this, that accepts as a fact and does not sort of make us have to think about creating systems or things that cannot accept failure, cannot error. So one example of this that comes to mind that we'll go into like unpack a little bit more, but we'll just kind of discuss as an initial example is the feature of immutability in Elixir. And in my mind immutability is at its core about is about having a particular philosophy on failure, that is that the role of the mutation of data has in introducing to introducing error. So that's kind of what we're going to be talking about this morning. I kind of covered at a high level some of the things that I really like about Elixir, but I haven't gone into much detail about that. We will explore some of those details. But really what I'll be talking about this morning is taking us through this journey of what it means to embrace errors as a reality. First considering how this idea sort of sprung up with Erlang and the history of the language. And then considering the additional ways that Elixir is able to build upon this philosophy of embracing error and failure. And then because I couldn't possibly turn up, oh yes? Yeah, I can make the slides available after the talk. Yeah. So yeah, so we'll cover some of the additional features and tooling that's available in Elixir. And then because I couldn't possibly turn up an opportunity to plug Elm, which has become quickly my favorite front-end language, I'll talk a little bit about some of the ways that I think Elm also embraces this philosophy of embracing errors and what we can learn from Elm as well. And then lastly, when I think about some of the implications of what it means more broadly to embrace errors, what we can learn from what these languages are doing in embracing an error-prone world and what we might be able to take away from that into our lives in general. All right. So I'm going to start off with this number that I imagine many people in this room have seen who's seen this number before. Yeah. Okay. So this is the cell for Erlang, right? So this is 99.9999999%. It represents the uptime of the flagship product, the flagship Erlang product, AXD 301. It was built by Ericsson where Erlang was originally developed. And at the time that this was reported, I think in 2007 by Joe Armstrong, one of the people as part of the team that built Erlang, the codebase had over 2 million lines of Erlang code, which is pretty impressive. And it had been in operation for 20 years. So let's put 99's reliability into context, right? So, you know, typically we consider five nines to be pretty good. That amounts to 5.2 minutes of downtime per year. Seven nines is considered by some to be nearly unachievable, but they got nine. Nine nines. So this is pretty stunning to kind of do the math to sort of see how incredible that is. So over 20 years, 365 days and a quarter. In a year, 24 hours, in a day, 60 minutes, in an hour, 60 seconds, so on and so forth. That comes out to under a second of downtime over 20 years. And again, like, yeah, I heard a wow. It is incredible, right? With just over, a little bit over half a second of downtime over 20 years, this is like fantastic. This is like the way you sell this language, I think. And I remember when someone first told me about this number, I was, A, I did not believe them. But yeah, this is incredible, right? So, one, I was incredulous, I didn't believe it. But then once I got over my disbelief, the first kind of thought that popped in my head was how could this be? Like, how could a system that's been around for 20 years fail so rarely? Or how could I have so few errors? And the more that I learned about Erlang, what I realized was that was really asking the wrong question. What I realized was this number is in a reflection of a language that prevented or avoided or tried to live in a world that was absent of errors, but one that recognized errors as a matter of fact in the world that we live in. Errors are unavoidable. So how do we build systems that can accept that world? I think this is really telling when you consider the title of Joe Armstrong's 2003 thesis, where he describes the background of how Erlang came to be. The title is Making Reliable Distributed Systems in the Presence of Software Errors, not despite not, you know, trying to avoid them. It's in the presence of them. We just accept as fact that these errors are going to be there. In the introduction to the thesis, he says, large systems will probably always be delivered containing a number of errors in the software. Nevertheless, such systems are expected to behave in a reasonable manner. And so this really stuck out to me because a lot of times when we talk about software development, when we talk about software engineering, we talk about what can we do to make sure that our code is error-free and we're going to throw tests at it and throw type safety at it. And we're just going to make sure that as much as we can, our code is just nothing wrong ever around this. And to realize that the genesis of the thing, which is coming from a place where, you know, these systems were so widely distributed, they were used by so many people. And so the engineers just took as fact prima facie that errors are going to happen. They will be introduced sometimes. And what we have to do is ensure that when those things, when some things fail, they can fail fast, and other processes can continue to march along. So to kind of understand a little bit more about how Erlang does this and what that entails, we have to sort of dive deep into a bit of history. And we're going to start in the 1980s, where at Ericsson, the computer science laboratory that Joe Armstrong was a part of, searched for ways to make these processes of developing software result in more of reliable systems that are both easier and less expensive to build and maintain. And that takes us to 1986. So in 1986, Joe Armstrong starts working on a language that would eventually become Erlang. So the interesting thing that I learned from reading his thesis was, at the time, the language started as an experiment to add concurrent processes to Prologue. And he actually wasn't even really intending to design a new programming language when he first started working on this. He was interested in working on a program called the Plain Old Telephony Service. And at the time, the best method for working on this was to use a variant of Prologue that was augmented with parallel processes, which, you know, again, people who have used OTP, this should sound somewhat familiar or sort of a hint to what's to come. But what was interesting is that, you know, back in the day, 30 odd years ago, there were really only two models for approaching concurrency. And the dominant one at the time was the idea of shared-state concurrency. So shared-state concurrency involves this idea of mutable state where there's, you know, literally memory that can be changed. We can mutate it, we can move stuff around. And languages like C, Java, C++, etc., they have this idea where there's this, you know, stuff called memory and we can poke at it and we can change it and we can do stuff to it. And this is fine. So long as you only have one process doing all the changing, right? As soon as you have multiple processes sharing and modifying the same memory, this becomes very quickly a recipe for disaster. Like, like things go wrong really, really quickly. And so the problem, right, is that all of a sudden when we have shared memory, you need to prevent against simultaneous modification of that shared memory. So once that problem is introduced, well, how do we solve that? So the, like, common fix for that is to have some kind of locking mechanism. So depending on the language that you're working with, you may call this a mutex, a synchronized method. But either way, it's a locking mechanism. So now that you have locks, now you have this new problem. And that problem emerges when programs crash in some kind of critical region when it's, at a time when they're holding the lock. And other programs don't know what to do. They have been waiting, right? And now all of a sudden, like, everything kind of doesn't know how to lurch forward. So how do, how do developers approach fixing these problems? So there, there's some ways, there's some solutions to this. Transaction memories is one way of approaching it. But at this point, if you've been following the narrative, we've kind of, like, continued to inherit these problems because we started off with this assumption of sharing state for concurrency, right? And so a different approach to avoid all of these problems altogether is to approach concurrency from the perspective of message passing. And this is sort of the idea that they're pursuing in the early, when they're starting to think about how to build these reliable systems over at Ericsson. So in message passing, passing concurrency, we just completely get rid of the idea of shared state. And as a result of that, any computation is going to happen inside of a process. And the only way to exchange data is to be able to pass messages across processes asynchronously. So this ends up having some pretty big implications. Now all of a sudden, we no longer need to rely on mutable data structures. And if we don't have to rely on mutable data structures, well, now we don't need locks anymore. And if we don't need locks anymore, then we don't run into that other problem that we had where if, you know, a program crashes while something's in a lock, then other things don't know what to do. And so all of a sudden, all those other problems that we were having, we don't have anymore. But what do we do about parallelization, right? Because that was why we were committing to all these things in the first place. Well, that turns out to be pretty trivial. If you just think about parallelization as a process of your developer breaking up the solution of this problem into a number of parallel processes that can then communicate. So the kind of neat thing about this is if you kind of go to like the root level of the problem, you eliminate all the problems that you had before, you don't need to have to like pile on additional like cluchy fixes on top of one thing after another after another until you kind of get to a place where you're like, wait, why are we even here? Why are we trying to solve these problems? So this is the idea of concurrency oriented programming. And I found this blog post from 2007 from Joe Armstrong where he boldly makes the claim that objects are out and concurrency is in. And 11 years later, I don't know, I don't know the word like really living up to that. But something that stood out from the post where he made this claim was he's really pushing for this idea that the reason why we might want to commit to this approach towards programming is because if we think about the world that we live in, our world is concurrent. It is parallel. Things happen all over the place at the same time. And how does that happen? Well, we pass messages to one another, right? So let's imagine this room, right? Like, I have some private memory, you all have some private memory. And right now I have this private memory of all the stuff that I learned about the history of Erlang and Elixir that I want to share with you, name doing it through like light waves, sound waves. And then you're going to take that and you're going to update your private memory in some way as well through some kind of update process. And if say like the speaker blows out and like you can't hear me anymore, like you can still do that. You can still process whatever information made it through, right? You are not going to like freak out and just like wait. I hope you don't. I hope you don't. So this goes back to my idea or the kind of argument that I started off with at the beginning that when we embrace errors as a consequence of being realistic about how the actual world works, instead of turning away from how reality actually is, we can incorporate these things into the design of our language and that in turn can create something really powerful when our languages are reflective of the worlds we actually live in that can give us a lot of expressive power and in the case of Erlang as we saw, a lot of like reliability as well. So while we're on the topic of kind of learning from the world and incorporating that into languages, I'm going to digress for a moment and mention an anecdote that reveals in a different way how important it is for languages to be reflective of the world around them. So does anyone recognize these symbols on the screen? Yes, I saw it hand. What is it? Korean characters. Yeah, so these are the five base consonants from Hangul, the Korean alphabet, and Hangul was created in the 15th century. So I'm sure at this point you're like, huh, I came for an elixir talk, but now I'm looking at, we talked about Erlang and now we're looking at Korean. What happened? So let me explain a little bit more. And I'm going to give a little bit of like personal exposition also because it'll also maybe explain why I'm really interested in both programming languages and natural languages. So prior to my career as a software engineer, it's been about a decade as a formal semantasis working on natural language linguistic theory. And it's also how I ended up like learning the love functional programming because I was doing a lot of work with the Lambda calculus and then someday someone said to me, oh, you should check out some of these programming languages. They kind of seem to be up your alley. But going back to Korean, over time, in my career as a linguist, how a lot of people come up to me and tell me, oh, you should check out Korean. It's really interesting. It's really easy to learn. And I usually get very skeptical when people tell me things like that because usually like, usability of learning is a very subjective thing. It's very dependent on what language background you've had in the past, what you can have as a context of comparison. But I recently started learning more about the history of Hangul. And it turns out it's quite interesting. So at the time in the 15th century, Korea was under Chinese rule. And so the writing system that was being used at the time was the Chinese writing system. So this immediately posed learnability problems because if anyone here is familiar with like the Chinese writing system, there's a lot of just like, wrote memorization. There's some things where like, if you learn like, 3,000 radicals, you've learned like 80 to 90% of the written words, but still like, kind of a lot of like, just wrote memorization, right? Simultaneously, what made this writing system hard for Koreans was that there were pretty significant language differences across the way Korean and Chinese was being spoken, that it didn't always make sense to have a Chinese writing system for Korean. This led to kind of rampant illiteracy at the time, where a lot of Koreans, especially in the lower classes, were just not given access to learn how to read and write. So, and I should say I learned all of this initially from a K drama that I'm pretty sure was just like, pop propaganda, but I have since confirmed this on both Wikipedia and people at the Korean Cultural Center. So, but so what happened was King Sejong at the time recognized that without some kind of language for the people to bring the people together to create for his people, like a unified sense of the Korean culture, they would always kind of be stuck relying on something that also wasn't serving the people. So, he had his royal court of scientists think about how they could represent the sound shapes of Korean in a way that lended itself to learnability. And so, again, as a linguist, as a person who has been always interested in both natural language and now programming languages, this idea of centering learnability, centering certain features in your design of the language kind of really piqued my interest. So, I started taking Korean last fall and the end of this anecdote is that it is actually that easy to learn. In two hours, I and like 50 other of my classmates learned most of the characters of Hangul and here's why it's so easy to learn. So, below each of the characters, the image is an image of sort of how that character was derived. It's derived from the actual articulatory features that your mouth makes when you're producing a certain sound. So, that first on the far left, that first character that looks kind of like a box, that corresponds to the sound mmm. And the idea is that when you close your mouth, your mouth kind of forms a little box shape. And the next one mmm, that you'll see there's a line in the picture here where the it's sort of showing how the tongue hits the hard palate at the top and then kind of comes back down in an L looking shape. And so on and so forth. So, this when I first saw this, my mind was blown because if anyone has taken like an introductory linguistics class, these images shouldn't look that foreign to you. You've done these things in phonetics. You see the sagittal section. You learn about you know where your mouth is forming closures for air and things like that. And so, what's been really interesting to me about learning Korean is that all of a sudden there's this like really easy mnemonic for learning these letters. And if you've ever like had to help someone learn the Latin alphabet for example, if you've ever had to help someone learn English, there isn't that one to one correlation. It takes a lot of rote memorization to get here. It takes a lot longer than two hours to get someone to learn all the way from A to Z. So, my point for bringing this up is that a lot of times I'll hear people saying things about Erlang and Elixir that because there are such significant paradigm shifts away from kind of the standard way of doing things that's functional, that data is immutable, that it privileges currency in this way, that's a hard language to learn or adopt. And I bring this up because I think that actually when we consider things like Korean, when we consider things around how when languages create connections between the real world and the representations within the language, it actually creates a foundation of learnability and accessibility that allows learners to draw on their real world experiences rather than have to think about the world that doesn't actually align with the language that you're writing in. And I say this as someone who started off as a functional programmer and then in my first software engineering job, we were using JavaScript and it was like mutating state all the time and it was like totally foreign to me. I was like, wait, I don't do this in real life all the time. I'm not like creating like arrays and then pushing stuff to them. Like, I'm creating in the real world, I'm passing data from myself to others and we're transforming data and state is not this thing that we just get to kind of plug and play or poke at all willy-nilly. So my claim here is that I actually think that some of the things that people say about Erlang and Elixir and in general functional languages is not actually true. It does require a paradigm shift but I think once you kind of are able to draw those connections between what's happening in the real world and how we think about what happens in the real world, it's actually a much closer representation to what we do outside of programming. That was a digression. We'll come back to Elixir. So that's a sort of talking about continuing to build accessible features I think is a nice segue to talking about Elixir which continues in this tradition that Erlang began and as we Elixir enthusiasts know, there are a lot of additional features and tools that build upon this like really strong foundation that Erlang gives us but makes the language a lot more accessible. There's a great talk by one of your NPEX co-organizers, Hannah, about idea scalability and why Erlang for all of its awesomeness is not more widely available and I think that's also relevant when we ask why we're not using Erlang now. But I think there's also the idea of where people coming from, especially people who are doing the types of development that they're doing with Elixir and why didn't they find Erlang accessible and I think Elixir really was able to capture the spirit of Erlang but be able to make it more accessible to a wider audience which has helped with its adoption. So some of those things and I'm going to start off with like a pretty simple one is pipes and the reason why I'm starting off with the simple one is I also want to kind of drive this idea that sometimes the things that we have, the things that we can do to make things more accessible can be really, really simple. It can be as simple as introducing something that Elixir didn't invent the notion of pipes like functional programmers have seen pipes in all kinds of languages, right? But the reason why this is so valuable is that in Erlang with the absence of pipes with this idea of immutability now all of a sudden like when you're trying to do a lot of stuff to state one thing after another you very quickly end up with code that is a lot of copy pasta with like a couple of variables changed or stuff that you really have to read all the way through to follow and see what's going on. So for example let's say this is kind of a little dummy example but let's say we have some state and we want to transform it with some functions. So in Erlang without pipes this is one way you can do it, right? You can assign the transformed state to another variable then transform that, assign that to another variable then transform that and so on and so forth. But in order to kind of see what's going on you actually have to like read every line and follow everything. Maybe that's not so bad but what can we do to improve on it? So maybe we inline it. Okay, now we can kind of see at least that we're transforming state you know three times over but now we have like these friends we have to keep track of and it's not that great, right? So what pipes do is pipes just make this really clear, they make it really simple and the nice thing about pipes again like this is not a new idea but it makes it so that our code now of now all of a sudden can read more like pros from top to bottom and we're able to highlight one of the strengths of functional programming, right? That we can treat functions as if they are these data transformers that can combine in various ways to achieve some kind of result. Cool, yeah okay so like I said simple example but I think it's like little syntactic sugar stuff like this that just kind of makes a world of difference when it comes together. So a few other things. So again none of these things alone is necessarily a new invention of elixirs but I think all of these pull together and then laid on top of that foundation of Erlang is to me what makes Erlang really or elixir really powerful and really a joy to work with. So additional syntax changes so things like optional friends things like that. Things that again like individually may not seem like they make a huge impact but put together you think about the joy that you have writing elixir. I think some of that is some of those syntax modifications. Also the power of metaprogramming. The ability for say macros to allow third party libraries to provide internal DSL so anyone who's incorporated Ecto under a project knows the power of this right? In terms of tooling having something like MIX that allows you to like really quickly and simply create processes that can scaffold a project that can help you with dependency management and also is extensible. The formatter this one is new to 1.6 and I was really excited about it. For me I work on a large team where we get team members pulled off and on to projects given like the pace of other work that's happening on other teams and so being able to have a consistently formatted code base is like a huge thing. It's again seems like such a little thing but especially when you're building large scale products that you might end up coming back to six months later and you need to be able to sort of know what's going on without working through someone else's quirky style. Having something like a formatter just built in is really huge. And then EARLing compatibility. I mean we already mentioned some of the benefits of having that foundation of EARLing but being able to call EARLing functions if something does it isn't available in elixir means that we get to benefit from over 30 years of research on this language. Okay cool. All right so I mentioned I was going to give a tiny little plug for Elm so who here has touched Elm at all? Cool. Sweet. Okay so I won't belabor the details but for those that haven't touched it here's my quick little plug. So Elm is a functional front-end language that was inspired heavily by Haskell. It first appeared in 2012 by Evan Shapliki and I think the cell that I give when I tell people about Elm is that it boasts virtually no runtime errors which for front-end programmers you know this is huge right? So one of my favorite things about Elm besides that those guarantees is how much care they put into their error messaging system so that error messages can be embraced instead of being some kind of mysterious like thing that you have to like decrypt and like work through to debug your app. So I'm going to go over some of the things that I think they've done really well in their error messaging but a caveat some of the specific types of error handling that you get in Elm is a direct consequence of its type system and the like power of type-inferencing that it's capable of doing as a result of that type system. So for the purposes of this talk I'm just going to be focused on like really the superficial stuff and not that type stuff if you care about that type stuff though I will talk your ear about it afterwards during a break or something. So one of the things that I think error messaging in Elm does really well is helping you find those relevant bits of code. So I'm sure there are plenty of people in here who remember getting error messages like program.x, colon 54, colon 96 and you have to decipher them and you have to like go through your file you have to find that file. Two you have to like go through find that line find that column you end up spending all this time scanning the code whereas in something like Elm it's they just tell you up front and they even take you know specific visual cues to show you where in that line the error occurred. Another thing that I think is really great about the error messaging in Elm is you get friendly language so I'm sure some of you can't see this in the back sorry. So in this example there's been a type error and again I'm not going to go into the type stuff but the error message reads the first argument to function is over 50 has an unexpected type looks like a record is missing the field age as I infer the type of your values flowing through your program I see a conflict between these two types like it's so nice to you it's like a friend who's giving you a suggestion and I think again that goes a long way because if you think about when something goes wrong when you hit an error in your code that's not a moment where you want someone to just be like no right so having something that just leaves like a little bit more empathetic just helps you in that moment where you're like I just want to get through this please tell me what happened and then finally this one this one just seems super superficial that I once I saw it happening in Elm I was like mad that it wasn't happening in other languages but just the use of color and formatting so those of us who build products for users know that layout and color matter right so why is it that so many of our error message systems usually are just like all one color like fire alarm red like and then there's like this giant big text dump with no consideration for layout at all again like the the nice thing in in this system is you know immediately what happened where and it's marked with color it's the lines are like laid out and everything's not just all squished up so you have to like I kind of like get in there to see what's going on it's designed for humans to read this and and be able to access it all right so that was my plug for Elm and as a case in point I and this is a bit unfair I realized but consider this example of an error in JavaScript right like so again the amount of information that we have about the errors here is going to be a little bit different because Elm's type inference system gives us a lot more power in terms of what we can pick up and I kind of stack the deck against JavaScript's favorite because this is an error message on like minified jcry source but even absent of all of these things like the considerations around like language color and layout could be better taken into place here still I think sorry that is just my moment to crap on JavaScript for a moment all right so finishing up we saw how languages that accept the reality of the world as error prone and that provide features and tools for developers to create fault-tolerant systems are both highly reliable and also maintainable so in this last part what I want to consider is what we can learn in the other direction what we from the real world might be able to take away from these systems so I think something that becomes really clear once you've started started using a language like elixir is that it forces us into a paradigm shift in terms of how we think about programs states and also how language can shape what we perceive to be possible through what can be expressed so for me this is really illuminating when I started working with the lambda calculus because it was so expressive but let's we can look at a somewhat more concrete example so I am not going to say the name of the city but this is the name of a city in Poland a lot of native English speakers have a problem pronouncing and the reason why is because we don't have this consonant cluster in English we have other consonant clusters we have sk school st stop but we don't have a gd so usually what we do in English when we encounter a consonant cluster that we don't have natively is we'll do a thing called vowel a pentassist and we'll put a vowel in between the two letters and that's what we do we say gdansk try saying it without the vowel in between you will find it impossible but Polish in fact does have this and I'm going to play hopefully this place so this is the the actual pronunciation of this of the city no it's not playing let's try and change the sound preferences really quickly great okay dance so loud sorry dance okay that's it that's it but you see how in the native pronunciation there's no vowel there right so what I think is interesting about this example is this informs how the language that we use everyday shapes what we think is possible in terms of what we can express and I think just as natural languages do this so too do our programming languages so I'd like to suggest that just like learning about what another language makes possible phonologically might do in terms of opening our minds in terms of what can be pronounced maybe we can learn something from these programming languages too in terms of how we can embrace error in the world so what have we learned from languages like these we've learned that error is a bound in the world that we live in and we can't avoid them if we avoid them then you know just other problems start to pile on really fast and I think this is a really important part of programming for me this was one of the things that I found most freeing when I first started programming the fact that like failure wasn't a thing that I had to control failure was just a thing that I had to learn how to like work with and yet I cite this as something that we need to be mindful of because I think despite living in an error prone world not everyone can abide by this rule to fail fast and I say this because I've for the past five years I've been working with educators in low-income communities of color across Los Angeles to teach computer science to middle school and high school students and I found really quickly that when it came to the idea of fail fast I didn't know what to say to these students because for a lot of these students for a lot of students of color for a lot of queer students for a lot of female students fail fast wasn't an option for them outside of my classroom right fail fast was something that sometimes could mean like violent outcomes failure to appear duly submissive with law enforcement for example might mean death failure to comply with society's ideas around gender and sexuality could also mean death and failure to correctly respond to unwanted advances from someone who is sexually harassing them could also mean death and so I think before we ask people to embrace fail fast fully we also need to think about what we can do to make the world a better place for failure and and and full of errors so I'm gonna finish with this which sadly also you can't see but I will share the slides after this this is from John Perry Barlow's 1977 25 principles of adult behavior and I've been seeing this image a lot this week because he sadly just passed and I knew as soon as I saw this that I wanted to incorporate this somehow and I wanted to talk about his legacy and honor his memory a little bit in the final moments of my talk but I wasn't sure how so I start I kept looking at this image I kept looking this this image and it has like advice like be patient no matter what don't trouble yourself with matters you cannot truly change tolerate ambiguity and as I started reading these items more and thinking about what I was talking about I was like oh duh it's just kind of we end here right because I think it's very fitting that someone who has spent his lifetime working on the connections between technology and policy would also produce something like this list these principles that we can apply equally to languages that we use to create new things in the world as well as the world that we inhabit when we bring these things to life that's it thank you
 Hi everyone. I am super thrilled to be here. I'm especially thrilled to be talking about  Elixir in LA and to end like such a cool venue also. This is probably the coolest venue setting  that I've ever been in. I don't know if I've ever given a talk under a disco ball. So thank  you, first like thank you to all the organizers. I think they've organized like a really great  day for us. So yeah, very exciting stuff. But yes, hi, I'm Emma as Desin said. I am based in  Los Angeles. I work at a startup, a sports tech startup based in LA at Second Spectrum. It's  called Second Spectrum. It's very close to here. It's in little Tokyo just up the street a few  blocks. And so what we do at Second Spectrum is we do a lot of work around both capturing data  and then also passing the video capture through machine learning and computer vision layers to  be able to derive certain insights from that video capture. We're currently the official optical  tracking and analytics provider for the MBA. And in addition to that, we build full stack data  visualization platforms that bring our advanced analytics data to life for coaches, leagues,  and media broadcasters. A lot of the work that we do on the full stack apps team requires our  products to have like reliable uptime, be able to serve a lot of users, and also be able to  process a lot of data. So we've been using Elixir and some of my products for the past couple of  years and we really come to love the language for a lot of reasons. A few of those reasons at a  high level. So the language features themselves, the tooling that comes with Elixir, and the legacy  that it inherits as a descendant of Erlang. And so I should pause here and say that as I was  putting together this talk, initially I was prepared to just talk about these things in greater  detail and kind of give you the pitch of like why Elixir. And I think it's important as a community  that we continue to reflect on why we love this language, what the benefits are so we can share  this with other people. And so I think that is a perfectly fine talk. But as I started to think  more about some of these things in greater detail, I realized that for both me and the team that I  work on, one of the reasons why we've come to love Elixir so much, and a common trend across some  of the details of these individual details, was that the language really reflects the realities  of the world we live in, rather than say an idealized version of it. And in particular what I  mean is both Elixir and Erlang deliberately provide a language that accepts as a fact that  sometimes things will fail. And to live in a world like this means that we have to design systems  that can account for these failures without everything kind of like halting to a crash. And  so being able to design these kinds of systems will require a language that prioritizes this,  that accepts as a fact and does not sort of make us have to think about creating systems or things  that cannot accept failure, cannot error. So one example of this that comes to mind that we'll go  into like unpack a little bit more, but we'll just kind of discuss as an initial example is the  feature of immutability in Elixir. And in my mind immutability is at its core about is about  having a particular philosophy on failure, that is that the role of the mutation of data has in  introducing to introducing error. So that's kind of what we're going to be talking about this morning.  I kind of covered at a high level some of the things that I really like about Elixir, but I  haven't gone into much detail about that. We will explore some of those details. But really what  I'll be talking about this morning is taking us through this journey of what it means to embrace  errors as a reality. First considering how this idea sort of sprung up with Erlang and the history  of the language. And then considering the additional ways that Elixir is able to build upon this  philosophy of embracing error and failure. And then because I couldn't possibly turn up, oh yes?  Yeah, I can make the slides available after the talk. Yeah. So yeah, so we'll cover some of the  additional features and tooling that's available in Elixir. And then because I couldn't possibly  turn up an opportunity to plug Elm, which has become quickly my favorite front-end language,  I'll talk a little bit about some of the ways that I think Elm also embraces this philosophy of  embracing errors and what we can learn from Elm as well. And then lastly, when I think about some  of the implications of what it means more broadly to embrace errors, what we can learn from what  these languages are doing in embracing an error-prone world and what we might be able to take away  from that into our lives in general. All right. So I'm going to start off with this number that I  imagine many people in this room have seen who's seen this number before. Yeah. Okay. So this is  the cell for Erlang, right? So this is 99.9999999%. It represents the uptime of the flagship product,  the flagship Erlang product, AXD 301. It was built by Ericsson where Erlang was originally  developed. And at the time that this was reported, I think in 2007 by Joe Armstrong, one of the  people as part of the team that built Erlang, the codebase had over 2 million lines of Erlang code,  which is pretty impressive. And it had been in operation for 20 years. So let's put 99's  reliability into context, right? So, you know, typically we consider five nines to be pretty  good. That amounts to 5.2 minutes of downtime per year. Seven nines is considered by some to be  nearly unachievable, but they got nine. Nine nines. So this is pretty stunning to kind of do the math  to sort of see how incredible that is. So over 20 years, 365 days and a quarter. In a year, 24 hours,  in a day, 60 minutes, in an hour, 60 seconds, so on and so forth. That comes out to under a second  of downtime over 20 years. And again, like, yeah, I heard a wow. It is incredible, right? With just  over, a little bit over half a second of downtime over 20 years, this is like fantastic. This is like  the way you sell this language, I think. And I remember when someone first told me about this  number, I was, A, I did not believe them. But yeah, this is incredible, right? So, one, I was  incredulous, I didn't believe it. But then once I got over my disbelief, the first kind of thought  that popped in my head was how could this be? Like, how could a system that's been around for 20  years fail so rarely? Or how could I have so few errors? And the more that I learned about  Erlang, what I realized was that was really asking the wrong question. What I realized was this  number is in a reflection of a language that prevented or avoided or tried to live in a world  that was absent of errors, but one that recognized errors as a matter of fact in the world that we  live in. Errors are unavoidable. So how do we build systems that can accept that world? I think  this is really telling when you consider the title of Joe Armstrong's 2003 thesis, where he  describes the background of how Erlang came to be. The title is Making Reliable Distributed  Systems in the Presence of Software Errors, not despite not, you know, trying to avoid them. It's  in the presence of them. We just accept as fact that these errors are going to be there. In the  introduction to the thesis, he says, large systems will probably always be delivered containing a  number of errors in the software. Nevertheless, such systems are expected to behave in a reasonable  manner. And so this really stuck out to me because a lot of times when we talk about software  development, when we talk about software engineering, we talk about what can we do to make sure that  our code is error-free and we're going to throw tests at it and throw type safety at it. And we're  just going to make sure that as much as we can, our code is just nothing wrong ever around this.  And to realize that the genesis of the thing, which is coming from a place where, you know, these  systems were so widely distributed, they were used by so many people. And so the engineers just  took as fact prima facie that errors are going to happen. They will be introduced sometimes. And  what we have to do is ensure that when those things, when some things fail, they can fail fast,  and other processes can continue to march along. So to kind of understand a little bit more about  how Erlang does this and what that entails, we have to sort of dive deep into a bit of history.  And we're going to start in the 1980s, where at Ericsson, the computer science laboratory that  Joe Armstrong was a part of, searched for ways to make these processes of developing software  result in more of reliable systems that are both easier and less expensive to build and maintain.  And that takes us to 1986. So in 1986, Joe Armstrong starts working on a language that would  eventually become Erlang. So the interesting thing that I learned from reading his thesis was,  at the time, the language started as an experiment to add concurrent processes to Prologue. And he  actually wasn't even really intending to design a new programming language when he first started  working on this. He was interested in working on a program called the Plain Old Telephony Service.  And at the time, the best method for working on this was to use a variant of Prologue that was  augmented with parallel processes, which, you know, again, people who have used OTP,  this should sound somewhat familiar or sort of a hint to what's to come. But what was interesting  is that, you know, back in the day, 30 odd years ago, there were really only two models for  approaching concurrency. And the dominant one at the time was the idea of shared-state concurrency.  So shared-state concurrency involves this idea of mutable state where there's, you know, literally  memory that can be changed. We can mutate it, we can move stuff around. And languages like C,  Java, C++, etc., they have this idea where there's this, you know, stuff called memory and we can  poke at it and we can change it and we can do stuff to it. And this is fine. So long as you  only have one process doing all the changing, right? As soon as you have multiple processes  sharing and modifying the same memory, this becomes very quickly a recipe for disaster. Like,  like things go wrong really, really quickly. And so the problem, right, is that all of a  sudden when we have shared memory, you need to prevent against simultaneous modification of  that shared memory. So once that problem is introduced, well, how do we solve that? So the,  like, common fix for that is to have some kind of locking mechanism. So depending on the language  that you're working with, you may call this a mutex, a synchronized method. But either way,  it's a locking mechanism. So now that you have locks, now you have this new problem. And that  problem emerges when programs crash in some kind of critical region when it's, at a time when  they're holding the lock. And other programs don't know what to do. They have been waiting, right?  And now all of a sudden, like, everything kind of doesn't know how to lurch forward. So how do,  how do developers approach fixing these problems? So there, there's some ways, there's some solutions  to this. Transaction memories is one way of approaching it. But at this point, if you've  been following the narrative, we've kind of, like, continued to inherit these problems because we  started off with this assumption of sharing state for concurrency, right? And so a different approach  to avoid all of these problems altogether is to approach concurrency from the perspective of  message passing. And this is sort of the idea that they're pursuing in the early, when they're  starting to think about how to build these reliable systems over at Ericsson. So in message  passing, passing concurrency, we just completely get rid of the idea of shared state. And as a  result of that, any computation is going to happen inside of a process. And the only way to  exchange data is to be able to pass messages across processes asynchronously. So this ends up  having some pretty big implications. Now all of a sudden, we no longer need to rely on mutable  data structures. And if we don't have to rely on mutable data structures, well, now we don't  need locks anymore. And if we don't need locks anymore, then we don't run into that other  problem that we had where if, you know, a program crashes while something's in a lock, then other  things don't know what to do. And so all of a sudden, all those other problems that we were  having, we don't have anymore. But what do we do about parallelization, right? Because that was  why we were committing to all these things in the first place. Well, that turns out to be pretty  trivial. If you just think about parallelization as a process of your developer breaking up the  solution of this problem into a number of parallel processes that can then communicate. So the kind  of neat thing about this is if you kind of go to like the root level of the problem, you eliminate  all the problems that you had before, you don't need to have to like pile on additional like  cluchy fixes on top of one thing after another after another until you kind of get to a place  where you're like, wait, why are we even here? Why are we trying to solve these problems? So this  is the idea of concurrency oriented programming. And I found this blog post from 2007 from Joe  Armstrong where he boldly makes the claim that objects are out and concurrency is in. And 11  years later, I don't know, I don't know the word like really living up to that. But something that  stood out from the post where he made this claim was he's really pushing for this idea that the  reason why we might want to commit to this approach towards programming is because if we  think about the world that we live in, our world is concurrent. It is parallel. Things happen all  over the place at the same time. And how does that happen? Well, we pass messages to one another,  right? So let's imagine this room, right? Like, I have some private memory, you all have some  private memory. And right now I have this private memory of all the stuff that I learned about  the history of Erlang and Elixir that I want to share with you, name doing it through like  light waves, sound waves. And then you're going to take that and you're going to update your private  memory in some way as well through some kind of update process. And if say like the speaker blows  out and like you can't hear me anymore, like you can still do that. You can still process whatever  information made it through, right? You are not going to like freak out and just like wait.  I hope you don't. I hope you don't. So this goes back to my idea or the kind of argument that I  started off with at the beginning that when we embrace errors as a consequence of being realistic  about how the actual world works, instead of turning away from how reality actually is,  we can incorporate these things into the design of our language and that in turn can create something  really powerful when our languages are reflective of the worlds we actually live in that can give us  a lot of expressive power and in the case of Erlang as we saw, a lot of like reliability as well.  So while we're on the topic of kind of learning from the world and incorporating that into languages,  I'm going to digress for a moment and mention an anecdote that reveals in a different way how  important it is for languages to be reflective of the world around them. So does anyone recognize  these symbols on the screen? Yes, I saw it hand. What is it? Korean characters. Yeah, so these are  the five base consonants from Hangul, the Korean alphabet, and Hangul was created in the 15th century.  So I'm sure at this point you're like, huh, I came for an elixir talk, but now I'm looking at,  we talked about Erlang and now we're looking at Korean. What happened? So let me explain a little  bit more. And I'm going to give a little bit of like personal exposition also because it'll also  maybe explain why I'm really interested in both programming languages and natural languages.  So prior to my career as a software engineer, it's been about a decade as a formal semantasis  working on natural language linguistic theory. And it's also how I ended up like learning the  love functional programming because I was doing a lot of work with the Lambda calculus and then  someday someone said to me, oh, you should check out some of these programming languages. They kind  of seem to be up your alley. But going back to Korean, over time, in my career as a linguist,  how a lot of people come up to me and tell me, oh, you should check out Korean. It's really  interesting. It's really easy to learn. And I usually get very skeptical when people tell me  things like that because usually like, usability of learning is a very subjective thing. It's very  dependent on what language background you've had in the past, what you can have as a context of  comparison. But I recently started learning more about the history of Hangul. And it turns out  it's quite interesting. So at the time in the 15th century, Korea was under Chinese rule. And so  the writing system that was being used at the time was the Chinese writing system. So this  immediately posed learnability problems because if anyone here is familiar with like the Chinese  writing system, there's a lot of just like, wrote memorization. There's some things where like,  if you learn like, 3,000 radicals, you've learned like 80 to 90% of the written words, but still like,  kind of a lot of like, just wrote memorization, right? Simultaneously, what made this writing  system hard for Koreans was that there were pretty significant language differences across the way  Korean and Chinese was being spoken, that it didn't always make sense to have a Chinese writing  system for Korean. This led to kind of rampant illiteracy at the time, where a lot of Koreans,  especially in the lower classes, were just not given access to learn how to read and write.  So, and I should say I learned all of this initially from a K drama that I'm pretty sure was just like,  pop propaganda, but I have since confirmed this on both Wikipedia and people at the Korean Cultural  Center. So, but so what happened was King Sejong at the time recognized that without some kind of  language for the people to bring the people together to create for his people, like a unified sense  of the Korean culture, they would always kind of be stuck relying on something that also wasn't  serving the people. So, he had his royal court of scientists think about how they could represent  the sound shapes of Korean in a way that lended itself to learnability. And so, again, as a  linguist, as a person who has been always interested in both natural language and now programming  languages, this idea of centering learnability, centering certain features in your design of the  language kind of really piqued my interest. So, I started taking Korean last fall and the end of  this anecdote is that it is actually that easy to learn. In two hours, I and like 50 other of my  classmates learned most of the characters of Hangul and here's why it's so easy to learn. So, below  each of the characters, the image is an image of sort of how that character was derived. It's  derived from the actual articulatory features that your mouth makes when you're producing a  certain sound. So, that first on the far left, that first character that looks kind of like a box,  that corresponds to the sound mmm. And the idea is that when you close your mouth, your mouth kind  of forms a little box shape. And the next one mmm, that you'll see there's a line in the picture here  where the it's sort of showing how the tongue hits the hard palate at the top and then kind of  comes back down in an L looking shape. And so on and so forth. So, this when I first saw this,  my mind was blown because if anyone has taken like an introductory linguistics class,  these images shouldn't look that foreign to you. You've done these things in phonetics. You  see the sagittal section. You learn about you know where your mouth is forming closures for air  and things like that. And so, what's been really interesting to me about learning Korean is that  all of a sudden there's this like really easy mnemonic for learning these letters. And if you've  ever like had to help someone learn the Latin alphabet for example, if you've ever had to  help someone learn English, there isn't that one to one correlation. It takes a lot of rote  memorization to get here. It takes a lot longer than two hours to get someone to learn all the way  from A to Z. So, my point for bringing this up is that a lot of times I'll hear people saying  things about Erlang and Elixir that because there are such significant paradigm shifts away from  kind of the standard way of doing things that's functional, that data is immutable, that it privileges  currency in this way, that's a hard language to learn or adopt. And I bring this up because I think  that actually when we consider things like Korean, when we consider things around how  when languages create connections between the real world and the representations within the language,  it actually creates a foundation of learnability and accessibility that allows learners to draw on  their real world experiences rather than have to think about the world that doesn't actually align  with the language that you're writing in. And I say this as someone who started off as a functional  programmer and then in my first software engineering job, we were using JavaScript and it was like  mutating state all the time and it was like totally foreign to me. I was like, wait, I don't do this  in real life all the time. I'm not like creating like arrays and then pushing stuff to them. Like,  I'm creating in the real world, I'm passing data from myself to others and we're transforming data  and state is not this thing that we just get to kind of plug and play or poke at all willy-nilly.  So my claim here is that I actually think that some of the things that people say about  Erlang and Elixir and in general functional languages is not actually true. It does require a  paradigm shift but I think once you kind of are able to draw those connections between what's  happening in the real world and how we think about what happens in the real world, it's actually  a much closer representation to what we do outside of programming. That was a digression.  We'll come back to Elixir. So that's a sort of talking about continuing to build accessible  features I think is a nice segue to talking about Elixir which continues in this tradition  that Erlang began and as we Elixir enthusiasts know, there are a lot of additional features and  tools that build upon this like really strong foundation that Erlang gives us but makes the  language a lot more accessible. There's a great talk by one of your NPEX co-organizers, Hannah,  about idea scalability and why Erlang for all of its awesomeness is not more widely available  and I think that's also relevant when we ask why we're not using Erlang now. But I think there's  also the idea of where people coming from, especially people who are doing the types of  development that they're doing with Elixir and why didn't they find Erlang accessible and I think  Elixir really was able to capture the spirit of Erlang but be able to make it more accessible to a  wider audience which has helped with its adoption. So some of those things and I'm going to start  off with like a pretty simple one is pipes and the reason why I'm starting off with the simple  one is I also want to kind of drive this idea that sometimes the things that we have, the things  that we can do to make things more accessible can be really, really simple. It can be as simple as  introducing something that Elixir didn't invent the notion of pipes like functional programmers  have seen pipes in all kinds of languages, right? But the reason why this is so valuable is that  in Erlang with the absence of pipes with this idea of immutability now all of a sudden like  when you're trying to do a lot of stuff to state one thing after another you very quickly end up  with code that is a lot of copy pasta with like a couple of variables changed or stuff that you  really have to read all the way through to follow and see what's going on. So for example let's say  this is kind of a little dummy example but let's say we have some state and we want to transform  it with some functions. So in Erlang without pipes this is one way you can do it, right? You can  assign the transformed state to another variable then transform that, assign that to another variable  then transform that and so on and so forth. But in order to kind of see what's going on you  actually have to like read every line and follow everything. Maybe that's not so bad but what can  we do to improve on it? So maybe we inline it. Okay, now we can kind of see at least that we're  transforming state you know three times over but now we have like these friends we have to keep  track of and it's not that great, right? So what pipes do is pipes just make this really clear,  they make it really simple and the nice thing about pipes again like this is not a new idea  but it makes it so that our code now of now all of a sudden can read more like pros from top to bottom  and we're able to highlight one of the strengths of functional programming, right? That we can treat  functions as if they are these data transformers that can combine in various ways to achieve some  kind of result. Cool, yeah okay so like I said simple example but I think it's like little syntactic  sugar stuff like this that just kind of makes a world of difference when it comes together. So  a few other things. So again none of these things alone is necessarily a new invention of elixirs  but I think all of these pull together and then laid on top of that foundation of Erlang is to  me what makes Erlang really or elixir really powerful and really a joy to work with. So  additional syntax changes so things like optional friends things like that. Things that again like  individually may not seem like they make a huge impact but put together you think about  the joy that you have writing elixir. I think some of that is some of those syntax modifications.  Also the power of metaprogramming. The ability for say macros to allow third party libraries to  provide internal DSL so anyone who's incorporated Ecto under a project knows the power of this  right? In terms of tooling having something like MIX that allows you to like really quickly and  simply create processes that can scaffold a project that can help you with dependency  management and also is extensible. The formatter this one is new to 1.6 and I was really excited  about it. For me I work on a large team where we get team members pulled off and on to projects  given like the pace of other work that's happening on other teams and so being able to have a  consistently formatted code base is like a huge thing. It's again seems like such a little thing  but especially when you're building large scale products that you might end up coming back to  six months later and you need to be able to sort of know what's going on without working  through someone else's quirky style. Having something like a formatter just built in is really huge.  And then EARLing compatibility. I mean we already mentioned some of the benefits of having that  foundation of EARLing but being able to call EARLing functions if something does it isn't  available in elixir means that we get to benefit from over 30 years of research on this language.  Okay cool. All right so I mentioned I was going to give a tiny little plug for Elm so who here  has touched Elm at all? Cool. Sweet. Okay so I won't belabor the details but for those that  haven't touched it here's my quick little plug. So Elm is a functional front-end language that was  inspired heavily by Haskell. It first appeared in 2012 by Evan Shapliki and I think the cell  that I give when I tell people about Elm is that it boasts virtually no runtime errors which  for front-end programmers you know this is huge right? So one of my favorite things about Elm  besides that those guarantees is how much care they put into their error messaging system so that  error messages can be embraced instead of being some kind of mysterious like thing that you have  to like decrypt and like work through to debug your app. So I'm going to go over some of the things  that I think they've done really well in their error messaging but a caveat some of the specific  types of error handling that you get in Elm is a direct consequence of its type system and the  like power of type-inferencing that it's capable of doing as a result of that type system. So for  the purposes of this talk I'm just going to be focused on like really the superficial stuff and  not that type stuff if you care about that type stuff though I will talk your ear about it afterwards  during a break or something. So one of the things that I think error messaging in Elm does really  well is helping you find those relevant bits of code. So I'm sure there are plenty of people in  here who remember getting error messages like program.x, colon 54, colon 96 and you have to  decipher them and you have to like go through your file you have to find that file. Two you have to  like go through find that line find that column you end up spending all this time scanning the  code whereas in something like Elm it's they just tell you up front and they even take you know  specific visual cues to show you where in that line the error occurred. Another thing that I think  is really great about the error messaging in Elm is you get friendly language so I'm sure some of  you can't see this in the back sorry. So in this example there's been a type error and again I'm  not going to go into the type stuff but the error message reads the first argument to function is  over 50 has an unexpected type looks like a record is missing the field age as I infer the type of  your values flowing through your program I see a conflict between these two types like it's so nice  to you it's like a friend who's giving you a suggestion and I think again that goes a long  way because if you think about when something goes wrong when you hit an error in your code  that's not a moment where you want someone to just be like no right so having something that  just leaves like a little bit more empathetic just helps you in that moment where you're like I just  want to get through this please tell me what happened and then finally this one this one just  seems super superficial that I once I saw it happening in Elm I was like mad that it wasn't  happening in other languages but just the use of color and formatting so those of us who build  products for users know that layout and color matter right so why is it that so many of our  error message systems usually are just like all one color like fire alarm red like and then there's  like this giant big text dump with no consideration for layout at all again like the the nice thing  in in this system is you know immediately what happened where and it's marked with color it's  the lines are like laid out and everything's not just all squished up so you have to like I kind of  like get in there to see what's going on it's designed for humans to read this and and be able  to access it all right so that was my plug for Elm and as a case in point I and this is a bit  unfair I realized but consider this example of an error in JavaScript right like so again the amount  of information that we have about the errors here is going to be a little bit different because  Elm's type inference system gives us a lot more power in terms of what we can pick up and I kind  of stack the deck against JavaScript's favorite because this is an error message on like minified  jcry source but even absent of all of these things like the considerations around like language color  and layout could be better taken into place here still I think sorry that is just my moment to  crap on JavaScript for a moment all right so finishing up we saw how languages that accept  the reality of the world as error prone and that provide features and tools for developers to create  fault-tolerant systems are both highly reliable and also maintainable so in this last part what I  want to consider is what we can learn in the other direction what we from the real world might be  able to take away from these systems so I think something that becomes really clear once you've  started started using a language like elixir is that it forces us into a paradigm shift in terms  of how we think about programs states and also how language can shape what we perceive to be  possible through what can be expressed so for me this is really illuminating when I started working  with the lambda calculus because it was so expressive but let's we can look at a somewhat more  concrete example so I am not going to say the name of the city but this is the name of a city in  Poland a lot of native English speakers have a problem pronouncing and the reason why is because  we don't have this consonant cluster in English we have other consonant clusters we have sk school  st stop but we don't have a gd so usually what we do in English when we encounter a consonant  cluster that we don't have natively is we'll do a thing called vowel a pentassist and we'll put a  vowel in between the two letters and that's what we do we say gdansk try saying it without the vowel  in between you will find it impossible but Polish in fact does have this and I'm going to play  hopefully this place so this is the the actual pronunciation of this of the city  no it's not playing  let's try and change the sound preferences really quickly great okay  dance so loud sorry dance okay that's it that's it but you see how in the native pronunciation  there's no vowel there right so what I think is interesting about this example is this informs how  the language that we use everyday shapes what we think is possible in terms of what we can  express and I think just as natural languages do this so too do our programming languages so I'd  like to suggest that just like learning about what another language makes possible phonologically  might do in terms of opening our minds in terms of what can be pronounced maybe we can learn something  from these programming languages too in terms of how we can embrace error in the world so what have  we learned from languages like these we've learned that error is a bound in the world that we live  in and we can't avoid them if we avoid them then you know just other problems start to pile on really  fast and I think this is a really important part of programming for me this was one of the things  that I found most freeing when I first started programming the fact that like failure wasn't  a thing that I had to control failure was just a thing that I had to learn how to like work with  and yet I cite this as something that we need to be mindful of because I think despite living in an  error prone world not everyone can abide by this rule to fail fast and I say this because I've for  the past five years I've been working with educators in low-income communities of color across Los  Angeles to teach computer science to middle school and high school students and I found really quickly  that when it came to the idea of fail fast I didn't know what to say to these students because for a  lot of these students for a lot of students of color for a lot of queer students for a lot of  female students fail fast wasn't an option for them outside of my classroom right fail fast was  something that sometimes could mean like violent outcomes failure to appear duly submissive with  law enforcement for example might mean death failure to comply with society's ideas around  gender and sexuality could also mean death and failure to correctly respond to unwanted advances  from someone who is sexually harassing them could also mean death and so I think before we ask  people to embrace fail fast fully we also need to think about what we can do to make the world  a better place for failure and and and full of errors so I'm gonna finish with this which  sadly also you can't see but I will share the slides after this this is from John Perry Barlow's  1977 25 principles of adult behavior and I've been seeing this image a lot this week because  he sadly just passed and I knew as soon as I saw this that I wanted to incorporate this somehow  and I wanted to talk about his legacy and honor his memory a little bit in the final moments of  my talk but I wasn't sure how so I start I kept looking at this image I kept looking this this  image and it has like advice like be patient no matter what don't trouble yourself with matters  you cannot truly change tolerate ambiguity and as I started reading these items more and thinking  about what I was talking about I was like oh duh it's just kind of we end here right because  I think it's very fitting that someone who has spent his lifetime working on the connections  between technology and policy would also produce something like this list these principles that  we can apply equally to languages that we use to create new things in the world as well as the  world that we inhabit when we bring these things to life that's it thank you
Morning_Keynote_0_83.png Morning_Keynote_84_179.png Morning_Keynote_180_863.png Morning_Keynote_864_971.png Morning_Keynote_972_1895.png Morning_Keynote_1896_2663.png Morning_Keynote_2664_5903.png Morning_Keynote_5904_8039.png Morning_Keynote_8040_11471.png Morning_Keynote_11472_14771.png Morning_Keynote_14772_16019.png Morning_Keynote_16020_19463.png Morning_Keynote_19464_21935.png Morning_Keynote_21936_25391.png Morning_Keynote_25392_25679.png Morning_Keynote_25680_28427.png Morning_Keynote_28428_28691.png Morning_Keynote_28692_30155.png Morning_Keynote_30156_30659.png Morning_Keynote_30660_31259.png Morning_Keynote_31260_36203.png Morning_Keynote_36204_37943.png Morning_Keynote_37944_38183.png Morning_Keynote_38184_38951.png Morning_Keynote_38952_39167.png Morning_Keynote_39168_40343.png Morning_Keynote_40344_41231.png Morning_Keynote_41232_44219.png Morning_Keynote_44220_46271.png Morning_Keynote_46272_47303.png Morning_Keynote_47304_48611.png Morning_Keynote_48612_49967.png Morning_Keynote_49968_50963.png Morning_Keynote_50964_51599.png Morning_Keynote_51600_52259.png Morning_Keynote_52260_54851.png Morning_Keynote_54852_57131.png Morning_Keynote_57132_58775.png Morning_Keynote_58776_58907.png Morning_Keynote_58908_58955.png Morning_Keynote_58956_59003.png Morning_Keynote_59004_59051.png Morning_Keynote_59052_59098.png
Hi everyone. I am super thrilled to be here. I'm especially thrilled to be talking about Elixir in LA and to end like such a cool venue also. This is probably the coolest venue setting that I've ever been in. I don't know if I've ever given a talk under a disco ball. So thank you, first like thank you to all the organizers. I think they've organized like a really great day for us. So yeah, very exciting stuff. But yes, hi, I'm Emma as Desin said. I am based in Los Angeles. I work at a startup, a sports tech startup based in LA at Second Spectrum. It's called Second Spectrum. It's very close to here. It's in little Tokyo just up the street a few blocks. And so what we do at Second Spectrum is we do a lot of work around both capturing data and then also passing the video capture through machine learning and computer vision layers to be able to derive certain insights from that video capture. We're currently the official optical tracking and analytics provider for the MBA. And in addition to that, we build full stack data visualization platforms that bring our advanced analytics data to life for coaches, leagues, and media broadcasters. A lot of the work that we do on the full stack apps team requires our products to have like reliable uptime, be able to serve a lot of users, and also be able to process a lot of data. So we've been using Elixir and some of my products for the past couple of years and we really come to love the language for a lot of reasons. A few of those reasons at a high level. So the language features themselves, the tooling that comes with Elixir, and the legacy that it inherits as a descendant of Erlang. And so I should pause here and say that as I was putting together this talk, initially I was prepared to just talk about these things in greater detail and kind of give you the pitch of like why Elixir. And I think it's important as a community that we continue to reflect on why we love this language, what the benefits are so we can share this with other people. And so I think that is a perfectly fine talk. But as I started to think more about some of these things in greater detail, I realized that for both me and the team that I work on, one of the reasons why we've come to love Elixir so much, and a common trend across some of the details of these individual details, was that the language really reflects the realities of the world we live in, rather than say an idealized version of it. And in particular what I mean is both Elixir and Erlang deliberately provide a language that accepts as a fact that sometimes things will fail. And to live in a world like this means that we have to design systems that can account for these failures without everything kind of like halting to a crash. And so being able to design these kinds of systems will require a language that prioritizes this, that accepts as a fact and does not sort of make us have to think about creating systems or things that cannot accept failure, cannot error. So one example of this that comes to mind that we'll go into like unpack a little bit more, but we'll just kind of discuss as an initial example is the feature of immutability in Elixir. And in my mind immutability is at its core about is about having a particular philosophy on failure, that is that the role of the mutation of data has in introducing to introducing error. So that's kind of what we're going to be talking about this morning. I kind of covered at a high level some of the things that I really like about Elixir, but I haven't gone into much detail about that. We will explore some of those details. But really what I'll be talking about this morning is taking us through this journey of what it means to embrace errors as a reality. First considering how this idea sort of sprung up with Erlang and the history of the language. And then considering the additional ways that Elixir is able to build upon this philosophy of embracing error and failure. And then because I couldn't possibly turn up, oh yes? Yeah, I can make the slides available after the talk. Yeah. So yeah, so we'll cover some of the additional features and tooling that's available in Elixir. And then because I couldn't possibly turn up an opportunity to plug Elm, which has become quickly my favorite front-end language, I'll talk a little bit about some of the ways that I think Elm also embraces this philosophy of embracing errors and what we can learn from Elm as well. And then lastly, when I think about some of the implications of what it means more broadly to embrace errors, what we can learn from what these languages are doing in embracing an error-prone world and what we might be able to take away from that into our lives in general. All right. So I'm going to start off with this number that I imagine many people in this room have seen who's seen this number before. Yeah. Okay. So this is the cell for Erlang, right? So this is 99.9999999%. It represents the uptime of the flagship product, the flagship Erlang product, AXD 301. It was built by Ericsson where Erlang was originally developed. And at the time that this was reported, I think in 2007 by Joe Armstrong, one of the people as part of the team that built Erlang, the codebase had over 2 million lines of Erlang code, which is pretty impressive. And it had been in operation for 20 years. So let's put 99's reliability into context, right? So, you know, typically we consider five nines to be pretty good. That amounts to 5.2 minutes of downtime per year. Seven nines is considered by some to be nearly unachievable, but they got nine. Nine nines. So this is pretty stunning to kind of do the math to sort of see how incredible that is. So over 20 years, 365 days and a quarter. In a year, 24 hours, in a day, 60 minutes, in an hour, 60 seconds, so on and so forth. That comes out to under a second of downtime over 20 years. And again, like, yeah, I heard a wow. It is incredible, right? With just over, a little bit over half a second of downtime over 20 years, this is like fantastic. This is like the way you sell this language, I think. And I remember when someone first told me about this number, I was, A, I did not believe them. But yeah, this is incredible, right? So, one, I was incredulous, I didn't believe it. But then once I got over my disbelief, the first kind of thought that popped in my head was how could this be? Like, how could a system that's been around for 20 years fail so rarely? Or how could I have so few errors? And the more that I learned about Erlang, what I realized was that was really asking the wrong question. What I realized was this number is in a reflection of a language that prevented or avoided or tried to live in a world that was absent of errors, but one that recognized errors as a matter of fact in the world that we live in. Errors are unavoidable. So how do we build systems that can accept that world? I think this is really telling when you consider the title of Joe Armstrong's 2003 thesis, where he describes the background of how Erlang came to be. The title is Making Reliable Distributed Systems in the Presence of Software Errors, not despite not, you know, trying to avoid them. It's in the presence of them. We just accept as fact that these errors are going to be there. In the introduction to the thesis, he says, large systems will probably always be delivered containing a number of errors in the software. Nevertheless, such systems are expected to behave in a reasonable manner. And so this really stuck out to me because a lot of times when we talk about software development, when we talk about software engineering, we talk about what can we do to make sure that our code is error-free and we're going to throw tests at it and throw type safety at it. And we're just going to make sure that as much as we can, our code is just nothing wrong ever around this. And to realize that the genesis of the thing, which is coming from a place where, you know, these systems were so widely distributed, they were used by so many people. And so the engineers just took as fact prima facie that errors are going to happen. They will be introduced sometimes. And what we have to do is ensure that when those things, when some things fail, they can fail fast, and other processes can continue to march along. So to kind of understand a little bit more about how Erlang does this and what that entails, we have to sort of dive deep into a bit of history. And we're going to start in the 1980s, where at Ericsson, the computer science laboratory that Joe Armstrong was a part of, searched for ways to make these processes of developing software result in more of reliable systems that are both easier and less expensive to build and maintain. And that takes us to 1986. So in 1986, Joe Armstrong starts working on a language that would eventually become Erlang. So the interesting thing that I learned from reading his thesis was, at the time, the language started as an experiment to add concurrent processes to Prologue. And he actually wasn't even really intending to design a new programming language when he first started working on this. He was interested in working on a program called the Plain Old Telephony Service. And at the time, the best method for working on this was to use a variant of Prologue that was augmented with parallel processes, which, you know, again, people who have used OTP, this should sound somewhat familiar or sort of a hint to what's to come. But what was interesting is that, you know, back in the day, 30 odd years ago, there were really only two models for approaching concurrency. And the dominant one at the time was the idea of shared-state concurrency. So shared-state concurrency involves this idea of mutable state where there's, you know, literally memory that can be changed. We can mutate it, we can move stuff around. And languages like C, Java, C++, etc., they have this idea where there's this, you know, stuff called memory and we can poke at it and we can change it and we can do stuff to it. And this is fine. So long as you only have one process doing all the changing, right? As soon as you have multiple processes sharing and modifying the same memory, this becomes very quickly a recipe for disaster. Like, like things go wrong really, really quickly. And so the problem, right, is that all of a sudden when we have shared memory, you need to prevent against simultaneous modification of that shared memory. So once that problem is introduced, well, how do we solve that? So the, like, common fix for that is to have some kind of locking mechanism. So depending on the language that you're working with, you may call this a mutex, a synchronized method. But either way, it's a locking mechanism. So now that you have locks, now you have this new problem. And that problem emerges when programs crash in some kind of critical region when it's, at a time when they're holding the lock. And other programs don't know what to do. They have been waiting, right? And now all of a sudden, like, everything kind of doesn't know how to lurch forward. So how do, how do developers approach fixing these problems? So there, there's some ways, there's some solutions to this. Transaction memories is one way of approaching it. But at this point, if you've been following the narrative, we've kind of, like, continued to inherit these problems because we started off with this assumption of sharing state for concurrency, right? And so a different approach to avoid all of these problems altogether is to approach concurrency from the perspective of message passing. And this is sort of the idea that they're pursuing in the early, when they're starting to think about how to build these reliable systems over at Ericsson. So in message passing, passing concurrency, we just completely get rid of the idea of shared state. And as a result of that, any computation is going to happen inside of a process. And the only way to exchange data is to be able to pass messages across processes asynchronously. So this ends up having some pretty big implications. Now all of a sudden, we no longer need to rely on mutable data structures. And if we don't have to rely on mutable data structures, well, now we don't need locks anymore. And if we don't need locks anymore, then we don't run into that other problem that we had where if, you know, a program crashes while something's in a lock, then other things don't know what to do. And so all of a sudden, all those other problems that we were having, we don't have anymore. But what do we do about parallelization, right? Because that was why we were committing to all these things in the first place. Well, that turns out to be pretty trivial. If you just think about parallelization as a process of your developer breaking up the solution of this problem into a number of parallel processes that can then communicate. So the kind of neat thing about this is if you kind of go to like the root level of the problem, you eliminate all the problems that you had before, you don't need to have to like pile on additional like cluchy fixes on top of one thing after another after another until you kind of get to a place where you're like, wait, why are we even here? Why are we trying to solve these problems? So this is the idea of concurrency oriented programming. And I found this blog post from 2007 from Joe Armstrong where he boldly makes the claim that objects are out and concurrency is in. And 11 years later, I don't know, I don't know the word like really living up to that. But something that stood out from the post where he made this claim was he's really pushing for this idea that the reason why we might want to commit to this approach towards programming is because if we think about the world that we live in, our world is concurrent. It is parallel. Things happen all over the place at the same time. And how does that happen? Well, we pass messages to one another, right? So let's imagine this room, right? Like, I have some private memory, you all have some private memory. And right now I have this private memory of all the stuff that I learned about the history of Erlang and Elixir that I want to share with you, name doing it through like light waves, sound waves. And then you're going to take that and you're going to update your private memory in some way as well through some kind of update process. And if say like the speaker blows out and like you can't hear me anymore, like you can still do that. You can still process whatever information made it through, right? You are not going to like freak out and just like wait. I hope you don't. I hope you don't. So this goes back to my idea or the kind of argument that I started off with at the beginning that when we embrace errors as a consequence of being realistic about how the actual world works, instead of turning away from how reality actually is, we can incorporate these things into the design of our language and that in turn can create something really powerful when our languages are reflective of the worlds we actually live in that can give us a lot of expressive power and in the case of Erlang as we saw, a lot of like reliability as well. So while we're on the topic of kind of learning from the world and incorporating that into languages, I'm going to digress for a moment and mention an anecdote that reveals in a different way how important it is for languages to be reflective of the world around them. So does anyone recognize these symbols on the screen? Yes, I saw it hand. What is it? Korean characters. Yeah, so these are the five base consonants from Hangul, the Korean alphabet, and Hangul was created in the 15th century. So I'm sure at this point you're like, huh, I came for an elixir talk, but now I'm looking at, we talked about Erlang and now we're looking at Korean. What happened? So let me explain a little bit more. And I'm going to give a little bit of like personal exposition also because it'll also maybe explain why I'm really interested in both programming languages and natural languages. So prior to my career as a software engineer, it's been about a decade as a formal semantasis working on natural language linguistic theory. And it's also how I ended up like learning the love functional programming because I was doing a lot of work with the Lambda calculus and then someday someone said to me, oh, you should check out some of these programming languages. They kind of seem to be up your alley. But going back to Korean, over time, in my career as a linguist, how a lot of people come up to me and tell me, oh, you should check out Korean. It's really interesting. It's really easy to learn. And I usually get very skeptical when people tell me things like that because usually like, usability of learning is a very subjective thing. It's very dependent on what language background you've had in the past, what you can have as a context of comparison. But I recently started learning more about the history of Hangul. And it turns out it's quite interesting. So at the time in the 15th century, Korea was under Chinese rule. And so the writing system that was being used at the time was the Chinese writing system. So this immediately posed learnability problems because if anyone here is familiar with like the Chinese writing system, there's a lot of just like, wrote memorization. There's some things where like, if you learn like, 3,000 radicals, you've learned like 80 to 90% of the written words, but still like, kind of a lot of like, just wrote memorization, right? Simultaneously, what made this writing system hard for Koreans was that there were pretty significant language differences across the way Korean and Chinese was being spoken, that it didn't always make sense to have a Chinese writing system for Korean. This led to kind of rampant illiteracy at the time, where a lot of Koreans, especially in the lower classes, were just not given access to learn how to read and write. So, and I should say I learned all of this initially from a K drama that I'm pretty sure was just like, pop propaganda, but I have since confirmed this on both Wikipedia and people at the Korean Cultural Center. So, but so what happened was King Sejong at the time recognized that without some kind of language for the people to bring the people together to create for his people, like a unified sense of the Korean culture, they would always kind of be stuck relying on something that also wasn't serving the people. So, he had his royal court of scientists think about how they could represent the sound shapes of Korean in a way that lended itself to learnability. And so, again, as a linguist, as a person who has been always interested in both natural language and now programming languages, this idea of centering learnability, centering certain features in your design of the language kind of really piqued my interest. So, I started taking Korean last fall and the end of this anecdote is that it is actually that easy to learn. In two hours, I and like 50 other of my classmates learned most of the characters of Hangul and here's why it's so easy to learn. So, below each of the characters, the image is an image of sort of how that character was derived. It's derived from the actual articulatory features that your mouth makes when you're producing a certain sound. So, that first on the far left, that first character that looks kind of like a box, that corresponds to the sound mmm. And the idea is that when you close your mouth, your mouth kind of forms a little box shape. And the next one mmm, that you'll see there's a line in the picture here where the it's sort of showing how the tongue hits the hard palate at the top and then kind of comes back down in an L looking shape. And so on and so forth. So, this when I first saw this, my mind was blown because if anyone has taken like an introductory linguistics class, these images shouldn't look that foreign to you. You've done these things in phonetics. You see the sagittal section. You learn about you know where your mouth is forming closures for air and things like that. And so, what's been really interesting to me about learning Korean is that all of a sudden there's this like really easy mnemonic for learning these letters. And if you've ever like had to help someone learn the Latin alphabet for example, if you've ever had to help someone learn English, there isn't that one to one correlation. It takes a lot of rote memorization to get here. It takes a lot longer than two hours to get someone to learn all the way from A to Z. So, my point for bringing this up is that a lot of times I'll hear people saying things about Erlang and Elixir that because there are such significant paradigm shifts away from kind of the standard way of doing things that's functional, that data is immutable, that it privileges currency in this way, that's a hard language to learn or adopt. And I bring this up because I think that actually when we consider things like Korean, when we consider things around how when languages create connections between the real world and the representations within the language, it actually creates a foundation of learnability and accessibility that allows learners to draw on their real world experiences rather than have to think about the world that doesn't actually align with the language that you're writing in. And I say this as someone who started off as a functional programmer and then in my first software engineering job, we were using JavaScript and it was like mutating state all the time and it was like totally foreign to me. I was like, wait, I don't do this in real life all the time. I'm not like creating like arrays and then pushing stuff to them. Like, I'm creating in the real world, I'm passing data from myself to others and we're transforming data and state is not this thing that we just get to kind of plug and play or poke at all willy-nilly. So my claim here is that I actually think that some of the things that people say about Erlang and Elixir and in general functional languages is not actually true. It does require a paradigm shift but I think once you kind of are able to draw those connections between what's happening in the real world and how we think about what happens in the real world, it's actually a much closer representation to what we do outside of programming. That was a digression. We'll come back to Elixir. So that's a sort of talking about continuing to build accessible features I think is a nice segue to talking about Elixir which continues in this tradition that Erlang began and as we Elixir enthusiasts know, there are a lot of additional features and tools that build upon this like really strong foundation that Erlang gives us but makes the language a lot more accessible. There's a great talk by one of your NPEX co-organizers, Hannah, about idea scalability and why Erlang for all of its awesomeness is not more widely available and I think that's also relevant when we ask why we're not using Erlang now. But I think there's also the idea of where people coming from, especially people who are doing the types of development that they're doing with Elixir and why didn't they find Erlang accessible and I think Elixir really was able to capture the spirit of Erlang but be able to make it more accessible to a wider audience which has helped with its adoption. So some of those things and I'm going to start off with like a pretty simple one is pipes and the reason why I'm starting off with the simple one is I also want to kind of drive this idea that sometimes the things that we have, the things that we can do to make things more accessible can be really, really simple. It can be as simple as introducing something that Elixir didn't invent the notion of pipes like functional programmers have seen pipes in all kinds of languages, right? But the reason why this is so valuable is that in Erlang with the absence of pipes with this idea of immutability now all of a sudden like when you're trying to do a lot of stuff to state one thing after another you very quickly end up with code that is a lot of copy pasta with like a couple of variables changed or stuff that you really have to read all the way through to follow and see what's going on. So for example let's say this is kind of a little dummy example but let's say we have some state and we want to transform it with some functions. So in Erlang without pipes this is one way you can do it, right? You can assign the transformed state to another variable then transform that, assign that to another variable then transform that and so on and so forth. But in order to kind of see what's going on you actually have to like read every line and follow everything. Maybe that's not so bad but what can we do to improve on it? So maybe we inline it. Okay, now we can kind of see at least that we're transforming state you know three times over but now we have like these friends we have to keep track of and it's not that great, right? So what pipes do is pipes just make this really clear, they make it really simple and the nice thing about pipes again like this is not a new idea but it makes it so that our code now of now all of a sudden can read more like pros from top to bottom and we're able to highlight one of the strengths of functional programming, right? That we can treat functions as if they are these data transformers that can combine in various ways to achieve some kind of result. Cool, yeah okay so like I said simple example but I think it's like little syntactic sugar stuff like this that just kind of makes a world of difference when it comes together. So a few other things. So again none of these things alone is necessarily a new invention of elixirs but I think all of these pull together and then laid on top of that foundation of Erlang is to me what makes Erlang really or elixir really powerful and really a joy to work with. So additional syntax changes so things like optional friends things like that. Things that again like individually may not seem like they make a huge impact but put together you think about the joy that you have writing elixir. I think some of that is some of those syntax modifications. Also the power of metaprogramming. The ability for say macros to allow third party libraries to provide internal DSL so anyone who's incorporated Ecto under a project knows the power of this right? In terms of tooling having something like MIX that allows you to like really quickly and simply create processes that can scaffold a project that can help you with dependency management and also is extensible. The formatter this one is new to 1.6 and I was really excited about it. For me I work on a large team where we get team members pulled off and on to projects given like the pace of other work that's happening on other teams and so being able to have a consistently formatted code base is like a huge thing. It's again seems like such a little thing but especially when you're building large scale products that you might end up coming back to six months later and you need to be able to sort of know what's going on without working through someone else's quirky style. Having something like a formatter just built in is really huge. And then EARLing compatibility. I mean we already mentioned some of the benefits of having that foundation of EARLing but being able to call EARLing functions if something does it isn't available in elixir means that we get to benefit from over 30 years of research on this language. Okay cool. All right so I mentioned I was going to give a tiny little plug for Elm so who here has touched Elm at all? Cool. Sweet. Okay so I won't belabor the details but for those that haven't touched it here's my quick little plug. So Elm is a functional front-end language that was inspired heavily by Haskell. It first appeared in 2012 by Evan Shapliki and I think the cell that I give when I tell people about Elm is that it boasts virtually no runtime errors which for front-end programmers you know this is huge right? So one of my favorite things about Elm besides that those guarantees is how much care they put into their error messaging system so that error messages can be embraced instead of being some kind of mysterious like thing that you have to like decrypt and like work through to debug your app. So I'm going to go over some of the things that I think they've done really well in their error messaging but a caveat some of the specific types of error handling that you get in Elm is a direct consequence of its type system and the like power of type-inferencing that it's capable of doing as a result of that type system. So for the purposes of this talk I'm just going to be focused on like really the superficial stuff and not that type stuff if you care about that type stuff though I will talk your ear about it afterwards during a break or something. So one of the things that I think error messaging in Elm does really well is helping you find those relevant bits of code. So I'm sure there are plenty of people in here who remember getting error messages like program.x, colon 54, colon 96 and you have to decipher them and you have to like go through your file you have to find that file. Two you have to like go through find that line find that column you end up spending all this time scanning the code whereas in something like Elm it's they just tell you up front and they even take you know specific visual cues to show you where in that line the error occurred. Another thing that I think is really great about the error messaging in Elm is you get friendly language so I'm sure some of you can't see this in the back sorry. So in this example there's been a type error and again I'm not going to go into the type stuff but the error message reads the first argument to function is over 50 has an unexpected type looks like a record is missing the field age as I infer the type of your values flowing through your program I see a conflict between these two types like it's so nice to you it's like a friend who's giving you a suggestion and I think again that goes a long way because if you think about when something goes wrong when you hit an error in your code that's not a moment where you want someone to just be like no right so having something that just leaves like a little bit more empathetic just helps you in that moment where you're like I just want to get through this please tell me what happened and then finally this one this one just seems super superficial that I once I saw it happening in Elm I was like mad that it wasn't happening in other languages but just the use of color and formatting so those of us who build products for users know that layout and color matter right so why is it that so many of our error message systems usually are just like all one color like fire alarm red like and then there's like this giant big text dump with no consideration for layout at all again like the the nice thing in in this system is you know immediately what happened where and it's marked with color it's the lines are like laid out and everything's not just all squished up so you have to like I kind of like get in there to see what's going on it's designed for humans to read this and and be able to access it all right so that was my plug for Elm and as a case in point I and this is a bit unfair I realized but consider this example of an error in JavaScript right like so again the amount of information that we have about the errors here is going to be a little bit different because Elm's type inference system gives us a lot more power in terms of what we can pick up and I kind of stack the deck against JavaScript's favorite because this is an error message on like minified jcry source but even absent of all of these things like the considerations around like language color and layout could be better taken into place here still I think sorry that is just my moment to crap on JavaScript for a moment all right so finishing up we saw how languages that accept the reality of the world as error prone and that provide features and tools for developers to create fault-tolerant systems are both highly reliable and also maintainable so in this last part what I want to consider is what we can learn in the other direction what we from the real world might be able to take away from these systems so I think something that becomes really clear once you've started started using a language like elixir is that it forces us into a paradigm shift in terms of how we think about programs states and also how language can shape what we perceive to be possible through what can be expressed so for me this is really illuminating when I started working with the lambda calculus because it was so expressive but let's we can look at a somewhat more concrete example so I am not going to say the name of the city but this is the name of a city in Poland a lot of native English speakers have a problem pronouncing and the reason why is because we don't have this consonant cluster in English we have other consonant clusters we have sk school st stop but we don't have a gd so usually what we do in English when we encounter a consonant cluster that we don't have natively is we'll do a thing called vowel a pentassist and we'll put a vowel in between the two letters and that's what we do we say gdansk try saying it without the vowel in between you will find it impossible but Polish in fact does have this and I'm going to play hopefully this place so this is the the actual pronunciation of this of the city no it's not playing let's try and change the sound preferences really quickly great okay dance so loud sorry dance okay that's it that's it but you see how in the native pronunciation there's no vowel there right so what I think is interesting about this example is this informs how the language that we use everyday shapes what we think is possible in terms of what we can express and I think just as natural languages do this so too do our programming languages so I'd like to suggest that just like learning about what another language makes possible phonologically might do in terms of opening our minds in terms of what can be pronounced maybe we can learn something from these programming languages too in terms of how we can embrace error in the world so what have we learned from languages like these we've learned that error is a bound in the world that we live in and we can't avoid them if we avoid them then you know just other problems start to pile on really fast and I think this is a really important part of programming for me this was one of the things that I found most freeing when I first started programming the fact that like failure wasn't a thing that I had to control failure was just a thing that I had to learn how to like work with and yet I cite this as something that we need to be mindful of because I think despite living in an error prone world not everyone can abide by this rule to fail fast and I say this because I've for the past five years I've been working with educators in low-income communities of color across Los Angeles to teach computer science to middle school and high school students and I found really quickly that when it came to the idea of fail fast I didn't know what to say to these students because for a lot of these students for a lot of students of color for a lot of queer students for a lot of female students fail fast wasn't an option for them outside of my classroom right fail fast was something that sometimes could mean like violent outcomes failure to appear duly submissive with law enforcement for example might mean death failure to comply with society's ideas around gender and sexuality could also mean death and failure to correctly respond to unwanted advances from someone who is sexually harassing them could also mean death and so I think before we ask people to embrace fail fast fully we also need to think about what we can do to make the world a better place for failure and and and full of errors so I'm gonna finish with this which sadly also you can't see but I will share the slides after this this is from John Perry Barlow's 1977 25 principles of adult behavior and I've been seeing this image a lot this week because he sadly just passed and I knew as soon as I saw this that I wanted to incorporate this somehow and I wanted to talk about his legacy and honor his memory a little bit in the final moments of my talk but I wasn't sure how so I start I kept looking at this image I kept looking this this image and it has like advice like be patient no matter what don't trouble yourself with matters you cannot truly change tolerate ambiguity and as I started reading these items more and thinking about what I was talking about I was like oh duh it's just kind of we end here right because I think it's very fitting that someone who has spent his lifetime working on the connections between technology and policy would also produce something like this list these principles that we can apply equally to languages that we use to create new things in the world as well as the world that we inhabit when we bring these things to life that's it thank you
do at Second Spectrum is we do a lot of work to that, we build full stack data visualization broadcasters. A lot of the work that we do on the where at Ericsson, the computer science when they're starting to think about how to build here? Why are we trying to solve these problems? interested in both programming languages and consider things around how when languages create have seen pipes in all kinds of languages, right? combine in various ways to achieve some kind of things like the considerations around like low-income communities of color across Los Angeles to teach computer science to middle a lot of students of color for a lot of queer