Adam: I have been confused about something. I really like having static type information when I code. When I think about building something, I think about defining types, writing things to map from my one type to my other. That’s kind of how I design in my head when I’m thinking about how to solve problem.
However, smart people, talented people that I know view things very differently. There are skilled people who would leave their job before using language with static types. So I emailed this guy.
Jared: I’m Jared Forsyth. I am a software developer at Khan Academy.
Adam: Jared started in one camp and moved to the other. Well sort of, because now he’s all about the inferred types.
And maybe that’s the best of both worlds, but I’ll let him explain.
Jared: I’ll admit I was definitely scarred by Java and C plus plus and, um, intro to programming class. And I never want to look at types again camp. My first language was Python and followed closely by Java script, and so I was loving the loosey-goosey scripting language.
just all over the place and. It was actually really refreshing in flow and TypeScript and also reason, which we’ll talk about, we are, so much of the typing can be inferred for you. So you declare a function, you use it one place, and kind of from the contents of the function, the type system can discover, Oh, they’re adding this variable to another.
Those are going to be numbers or strengths depending on, it can be really clever about that so that you don’t have to be writing types everywhere, but you do still get the checking and you can hover over a variable to discover what’s the type that was infered for this, which is super nice.
Adam: Like there must have been some moment where you were like, “Oh, this thing got caught”, or “Hey, I can go to definition” or something where you were like, Oh, the light bulb turns on?
Jared: Thing that really has made it so that I never want to go back. Is the way that having an explicit type system changes the way you think about code. And where are you define explicitly this is the shape of the data that I’m going to be dealing with.
Here are the data structures. I’m going to lay those out, and then I can write functions that will manipulate those . It results in much better organized code. And is it just such a help in me being able to process new code that I’m reading or code that I wrote two weeks ago and I’ve forgotten entirely about?
Adam: So I had a previous interview with a DHH, who created Ruby on rails. And he was, I think he said he doesn’t get it right. He’s like, I get, some people really want types. I don’t want them. It’s like a personal taste thing. So you know, you’ve made this transition. So I’m trying to figure out, there’s a thought process or a perspective that needs to change, or am I just missing something?
Jared: No, it’s true. And I’ve heard also Rich Hickey, the creator of closure is famously skeptical about types and in fact has come up with a different thing that he uses in place of types, schema. And it’s, it’s runtime schema checking. But it’s not really a type system. So I’ve also kind of listen to him discoursing on why types are just a matter of taste.
And so I’m familiar with that perspective. I think it’s maybe a cop out to say that we’re not talking about the same things, but I think it might be a matter of misperception. . Like I said before, I was sold on static typing. I viewed it as this is going to be a lot of manual labor and yes, maybe it will find some bugs for me, but I can write you in a test and that’s fine.
Right? Certainly the Ruby community is all in on unit tests and w we’re going to do exhaustive tense thing and that will be great, but it’s possible that you’d be able to find some programmers out there that would say commenting your code as a matter of taste. But I th I think in professional development it’s pretty standard that, yeah, you want some doc comments to describe at a higher level, kind of at a human level, here’s what this class is going to be doing.
And maybe I should read some of DHH’s code, but I would guess that the code that he’s writing is easy to type. It’s not like, Oh yeah, I love to have functions that take a ton of different types of arguments depending on how you call it. No, that’s actually bad practice. Generally. So having a type checker just helps you read other people’s code, and especially as the size of a team gets larger, keeping everyone on board, it’s so much easier if there’s something that’s enforcing kind of those coding practices.
Adam: It’s kind of like the TypeScript slogan about scaling, right? They’re talking about like scaling a team actually, not really in terms of the
Adam: Whatever amount of data you’re going to throw at it.
You’re like, where does this value even come from? what guarantees do I have? Okay. zero I have zero guarantees. So then another direction to take it is I’m going to do a million dynamic checks at the top of this function. Mm. And this is what we had in like 2013 2014 Java script.
Adam: Like check the number of arguments
Jared: and the, yeah, we’re, we’re going to check the number of arguments, we’re going to do a bunch of type of checks to be like, okay, make sure this is a string and this is a number on this. There’s an object that has these attributes. That’s so much code that is, you know, it’s defensive programming. We’ve got a better way now and it’s fantastic.
Adam: Yeah, that makes sense. If you think of that, the type checker is something just doing all that defensive stuff for you, right?
Yeah. What about prop types and react?
Jared: Prop types were a gateway drug, I guess the creator of react. Jordan Walker is also the creator of reason, again to Ocaml all begin to types. And one of reacts big selling points early on is this is a framework that can scale because it does really dials in hard on encapsulation.
So these components can be reused. In comparison to angular at the time with kind of the dynamic scoping stuff that was going on there, made it moderately dangerous to reuse code, react, really dialing in on, let’s make these things were usable and in order to really deliver on that promise, especially with a team that’s large.
Adam: Today’s episode is sponsored by springboard.
If you want to learn how to write machine learning algorithms or if you want hands on experience deploying a machine learning model into production, or if you want to learn how to build and deploy a deep learning prototype, check out their machine learning engineering career track. When you join this program, you’ll be paired with a machine learning expert who provides one-on-one mentorship throughout the course.
This program is designed for software engineers, so you must have at least one year of experience in a modern programming language like Java or C plus plus or Python. Now, here’s the cool part. Cool. Recursive is exclusively offering 20 scholarships of $500 to eligible applicants. Make sure you use code AI springboard.
When you enroll. I’ll put a link in the show notes as well. The 20 scholarships are awarded on a first come first serve basis. Check it out. See if you are eligible. Applying is free and it only takes 10 minutes. Thank you. Springboard.
Adam: And then where does reason come into this?
Jared: So reason is reason is built on OCAML. Ocaml is one of those languages that routinely makes it onto . Gotta learn these five languages to change the way you think about code. You know, there’s going to be probably closure on, there are some other lists and there’s going to be Haskell and there’s going to be ocaml, it’s something like 25 years old, been around for a really long time, and a lot of the modern, cool languages are.
For many people, myself included at the beginning, I was looking at Haskell, I was looking at Elm. Elm is a very cool language, but the syntax is so foreign. It takes me so long to read a snippet of code cause I just don’t know how to parse it. Gotta be like, okay, what’s the precedents here? How do we deal with, is this getting called with arguments or is it just getting past?
So that’s, I don’t know how well I described reason for him, but that’s what it is.
Adam: But then reason is not okay.
Most strictly speaking, it’s a different language, right?
Jared: It depends on what you call it. Language is elixir, a different language from Erlang. If you’re familiar with those two, Elixir is literally just a new syntax for Erlang. Maybe. I think it has any standard library, but is Scala a different language from Java?
They both were on. The JVM scholar is probably arguably more of a different language than reason is because uses the exact same compiler as Ocaml does, but it is a new syntax and tool chain is often what I call it. We’re Campbell.
Adam: So you have, okay, we’ll compiler. You take off the front, right, and you put some new syntax on the back.
Jared: That’s right.
Adam: And then, but then haven’t you removed everything,
Jared: Well the type system is the same.
Adam: Oh, okay.
Jared: Yeah. And that’s really the bones of, if you look at the, okay, a compiler, the compiler itself has a number of, there’s the Lexer, there’s the parser, there’s the type checker, and then there’s the, the thing that generates the assembly, and it’s really the only last bit.
Generally no assembly change it. Well, there’s a couple other internal steps, but there’s a lot that is shared. And that is. I think the things that make
Ocaml. Great. The language semantics, if you will. The module system, the function system, all of that is the same.
Adam: Ah, I see. I think I get what you’re saying.
Jared: yeah. Yeah. So literally you could go through, and I mean initially the changes to the parser, like it was based on the OCAML parser and it was like, let’s just switch out, let out some, tell me Colin’s here and add some parentheses here.
In, in the intervening years, it’s gotten further from that, but it is still based on the parser and has a, most of it is shared.
Adam: Yeah. And so we started off talking about types. So it is the exciting bit of reason.
Reason has an OCAML has an almost entirely inferred type system. So whereas with TypeScript and flow, in order to really. Get the advantages from it. You need to right function signatures or at least for the export functions, and you did write your interfaces and stuff, but with reason I only right data types, right?
I create the data type and this is like I was saying before, when I’m thinking about a problem, I will write out the shape of the data and then I just use it and that I just used the variables and everything is inferred, but unlike flow and TypeScript. There is no any that would just be pervasive throughout everything, right?
Like it is milliseconds to do a full rebuild of a reasonably large project. And you used a Webpack or babble or you’ll be blown away as well.
Adam: Oh, so it might actually be faster than my existing JS.
You’re giving away 200 milliseconds for every process. And your reason build chain can completed 10 times in that. I’m going to do that.
Adam: Oh wow. I wouldn’t have expected that. That’s impressive. So you mentioned laying out a data type and then using that, do you have an example that might help us understand?
Jared: Well, let’s see. We could talk to new MVC. What’s your, to do item shape? It’s going to have a title that’s going to have an author. Maybe it’s going to have a Boolean for whether it’s been completed.
Adam: Yeah. So I define a to do item. It has some properties. And then if it were TypeScript, then my functions that dealt with that, I would just put like type annotations on them.
Right, and you’re saying I don’t have to do that.
You can access attributes and all that, and you don’t have to be. Dropping annotations anytime you want to use it.
Adam: But so can I if I want to.
Jared: Certainly. Yeah. For the purposes of reading code, especially if you’re reading it on good habits. Nice to have the annotations there, cause you don’t have the hover for type kind of stuff.
Adam: What else does reason to have? What else makes it
Doesn’t enforce that we are nearly to the next step. You write your type adaptations for what you expect Java script to give you, and that’s that. You can call the function synchronously. There’s not, that’s the realization bridge. There’s not nearly as much work two bind to a node module, for example. Now that comes with unsafety, right?
Adam: Yeah, so Elm is they want it to be completely sound, so then they lock it down, but. It prohibits adoption to a certain extent,
Jared: right? I mean, and it can make some performance things more difficult and some other things.
Now, one thing that I love about Elm that it has kind of narrowed the scope of what it wants to do, right? It is, this is a language for building UIs and it’s phenomenal at that. Because of that, it can make some tradeoffs. Generally, UIs are not performance bound despite what the demos might suggest.
Your unlikely to be rendering 10,000 elements on a page. Okay. most of us don’t do that in general, and so the trade off that it’s made, I think are are perfectly reasonable reason. And OCAML are much more of a, this is a language that we can use for UIs. We can also use a per servers and for embedded devices we can use it.
Adam: How are you writing a Android app in reason?
Jared: That’s right. Yeah. And this is taking advantage of the incredible work that’s been done in the OCAML world, where there’s no ocaml backend for Android for iOS. So I’m not bringing in NPM libraries. my Android app. Yeah. But there is a wealth of code that has just been written in pure ocaml, pure reason, and you can just bring that in.
Adam: It’s really exciting. I could see how it could be a limitation too. And just like you’re spreading yourself very thin. If people are using this language to do this and that and not, it’s like, I don’t know. Sometimes it’s really great to have a certain domain where people use things and libraries build up in it.
Using it as a reason, it is a dream, and so we’ve got a lot of people doing reaction reason and then certainly much smaller communities doing game development, doing native development, that kind of thing.
Adam: What’s the advantage of react and reason? Like what is reason by you in the react ecosystem?
Jared: It’s nice that it’s a mutable by default, right?
Adam: you say the react creator created reason?
Jared: That’s right. Yeah. Jordan walk was originator of react and you know, helped by a bunch of other really excellent people. And then he also started at the reason project.
Adam: Oh, very cool. I’m primarily a backend developer. I do a lot of FP stuff and people use that term very generically.
Right. And I think, at least in my little group, we mean something pretty specific that has to do with types and immutability and kind of composing things. We’re trying to always convince other people that this is super useful. It’s been a new discovery to me that actually on the front end, people have been figuring this out.
Like while I wasn’t looking, I guess like react seems very, uh. It seems to have a lot of this spirit, I guess in it, maybe.
Jared: Yes, definitely. That’s actually another good point with reason and react because react is built very much in an FP mindset. And the reason I know OCAML are kind of the, what you might think of as the original FP is Ocaml Haskell, like those are the things that people are drawing from these days.
Unless you want untapped FP and then it’s the lisp side of things. But if you want reason has immutability, automatic currying of all functions. And just generally functions are the way to do things as opposed to classes that encapsulate both data and functionality.
Adam: You mentioned immutability. How does that work?
I know that my thoughts, how I do things and we’ve got map and filter and reduce and all these things.
Jared: So, ocaml has arrays and lists, unless they’re linked. So if you’re using a raise, they are mutable and there are certain cases where you’re writing reason and a raise make sense. But most of the time I’m just using the default list implementation and the functional methods that go along with that.
You’re not transforming a million items and somebody’s browser. Yeah, that’s true. Yeah. But there is some trade off things where you’re like, what’s the best tool for this job, right? And there are the hash array maps trie thing that. Uh, that clojure has that. It has some cool properties, their implementations of that for ocaml.
Adam: Well, why would I want something to be immutable.
Jared: Immutability saves you from spooky action at a distance as generally my pitch, I mean, there’s so much uncertainty around I’m doing this thing and I call this function, and what if this function completely messes up the object that I passed to it? Right? So I’ve got a clone object before I hand it in or whatever.
Like again, defensive programming and in a large code base where mutation is the norm, you just have to be looking over your shoulder all the time. Now in, uh, the code bases that I work on at work, immutability is the norm. And so I generally just trust that I don’t have to be worried about somebody changes something out from under me.
It would be nicer to have that statically guaranteed by the language system. But, uh, we do what we gotta do.
Adam: Yeah. So it’s like you’re working in a world where you just assume immutability, but, and that generally probably works, right? Because everybody has the same assumption.
Jared: Right? And if you’re using react and you’re using redux, especially.
Redox will fail in comical ways if you start mutating objects. And so I think these libraries have done a lot to bring immutability as a norm into professional jobs. Group development.
Adam: Yeah. What about some types and algebraic data types?
Jared: Yeah. It’s hard to pitch something that you don’t know you don’t have right.
And so like you’re just dying inside as you have to come up with different variable names. So they don’t.
Adam: I didn’t know that.
Jared: Oh, for right now it’s the worst because there’s automatic fall for, right. And so like, Oh,
Adam: I feel like we need to put an example on it.
I’m trying to.
Jared: Right? No, I mean the biggest or the most important, some type that we have in our code base that’s using flow is our loadable data type. This is for anything we fetched from the network that we’re putting in Redux, and kind of the, the naive implementation would be on your reacts component.
On state, you would have a, a Boolean that is whether I am loading like, so there’s loading, which is a Boolean, and you would have error, which is an optional error. And then you’d have data, which is optional data. Right? And so on component dead Mount, you set loading to true and you kickoff the fetch and then when the fetch comes back, either you set the error to something or the data to something, and then in your render method I have a couple of his statements.
If we’re loading, then render this. Otherwise if there’s an error under this, otherwise hope you have the data and nobody messed up your state and render them with the data. But having a some type that and forces, there are three disjoint States. One of them is loading, one of them is. Loaded with error and one of them is loaded with data.
You don’t have to worry that somebody’s gonna accidentally set both data and error to something like how do you render that it’s just impossible. there’s a a couple of really good talks about making impossible States on representable where this doesn’t make sense. To have loading be true and data be true.
Yeah. Unless you’re refreshing, in which case, let’s account for that in the data type as opposed to just like some coincidence of the way you’ve set things up. How
Adam: would I pull this apart in reason or flow for that matter
Jared: in reason, you would switch on the floating state and critically, it’s impossible to get anything out of the loading state unless you switch on it.
And so you can’t make assumptions about, you have to switch and say, is this loading or is this loaded, or is this failed? And you have to handle all of those cases. Right. I can’t tell you how many bugs and web apps are caused by someone for getting one of the cases. Oh, I forgot that it could be loading here.
And it is, and so everything’s dead.
Adam: It’s not just web apps. I think it’s the world,
Jared: right? Yeah. Yeah. And so having that enforced for you. Again, this is another, I can offload this from my internal Ram. I don’t have to like try and remember what other cases this can be in. The compiler makes it so you can’t forget.
Adam: I think we talked about why this might be a smoother onboarding than Elm. How would you compare it to TypeScript or flow?
Adam: Yeah. So how would you describe, and maybe I don’t have the right words here, how would you describe that distinction?
Jared: So there are a couple of continue, uh, continuums. Okay. And I would have to pull up on the spectrum from all mutability all the time versus all immutability. All immutability is where Elm is at, right?
But then you can call that, you know, it’s just sitting in your reason code so you can get on with your life and then later when it has bugs are, when you feel bad about it, you can go back and rewrite it the correct way. How does that work?
Adam: Because you said there’s no any type, so what happens there?
Jared: It is inferred to be, what do you think it should be.
Adam: I see whatever you call it, as it becomes that right.
It has to be explicit.
Jared: It’s like the good parts are enforced and you can rely on them.
Adam: Part of the allure of like TypeScript, I’m less familiar with flow, is just like how easy it is. Like you can just rename your files and start there. What’s the adoption path to get to reason?
Adam: So have you made the transition in your day job?
Jared: Not in my day job. And there are a number of things that go into that. We recently converted to react native from native iOS and Android, and we’ve adopted flow and graphQL, and we’re rewriting our whole backend and go.
It is mostly about people and it is incidentally about code. But if I were on a smaller team, five to 10 people, I choose the reason in a heartbeat.
Jared: That depends on how strict you are because flow has any. And you can just say, ah, I’ll type it does any and I will pay the cost and bugs and developer tiers down the line.
Adam: Yeah. Yeah. It’s a messy world out there. I guess with TypeScript, I know that somebody was talking to is having problems just because they had a lot of stuff that took like a variable number of arguments.
It was perfectly acceptable to call it with one or five or whatever. Right. I don’t think TypeScript, I may be getting the example wrong. But it seemed like it was. Yeah. I don’t know what to do with that.
Jared: Yeah. There are libraries, especially libraries written in 2010 that were like, my favorite thing is to have a function that can be called 11 different ways with these different specific arguments.
And my response to that is, that’s a bad idea. Okay. When I’m using these functions, I have to remind myself, okay, is it three arguments or is it four? The behavior changes drastically based on that’s just not, can it be easy to maintain? Now, if you mean like a spread of arguments, like I want to be able to call this with the math.
Dot. Min function can take any number of numbers and I’ll just take a the of them. That’s fine. That’s easy to type both in TypeScript flow. But if you’re like for some interesting reason, I want my library to only export one function when it could just as well expect support 10 I’m like, why are you doing that?
Adam: Yeah. Or curried functions that people have written where you can call it with one argument and then it returns a function that takes the next one, right?
What’s your sales pitch for types and reason?
Adam: dynamic type people listening. What do you think? Do you buy it? Maybe you were just thinking of telling me where to take my static type propaganda.
I don’t know, but I hope you find Jared’s perspective. Interesting. Go check out ReasonML and Jared’s podcast called reason town. There’s a link in the show notes to both. Speaking of show notes, springboards special scholarship program is linked in the show notes. Springboard with my first sponsor.
Woo, They reach out to me and the mentorship program they have sounds super cool. So check it out.
Until next time. Thank you so much for listening. .