Joseph Ni (aka Mordrax) shares the twisting tale of how an obscure 90s video game got him his first job with Elm, and how it brought him face to face with 10,000 lines of legacy code.
Joseph Ni (aka Mordrax) shares the twisting tale of how an obscure 90s video game got him his first job with Elm, and how it brought him face to face with 10,000 lines of legacy code.
Thank you to our sponsor, Culture Amp.
Special thanks to Xavier Ho (@Xavier_Ho) for editing and production of this episode!
Recording date: 1 April 2020
00:00:00 Intro and sponsors
00:01:42 Mordrax's history with programming
00:05:16 Getting into front end web development
00:07:45 Getting into Elm
00:11:40 Castle of the Winds
00:15:10 First impressions of Elm…
00:18:00 Playing Castle of the Winds in Elm
00:19:36 Pacific Health Dynamics (PHD)
00:22:35 Flattening state in 10,000 lines of Elm
00:27:17 Growth of Elm at PHD
00:28:41 Sign-off and Outro
[00:00:00] Kevin Yank: Hello again. It's your old friend Kevin, and we're back with another episode of Elm town. This episode. I'm joined by Joseph Ni. You might know him as Mordrax in the various online communities we frequent. Today he's gonna be here to talk about his journey with Elm and, how it's been used at a little company here in Australia called Pacific Health Dynamics.
[00:00:22] Before we get into it, just a word of thanks as usual to Culture Amp for paying my salary while I record this. they support the show with my time and, it feels great to be able to do this in the middle of a Workday when I'm wide awake. And thank you to Culture Amp as you have probably heard by now, listener. We build a web app that companies use all over the world to invest in their people and their workplaces – to make the workplaces of the world better places to work is how I like to put it. We build our front end, at least in part, in Elm, in production.
[00:00:54] And so if that is the sort of thing you would like to do for a job, you should reach out. My email address is kevin@cultureamp.com and you can visit https://cultureamp.com/jobs to see what open roles we have at any given time.
[00:01:09] I'd also like to thank Xavier Ho for editing this podcast every single episode. He makes us sound great. We were just chatting the other day about some new software. He was looking at to do some live transcription of the rough cut so that you could then edit the transcript and that would cause the episode to be edited in a rough form that he could then tidy up. So he is always looking for ways to make this show better.
[00:01:35] And I really appreciate that. If we sound at all good, it is mostly thanks to Xavier Ho. Joseph, welcome to the show.
[00:01:42] How long have you been writing software for a living?
[00:01:46] Joseph Ni (Mordrax): So writing software for living, pretty much ever since uni. And even before that, you know, I fell in love with the 286 with, QBasic and I'd be writing games and, and various calculators and whatnot pretty much my whole life.
[00:02:02] Kevin Yank: So that's early. nineties, if not late eighties?
[00:02:07] Joseph Ni (Mordrax): That's early to mid nineties. Yeah. Early to mid nineties. Floppy disks, five and a half inch. Those, those were the days. Yeah.
[00:02:16] Kevin Yank: So what, what was your first language?
[00:02:19] Joseph Ni (Mordrax): QBasic actually. Yeah.
[00:02:20] Kevin Yank: Wow. Okay. Yeah, I came up on the Apple Basic.
[00:02:24] Joseph Ni (Mordrax): You know, back then it was, it was all brand new. And, I was just amazed that I could actually get the computer to do something. And I was very much into kind of the D&D pen and paper role play, and, you know, and I've kind of tried to make a few games out of that. I was making along the lines of Grand Strategies, kingdom management and kingdom simulations. And then I moved on, to my first Windows machine, and then fell in love with couple of RPGs. Castle of the Winds was one of them. And that will come up again and again. (laugh)
[00:02:59] Kevin Yank: My partner Jessica was a big fan of Castle of the Winds. It was her first, addiction as a video game. there are lots of fans out there who still remember that very fondly. So the programming bug, but you early, you were writing it as a hobbyist, as a gamer, as many of us were back in those days.
[00:03:17] And then at a certain point, the web took over the world. What form did that take as it entered your life and, and I guess eventually became a career for you?
[00:03:26] Joseph Ni (Mordrax): I kind of resisted the web for quite a long time. I was, you know, doing back ends, and I was doing a Windows desktop development for a while.
[00:03:35] And before that I was, you know, at a big company, Honeywell doing a very, little known software called InstallScript. You know, when, whenever you're on Windows, then you double click on an MSI file to do an install. Powered by InstallScript, in the backend. It's a basic scripting language, and it's got, you know, basic kind of programming concepts. You've got functions, you've got, you know, variables, conditionals, and it's meant to be moving files, but, with the install, you've got a certain level of configuration of the system.
[00:04:12] And within Honeywell I was in the, the EBI Enterprise Buildings Integrator. There is a lot of configurations required and depending on what version of Windows you're on, depending on what previous, I guess, updates have been installed, things can differ drastically from one install to the next.
[00:04:32] So at that level of complexity, I found and discovered, was really hard to manage when you don't have proper tools and you've just got like a basic scripting language. I would've preferred to use QBasic.
[00:04:46] Kevin Yank: When you said Honeywell, my mind went immediately to the favorite mouse I have ever owned: the Honeywell mouse. I had it for many years and I didn't want to give it up because there was nothing as good available to replace it with. It's the only mouse I've ever had that had two wheels on the bottom, a horizontal and a vertical wheel rather than a single ball.
[00:05:07] It had two wheels and it just felt so accurate. And so reliable compared to everything else I've ever used. So what pulled you away from Honeywell?
[00:05:16] Joseph Ni (Mordrax): Well, actually it was pretty much all about necessity, to be completely honest. I was writing, you know, Windows services and SOAP web services, I was writing Windows desktop applications. And my partner in crime at that time, at that startup, was doing most of the classic ASP web front end that was used in the offices.
[00:05:40] And then, business didn't really go anywhere. My partner in crime left. And then I took over, took over the front end as well I kind of had to learn that.
[00:05:50] Kevin Yank: So out of necessity, you mean there was no one else to do it?
[00:05:53] Joseph Ni (Mordrax): Yeah.
[00:05:54] At that point in time, I was exploring TypeScript, TypeScript was the stepping stone into JavaScript. I tried to kind of ease into JavaScript with the type system. Early on though, TypeScript wasn't particularly well known.
[00:06:11] A lot of libraries didn't have TS, you know, definition files and so— and, and types was really easy to get around with a get around as well. So it just felt like there was a lot of, you know, kind of things in your way that we didn't contribute in the end.
[00:06:30] At that time, I hadn't gone into JavaScript that much at all. So I thought, okay, let's. Let's put that aside and really get into it. Loved the language though, because that was the first language that I used where functions was considered as first class citizens.
[00:06:46] Now I've got things that I can just call. Like it's just the function. It has no baggage of or concept of. Well, okay, you did have context. Yeah, you did have closure within JavaScript, but, you could explicitly just declare a function, pass it around as a parameter, and just say, “Hey, use this method or use this function, you know, for these parameters.”
[00:07:10] And it didn't come with a class. It didn't come with any state of its own. That was brilliant. And I loved that.
[00:07:18] Kevin Yank: And how quickly from there where you sucked down the functional programming wormhole?
[00:07:24] Joseph Ni (Mordrax): Not very quick. It took TypeScript, Meteor, Ember, React, to eventually get to Elm. So I pretty much bumped into, you know, every popular framework. Drank every Kool-Aid. “Hey, this is great. Angular's gonna win.” And then 2013: “Yay. Meteor is great.” You know.
[00:07:45] Kevin Yank: So you were telling me that, when you started at PHD, your Elm expertise was one of the things they were looking for. So, how did that expertise come about? where did Elm start with you and what did you cut your teeth on?
[00:08:00] Joseph Ni (Mordrax): So right before PHD, I was at a place called a Blake E-Learning, and they made educational games for kids. While I was at, you know, Blake E-Learning. These guys are really, really supportive of technologies and, you know, explorations.
[00:08:17] Kevin Yank: I've met a few people from Blake over the years at, like coding camps and things like that. And they always seem very open to experimenting with the latest tech.
[00:08:26] Joseph Ni (Mordrax): They had Haskell groups, Elm groups, Ruby groups. They had, Elixir groups. So all of these lunchtime learning groups, and, you know, there were a great bunch of people, don't get me wrong. It was a really, really hard position, leaving it, because really, they fostered and really encouraged me, to, to learn and to really grow and, and to kind of analyze, you know, languages as well as concepts, you know, like what was good, what was bad.
[00:08:58] So, you know, within Blake, that was kind of where my Elm journey really took off. Work at Blake consisted of CoffeeScript and Ember and Ruby.
[00:09:07] It was actually quite interesting because I had already had, heard about Elm, you know, quite a few times just within the last year within the community, you know, listing out the new things. And then when I first joined Blake during the interview process, I was talking to Martin, the tech lead there at the time.
[00:09:27] And you know, he had said, he had started talking about Elm and he said he'd built some things in it, you know. I was like,“What, what? That's, that's crazy. That's amazing.” And so, yeah, so I really started exploring that on the side. The last time that I had done any functional programming, was in first year in uni.
[00:09:49] Kevin Yank: I had a similar experience that FP is something I learned at university and then did not use for a decade.
[00:09:55] Joseph Ni (Mordrax): And it was in Haskell. Loved it. Absolutely loved it. I had a lot of fond memories from Haskell, especially how it unpacked complex problems using recursion. It almost just makes the problem go away, you know, by kind of reducing your, your problem space from, “Oh, how do you solve this whole problem?” to just “How do you solve the current issue that you have at hand?” On the larger scale as well, it's like, “Oh, how do you solve this, this company's whole issue?” Well, how do you solve the current issue you have at hand? And typically that is, you know, in my view, the most optimal way of moving ahead: by solving the issue that you have at hand rather than worrying or holding within your memory and, you know, spending your time and resources,
[00:10:42] right, within this cycle on everything else that needs to be solved in the future
[00:10:47] Kevin Yank: Well, the really satisfying thing that I think you're getting at about recursion is that you are able to set aside the big problem, solve a small problem, and then realize that by solving that small problem, you have actually solved the big problem.
[00:11:05] Joseph Ni (Mordrax): Exactly. And so the big problem that you thought was a big problem, is just really the same pattern of small problems over and over and over again. But I mean, so that was, that was the one really notable theme that I had from learning Haskell.
[00:11:21] Kevin Yank: I'd venture to say that combination of functional programming that you had fond memories of and the type system that ever since you had moved into JavaScript land, you were looking for something as strong as the type systems you'd worked with in .NET. So that was, I guess, an irresistible combination.
[00:11:40] Joseph Ni (Mordrax): So what I'd been doing in React was writing or rewriting a game called Castle of the Winds and as many who you know, have met me would know, I keep talking about this, this is the game that I keep rewriting over and over again.
[00:11:54] Kevin Yank: So for people who have not heard of Castle of the Winds, can you describe the game?
[00:11:59] Joseph Ni (Mordrax): So Castle of the Winds is a top-down RPG. So tile based RPG, made by Rick Saada in the late eighties, I believe. And it was targeted at Windows 3.1. It was a, it's a very old game. But I love it to bits. It was my first RPG that, that's what got me into RPGs. You're going into towns and randomly generated caves, you know, turn-based. And you're just clicking around. It's got, your basic warrior and your mage, really simple in its concept. And that's why I thought, okay, it'd be awesome if I could recreate this, you know, relive my childhood dream in some ways, but as I've found over and over again, RPGs, you know, and,
[00:12:42] this is to kids at home: don't pick RPGs that you first game to remake! I'd been remaking this game, you know, but at every opportunity using a different language. It actually started, first with Python 2, and then, you know, I was doing it with TypeScript and jQuery of all things, and that was horrendous.
[00:13:04] And then I tried to remake it in Meteor, and finally I moved to React and then replaced the Meteor backend. I reached a point where it was kind of like the momentum was sapped by continual changes. Continual refactorings continual type changes. I had test cases in place to test for when things breaks, right.
[00:13:30] Did this item in the inventory gets stowed away properly or did a purchase of a potion, was that purchase successful. And whenever I made refactoring changes, you know, you may break some things and I knew about it, but it kind of inhibited me from making those changes because I knew every single time I tried to do a system wide change,
[00:13:52] it would then, you know, take me a few more days of debugging to fix everything again. Right at the beginning as a project ramps up, you're like, ah, okay, I'm making a lot of progress. Everything's great. You know, 1,000 lines, 2,000 lines, 4,000 lines, 5,000 lines, 6,000 lines, and then eventually you hit a point where you don't want to make system wide architectural changes anymore because it's just, you just don't know what's going to happen. And then you're constantly adding tests.
[00:14:22] So it was at that point that I joined Blake, with my Castle of the Winds. All right. Let's derail with this one last time. This thing called Elm, what is, what is this thing called Elm? Let's just try it out. And so that first two weeks I was absolutely, absolutely gobsmackedly hooked onto it. It was really amazing.
[00:14:48] Kevin Yank: It's good to have a specific project that you're craving the existence of, to drive your learning in something like a new language.
[00:14:56] That's advice I give to junior engineers all the time. They'll say how should I learn a new programming language? And the first question I'll usually ask is like, find something you really want to build with it. Because that will motivate you through the hard parts.
[00:15:10] Joseph Ni (Mordrax): What really kind of struck me was the workflow: the process of getting something working. At the beginning it was actually a frustration. So what I mean by that was, you know, when you're in Elm and you're coding, you're constantly getting these compile time errors, right? And you're like, that's slowing me down.
[00:15:32] What, what's all these errors? Why are you throwing errors at me? You know, I'm just like writing a few lines of code. What is this type inference issue that you keep talking about? But then, when you read into it, or when I read it back into it at that time, it's, oh, okay, well that makes sense. You know, I'm trying to pass a, a an Int attribute into a String type, well, fine where you can't do your own coercion and I'll, I'll do it.
[00:15:56] So that was kind of like slowing me down a bit. And then once I got past it and it compiled, you know, things just kind of just worked, right? I didn't have to debug it. And on the flip side, it was actually hard to debug during run time as well. So one of the things that you know, has really changed in the process, and this is future me talking, is my debugging process has completely changed from, analyzing issues during run time to just thinking about systems.
[00:16:27] Thinking about the problem. And nowadays, whenever a bug comes in, I'll pause for a moment and think, well, okay, so this bug affects this subsystem. There are only two places in the code that changes this state, and it's either A or B. It's not 100% of the time that I get it right, right? It is 99% of the time that I get it right. To me, that's like one of the hidden strengths of Elm that I don't hear people talking about it. But it's there for big systems, right? And it's like, okay, so you've got, you know, it routes to a page, but that data doesn't exist.
[00:17:03] Well, so the data exists in one state is the, you know, it's kind of like initialized in two different places. These are the only three places that it can ever come or disappear from.
[00:17:13] What blew me away was that when, when it compiled it just worked, right. I'm not used to that as, as a JavaScript programmer, you know. When it compiles, you then kind of settle in for an hour of debugging. You think, Oh geez, what about regressions? And if you have a set of test cases, great. Well, first you spend like half an hour writing the test and then you settle in for debugging, and then you think, well, okay, if all these tests pass, then surely everything must be kind of okay.
[00:17:46] Kevin Yank: You get to a moment where success requires that you outsmart yourself in order to detect the problems with the thing that you just wrote, trying to be as smart as possible. Yeah, I know that feeling. For our listeners, if you happen to be in front of a computer as you're listening to this, you should go to game.castleofthewinds.com and join me in tapping around this little world, written in Elm.
[00:18:11] I have a, as you were speaking there, I went down a well, I walked around and killed a goblin and now I'm face to face with a giant rat.
[00:18:19] Joseph Ni (Mordrax): You went down the well? That's the cheat way!
[00:18:24] Kevin Yank: (laughs) Is it? I have— I must confess, I walked around the town a little bit and then I went, oh, there's a well there. I bet if I try to walk into it, it won't let me because there's a well in the way, and then I was, I was in a cave.
[00:18:34] Joseph Ni (Mordrax): Then you were in the cave. Yeah, that was, when I was doing, what is it called?
[00:18:38] A randomized dungeon generation way of getting into a random dungeon.
[00:18:42] Kevin Yank: Ah, okay. It's just there for developer convenience.
[00:18:46] Joseph Ni (Mordrax): I'm glad that that's still up. There's a story behind that site as well. I was remaking, you know, this game in Elm, and I thought, oh, I got to host this up somewhere, you know, and tell the whole world about it. And I just looked up www.castleofthewinds.com. Someone had the domain name and, I contacted him, Sean in the US and, you know, just kind of, laid out, you know, it's like, just splurge:
[00:19:12] Oh, Castle of the Winds, so awesome. I'm a massive fan. I'm doing a remake. And he said, yeah, that's great. Look, I mean, if you ever want to host it as a subdomain here, you know, just give me the link.
[00:19:24] Kevin Yank: This port of Castle of the Winds, this third remake of it, if the README as accurate, it started while you were at Blake e-learning, is it safe to say the Castle of the Winds got you your job at PHD?
[00:19:35] Joseph Ni (Mordrax): Yeah.
[00:19:36] Kevin Yank: I think we need to maybe set the scene for a moment and like, what is PHD? What do they do? What are they make? What is their tech stack like?
[00:19:46] Joseph Ni (Mordrax): Right, so PHD is a, is a private health insurance software vendor, and we write software for a line of business app, you know, for, health insurance staff members who's on the phone talking to their clients, their members. And so our software helps, you know, with claims processing, with creating and maintaining covers payments, with distributing health insurance cards so it's, it's all around kind of the office management of, you know, the day to day's kind of use of private health insurance for members. So where they're at PHD and you know, they're a sort of corporate-y, you know, a company. Their backend's in C#, you know, SQL. So very, very much a Microsoft shop. Then this guy rings me up, and he goes, well, Hey Joe, you know.
[00:20:43] You do Elm right? So what I learned was that there was a greenfield Elm project in progress and they were looking for someone to continue that project to basically lead the front end.
[00:20:55] Because what had happened was that the engineer had left, so they had no one on the front end. They had about 10,000 lines of code. And so they were looking for anyone who has even vaguely heard of Elm. There was a project manager there whom I had worked with in the past, and he contacted me for that role.
[00:21:15] From my perspective, that was the only Elm role in existence in Sydney. And at that point in time as well, you know, at Blake, I had spent about a week debugging this issue, you know, and so, eventually I worked out that the problem was caused by a change in some back end, field naming.
[00:21:37] That then propagated to the front end and was missed, you know, and then was passed into the game state, and then, you know, it caused the game not to get that value.
[00:21:50] Kevin Yank: So you were at peak wishing for the guarantees that Elm would give you?
[00:21:54] Joseph Ni (Mordrax): Well, yeah, it was, it was kind of like everything,
[00:21:59] every bug that I looked at, you know, just reinforced that voice in my head. This class of bugs would not exist had I had a strongly typed language. This isn't even ADT, right? I'm not even getting into ADTs yet. This is just strongly typing an endpoint so that, you know, your fields that you're passing in the JSON object exists. Okay, we can't even have that. Right. I was at peak wishing, and this opportunity came up and I was like, ah, I have to go for it. And I did.
[00:22:35] Kevin Yank: And 10,000 lines of Elm code. That's not small.
[00:22:40] Joseph Ni (Mordrax): No, it isn't. And you know, the thing about 10,000 lines of Elm code is,
[00:22:46] you can write Elm code really, really badly, right? And I discovered that, you know, at that place, and you can write it so badly that it's actually not feasible to untangle it in some ways as well. I really had to isolate quite a lot of the systems. And then kind of build things from scratch and then put things back.
[00:23:14] When I first started with PHD, I had a tendency to model my state, like the UI. And so what I mean by that is, you know, you've got pages and then each page will have their own state, and then within a page you might have some forms.
[00:23:30] And then those forms' state is actually within the page state. And so when you've got that going on, then you want to communicate between that form and something else somewhere else, then you know, it's kinda like, visually, you're representing, or from a state point of view, you're representing your state, like what you see visually.
[00:23:52] So you have to kind of climb out of that form, out of that page, into your menu system, into a sub menu, into something else to get communication going. So, and that's like a really hierarchichally nested, you know, architecture. So what I'm advocating for, and what I'm doing now within our system, is to flatten pretty much everything.
[00:24:17] Moving forms out of pages, moving things that aren't, you know, related from a UI, like they're nested from a UI point of view, but their state doesn't have to be nested. When you have nested state, your messages also have to kind of jump, you know, the hoop to communicate between those two nested states, right.
[00:24:39] But if all of those states are at one level, then you don't have to do that. That's kind of the ultimate, moving away from child to parent communication. Your UI can still be as nested as you want. You can nest your views, right? But the state that you refer to, you know, is flat, and you can kind of like, just talk between any parts of that state.
[00:25:03] So that's kind of like roughly what where we're heading towards. We've still got, you know, two and a half years worth of legacy code. And it's, it's constantly evolving. It's ever evolving. But another great thing about Elm, you know, evolution is awesome, right? People say this all the time.
[00:25:21] I dunno if anyone realizes how awesome it is at 120,000 lines of code, right? Like, you can, you can make a change without fear. And I imagine it would exist at 500,000 lines of code as well.
[00:25:34] Kevin Yank: You've got the legacy code that has some of those older patterns, but you have managed to carve out these new patterns that you are building new things with this flattened state representation.
[00:25:45] The team knows what that healthy pattern looks like and is gradually adopting it, moving things to it opportunistically, I imagine. is that kind of where you find yourself at the moment?
[00:25:57] Joseph Ni (Mordrax): It does take a bit of convincing and you know, within Elm there is kind of no right and wrong, or maybe there is right and wrong. It's kind of like Lego pieces, right? And if, if you've never built yourself into a hole before, you end up building yourself into a hole to learn about it anyway. It's almost like being guided by intuition. I have to formulate, the reasons down the line for why you would not go to this extreme, but it's a lot easier within Elm to talk about these concepts because there is a lot less ways to get things wrong than there is in JavaScript.
[00:26:33] Let's put it that way. Like, if you've got you know, state within a module and the module's opaque, then that really forces your hand quite a bit, you know? So it's kind of like some part of the argument would be working out where state exists and where that state exists would determine where those types and messages exist.
[00:26:57] And that will really determine how, you know, other modules use it. So, you know, the, the conversation can be quite structured around scoping of module scoping of states, and then, you know, then we can get the team on board to, to solve problems in a certain way. But really that's, that's still up for discussion.
[00:27:17] Kevin Yank: You told the story of how out of nowhere who you assumed was a .NET person and had never heard of functional programming, offered you the only Elm job in Sydney. Is it still the only Elm job in Sydney? Is PHD looking for more Elm fans to join the team? What's the ecosystem and what's the growth of PHD and its Elm team look like?
[00:27:40] Joseph Ni (Mordrax): It's definitely not the only Elm job in Sydney anymore. We've got four strong now. you know, we're based kind of, I'd say all around Australia, around, in India as well as all around the world.
[00:27:52] And we're still hiring. The product has been a pretty big success within the industry. And we need more, you know, hands on deck. We need more people to flesh out ever-growing requirements. So, definitely, if you're interested in Elm and you'd like to see first hand what this legacy system, is all about and how to write Elm at scale and think and approach problems as scale, in Elm in Sydney,
[00:28:22] then yeah, contact me on Slack, and we'd like to hear from you.
[00:28:27] Kevin Yank: Yeah, great. And you don't have to have attempted a port of a obscure nineties video game in order to get a job there. Just to be clear.
[00:28:34] Joseph Ni (Mordrax): No. No, but we will look favorably on that. (laughs)
[00:28:39] Kevin Yank: Good. (laughs) Well I think that is a great place to leave it.
[00:28:41] Thank you, Joe for, the walk down memory lane.
[00:28:46] Joseph Ni (Mordrax): Thanks Kevin for having me. And it was lovely having a chat about this.
[00:28:49] Kevin Yank: Yeah. I can't wait to hear what's next for you. And for PHD.
[00:28:53] Joseph Ni (Mordrax): Cheers.
[00:28:53] Kevin Yank: And thank you, listener, for joining us once again in Elm Town. One of the nice things about being locked inside at the moment is I'm getting a lot of time to record new podcast episodes, so watch for the next episode of Elm Town coming real soon.
[00:29:07] Bye for now.