CoRecursive: Coding Stories - Tech Talk: Erlang And Distributed Systems with Steven Proctor
Episode Date: May 2, 2018Tech Talks are in-depth technical discussions. Today's interview is with Steven Proctor, the host of the functional geekery podcast. We talk about distributed programming in general and specifically... how erlang supports distributed computing. We also talk about things he's learned about functional programming and applying FP principles to various non FP contexts. Contact Proctor: Functional Geekery Podcast @stevenproctor @fngeekery
 Transcript
 Discussion  (0)
    
                                         Let's do the object-oriented idea, which is a good idea, and we're just going to turn it up to 11.
                                         
                                         Hey, in today's interview we talk about distributed systems and functional programming,
                                         
                                         specifically a lot about Erlang, and also we touch a little bit on my favorite topic,
                                         
                                         which is building your own mechanical keyboard.
                                         
                                         Proctor is the host of the Functional Geekery podcast and also runs an Erlang meetup.
                                         
                                         Proctor, welcome to the podcast.
                                         
                                         Thanks for having me.
                                         
                                         So I'm a longtime fan of your podcast and I have some questions for you.
                                         
    
                                         So what is functional programming?
                                         
                                         What is functional programming?
                                         
                                         I'm not really sure. That's one of those things that I've heard a bunch of other people try and say their definitions.
                                         
                                         And I've heard the quote, I think it's, you ask a thousand people what functional programming is, you'll get at least a thousand and one different answers.
                                         
                                         So I think at this point, the basis for what appeals to me, at least, of functional programming is limiting side effects.
                                         
                                         And by limiting those side effects, you drive towards what people commonly think of as functional programming solutions.
                                         
                                         So it comes down to limiting, in my view, where the side effects in your system happen. So you try to limit the proportion of
                                         
                                         your code base that does
                                         
    
                                         side effects to the minimum
                                         
                                         part that
                                         
                                         you can. So what's the advantage
                                         
                                         of that? So for me,
                                         
                                         that gets
                                         
                                         back down to having worked on an
                                         
                                         app at one point for
                                         
                                         10 years.
                                         
    
                                         There were a lot of innocuous decisions or decisions that seemed
                                         
                                         innocuous at the time that five, seven, 10 years later was like, oh, this is real pain. And so I
                                         
                                         started feeling these pain points. And it was trying to figure out what these things are. And
                                         
                                         some of that came from the test driven design side and making contracts and kind of having the hint of pure functions.
                                         
                                         It's easier to test if data coming in or data coming out is dependent on data coming in and getting rid of mocks.
                                         
                                         So if you have to mock it, you realize it's harder.
                                         
                                         And these ideas were kind of setting that foundation that when I saw functional programming, I was like, okay, I see where this,
                                         
                                         like this thing's going even further.
                                         
    
                                         So single responsibility principle,
                                         
                                         single responsibility principle and object oriented says it has one reason to
                                         
                                         change. Well, if you take that to the extreme at a certain point,
                                         
                                         that's just an interface with one method on it.
                                         
                                         And that method is really almost a function because you don't change the data underneath it.
                                         
                                         You just change the behavior.
                                         
                                         Or you have interface segregation principle and object-oriented side,
                                         
                                         which is things that don't change together get separated out.
                                         
    
                                         And so if you take that to the extreme,
                                         
                                         well, every interface is just one function.
                                         
                                         Can I push something?
                                         
                                         I have something that's pushable.
                                         
                                         I can push something onto a stack.
                                         
                                         But I can push something onto a list,
                                         
                                         or I can push something onto this.
                                         
                                         And so the interface is really pushable,
                                         
    
                                         which is just a push method.
                                         
                                         Things like mappable, or I have things that are stop-poppable,
                                         
                                         or I have things that are enumerate, where I just iterate over the next,
                                         
                                         and I can just call next, and that becomes like a stream.
                                         
                                         So some of these ideas were kind of setting that thing,
                                         
                                         and I saw functional programming, and it realized that, yeah,
                                         
                                         some of these things are functions.
                                         
                                         And it kind of realized that if I want to limit these changes, I can start doing this.
                                         
    
                                         And that's kind of where the appeal for functional programming came for me was all these principles that get touted in object-oriented or procedural, they're the same principles in functional programming.
                                         
                                         They're just looked at it from a different side and almost taken to the extreme of, oh,
                                         
                                         because data is one reason to change and behavior is another reason to change.
                                         
                                         So maybe your data and your behavior doesn't necessarily belong together.
                                         
                                         And so it was a lot of all these things that kind of pushed me down that track
                                         
                                         and seeing what are those things that go
                                         
                                         and what are the common principles,
                                         
                                         whether or not it's from functional or from OO.
                                         
    
                                         And so there was a lot of these ideas that formed
                                         
                                         that I think functional programming, to me,
                                         
                                         is just a lot of these ideas about
                                         
                                         how do we control what goes on in our
                                         
                                         system?
                                         
                                         And by pushing to these bounds,
                                         
                                         you wind up in a more functional programming oriented mindset.
                                         
                                         So you're saying functional programming is sort of best practices from the OO
                                         
    
                                         world,
                                         
                                         you know,
                                         
                                         taken to a,
                                         
                                         to a larger,
                                         
                                         taken to a more extreme stance so do you find is oo and
                                         
                                         and fp like in conflict with each other or or do they sit well together
                                         
                                         i think they sit well because there are points at which you need to
                                         
                                         actually modify stuff and i think in that case of modifying stuff, the object oriented side
                                         
    
                                         can fit together. And some of this object oriented side is more of the Alan Kay's small talk
                                         
                                         vision of message passing between things. So this is where people who are familiar with Erlang say
                                         
                                         Erlang is actually both functional programming and it's
                                         
                                         object-oriented and it's probably one of the more object-oriented languages besides small talk that
                                         
                                         you actually find maybe Eiffel's up there as well but I think there's a lot of the sense of
                                         
                                         they live well together in a certain extent now again I haven't gotten into monads and free monads
                                         
                                         and a lot of these other side effects capturing concepts.
                                         
                                         So I'm not quite sure how well that fits in.
                                         
    
                                         But I've heard other people, Michael Feathers, I believe,
                                         
                                         Gary Bernhardt, I believe, and a couple of other people
                                         
                                         talk about functional core, imperative shell.
                                         
                                         And some of this stuff is Alistair Coburn's hexagonal architecture.
                                         
                                         The outside of your system, you push everything that does side effects as far out of your system
                                         
                                         as you can. And you keep the pure stuff and you keep the center, you keep the core domain stuff
                                         
                                         as pure as you can. So I think there is a place where both of these fit in.
                                         
                                         Because eventually, as a lot of people tout that if you didn't have side effects, you wouldn't be
                                         
    
                                         doing anything because even at the purest level, running this computation is going to eventually
                                         
                                         make your fan run hot. So there is some side effects there on our current architecture, it's controlling those and pushing them to the
                                         
                                         outer bounds of the system. So in a lot of cases, for anybody who's doing object oriented programming,
                                         
                                         people talk about checking your data at the perimeter and assuming once it gets inside your
                                         
                                         system, all the data is good. So do all your null checks at the very edge of your system.
                                         
                                         Assume once you're in your domain logic,
                                         
                                         you'd never have any nulls.
                                         
                                         If you take that idea and you just treat that with side effects as well,
                                         
    
                                         it's put all the side effects
                                         
                                         at the outer boundaries of your system.
                                         
                                         And then anything that needs to happen
                                         
                                         already has its data.
                                         
                                         And then you can just do data transformations
                                         
                                         and modifications through the rest of your system,
                                         
                                         and it starts being easy.
                                         
                                         And then you build immutability on top of that
                                         
    
                                         as another way of limiting your side effects
                                         
                                         and the way you interact with things and change things.
                                         
                                         Then you know that, okay, if this thing is this, it's always that.
                                         
                                         And in other languages like Erlang and Haskell
                                         
                                         and certain other languages, you only have binding.
                                         
                                         So you can only set it once in that scope too.
                                         
                                         So you know if X is Y, X is always Y for that scope
                                         
                                         and it's never going to change and all of a sudden X becomes Z.
                                         
    
                                         So that's the view that I found.
                                         
                                         And sadly, I don't get to do functional programming day to day.
                                         
                                         As a lot of people would say, oh, you're working in a Haskell,
                                         
                                         you're working in an Erlang or Elm or PureScript or Scala
                                         
                                         or pick your closure or pick your functional language of your choice.
                                         
                                         A lot of this is still, okay, I'm in JavaScript,
                                         
                                         or I'm in Ruby, or I'm in Bash programming,
                                         
                                         or I'm in whatever it is that requires me to do it.
                                         
    
                                         How can I essentially bring the most sanity to what I'm doing?
                                         
                                         So that's a good question. So you're saying day-to-day you're working in Bash and Ruby and JavaScript.
                                         
                                         So how do these principles influence what you do in those languages?
                                         
                                         Some of that is, like all good answers, it depends.
                                         
                                         If there's some certain areas, I try and think of data transformations first.
                                         
                                         That becomes easier in certain languages.
                                         
                                         Potentially, JavaScript might be a little bit easier to pull that off
                                         
                                         if you fold in underscore or Lodash,
                                         
    
                                         or potentially you can sneak in some Ramda
                                         
                                         because people understand underscore,
                                         
                                         and you can kind of say well here's underscore like improved and
                                         
                                         evolved so pretty much everything you know about underscore here's a few things and you can use it
                                         
                                         pretty much the same but if you need to you can do this other stuff uh if you're doing ruby sometimes
                                         
                                         you can find off the place that okay well what if we copied this or what if we just took this object and it returned a new
                                         
                                         object and didn't really modify this,
                                         
                                         or at least what if we think of a transformation,
                                         
    
                                         even if we are modifying it because of the constraints render,
                                         
                                         but think of this as a series of map and reduce and folds in any other
                                         
                                         operations.
                                         
                                         And we can kind of just chain these things
                                         
                                         and think of it as that pipeline operator
                                         
                                         that certain functional programming languages have,
                                         
                                         where you can say, here's the series of transformations
                                         
                                         instead of, okay, well, it's a series of a bunch of these other calls.
                                         
    
                                         And when you say, to make sure I understand this,
                                         
                                         when you say a data transformation, you're saying
                                         
                                         immutability is like a functional programming principle.
                                         
                                         And so in Ruby or wherever I am, rather than changing the value of a user,
                                         
                                         my function can create a new user with that value changed.
                                         
                                         Is that what you mean by transformation?
                                         
                                         Sometimes, if I can get away with that.
                                         
                                         Sometimes in Ruby, sometimes in JavaScript or these other languages,
                                         
    
                                         to do that, A becomes hard.
                                         
                                         It becomes hard A because that's not how that language is necessarily shaped.
                                         
                                         So sometimes there's things where you're like, okay, let's just take the hit,
                                         
                                         we can take this hit. Other times it's, well, you're on an existing code base, you can't all
                                         
                                         of a sudden just go make this object immutable. That's going to break too many other things.
                                         
                                         So at least with data transformation, maybe we can outline it as a series of steps that this
                                         
                                         data goes through. So this data, this thing happens,
                                         
                                         and then this thing happens, and then this thing happens. So yes, I may be modifying it in place,
                                         
    
                                         which is kind of cringeworthy, but at least I've outlined the discrete steps of how this data gets
                                         
                                         transformed and thinking about it in a pipeline or composition
                                         
                                         of these things together. Even if it is mutating the state, I can at least start to
                                         
                                         ship that mindset of it's a series of steps that we're going to do. This is we're thinking in an
                                         
                                         algorithm. So let's actually think in the steps and outline those steps that the data goes through,
                                         
                                         even if it is being transformed on the same objects. Yeah, because there is a cost to
                                         
                                         immutability, especially depending on the language, right, of actually making copies of things.
                                         
                                         And it's not just that cost, it's the cost of the introduction to teammates, potentially.
                                         
    
                                         If you're in a team where a bunch of people
                                         
                                         may or may not be familiar
                                         
                                         with the functional programming ideas,
                                         
                                         you start introducing immutability everywhere.
                                         
                                         That might be a harder push
                                         
                                         as opposed to just say,
                                         
                                         okay, well, let's think about
                                         
                                         how we're changing the data.
                                         
    
                                         And then maybe once we get that,
                                         
                                         we can show that,
                                         
                                         well, do we need to change the data or can we create a copy? And it's that slow evolution of some of these ideas.
                                         
                                         So it's a culture war within your workplace where you have to convince them that you're not crazy, A, if people aren't bought in to begin with, just to essentially make it a sink or swim idea in something that is an existing context becomes something you want to watch out for because then you don't want to start that culture war, right?
                                         
                                         If you're taking a Ruby and saying rewrite it in Haskell, then you don't want to start that culture war, right? If you're going into, if you're taking a Ruby and saying,
                                         
                                         rewrite it in Haskell, then you're thinking in Haskell.
                                         
                                         If you're saying Ruby and let's think in terms of more functional styles
                                         
                                         in a more object-oriented language, then it may just be,
                                         
    
                                         how do we start to think these things?
                                         
                                         Because even then, these are still potential object-oriented things.
                                         
                                         We think of workflows.
                                         
                                         We think of pipelines.
                                         
                                         We think of potentially state machines.
                                         
                                         Even if that state machine or that pipeline is modifying the same data,
                                         
                                         can you take these ideas and introduce them
                                         
                                         so it's not one of those things that's completely unfamiliar and you lose the battle, you lose the war before the first battle is even finished in the fact of just trying to get exposure to these things.
                                         
    
                                         Right. So there's a thing, there's the idea that's more of the pragmatist that says, yes, I love functional programming.
                                         
                                         Yes. I wish I could write every code functionally.
                                         
                                         Even I'm bad at that in non-functional languages that don't keep me strict.
                                         
                                         So how can I, knowing my limitations,
                                         
                                         how can I make this easier for someone
                                         
                                         instead of making them swallow everything at the same time and slowly expose these ideas
                                         
                                         and build upon ideas little by little and exposure by exposure and saying, okay,
                                         
                                         what if we did it this way? How do we think about this? Instead of redoing and reintroducing
                                         
    
                                         someone and making them feel like they don't know anything about coding
                                         
                                         or challenging and saying, you don't know anything about coding. Here's how you do this. And this is
                                         
                                         the much better way, even though what you're doing has worked for you and you've been successful with
                                         
                                         it in your career. I'm going to completely invalidate it. It's more about how do we
                                         
                                         approach these things? How do we make this more familiar instead of, and therefore easier to grasp onto because
                                         
                                         that familiarity is there instead of saying, no, now for something completely different.
                                         
                                         And I expect you to learn this and cater to my will, even if the language is not even
                                         
                                         wanting to cater to my will.
                                         
    
                                         Yeah, I can understand that battle can be hard to fight. But a pragmatic approach,
                                         
                                         I think, always makes sense. You mentioned Erlang. So for anyone who's not familiar,
                                         
                                         what is Erlang? So Erlang was the solution to the software crisis that Ericsson was identifying in the 80s.
                                         
                                         They had Joe Armstrong, Robert Verding, and Mike Williams as part of this lab.
                                         
                                         Their goal was to, people are expensive, software is expensive to write.
                                         
                                         How do we do this? We need to solve this problem of making our telephone switches
                                         
                                         and doing the software for this and making it reasonable to write.
                                         
                                         Can you go off and solve this problem?
                                         
    
                                         Because we need constraints of high availability
                                         
                                         because we get fined if the phone lines are down.
                                         
                                         You don't want the phone lines cutting out when you have to make a 911 call.
                                         
                                         You don't want phone lines to go down because my call with you is ruining someone else's call
                                         
                                         because our call goes bad. So they had a bunch of these constraints. And so Joe, Mike, and Robert went off and started looking at a bunch of different solutions. And essentially Erlang was a language that they evolved in what sounds like a very agile way of sitting with the people who are actually going to be writing the software and building a tool for them that solved their problems. And so Erlang became, out of necessity of the problems they were solving,
                                         
                                         it became functional because they needed to limit their side effects.
                                         
                                         It became functional because they couldn't have shared state.
                                         
                                         So if things are running on five switches, if one switch goes down, you can't share that state.
                                         
    
                                         It's got to be isolated.
                                         
                                         So you kind of start being functional in that way.
                                         
                                         It became message passing because of the way that they were dealing with concurrency.
                                         
                                         And these things can happen in whatever order they can happen. And a lot of these constraints kind of led them to reinventing an active model, as they say.
                                         
                                         They didn't know they were doing an active model with message passing.
                                         
                                         They didn't realize they had functional programming experience, but a lot of that functional programming stuff became implicit because of the problem they were trying to solve.
                                         
                                         If we take down one computer, we take down one switch in the network, we can't crash the whole network.
                                         
                                         We need to be able to move things around. And so Erlang became this functional message passing
                                         
    
                                         system that was designed for high throughput, high availability, had things to schedule. So it was near real-time requirements,
                                         
                                         not absolute real-time, but very near real-time. So they couldn't starve any piece of work
                                         
                                         for too long. There were all these other constraints that made them wind up with
                                         
                                         Erlang as it is. And it became a very interesting language and it made me, one of the things that I appreciated about Erlang was it made me rethink how
                                         
                                         some of these systems work.
                                         
                                         There's a lot of distributed systems stuff that gets tied into the Erlang
                                         
                                         ecosystem.
                                         
                                         Like they were doing distributed cloud programming.
                                         
    
                                         I mean,
                                         
                                         it wasn't called that,
                                         
                                         but it was definitely distributed programming way before everybody else.
                                         
                                         Yeah, because all these switches were everywhere.
                                         
                                         And one of the things that Erlang did was, because it was isolated, because they had the code across these switches, if a switch crashed, they needed to be able to recover from that crash.
                                         
                                         And some of that is their way of supervisors and management of applications,
                                         
                                         of what they call applications, which are like micro apps,
                                         
                                         with supervisors and workers.
                                         
    
                                         And then because of the distributed sense, and if this thing happens,
                                         
                                         we don't know which switch it's going to be on. And so they had an idea of location transparency. So you have this process identifier
                                         
                                         and that is encoded where this is running, which node this is running on. But for all intents and purposes, you as the client don't really know
                                         
                                         and can't really be involved about which node this is running, other than a few constraints about
                                         
                                         you can't manage, you can't supervise something that's on another node. But if you're just
                                         
                                         sending a message to something, you don't care if that's your local machine, you don't care if that's a different machine.
                                         
                                         So all these things that they were doing
                                         
                                         was essentially distributed to cloud in a sense
                                         
    
                                         because if we're going to put this on however many switches,
                                         
                                         we don't know at any given point
                                         
                                         which switch is going to be running which piece of code.
                                         
                                         And it could be running on a bunch of different stuff.
                                         
                                         It could be running on one place and we don't know.
                                         
                                         And we, at a certain point, don't care.
                                         
                                         And so, yeah, in the case, it was essentially a managed cloud in a way.
                                         
                                         These switches were servers that were managed by this.
                                         
    
                                         But when it came down to running it, which piece of code is running on which server?
                                         
                                         Well, who knows?
                                         
                                         Maybe this code detects something else went down and we start up another instance on this thing because we can't communicate that.
                                         
                                         So we've got a process that just spins up a new application here and starts managing that lifecycle here.
                                         
                                         And we can broadcast that, hey, we've got this service running. And so there was some stuff around that are very much the problems that we're hitting today
                                         
                                         with my understanding of Kubernetes
                                         
                                         and some of these Docker orchestration levels
                                         
                                         and microservices and all this other stuff
                                         
    
                                         about making what's running where invisible
                                         
                                         and not really caring about it
                                         
                                         and having these small things that if they crash
                                         
                                         how do we monitor that crash how do we restart it back up okay good we got it did we start it up in
                                         
                                         the same place maybe maybe not i never thought of this kubernetes connection but yeah i guess
                                         
                                         for anyone who's not familiar like my understanding may be wrong, so just jump in there. But like the message passing actor system
                                         
                                         in Erlang is like each function has a mailbox, right? Which is basically a queue.
                                         
                                         So messages can sit in front of it and pile up and it runs within a cluster. So it could be running
                                         
    
                                         on one machine or another, right? And I guess, yeah, I can see what you're saying.
                                         
                                         This is very similar to sort of a microservices architecture,
                                         
                                         except a lot more lightweight, right?
                                         
                                         Because you talk about today, like, you know,
                                         
                                         I have a Docker container with a JVM instance running in it.
                                         
                                         And that's being distributed by Kubernetes.
                                         
                                         And there's a whole bunch of other things.
                                         
                                         But in Erlang, this is just actually a function, right?
                                         
    
                                         Like it's a much
                                         
                                         smaller unit of distribution. Yeah. And there's a little bit of a distinction, just to be clear,
                                         
                                         is between functions and processes. So processes run functions. So you can actually call a function
                                         
                                         without having to go across that mailbox boundary. And depending on how you define it,
                                         
                                         I know I've done early days where it's like,
                                         
                                         okay, well, everything is concurrent,
                                         
                                         so let's spawn up a whole bunch of these things
                                         
                                         and every module is now its own process.
                                         
    
                                         Well, sometimes that gets you a bottleneck
                                         
                                         if you've got a hot code path.
                                         
                                         Now you're going through a mailbox when that could just be,
                                         
                                         I can invoke it as a function or I can start it up as a process. hot code path, now you're going through a mailbox when that could just be like,
                                         
                                         I can invoke it as a function, or I can start it up as a process.
                                         
                                         And that was one of the questions that I kind of was talking to with Martin Logan on one of the early podcasts is, how do you define that boundary of
                                         
                                         what's a function? What's just a function in a module? And what's a process that you spawn up to handle something?
                                         
                                         And so that's kind of the same in the microservices world of
                                         
    
                                         at what point do I start up a service and invoke a service to do something
                                         
                                         versus at what point do I just call a function?
                                         
                                         And even Lambda on AWS and other function as a service things
                                         
                                         are more than just a function, right?
                                         
                                         Those are still super small services
                                         
                                         because if you need to calculate a min and max value,
                                         
                                         you're not spinning up a Lambda to invoke max
                                         
                                         to give two numbers, right?
                                         
    
                                         Yeah, totally.
                                         
                                         So there are certain things you start to think about.
                                         
                                         This is a functional unit
                                         
                                         but maybe there's still functions here but when i need to do side effects and i need to go to
                                         
                                         outside stuff that's when i start to figure out where those boundaries when it gets elevated from
                                         
                                         a function to a process and and the confusion i think where i've seen people get confused on
                                         
                                         the process and function and i think where i started was to start a process, you just essentially give it a function.
                                         
                                         So if you just have one function that runs, that can be a process.
                                         
    
                                         You can start up a process that just invokes this function.
                                         
                                         And if it just does something and immediately returns, that process spawns up quickly, does its work, and dies.
                                         
                                         And sometimes when you're first learning this,
                                         
                                         I know I fell into
                                         
                                         it a couple of other people I know have fallen into it,
                                         
                                         was like, process everything.
                                         
                                         And
                                         
                                         that is one of those things that you have to figure
                                         
    
                                         out where
                                         
                                         does it make sense to have a process that's
                                         
                                         the equivalent of a max function
                                         
                                         or a string length function?
                                         
                                         Or do I just call that as a function with a module namespace?
                                         
                                         So how do you decide?
                                         
                                         How do you decide where to draw these lines?
                                         
                                         One of the good ideas was after I asked Martin Logan that question on it
                                         
    
                                         when I was still trying to process it myself,
                                         
                                         his answer was, what are the concurrent operations? So that was one of the things that informed it he
                                         
                                         was gave an example i think it was lambda dam up in chicago a number of years ago that was talking
                                         
                                         about this and he outlined a vending machine and he said here's the parts that are concurrent like
                                         
                                         if this thing goes down what parts of the vending machine could still operate?
                                         
                                         What parts of the things are the concurrent and isolated factors?
                                         
                                         So some of that is what's concurrent, what can be run whenever and in whatever order.
                                         
                                         Some of that is back to the supervision.
                                         
    
                                         The supervisor has restart strategy
                                         
                                         so it can monitor the worker processes
                                         
                                         and some of those can be other supervisors,
                                         
                                         but it can know when that process terminates.
                                         
                                         And some of that boundary is
                                         
                                         if this thing terminates,
                                         
                                         what goes along with it?
                                         
                                         What has to,
                                         
    
                                         if I have to terminate and restart this,
                                         
                                         what kind of failures cascade and how do they cascade well i think one of his examples with the vending machine
                                         
                                         was if my change if my money part the part that takes in the coins takes in the coins, takes in the dollars, and dispenses change and accumulates change fails,
                                         
                                         does that die?
                                         
                                         When that dies, when that air is out, does that kill the cooling system?
                                         
                                         That keeps the drinks cold.
                                         
                                         Well, if the refrigeration of the cans and the vending machine die when the coins become inoperable
                                         
                                         or there's a jam or it's out of money and it can't take money,
                                         
    
                                         there's a resiliency boundary there, so maybe those are different processes.
                                         
                                         Isn't it true that the cooling system doesn't even interact
                                         
                                         with the change system?
                                         
                                         Yeah, and so therefore, if the change system. Yeah, and so therefore, if the change system dies,
                                         
                                         why do you take down the cooling system, right?
                                         
                                         So those become two different domains in your system
                                         
                                         that become obvious process boundaries.
                                         
                                         Just because things interact doesn't mean they have to be in the same process,
                                         
    
                                         I'm assuming.
                                         
                                         Correct.
                                         
                                         And some of that's the concurrent.
                                         
                                         So the first thing was, what are the concurrent pieces of the system, right?
                                         
                                         So the cooling thing can operate independently of the change.
                                         
                                         So once you start to realize that, you start to see, oh, yeah, maybe it is taking a step back.
                                         
                                         Do I really want to kill my cooling when my change goes or vice versa? Okay, there's a
                                         
                                         boundary of some processes. The other part is some of that state management and which processes
                                         
    
                                         hold which parts of state. So once you get the dividing line of some of those concurrent
                                         
                                         activities and failure modes and which things are actually related to each other you say okay well do i have an individual process for each rack of drinks
                                         
                                         potentially in that vending machine maybe i have something there and if i'm empty in one, if that one spinner or release or whatever dispenser is broken for that spot in the vending machine, and that has its state of its own sodas or its own beers, whatever you're stocking in that vending machine. So if A3 breaks, does that break A2?
                                         
                                         Does that break A6?
                                         
                                         So that one can break.
                                         
                                         So, but that has its own state.
                                         
                                         It has its own level of how full that thing is.
                                         
                                         So the whole row of A may be the same drink because that's a very popular drink.
                                         
    
                                         But if one of those slots in that row breaks,
                                         
                                         do I want to have everything else break, right?
                                         
                                         So if that state gets messed up, if that thing's empty,
                                         
                                         can I not dispense any other things?
                                         
                                         So there's a little bit of isolation there
                                         
                                         in the fact that it's got its own state.
                                         
                                         Its state mirrors other states.
                                         
                                         I think one of the important things about the data is that
                                         
    
                                         because because each process is like single threaded um it's a good it's a good um it's a
                                         
                                         good way to prevent like concurrency issues with data right if you're like this very small process
                                         
                                         this very small instance of a whatever of a thing that's running is the only thing that can touch this state um
                                         
                                         and it has it has a message queue so so like work it needs to do can pile up
                                         
                                         but only ever one you know mutation will happen at a time
                                         
                                         yeah absolutely and in that process that process single threaded, but you extract the concurrency out. And that gets one of those things back to the object oriented if there is concurrency well the concurrency is
                                         
                                         different things being concurrent not i have three different things modifying this same state at the
                                         
                                         same time yeah the way i think about the uh like the actor you know model of concurrency is like
                                         
    
                                         as an actor like as a person right it's like the the concurrency model is like
                                         
                                         you have like a guy or like a gal like a process that's sitting there and only it can can manage
                                         
                                         this data that it's in charge of so like there can be as many things in parallel telling it to
                                         
                                         make various updates but they just get put in its mailbox and it processes them one at a time.
                                         
                                         That's the way that they kind of cut that knot of concurrent data.
                                         
                                         Yeah.
                                         
                                         And that was one of the metaphors, I think, Alan Katie said, along with cells, was each
                                         
                                         cell is isolated, but if you take it out and it's an actor, yeah, I send you a message.
                                         
    
                                         If I'm going to, I might send you an email
                                         
                                         and someone else might send you an email
                                         
                                         and someone else might send you an email
                                         
                                         and you're only ever going to work one of those emails at a time.
                                         
                                         We don't communicate.
                                         
                                         We're all locked in rooms.
                                         
                                         And all we have is that little drop box of an inbox and an outbox
                                         
                                         that we can communicate through.
                                         
    
                                         So whatever I do, you don't know.
                                         
                                         Yeah.
                                         
                                         And I mean, that's quite functional, right?
                                         
                                         All your only inputs are this mailbox and your only outputs are also the mailbox.
                                         
                                         And it ties back to your single responsibility principle, I guess, right?
                                         
                                         Because you're like, this process is in charge of the A1 row of this vending machine and that's it. Yeah, exactly. And my responsibility is either to
                                         
                                         supervise things that are doing jobs or do a job. So what does the supervisor do? I know you've
                                         
                                         mentioned supervisor a couple of times, but what's the role? So a supervisor essentially is a process that monitors other processes.
                                         
    
                                         So it has children processes, and it can either have workers or it can have other supervisors.
                                         
                                         So you can get this nice nested hierarchy of supervision.
                                         
                                         You can think of it like the company you're in, right?
                                         
                                         Hopefully, hopefully it's the same company and you're not reporting to multiple supervisors,
                                         
                                         but you've got a supervisor at the top level.
                                         
                                         So maybe you've got the CEO, CEO has its own set of supervisors. That's the CIO, the CTO, the COO,
                                         
                                         all these other whatever levels that that organization has.
                                         
                                         They have their supervisors,
                                         
    
                                         but they also have people who don't supervise and do stuff.
                                         
                                         So they may have administrative assistants.
                                         
                                         They may have some other people who do research for them, gathering data,
                                         
                                         go to meetings for them, but they don't report. They may have consultants as in contractors,
                                         
                                         but people that go through and say, okay, you're my sounding board. So I'm going to bounce ideas
                                         
                                         off of you. You're a domain expert. So you'm going to bounce ideas off of you.
                                         
                                         You're a domain expert, so you've got this thing.
                                         
                                         So you might have this whole hierarchy of an organization,
                                         
    
                                         and you have a hierarchy of an organization in your code.
                                         
                                         You have a web server, which handles multiple web requests.
                                         
                                         So every time you get a web request coming in,
                                         
                                         in a lot of applications, you have something that says,
                                         
                                         how many web requests can I have at a time?
                                         
                                         Okay, this web request goes off and does some work.
                                         
                                         It may have its own set of things to do.
                                         
                                         And so all these processes are isolated and you get down to the things that are actually
                                         
    
                                         doing the work.
                                         
                                         And so when this thing does a work, it works, it does its job.
                                         
                                         Supervisor, you can have long-lived workers,
                                         
                                         you can have just dynamic workers.
                                         
                                         But when a supervisor detects that the worker's not working,
                                         
                                         so the supervisor thinks it's died, it's not responding to any messages,
                                         
                                         it gets a message that this process is terminated,
                                         
                                         it can take that and it can act on that and say, okay, well, this process has died.
                                         
    
                                         What do I need to do?
                                         
                                         Can I restart that?
                                         
                                         How do I restart that?
                                         
                                         And how many restarts can I do in a given period of time?
                                         
                                         So Supervisor has different, they call supervision strategies and thresholds.
                                         
                                         So if this thing keeps crashing and crashing and crashing,
                                         
                                         well, maybe it's time for me to just die myself
                                         
                                         and let someone else higher handle this error.
                                         
    
                                         So it's part of an error propagation strategy too.
                                         
                                         Dave, Joe, and Mike and Robert have joked about the, have you tried turning
                                         
                                         it off and on again? That's applied to processes via the supervision strategy.
                                         
                                         If you've used Word or Excel or Outlook and something's acting up, sometimes you might
                                         
                                         have multiple Word documents and this thing's acting up. Okay, well, let me close that one
                                         
                                         Word document, reopen it, restart it, reopen it, see if it's still acting up. Okay, well, let me close that one Word document, reopen it, restart it, reopen it,
                                         
                                         see if it's still acting up. If that's acting up, maybe I close out all my instances of all my Word
                                         
                                         documents that I have open because I have 10 different Word documents that I'm working on now.
                                         
    
                                         Okay, well, does that work? Okay, cool. Now I'm back and I'm in a known good state. If not, okay, well, now I close every
                                         
                                         Office program because there's some shared library code in Office and maybe something
                                         
                                         in some sort of shared state higher got affected. So maybe I close all of Office down, close my
                                         
                                         PowerPoints, close Outlook, close Excel, and reopen it and restart Word. Okay, cool.
                                         
                                         Now that's working.
                                         
                                         If that didn't, well, maybe it's time to go nuclear and restart the whole computer, right?
                                         
                                         So you've got the supervision strategy, which kind of is levels of escalation of, can I
                                         
                                         handle this error?
                                         
    
                                         Yes.
                                         
                                         Okay, let me try.
                                         
                                         Okay, cool.
                                         
                                         Or if I keep getting repeated failures, it's like, I can't handle this.
                                         
                                         Let's escalate it to the supervisor above me.
                                         
                                         It definitely mirrors the way that debugging works.
                                         
                                         I think that also,
                                         
                                         isn't there an Erlang phrase about to fail fast?
                                         
    
                                         Or I don't know, if you don't know what you're doing,
                                         
                                         kill yourself?
                                         
                                         I'm not sure.
                                         
                                         They talk about fail fast, let it crash.
                                         
                                         Okay.
                                         
                                         So some of that is, again,
                                         
                                         back to the separation of concerns
                                         
                                         and do one thing and do one thing well.
                                         
    
                                         If your code crashes,
                                         
                                         there are some things that you might know about,
                                         
                                         like, okay, that file's not there.
                                         
                                         I expect it to be there.
                                         
                                         So if I'm writing, I just touch that file and reopen it. But if there's things that like,
                                         
                                         I don't know how to handle, don't litter your stuff with the try catch and error handling
                                         
                                         clauses and if checks and all this stuff, essentially code for the happy path.
                                         
                                         And then if you, there's something you can't do, your code is not responsible.
                                         
    
                                         Your process, your code is not responsible for handling that.
                                         
                                         Let's light that up.
                                         
                                         Let the parent, let the supervisor know how to try and handle these failures.
                                         
                                         Because then you isolate your error handling from your work.
                                         
                                         In a lot of cases, you get some of these languages where, or some of this code where you've got all these guard conditions and you're like, what part is the error handling and error checking and making sure that the contract's good?
                                         
                                         And what part is the actual work?
                                         
                                         And I know I've been in places where I've even wrote a code that was probably 75% error handling and 25% work.
                                         
                                         And maybe that's a good ratio for that piece of code.
                                         
    
                                         But now it's like, okay,
                                         
                                         I can actually understand what this thing's trying to do.
                                         
                                         And I can look at the error handling as a separate concern that says,
                                         
                                         okay, here's the cases of when it crashes.
                                         
                                         How do I handle that?
                                         
                                         And so I'm going to let it crash and I'm going to restart from a clean state because maybe I'm assuming that something got corrupted again.
                                         
                                         The joke of have you tried turning it on and off again goes to your processes.
                                         
                                         So do you still have the 75% of the code that's error handling?
                                         
    
                                         It's just it's in a different place? Or is it not needed anymore?
                                         
                                         You still have some of it.
                                         
                                         It gets moved to a different place.
                                         
                                         So then it gets condensed because now you're handling a set of classes of errors
                                         
                                         instead of every potential different permutation of it.
                                         
                                         And then the other side is maybe it just goes away in some cases because it gets reduced because you're like,
                                         
                                         I don't really care about that class of error.
                                         
                                         Let me just retry this process.
                                         
    
                                         Let me turn it off and turn it back on again.
                                         
                                         I got into a bad state.
                                         
                                         I don't now i'd like at a certain point in some of those things it's like well if i've got my state and it's not necessarily a pure function because i've got an internal state let me just
                                         
                                         retry this and just restart from a clean clean known state that's well and maybe something
                                         
                                         because these processes hold their own state
                                         
                                         maybe some message came in that eventually
                                         
                                         caused it to corrupt its own state and get into
                                         
                                         a bad state so you just say
                                         
    
                                         instead of me trying to figure out
                                         
                                         all those error conditions of
                                         
                                         how a state can get
                                         
                                         into a bad state we just say
                                         
                                         eh whatever
                                         
                                         like kill it and restart it with a fresh
                                         
                                         state so it can be simplifying that's good one
                                         
                                         thing um about erlang and i guess maybe about the actor model in general yeah like it doesn't seem
                                         
    
                                         to work terribly well with with types like i mean erlang itself is is a dynamically typed language
                                         
                                         to my understanding and then like there's other implementations of actors.
                                         
                                         I know ACCA on the JVM,
                                         
                                         but also it tends to be untyped as well
                                         
                                         just because these messages coming in to these mailboxes
                                         
                                         can be anything, I guess.
                                         
                                         Erlang's a weird mix because it's typed.
                                         
                                         It's just got like,
                                         
    
                                         I think it's got eight or 10 types that it can be.
                                         
                                         And then you just build out more complex types in a sense that everything's either a tuple, a list, or a hash kind of thing, or an atom, which is just something that refers to itself.
                                         
                                         So the types are there. The way it's more dynamically leaning,
                                         
                                         at least for Erlang, and some of this is,
                                         
                                         I don't think it's impossible to do
                                         
                                         because they have Dialyzer,
                                         
                                         which you can give type specs
                                         
                                         and document the stuff,
                                         
    
                                         and it's pulled outside.
                                         
                                         Some of the catch is
                                         
                                         you could be running these systems and running these nodes,
                                         
                                         and the messages might change and evolve. So the message becomes a little bit more dynamic,
                                         
                                         because you could be dealing with different versions of the code running, because this
                                         
                                         thing got upgraded. And this, this thing got upgraded and this this node got
                                         
                                         upgraded this node didn't this process is still running version one of the api where this version
                                         
                                         is running node three of the api and it tries to send a node one to node three message so you might
                                         
    
                                         have a little bit more dynamic dynamic side there with that because you don't necessarily know which code is running and there's
                                         
                                         upgrade paths that it can go through so you can do some matching and pattern matching on this stuff
                                         
                                         but my understanding was it was more about the dynamic and long-lived code because
                                         
                                         one thing we didn't touch on earlier is it's got hot code upgrades, which means you can keep your app running,
                                         
                                         and it can hold two versions of your code in memory at the same time.
                                         
                                         And once it crosses a fully qualified function call,
                                         
                                         it will upgrade to the new version of the code.
                                         
                                         And so sometimes if you say this function takes this type of A,
                                         
    
                                         and now it's type of A prime,
                                         
                                         well, some of that could be due to how do you compile that
                                         
                                         when you can be running multiple versions of your code at the same time
                                         
                                         and how do you manage those types?
                                         
                                         And so I think some of those were just kind of...
                                         
                                         It's a constraint.
                                         
                                         A little bit of more...
                                         
                                         It's a constraint of...
                                         
    
                                         Yeah, it's a little bit of a constraint
                                         
                                         and pragmatic
                                         
                                         solution that says,
                                         
                                         sure, I can compile all this.
                                         
                                         And again, it's like,
                                         
                                         if you think of microservices, right?
                                         
                                         I can determine a contract,
                                         
                                         but that contract is an HTTP request
                                         
    
                                         or a message in a
                                         
                                         message queue or something else.
                                         
                                         If I'm going to communicate across these boundaries,
                                         
                                         I may not know who's calling me.
                                         
                                         So I just have to essentially match on these things,
                                         
                                         handle those messages I can,
                                         
                                         because it could be any one of these messages.
                                         
                                         And how do I do a type system like that
                                         
    
                                         when the types can evolve and the code can evolve
                                         
                                         and I can have
                                         
                                         three different versions of my services running at the same time kind of thing and which services
                                         
                                         are going to hit so how does it work with the hot code reloading like okay if i update this
                                         
                                         this uh receiver of this of this uh queue of this message
                                         
                                         mailbox. That's the word I'm looking for.
                                         
                                         So I update it,
                                         
                                         but now it's expecting
                                         
    
                                         a new field.
                                         
                                         But then the old messages are still in the mailbox.
                                         
                                         So do I explicitly handle that case?
                                         
                                         So each process has its own state and its own message. still in the mailbox. So do I explicitly handle that case?
                                         
                                         So each process has its own state and its own message.
                                         
                                         So if you get different versions of the messages in,
                                         
                                         you have to
                                         
                                         be responsible to
                                         
    
                                         pattern match on those different versions of
                                         
                                         messages you get in.
                                         
                                         But you also have versions of your state.
                                         
                                         So maybe I have
                                         
                                         a user.
                                         
                                         And instead of having an email address associated to that user,
                                         
                                         and this process manages the state for a user,
                                         
                                         the state now went from a record or a map of name to string and email to string to,
                                         
    
                                         and that's version one.
                                         
                                         In version two, it might be name of string and emails instead of email, which is a list of strings.
                                         
                                         So now you have to say, now you have to say this state that this process holds onto while
                                         
                                         it's running, how do I upgrade that internal state of what this user represents?
                                         
                                         And so there's a code change callback that gets invoked when it says, oh, I see you've got a new
                                         
                                         piece of code here. We're loading a new piece of code. We're going to take that state. I'm going
                                         
                                         to give you that old state. Here's the version and go from version one to version two. And then you code and say, okay, well, from version one to version two,
                                         
                                         I have email that needs to go to emails, and I put that single email in a list.
                                         
    
                                         And now I have other things I can do by appending in my new code.
                                         
                                         So there's some management around that as well that allows me to essentially
                                         
                                         do my database migration
                                         
                                         on the fly because my database is just the state that the process holds and not an outside
                                         
                                         database it has its own private variable that's its internal state that is its database non-persistent
                                         
                                         held in memory that it holds onto,
                                         
                                         but how do I do migrations of that data,
                                         
                                         that state between versions of the code while keeping that code running?
                                         
    
                                         Yeah, the migrations are per actor.
                                         
                                         That makes sense.
                                         
                                         I think you helped me to understand that.
                                         
                                         I have kind of a general question for you.
                                         
                                         So how do you learn?
                                         
                                         So it seems to me you've used a lot of languages in your time.
                                         
                                         You've played around with a lot of new technology.
                                         
                                         So how did you learn about Erlang and other things?
                                         
    
                                         What's your learning process?
                                         
                                         I was reading a bunch of technical books,
                                         
                                         trying to find things just across a bunch of different topics.
                                         
                                         It eventually got me into picking up SICP, picking up Clojure.
                                         
                                         Clojure evolved into hearing some podcasts about.NET Rocks with Brian Hunter, talking about Erlang,
                                         
                                         hearing some other people talk about Face Messenger and Erlang and RabbitMQ and Erlang
                                         
                                         and a couple of these things that were kind of getting popular at the time.
                                         
                                         Somewhere around the 2010 area, I started putting on my radar more,
                                         
    
                                         moved into a job where they had some Erlang as well,
                                         
                                         so worked to pick that up, started putting it on the user group.
                                         
                                         So the user group became one of those tools for forcing me to learn because now I have to explain it to other people.
                                         
                                         So essentially the, I don't have to outrun the bear. I just have to outrun you
                                         
                                         becomes, I have to, you ask a question. I can answer, I don't know at this meeting, but now it's something on my list
                                         
                                         to understand well enough to explain the answer back at the next meeting in the early days. So
                                         
                                         essentially that the best place to teach from is the person who just learned it.
                                         
                                         So putting myself in that route and then the podcast, I find these languages and I hear
                                         
    
                                         something else and that sparks an interest.
                                         
                                         It's like, well, okay, a lot of these podcast episodes that I do become curiosity of like, okay, let me ask questions.
                                         
                                         Let me see what kind of high level concepts I can start to put together and get a very high level, but very incomplete picture and see how some of these things fit together and
                                         
                                         what are the common patterns a across languages what are the common patterns across paradigms as
                                         
                                         well as i mentioned where o seems to be a lot of ideas and functional programming seem to be just
                                         
                                         let's do the functional programming idea which is a good idea or let's do the functional programming idea, which is a good idea, or let's do the object oriented idea,
                                         
                                         which is a good idea.
                                         
                                         And we're just going to like turn it up to 11.
                                         
    
                                         And then what's common between Haskell?
                                         
                                         What's common between Erlang?
                                         
                                         What's common between Elm or Clojure
                                         
                                         and the dynamic versus static languages
                                         
                                         and the strongly typed languages?
                                         
                                         And what are these things?
                                         
                                         And like, if you listen to
                                         
                                         me talking to edwin brady about interest is like i've just heard about this i still really don't
                                         
    
                                         understand this help me explain and eventually i get enough people where i can start to ask more
                                         
                                         and more intelligent questions but i also go in knowing that well if, if I'm asking this, I'm sure I'm not the only one. So maybe someone else who doesn't know this can be able to piggyback off my learning.
                                         
                                         I interviewed Edwin Brady, too.
                                         
                                         And I have the interest book and I've been working my way through it.
                                         
                                         And I found him to be like super modest.
                                         
                                         Like I was kind of blown away by all the things that this language presented.
                                         
                                         And he was kind of like, oh, yeah, this is what it does.
                                         
                                         A lot of these ideas just came from other places.
                                         
    
                                         And I'm just polishing them up and presenting them for programmers use.
                                         
                                         He was so modest.
                                         
                                         It was a bit surprising, I guess.
                                         
                                         I'm used to people kind of wanting to push their technology.
                                         
                                         So speaking of technology and your learnings
                                         
                                         what um what are you excited about right now with all your interviews and your um reading
                                         
                                         what technologies have uh are on your radar interest is still one i want to get deeper in for understanding dependent types. Haskell's still a bit on my
                                         
                                         radar and try and take some peeks in, try and understand some of the concepts better for
                                         
    
                                         that enforced purity and say, okay, well, I know I get impure. The LISPs are interesting
                                         
                                         because of all the metaprogramming stuff and treating that code as data and macros
                                         
                                         and how do you actually design a real DSL
                                         
                                         and essentially design from the outside in
                                         
                                         and say, well, this is what I want this to be.
                                         
                                         Let me write this and then I'll figure out
                                         
                                         how to transform this either via macros
                                         
                                         into something that's actually usable.
                                         
    
                                         Then you get things like Reason,
                                         
                                         which is appealing from a different perspective of
                                         
                                         how do I take this?
                                         
                                         This is OCaml made friendly to JavaScript,
                                         
                                         so it's not quite OCaml syntax,
                                         
                                         but maybe I could do OCaml
                                         
                                         and using their compiler of BuckleScript, compile OCaml
                                         
                                         down to JavaScript.
                                         
    
                                         But even shorter is if this is designed by the intent that we want to make this, bring
                                         
                                         all these ideas from functional programming and OCaml and make them more easily accessible to the JavaScript community and make it more familiar
                                         
                                         instead of being looked at and say, what, like, this feels like a far stretch, because now I've
                                         
                                         got to learn a syntax that's completely different, along with completely different ideas. OCaml seems
                                         
                                         appealing and or reason seems appealing in the fact that we're taking this
                                         
                                         and will this be coming up soon enough that it might actually be reasonable that
                                         
                                         where people talk about CoffeeScript or TypeScript now,
                                         
                                         probably TypeScript more than CoffeeScript, but CoffeeScript a number of years ago,
                                         
    
                                         or any of these babbles and taking some of these other JavaScript, even if it's future JavaScript and providing these functionalities of, there's reason close to being something that could be more mainstream, more introduced into a workplace environment with people who aren't necessarily the functional mindset converts,
                                         
                                         but be able to start introducing this and say,
                                         
                                         look, here's the way to do this.
                                         
                                         You've seen CoffeeScript, you've seen TypeScript,
                                         
                                         you've seen some of these other things.
                                         
                                         How much of this stuff, it's not that far of a leap,
                                         
                                         and now we can start taking advantage of some of these ideas.
                                         
                                         Elm's interesting for the React stuff.
                                         
    
                                         I think JavaScript is really an interesting space now, isn't it?
                                         
                                         I mean, it's just become the assembly language
                                         
                                         for a bunch of other languages.
                                         
                                         Yeah, and again, ClojureScript is appealing on a personal level.
                                         
                                         Elm and PeerScript are appealing on a personal level.
                                         
                                         I think Reason might have a chance of being one of those
                                         
                                         nice introductions to getting more functional
                                         
                                         JavaScript without feeling like the burden of
                                         
    
                                         having to learn a new syntax with Elm or Peerscript or going to
                                         
                                         full-on ClojureScript with parentheses everywhere.
                                         
                                         And again, I like Elm.
                                         
                                         I've actually pointed a couple of coworkers to Elm
                                         
                                         when we were doing a React project using Redux.
                                         
                                         I said, play with this, look through the Elm architecture.
                                         
                                         That's an interesting idea that these other,
                                         
                                         that have been fed back in, back and forth between these things.
                                         
    
                                         So that's, some of that stuff is looking at what are the concepts
                                         
                                         and what's appealing.
                                         
                                         That means I can bring that back easier.
                                         
                                         So in the Elm perspective is how can I understand Elm
                                         
                                         and the Elm architecture and play with that a little bit
                                         
                                         and then bring it back.
                                         
                                         And now when we start doing React and Redux,
                                         
                                         I've got a head start because I've
                                         
    
                                         understood the Elm architecture, which is what Redux was kind of cribbed off of and exchanged
                                         
                                         ideas from. So that's kind of the perspective I take in a lot of this stuff of learning is
                                         
                                         what are those principles that can come out and what can I learn from the principles that I can
                                         
                                         then apply even if I don't get to do functional programming directly in this thing.
                                         
                                         I understand those principles and practices
                                         
                                         that can help make some of the stuff I'm doing more sane
                                         
                                         than if I were to just go off and not even think about some of this stuff.
                                         
                                         I can understand that.
                                         
    
                                         And it's interesting to see these concepts move around
                                         
                                         from language to language or framework to framework. Totally unrelated question. I was kind of stalking you looking at your blog, and I saw that. Are you into like custom keyboards? Is that true? Yeah.
                                         
                                         Got into mechanical keyboards a number of years ago and then have gotten in via another co-worker.
                                         
                                         I got hooked on mechanical keyboards.
                                         
                                         He reinforced the ability to do custom keyboards.
                                         
                                         Very cool.
                                         
                                         I have a Plank keyboard here,
                                         
                                         and I have my customized firmware.
                                         
    
                                         I think it's pretty cool stuff.
                                         
                                         I actually have a couple commits in the QMK keyboard firmware.
                                         
                                         Yeah, my coworker got me hooked on some of this stuff.
                                         
                                         So I found Steve Walsh's a modern Space Max keyboard
                                         
                                         post a couple years ago and I started following
                                         
                                         his advice so I kind of software modded
                                         
                                         on my laptops
                                         
                                         by like
                                         
    
                                         I use Vim and we'll get
                                         
                                         the holy wars going
                                         
                                         a little bit but because
                                         
                                         Vim uses the escape key and I never
                                         
                                         use the caps lock key I turn
                                         
                                         caps lock into control and escape.
                                         
                                         And then that software was Carabiner.
                                         
                                         It stopped working with High Sierra.
                                         
    
                                         So based off my coworker who created essentially mini dongles, I went off that route and started doing mini USB adapters so I could actually put the firmware as essentially a
                                         
                                         key logger slash translator from what's the normal keyboard key into what I want.
                                         
                                         And it kind of just went down the rabbit hole and did a couple of adapters for a code keyboard
                                         
                                         that I had, a DOS keyboard that I had, and then found an old Apple M0110 from 1984 or 1985
                                         
                                         that takes the phone jack connector
                                         
                                         and actually created an adapter
                                         
                                         that's a phone jack connector on one side,
                                         
                                         an RJ22, and USB on the other side.
                                         
    
                                         And so I was able to...
                                         
                                         I started going down that
                                         
                                         within the past year.
                                         
                                         Actually, within the past couple months, I just finished
                                         
                                         in ErgoDocs and have been
                                         
                                         starting to love that.
                                         
                                         Kind of went down a little bit of the hardware
                                         
                                         hacking route as well.
                                         
    
                                         So that's one of the other things that
                                         
                                         sound interesting as far as upcoming
                                         
                                         topics.
                                         
                                         There's some spikes about functional languages
                                         
                                         running on hardware yeah yeah the one i'm i've been interested in is because uh like the qmk
                                         
                                         firmware that my keyboard runs and i think ergo docs can run it as well uh i have an old ergo doc
                                         
                                         somewhere like uh it it appears to be mainly composed out of like c uh macros like it's it's
                                         
                                         quite uh i don't know it seems hard to understand to me so i want
                                         
    
                                         to see like a rust version uh because you know rust is supposed to compile down to you know
                                         
                                         very small runtime and bc equivalent so i'd love to see like some of these more modern
                                         
                                         languages taking a stab at keyword keyboard firmware i think it'll be awesome yeah i've
                                         
                                         seen some again a closure with a macro system
                                         
                                         or some of the haskell with the types to know that yeah when you did this you didn't screw up
                                         
                                         this thing some of that stuff and being able to put that on some of these smaller arduino's or
                                         
                                         teensies or other microcontroller boards is something i'm anxiously looking forward to it
                                         
                                         well i think we went over but uh thanks so much for your time, Proctor.
                                         
    
                                         It's been great talking to you.
                                         
                                         Thank you for your time.
                                         
                                         Thanks for having me.
                                         
