00:00:14.400
Hey everybody, how's it going? For those of you who have seen me speak before, you know that I usually like to start my talks with something a little weird. This will be no exception; you will not be spared.
00:00:26.110
So, I want to first make sure that we're all sort of in sync. I'm going to count to three, and when I say three, everyone can just clap. Ready? One, two, three!
00:00:38.940
Hmm. Turns out sync needs a little work. Let's try again. Ready? One, two, three!
00:00:45.610
That's so much better! Let’s snap this time. One, two, three! Awesome!
00:00:50.920
Okay, so don't do it yet, but this time, when I get to three, everyone who is able to, please crack your knuckles. It's going to be weird! Anyone want to leave the room before this happens? Okay, ready? One, two... yeah, yeah.
00:01:12.509
That was weird. I like to start my talks with a little bit of disgust; that way, everything seems like an uphill climb afterwards.
00:01:25.299
I'm here today to talk to you about the future. It has no Vim today; no live coding, which is good because I have both hands occupied, so I can’t code with my face.
00:01:31.000
Alright, so I want to talk about the future, and I want to discuss the future of writing correct code. I think this is probably pretty important.
00:01:38.710
It's going to matter. I flew over here on an airplane that has apparently about five million lines of code in it. Yeah, and probably some of those awesome errors that Brittany pointed out, if I had to guess.
00:01:52.689
Not all of that code is safety-critical; I assume, but it's likely that we will soon be riding around in cars that have millions of lines of code in them.
00:02:00.700
Drones will fly over our heads, possibly with millions of lines of code. Trains and planes—it's all going to happen, I think. So writing correct code is important. Maybe that's not super relevant to us; I've never written safety-critical code—code that kills people if it's wrong.
00:02:18.400
But it's really important that code would be correct, even if you're writing web applications. To pick a totally hypothetical example, imagine you wrote some sort of web app that accidentally leaked about a hundred and forty-three million social security numbers out as a quasi-governmental agency. Let's just say that would be bad.
00:02:30.100
So I've been thinking a lot about what the future of writing correct code looks like. How are we going to do it? How do we do it today, and how can we do it better? That's what this talk is about. I asked myself early on: what is a good model? Where can we look for possible inspiration and clues about what this means for us?
00:02:54.910
The answer to me surprisingly came in the form of chess. Does anybody know who this guy is? Yeah, Garry Kasparov, a former world chess champion. For a while, he was the best chess entity in the world.
00:03:06.989
He was undeniably the most correct chess player there ever was. Then in 1997, do you know what happened? He got beat by a computer called Deep Blue, financed by IBM. He lost a six-game match, and this computer was so far advanced from what had been seen before that Garry actually accused the Deep Blue team of cheating, because there was a move in the second game that was so good he was convinced that only a human could have thought of it.
00:03:40.510
Turns out computers get better. Garry lost, and at that point, the best chess playing entity in the world, the most correct one, was this computer.
00:03:45.610
But then something was discovered: if you took a really strong chess engine and had it spit out potential moves to a grandmaster, that combination was stronger than just the chess engine alone. And that's actually still true today! So, if you pair a grandmaster with the strongest chess engine, that combination will beat the chess engine.
00:04:11.410
So today, if you want the most correct chess playing, the answer is a human plus a program to help that human. And I think that's where we're going. I don't think we're going to have much success in making dramatically smarter humans, and even if we did, we'd have to make all of us smarter.
00:04:39.070
But if you can make a really good, really smart program, you can help everyone, even if we don't make anybody else smarter. So I think that's the future—we might as well call it AI if you want to impress people—but programs to help us write programs, programs to check our work.
00:04:56.950
I have some bad news: I don't think Ruby is going to be the answer to this. I know we are at Rocky Mountain Ruby, but I don't think these programs are going to be written in Ruby. That's actually good news, though, because Ruby has been around a long time.
00:05:10.030
We would hope that we can do better, right? We would hope that we wouldn't be stuck with the same language forever and that things wouldn't progress. So that's actually good news.
00:05:22.210
I have more good news: the future is now! I've actually spent the last six months writing code with the help of programs to assist me.
00:05:28.000
It has completely changed things for me. I am writing dramatically more correct code, I am refactoring with much more confidence, and I am enjoying the heck out of it.
00:05:41.559
I want to tell you about the first program I used—my first book was Elm. Somebody asked about that over there. This dovetails nicely with Brittany's talk, because Elm solves a lot of these error message issues for us.
00:05:53.049
How many people have heard of Elm? Okay, how many people have run Elm in production? Aha, yes! Elm is an interesting programming language; it compiles into JavaScript. If you want to write some sort of UI for a browser, the browser is the target.
00:06:08.979
You might use React; you might instead use Elm. Elm has a really powerful type system. It's sort of descended from Haskell. If you've written some Haskell or heard of it, you might have heard people say, 'Oh my God, the types of Haskell are amazing!' And they are.
00:06:34.809
It's sort of like the creator of Elm chopped off the most complex parts of Haskell, simplified them a bit, and made a more beautiful language that still compiles into JavaScript. So, we don't have to write JavaScript, and the generated JavaScript can be quite correct.
00:06:52.029
I've been writing a lot of Elm and liking it quite a bit. Notice how we had a lot of people who have heard of Elm, but only a few who have run it in production? I think Elm is about to cross the chasm from something that only a couple of early adopters are using to something that crosses over into mainstream acceptance.
00:07:07.869
Enough people are using it, and enough companies are using it that people can trust that it's going to be good. That's part of my mission; I'm trying to help across the chasm right now. I'm hoping to inspire some of you to try this out.
00:07:18.669
Correctness is a pretty good measure. How many runtime exceptions do you get? Because every runtime exception is like—oh no, you screwed up; there's a thing that you didn't anticipate, something went wrong.
00:07:36.549
If you're running a pretty popular app that gets a decent amount of traffic, you're probably getting lots of these. Like, how many people have seen, like, ten exceptions a day? No? Okay, just me. I feel like if you look in your Honeybadger logs, you will be contradicted!
00:07:53.190
Runtime exceptions are not so good. Here's an example: there is a company that is running a hundred thousand lines of Elm. They're an early adopter and have embraced Elm very hard.
00:08:03.580
They've been running it for about three years in production. How many runtime exceptions do you think they had in those three years? Zero. None. I challenge you to write a hundred lines of JavaScript and run it for three years and get zero runtime exceptions. I don't think you can do it.
00:08:21.370
The reason you get so few runtime exceptions in Elm is because it has a type system. I know you've probably heard of type systems before. You might have experienced some type systems, maybe you wrote some Java and said, 'Yes, type systems are no good; Java is so verbose. I hate it!'
00:08:39.910
Not all type systems are created equal; Elm's type system is amazing. Let's look at some examples of Elm code, and I'll talk about the type system in these examples. So this top line is a type signature. It says the function 'length' has type: it takes a string and returns an integer.
00:09:05.700
Here are examples below: 'length' takes 'hey' and returns 3. Your length function takes an empty string and returns 0. This one line of code, which is simple to type and easy to think about, gives you quite a lot of security and guarantees.
00:09:22.390
So, the Elm type system will look through all calling sites of 'length' and make sure you only ever pass it a string. You cannot compile an Elm program that passes something that’s not a string to your length function. That's a guarantee: if it compiles, you have never done that.
00:09:39.190
Also, Elm will look through the body of the 'length' function, no matter how complex, and make sure it always returns an int. It will walk through all of the branches of your if statements, your case statements. You can't fool it. It knows you always return an int, guaranteed. That one line gives you so much security.
00:10:06.720
Here's another example: 'concat'. This takes a list of strings and returns a string. Here's our example down below. You can see our list and our output, exactly the same: you can never call this function if you're not passing in a list of strings, and it will always return a string. Strong guarantees!
00:10:28.720
Last example: here’s 'repeat'. This is a little bit of a new idea that you haven't seen yet. The 'repeat' function takes an int and some type 'a', returns a list of 'a's. Here’s our examples. We 'repeat' takes a 3, let's say, and an 'irand' (which is a string), and it returns a list of 'iran'.
00:10:48.020
Alright, nice! I wasn't sure if that was going to work. So this 'a' right here just stands for any type. Send me an int and something, and I'll make sure to send you a list of those somethings back. And again, that one-line Elm guarantees that this is true.
00:11:07.420
It's like a contract; it will not compile if this is not true. Furthermore, type signatures also make great documentation. So here we say the 'is admin' function takes a user and returns a boolean. That's pretty clear! It's like executable documentation.
00:11:25.700
I bet you could write that function just given that type signature. Now let’s take a look at 'map' in Ruby. This is some new syntax you haven't seen yet, but this says the type of 'map'. 'map' takes a function from A to B—that's what's in the parentheses—and a list of 'a's, and it returns a list of 'b's.
00:11:40.780
This makes sense if you sort of think about this in Ruby. Imagine you have a function from string to int, and a list of strings. You get back a list of ints. Every time you call 'map', Elm checks to make sure that this is working correctly. This type system makes a big difference.
00:12:02.519
It lets you have some pretty incredible error messages, which I wish Brittany could see. Here we go: the branches of this if produce different types of values! The 'then' branch has type string, but the 'else' branch is number. This needs to match so that no matter which branch we take, we always get back the same type of value. Right? That's a pretty darn good error message!
00:12:18.960
There’s actually a repo of all the possible error messages that an Elm program can generate. People file issues against this repo saying, 'This error could be better,' and they will add hints down at the bottom or links to further documentation.
00:12:36.190
Here’s another example, and this is the kind of thing that trips up newbies. They add an explicit error for this: 'This condition does not evaluate to a boolean value, true or false.' This is a common thing. So if you're a Ruby programmer, you probably assume that you can use this sort of truthiness type.
00:12:55.260
For instance, like the list length is this—you can use it in an if. Elm says, 'You haven't given me a condition with this type, int, but I needed it to be bool.' Hint: Elm does not have truthiness, such that lists and integers are automatically converted to booleans. You must do that conversion explicitly.
00:13:12.470
This kind of friendliness is all throughout the language; it's like having a friend debug your code for you. This is the kind of thing you can get with a type system and a smart compiler. This is a program helping me write programs. This stuff is a big deal!
00:13:32.860
I want to turn now to one of my favorite topics, which is nil. My favorite—I mean least favorite! I tweeted this a while ago.
00:13:49.890
The sad truth: a year! This is funny because it's true; unfortunately, I wish it weren't. Challenge: try this with your co-workers for a few weeks and see how long it takes them to catch on that this is all your doing during code review!
00:14:07.890
‘Can this be nil?’ What happens when this—Ruby loves to return nil when Ruby doesn't know what's gone wrong? Nil is, 'Oh, no! Something went wrong. What should we do? Return nil! It'll be great.'
00:14:22.790
So, let's go back to those Honeybadger errors, or your whatever error tracker you happen to be using. Whose most common error is 'No method error on nil?' Oh yeah! Everybody? Everybody? Those are classic errors. Go check it if you don’t believe me! If there were a quintessential Ruby error, it would be that one.
00:14:41.490
It would be that you got 'nil' somewhere and you accidentally called something on it, like what's the bug there? You thought you had a thing but you actually had nil, and you tried to call something on that nil.
00:14:58.600
Ruby's answer to this problem of, 'Hey, nil shows up all the time' is: 'Never forget to check for nil!' Just be perfect! You should always assume that something might be nil and you should have tons and tons of guard clauses all over the place.
00:15:14.640
Right? Nobody writes code like this. We read it very directly. We write a very simple unit test that has a perfect real-world scenario, and it passes.
00:15:31.440
Great, everything's good! Move on! And then later somehow that whatever thing is not there, you get a nil and it blows up, and you get an exception at runtime, which is when your users see it.
00:15:46.890
Let's talk about how Elm handles this. Here’s a concrete example. There’s a type called 'person.' A person is like an object and it has two pieces of data: it has a name, which is a string, and an age, which is an int. Then we have this 'can vote' function that takes a person and returns a boolean.
00:16:12.640
So we say, 'If the person's age is over 17, true; otherwise, false.' Okay, so imagine this scenario: we've written this code and we go, 'Oh, actually, you know what? A person might not always have an age. We might not always know the age of somebody. What do we do then?'
00:16:30.520
Well, Elm has an awesome answer! Ruby's answer would be: check for nil everywhere, every single time you use age! Don't forget to check for nil, and you go, 'Right! Definitely, I'm going to do that! I'm going to go do something else instead, and we're going to blow up in production all the time!'
00:16:49.620
Here's what Elm does: Elm has this interesting type called 'Maybe.' It’s like it has this interesting 'Maybe' in it; I kind of like that a lot, actually.
00:17:03.960
What we’ve done here is actually—think of 'Maybe' as a wrapper. We're sort of wrapping up the int that may or may not be there, and everywhere that we want to look at the person's age, we have to explicitly unwrap and say, 'I know this is not an int; it's actually a Maybe int. It's in that Maybe box.'
00:17:19.160
Since the Maybe box may have an int and it may have nothing, I will handle both sides. I'll handle both things, and Elm will not compile if you don't handle both things. You cannot forget to handle both things; it just will not compile!
00:17:36.190
So everywhere you go access that person's age, you have to say what you want to do if it's not there. That sounds a little annoying, but it's actually rigorous; it’s really saying we want our code to be correct.
00:17:56.190
If you're telling me that sometimes age is not there, you’ve got to tell me what I should do when it's not there.
00:18:10.950
Don’t worry about too much of the syntax here; there are some concepts we haven't covered, but here’s our new 'can vote' function when we switch into a Maybe int.
00:18:25.080
It basically just translates. It says let's look at the person's age: case 'person.age'. What's that? We look at their age: if they actually have an age and that age is over 17, then return true. If it's under 17, return false.
00:18:45.390
But if they don't have an age at all, then return false. So Maybe can be just 'Nothing'. It’s not so important that you understand that, but the clear thing here is that there's a line saying: this is what I want you to do when the age is actually there.
00:19:01.160
This kind of thing shows up in Ruby a lot; if 'age' is not present, Maybe you might get that. But basically, Elm won't compile if you eliminate lines of code that say here's what you should do when 'age' is not present.
00:19:19.080
This reduces so many bugs. It might be hard to imagine how this works in practice; I can tell you, once you get used to working with Maybe, looking at Ruby will give you panic attacks!
00:19:35.290
You’re like, 'Is that a Maybe? Isn't that a Maybe? Is that a Maybe?' It's such a difference, such a high level of rigor, and it prevents so many bugs. You'll never ever get a 'No method error on nil' in Elm; it just won't even compile!
00:19:51.420
So, I’m going to make a bold claim now—I’m echoing a bold claim, but I’m adding my emphasis to it. A former coworker of mine, who has written a lot of Elm, and he's written a lot of Ruby, says: 'I would have more confidence in a codebase that was an Elm codebase with no tests than a Ruby codebase with tons of tests.'
00:20:08.430
And that’s pretty huge because my code-to-test ratio is like two to one, ish—maybe one point eight to one. I’m running a lot of test code. I’d love to not write test code, and it turns out if your type system is strong enough, you need to write way fewer tests.
00:20:26.920
So you can go a lot faster, make fewer errors, and do less work because we have programs to help us write programs, and we should be using them.
00:20:41.900
I’ll talk to you about a real-world example—this is some Elm code I wrote. I decided I wanted to make a sort of image Evolver, and so I have a goal image and I want to randomly mutate my way from a set of random polygons into that image.
00:20:59.250
So, say I have a picture of my face and I will throw down a hundred random polygons on a canvas in the browser. I will mutate them, and if that image looks more like my face than it did before, I’ll keep that version and mutate from there. If not, I will throw away that mutation and try again.
00:21:16.380
It’s kind of like a hill climbing, like a naive hill climbing algorithm. I'm just sort of making these random changes, and every so often that change is closer to where I want to go—okay, that becomes my new baseline.
00:21:33.250
So here’s an example: on the left is the goal image, and those are the set of squares. On the right, we have 125 random polygons—random colors, random positions, and random transparency.
00:21:50.530
You’re watching the mutate; the bottom-left number is how many iterations. The bottom right number is our current similarity to the goal image, and you can kind of see we’re getting there.
00:22:07.030
You see how this flickering because it's trying lots of things, it's like, 'Is this better? Is this better?' It just picks, it'll pick like twenty polygons at random and change random things like one of their vertices: the color, the opacity—it just tweaks it and we're starting to get recognizable!
00:22:25.160
So this is a program I wrote because I want to kind of flex my own skills and see what this was like. Here is another example; this one’s just static. Faces are harder. The more detail there is, the harder it is. But you can see we’re getting there.
00:22:41.420
I wrote this program, and in the original version, I used circles instead of polygons on the canvas because it sounded simpler. I was like, 'Well a circle just has a center and a radius and that seems easier than a polygon that has a list of vertices, and I need to keep track of.'
00:22:57.240
I was new to Elm so I was like, 'I’ll just use circles!' So I built the first version and I got it working and I was like, 'Okay, this is going to work a lot better with polygons; I’m going to have to do this refactor.'
00:23:13.750
I made a new branch and was like, 'This is probably going to suck.' Here we go—by way of comparison, imagine you’ve written a Rails app and it’s a to-do app. You can create a to-do, you can rename it, assign it, and complete them.
00:23:34.190
And then someone comes along after a couple of days, and is like, 'Hey, guess what? That to-do app, we're actually going to make it now be an issue tracker for software development teams. So to-dos, we should rename to issues!'
00:23:49.590
And to-dos no longer have a due date, and when you assign it, you might actually assign it to a team of people instead of a single person. You have this change to a very fundamental data structure in your app! That's what I was changing.
00:24:00.670
The circle data structure was in basically every function of my app; it flowed through all the way the Elm map, and I was like, 'Okay, this is going to be pretty terrible.'
00:24:15.120
I made the change; the top-level said, 'Okay, hey, Elm, circles are nothing anymore. Now they're polygons, and they don’t have a center; they have a list of vertices.' A vertex looks like this, and these are the coordinates and all that.
00:24:32.370
And Elm immediately spits out like 15 errors. Oh my gosh, here we go! I guess the first error, and it's pretty simple in Elm, is like, 'Hey, you gave me a circle, and you need to give me a polygon.' I was like, 'Okay, no problem!'
00:24:47.460
It’s like, 'Oh hey, you referenced a radius and that’s not a thing anymore!' Yeah, now it’s a vertex. I very mechanically walked through this list of sixteen or so errors that actually were pretty straightforward.
00:25:03.260
They were well-explained and they're pretty easy, and then I finished and I solved the last one and it compiled. And I was like, 'No way!' I refreshed my browser, and it worked perfectly the first time.
00:25:19.960
I got goosebumps when that happened! It's just, oh my god! There were no tests in this. I was new to this thing; I wasn’t ready for any tests!
00:25:33.600
The type system and the compiler walked me through what would have been a really hairy refactor in any other language. It was simple! I never stressed. As soon as it compiled, it worked perfectly. It's just so mind-blowing!
00:25:50.920
Alright, let's talk about a second program that I've been using to help me write better code: property-based testing. Is anyone familiar with this? Okay, wow, not even at the chasm yet—awesome! This is great; I'm excited for you!
00:26:06.720
Okay, so let's say we want to write a function, and we want to make sure that the function is correct. So we’re like, 'Cool! We’re going to be good programmers!' We’ll write some unit tests. Let's think of an input.
00:26:25.340
Let’s say we have a 'reverse' function; I should pass it a list of three items, and then, when I call 'reverse' on that, it should be reversed. So we hand-write an input and we hand-write an output, and we say those should be the same.
00:26:41.490
And we did it a couple more times, and we're like, 'That seems good!' And we move on with our lives. We often miss a lot of edge cases, and it's because it’s annoying to come up with lots of inputs and think of lots of edge cases.
00:26:54.780
It’s annoying to have all that test code there. If you write 500 lines of tests for a 'reverse' function, you’re like, 'This seems stupid! Why am I spending all this time here?'
00:27:10.230
So property-based testing takes a different approach. It says, 'Hey, you know, thinking up test cases and checking that they’re correct? That sounds like a great job for a program! That's not a great job for a human!'
00:27:29.750
So let's imagine we are testing this reverse function with property-based testing. Instead of coming up with test cases, you come up with properties. Properties are things that are always true for the function you’re testing.
00:27:47.480
Can anyone think of a property that should hold for the reverse function? No matter what input we have, what should be true about the output? Can anyone think of some properties? Yeah, absolutely! That's a great one!
00:28:03.480
No matter what input I throw into reverse, the output of reverse should have the same length as the input, right? That should always be true unless something is horribly wrong! Excellent! Really good!
00:28:23.850
Any other ideas, any other properties? Yeah, it should still be a list! Absolutely, the type should be right, and we should still have a certain number of things.
00:28:32.890
We shouldn't lose elements or gain elements; we shouldn't accidentally duplicate things! Awesome. So just armed with those three properties that we just rattled off, we can then have property-based testing.
00:28:49.850
Elm has a property-based testing framework that generates us lots and lots of inputs and ensures that for every input the properties hold.
00:29:04.429
So, it says okay, here’s an empty list; do the properties hold? Yes! Okay, here is a list with 10,000 items; okay, the properties hold! Here’s a list with 20 Unicode items followed by some integers with a null byte tacked on at the end; okay, the property still holds!
00:29:22.760
It thinks of these lots of nasty edge cases for your code for you and makes sure that they’re right; so unlike a unit test, where you run five examples, you say, 'Okay, those tests pass,' a property-based test just hasn't failed yet.
00:29:37.710
So it will basically run, let’s say, a hundred different inputs through your function, make sure the properties hold, and say, 'You’re good!'
00:29:53.470
Let's move on to the next thing and you throw those in your test suite, and you basically have code testing your code for you.
00:30:09.300
This is a pretty big win! So here’s a question: Does this stuff actually work in practice? Does it actually catch real-world bugs?
00:30:25.640
And the answer is: yes! Here’s a real-world example that a friend of mine ran into. He had written some tests for a JSON encoding and decoding library.
00:30:43.790
When you have an encoding and decoding pair like that, property-based testing really shines because you can say, 'Generate me some input, encode it, decode it, make sure I have the same input back!'
00:31:01.010
You basically round-trip all the way through your program and back, and say, 'I should have that same thing back!' You can generate me a list of things, and I want you to make sure that everything works this way.
00:31:19.950
This is like a really powerful property and a really powerful test, and you can just set it up and say, 'That should be true. Throw examples at this all night. I’ll be back in the morning and run a billion tests through that, testing your encoder and decoder.'
00:31:37.570
He tried this and his tests almost immediately failed. He discovered something: when he encoded something, it had microsecond precision, and when he decoded it, it was down to millisecond precision; it had truncated that precision at the end!
00:31:55.920
Now does that matter? Maybe! For them, it actually matters! If you compare these two times, are they equal? That sounds like an opportunity for a pretty subtle bug where two times look like they should be equal when you encode and decode but they’re off by microseconds.
00:32:06.500
This is the kind of thing: how could you find this in a unit test? Can you imagine catching this in a unit test? Probably not! But this is the kind of thing that property-based testing catches with ease.
00:32:18.710
I'm just about done, and I want to tell you one more thing. Does anybody know who this is? David Allen? Yeah!
00:32:36.490
David Allen came up with a system called 'Getting Things Done,' and one of the core tenets of getting things done is that when you think of a thing you want to do, even if you maybe want to do it, you need to throw it in a system that you trust.
00:32:53.540
You need to get it out of your head because, as he says, 'Brains are for having ideas, not for remembering things.' I think we should take that and apply it to programming.
00:33:10.160
We realize that our brains are for dreaming up programs—programs that are ambitious and change the world and do wonderful things, and they are not for chasing down 'nil' and watching for edge cases and worrying about microseconds!
00:33:26.770
So that’s the talk! If you liked this, this is my newsletter; you will probably like the things I send out. I’m really fired up about Elm these days, so I talk about it a fair amount.
00:33:39.000
I’m also about to launch a course called 'Refactoring Rails' about taking care of aging Rails apps. So, if you have an aging Rails app and you're starting to feel the pain, you might enjoy that too.
00:33:56.850
If you sign up there, I’ll send you information about that course as well. Thanks very much! It’s been a lot of fun!
00:34:09.220
I had to write some things down. Okay, I had some complaints.
00:34:17.320
Yes! Good, good, good! The complaint is open. The first one is that you went through an example of demanding biographical details of a person’s age and name, all anchored around the discussion of `Maybe`, and you passed up the opportunity for phone number leading to obvious 'Call Me Maybe' jokes.
00:34:31.130
Oh, damn! Second strong criticism: more grievous! I was actually about to shout it, but I was like, 'No, I don’t want to blow the punchline!' And it never came! It looks like you were writing a CRUD app!
00:34:44.630
Would you like help with that? With a little Clippy graphic? Okay! Programs, I write programs!
00:34:58.340
Yeah, sure! Sure, sure! I thought that was coming in the intro!
00:35:05.360
Okay, other than that, all sold! I don’t know if anybody else, like—I used to do Java a long time ago, and just like types is a thing I have found myself craving, especially in teaching.
00:35:21.410
Seeing like a precondition, postcondition, or like input type-output type was honestly, I was like, it's like you're going home—it's so beautiful!
00:35:35.000
And like the error message about the type mismatch coming out of that if was like really, really neat!
00:35:42.790
And if you didn’t see those things, if you saw those things, you're like, why would I care? Then just look into those Honeybadger logs! Yeah, exactly!
00:36:04.610
So aside from my private commentary, is it time for a couple of questions?
00:36:17.170
Yeah, is there like comment Ruby contracts? That's called!? So I can actually recommend a gem—if you like the 'Maybe' idea, and you want to try it out in Ruby, it's not going to be as slick as Elm, but if you look at the 'wrapped' gem.
00:36:31.210
Like I said, some former co-workers of mine said like, I miss Maybe; so here’s the concept.
00:36:44.490
And it's not quite as slick, but it'll give you a sense of it. Yeah, yeah!
00:36:55.420
So, if you can't hear, he said he’s calling me out because in the past I have prescribed null objects as an answer to that nil problem.
00:37:07.330
And I don’t think what I said was in conflict with that, which is that nil is the problem and there are various ways to solve it.
00:37:20.610
I have really liked Elm a lot now! I would rather have a Maybe than a null object most of the time!
00:37:29.330
But because it’s enforced by the type system, if a thing expects an int, you can never hand it a Maybe int. It's just like, I'm not interested in that type; you've got to give me an int!
00:37:45.170
And you just can never forget, whereas you can still have runtime errors with a null object, right? You have a null object standing in for a user, like you have a guest, let’s say.
00:37:58.590
Then you call 'last signed in,' and you're like, 'Oh! I didn’t actually define last signed in on that! That object and it blows up! Yes!
00:38:12.190
So the question was: Is there a testing framework for Elm? And there is! Yeah, so that generate, that property-based testing is available in Elm as well.
00:38:27.820
So there's an Elm test library, it has normal unit testing, like you're used to seeing, but also they have called fuzz testing, but it's the same concept.
00:38:42.200
What are the major hurdles around getting Elm in production? That's a good question! I don’t think it’s mostly cultural—honestly, at this point it feels technologically ready.
00:38:57.920
There are fairly easy ways to get it working in like the Rails asset pipeline, for example, as like a Thappa—they are running quite a bit of Elm. It’s happening!
00:39:11.240
I think it’s mostly just like, do people trust it? We’re at that phase where people need to look around and say, 'Are other companies that are sort of conservative like us using it?'
00:39:29.750
Okay, fine—we'll use it! I think that’s where we’re at.
00:39:37.870
That's it. That’s all.