 So, my name is Ryan Finley. I've been primarily a Ruby developer for a long time now, and I'm here to talk to you about the Elixir programming language today, but first a bit about my perspective so you know where I'm coming from. At work, we work on projects that last for many years, not many months, so I'm hesitant to adopt any tools that might be short-lived. We've got more active projects than developers, so I need strong standards and norms from the communities of the tools that we pick. You could say that I'm conservative about what tools I'll recommend our customers use. So Erlang. I've been dabbling in Erlang for almost as long as I've been using Ruby, but it never really felt like it fit my problems as nicely as Ruby did for me. I never really got any momentum with it, even though I had a few friends that really fell in love with it. OTP is a collection of middleware and libraries in Erlang, and using it is pretty much how you get things done in Erlang. Erlang was originally developed at the Ericsson Computer Science Laboratory and used to build telephone switches in the 80s. OTP stands for Open Telecom Platform, which isn't really relevant anymore, and it's a collection, I already said, middleware and libraries. Elixir is to Erlang what Scala or Clojure are to Java, if Java was already a functional language to begin with. It's a Ruby-like syntax that compiles down to Erlang's VM. You can freely use your Erlang code in your Elixir code, and from my perspective, inheriting the stability of the Erlang platform provides a solid foundation, and it's what caught my attention. So as a Rubyist in the Elixir community, it kind of feels like being at an expat bar. Not everybody came from exactly the same place as you, but everyone's basically speaking the same language you're used to, even though they might sound a little funny. They have their own mantras that will maybe scratch an itch for you if you've been in the Ruby and Rails world for a while. For example, instead of don't repeat yourself, they say no magic, and in my mind, those two kind of balance each other. Phoenix is the dominant web application framework, and they like to say Phoenix is not your app because Elixir has a standard folder layout, and Phoenix conforms to it. If you want to get started with Elixir, I highly recommend the little Elixir and OTP guidebook. It took me about four or five times for someone recommending it to finally buy it, and it's been great. My advice to you, if you want to get started with Elixir, and if it's your first functional programming language, would be that it might feel a little weird at first, but to try the new ways of thinking and to do things the way the community does them before you try to make yourself feel comfortable. There's some videos up here linked. I guess I'll find a way to share these slides. The first one, it really addresses that point that it's called giving up the object-oriented ghost, and she covers a lot of the initial reactions you may have to being in a functional environment. The others are really good, too, if you want to do a deeper dive. I do a lot with active records, so I thought leveling up with Ecto was really fun, and then the abstractions one was just sort of just deep thoughts. I thought that was good. So the title of this talk is object-oriented thinking, so enough about the background. On the left side, you'll see the definition of object-oriented according to Al and Kay, according to a wiki. On the right side, you'll see the definition of the Erlang worldview according to Joe Armstrong, according to Wikipedia. This is not all of its relevance to this short talk, so I removed a bunch of things to help us focus. You'll see two things are pretty much the same for our purposes. And once you do that, you see in the Ruby world, everything is an object. In the Erlang world, everything is a process. In the Ruby world, objects communicate by sending and receiving messages, and message passing is the only way for Erlang processes to interact. And objects have their own memory. Processes are strongly isolated and share no resources. So that's what I mean by object-oriented thinking. It's about message passing and private internal state. In Ruby, message passing means calling a method. But in Erlang, they have this thing called the actor model, where every process is uniquely identified by a name or a PID and has a mailbox. So you can communicate with any process by sending messages to its mailbox and you receive responses in your mailbox. Erlang added symmetric multi-processing support in 2006. So that means if you've got multiple cores, it automatically uses them all and you get that performance benefit like Apple more recently did with Grand Central Dispatch. But there's an added benefit in the Erlang world that there's something called distributed Erlang, where you can run Erlang on a bunch of boxes, and if it fits your model, you can scale that way. So all of your actors can live on different machines and you can just scale up pretty indefinitely for some use cases. So I'm going to show you a really contrived Ruby example of a chat application, it's the beginnings of a chat application. So all you can do is post the message. You can get your full history, you can reset your history, and then we have a private method that records the message with a timestamp. So this should make sense to, I think, most of the people in the room. And here's a version of it that you would probably get upset if you found in a code base, where I'm using method missing to look a bit more like the elixir code that's coming up and to put the emphasis on the messages that we're receiving. So you still have your post message, your get history, and your reset history, and your private method that timestamps things. So a problem for object-oriented programmers in a functional world is how do you preserve your state? And this one simple trick is how you do that. You'll see that the receive block here looks a lot like the method missing we had, there's three separate cases here that we handle. We handle the processing and response, but it's all wrapped in a loop that passes, so each call, each post message, get history, reset, invokes loop again recursively and passes in the modified history. In the Ruby world, if you did this, you'd get a stack overflow, but this is a completely valid approach in elixir because of the magic of tail recursion, and I've got a relevant XKCD here. So now that we've got this state in our infinite loop, how do we communicate with it to find out from elsewhere in our code what's been going on? The way we do that is we spawn a process. So I've got some example code here. Can you guys see that? It's tough. All right, I'm not sure what I can do now. Sorry, I guess I'll read what's going on. So this is IEX, it's just like IRB, but for elixir. On line number one, I'm spawning the process and receiving the PID into a variable. Lines two and three use the PID to send a message. Line four asks for the complete history, and then this is all asynchronous. So when you use send, it'll send something back, but that goes into your inbox, which in our case belongs to IEX. So flush is gonna read our inbox, dump it to the screen. So this is the contrived elixir example again. You see when you call get history, it calls send using the PID of the person that made the request. So that's how we got all that information. But then we had to call flush in order to be able to see that in this example. So this example, so with our previous example, you've got processes that can send or receive messages. But that alone is a little bit difficult to work with. We've got to keep track of our PIDs, everything's asynchronous, and we haven't handled errors or any other failures yet. So this is an example, probably also hard to read, sorry. Rewritten using an OTP template. So on line one, we call start link, which spawns the process. But also links it to the parent process, which I'll talk about more in a second. Two and three sends in the chat messages the same as before, but this time it looks a lot more like calling a method on an object or a class. And line four, we call get history again. But you'll notice there's no line five because everything's synchronous now. Because we can define it that way pretty simply, which I'll get to in a second. This, you'll notice, is much longer than the Ruby code. I think no magic sometimes means much more verbose. I'm gonna break this into sections and step through each. So the first here, we're saying use gen server. Gen server is generic OTP behavior. The advantage of using it over just spawning a process is that it'll include functionality for tracing and error reporting. And it'll also fit it into a supervision tree, which is how you build resilient code. It comes with restart strategies and a bunch of other stuff that is really interesting to read about if you're so inclined. The gen server design pattern also communicates our intentions with other developers reading the code or our future selves. Makes our code much more maintainable. And then on line four, you notice we have a name parameter here that looks like a Ruby instance variable. This is, lets us do sort of a singleton pattern where we don't need to keep track of the pit anymore. So the next section is the client API. We've got the start link, which we use to start the process and link to the parent process. Then we have our post message, get history and reset history just like before. You'll notice that lines 13 and 17 use call and lines 21 and 25 use cast. Your call is for synchronous methods that you want to return instantly and cast is for asynchronous that you don't care when it's done. So those, these API methods call our server callbacks that we also have to define. So this looks a lot like our receive block that looked a lot like our method missing block where we've got post message, get history and reset history. But they can, they're using the OTP sort of framework to either reply or not reply because they're synchronous or asynchronous. And this lets us, instead of one big receive block, we have more manageable small functions. You'll notice that these methods pass the state around using a variable called history the same way we did in our loop. So this is sort of housekeeping stuff at the bottom. GenServer has an init and a terminate that's a lot like set up and tear down in an object. And handleInfo is a genServer thing to help you track things down, debug. That concludes my tour of contrived OTP code. If you have any questions, I'll be happy to talk to you about it around the conference. Thanks.