 Yeah, thanks everyone. It's a really great honor to be back here again. This is such a great conference. If anything in here you want to talk to me about, this is how you can reach me on Twitter. My website is a site. You can check it out. So I'm currently working at a company called Citus Data. And what they do is it's a Postgres extension that lets you, it takes care of all the sharding. And so you can have regular tables, but you can say this table, I want this sharded amongst several machines, and that way you can have lots and lots of data. It's pretty cool if you use Postgres and you have or will have a lot of data come talk to me. If that sounds like something you want to work on, come talk to me if you don't use Postgres. So this talk is going to be sort of in a couple of different parts. The first part is what is the crystal programming language, why I'm excited about it. And then the last part is going to be some examples to show you how it's similar and how it's different from Ruby. Last week, the crystal people put out a new thing where you can type at the command line crystal play, and it pops open a browser and you can sort of like do live interactive things. And I thought this is really cool. And so I hacked it up a little bit with the help of one of the members of the crystal core team, and it's not released yet, but in the next version of crystal there will be this way that you can have like a workbook, and so you can have little samples that go along with your library or whatnot. And so I switched the talk to use that instead. The good side is that I think it's going to be a little more interesting to see the code actually run. The downside is it's just a lot of code. And so I was thinking, I can get kind of dull, I couldn't figure out how to get pictures into it, and so like there's not even pictures to help. So I figured I'd tell one of my favorite Norm McDonald jokes to sort of compensate for all that. And so I don't know if any of you have heard the story about the frog that tried to get a loan, but it goes like this. A frog is going down the street and he walks into a bank and he asks the teller, hey, I'm here, I'd really like to get a loan. And the teller's like, you're a frog. And he's like, yeah, I get that a lot. But still, can you help me? And she's like, well, the loan manager, her name is Patricia Wack. I don't know you here, you can talk to her and she'll see what she can do. And so he waits a little bit. Patricia opens the door, pulls you into the office and is like, so I understand you're looking to get a loan. And he's like, yes. And she's like, well, this is very irregular. We usually only give loans to humans. And he's like, yeah, yeah, but can you help me out? She's like, well, let's collect some information and we'll put it in and see how it goes. And she's like, okay, so first off, what's your name? And he's like, kind of takes a breath. He's like, my name is Kermit. And she's like, you're not Kermit the frog. I know what Kermit the frog looks like. That's not you. He's like, yeah, yeah, yeah. My first name is Kermit. My last name is Jagger. My father was Mick Jagger. My mom's a frog. I'll leave that up to your imagination. But so, you know, my name is Kermit Jagger. And she's like, well, what do you need a loan for? He's like, well, Ms. Whack. And she's like, stop, please call me Patty. He's like, well, Patty, I, you know, I just need a bigger lily pad for my family. And she's like, okay, that's understandable. This is still very irregular. Do you have any sort of collateral, anything at all? He's like, well, I have this. And she hands over this little like, little carving of an elephant. It's like pink. And it's kind of intricate, but it's just small and wooden. And she's like, Patty's looks at it. She's like, I don't know what to do with this. So she takes it back to the, she's like, I'm going to talk with my boss. He takes it back to the manager of the, that branch of the bank. He's like, tells her, explains, you know, this Kermit Jagger is trying to get a loan, but he's a frog. And this is all he has for collateral. And the manager looks at it. Oh, I see what this is. It's a knickknack, Patty Whack. Give the frog a loan. His old man's a rolling stone. So, so completely differently, the crystal programming language. It's, it's a programming language. It is unabashedly Ruby inspired. The syntax, the idioms and everything is, as you'll see soon, very similar to Ruby. But it's completely compiled. There's no virtual machine running the code at runtime. And it's built on top of LLVM. And LLVM, especially in the last years, has really become a marvelous project. It's, you know, the kind of work of Apple, Google, some other companies, and the machine code that it's able to generate and the optimizations does is just really astounding. And the entire crystal project, there's not really that many contributors. I haven't done all that much work with the language, like maybe 80 some commits, but I'm still like one of the bigger contributors to the language. And the reason that that's possible is one, like the top two people, the top three people are very proficient or prolific, especially the main creator. But also, because LLVM is doing all of the optimizations, all the work, you can get incredibly fast programs and crystals more of just like a front end to LLVM. And I really think that the next 10 years of languages, I always thought, you know, last 10 years, Ruby has done, you know, dynamic languages have been phenomenal. But I always thought as computers got faster, more cores and stuff like the languages, dynamic languages get faster. But what it seems to me is happening is the compile step on these compile languages is just getting shorter and shorter and shorter. And so the foundation here of a language that's built on LLVM, I think is going to be a dominant player in the next 10 years. If it's not crystal, it's maybe some other language built on this, but I think it's the best foundations that you can have going forward. Some differences from Ruby, it has all static method dispatch. So there's no runtime dynamism. Once the program is compiled, it knows statically at every single call site what it's going to be. But that said, you don't give up a lot of the sort of nice interfaces that you have in your Ruby programs. You still have the ability to define dynamically, or not dynamically, but define, you know, programmatically, getters and setters and like macros and so on. It's all also statically typed. And this is the first language, I'm not a language kind of story. I'm sure there's other examples of languages that have, you know, phenomenal type systems. This one just, it feels really good. Like you don't have to say types almost anywhere. It figures it all out. It does automatic unions of types, which I'll show you some examples of. And then also it's very easy to link against C libraries, so you can have a nice ecosystem sort of ready to go. And it's also very fast. Micro benchmarks, you know, take them with a grain of salt, of course. But this on the left here is a crystal program with a library that's a Sinatra clone. And on the right, there's just regular Sinatra. And running it with Puma, using the work tool to generate load, you can see it's order magnitude faster, and order magnitude less latency, and two orders of magnitude less RAM. So like, you know, this is just a micro benchmark. Of course, like real applications would be very different. But this, you know, it's pretty cool. It's been going on for a couple of years now. It became self hosted in early on. And so that means that the compiler, the standard library, the lecture, the parser, everything is in crystal itself. And this is very cool because it makes it really easy to contribute to the project itself, you know, sort of like Rubinius is mostly in Ruby. This, you know, everything is all crystal top to bottom. And so now we're going to get into the samples. I did have to compile a custom version of it because it's not quite out yet. And so I hope it works. It just opens up this nice browser that you can do things. And so all these codes are, samples are available. You can check it out now. You can't really use it until the next release, but I saw they're prepping for a release. So that should be probably the next couple of days, if not tonight. And then also to go along with the theme, I put in a couple of carpentry jokes. And so I never really wanted to be around Rubinius. He was stealing from his job as a road worker. But when I got home, all the signs were there. And so similarities between Ruby and crystal, you have, you know, of course, ranges here are the same P to do puts with inspect, turning it to an array, being able to chain methods, blocks, lambdas, closures, and so on and so forth. This is all, you know, this code would work the exact same way in crystal as it does in Ruby. The classes, object programming implicitly of methods, this is all, you know, very similar. You know, instance variables. Also classes are open. And so whatever the last definition overwrites, you know, the same as Ruby. And what's really cool about this is that the standard library is also in crystal, as I mentioned. And so you can reach, you know, if there's something that's not quite light that you don't like about the standard library, you can reach in and modify it. And you're not going to pay any performance penalty. So if I, like, do this and do size, it'll say that the size is two, because there's two characters. I can reopen string and call my size on it. And you can see it, you know, is just there as if it were a thing. So this is something that's common in Ruby, but it's cool that this is here in a compiled language. Modules, mix-ins, you know, you have include, extend, so on and so forth. This is the same. But what's really cool is that common idioms work the same also. And so having question marks for Boolean methods as a convention, being able to trail conditionals at the end for nice, readable statements. And then also, you know, being able to do or equals for memoization, being able to call things optionally with or without parentheses. All of this is there. And what this gives you is overall structures of programs, how you approach solving problems in this language is the same as the experience you've built up with Ruby. Learning the syntax or properties of a new language doesn't take, you know, that long, but be able to be proficient and confident in a language that can take years and years and years. And be able to piggyback on all of that experience is a huge, is a huge boon. The spec framework is included in the standard library and that's kind of nice, too. So how do construction workers party? They raise the roof. So you might be thinking, so what, is this just the same thing as Ruby? Like, what's the difference? What's the point? No, there's some cool differences. And so one thing that's, you know, sort of, you know, it's not that different, but it's sort of a small nicety, is that this is a, you know, would work the same in Ruby, but this sort of pattern of always just assigning the arguments to an instance variable, you see that a lot. It's a lot of boilerplate code. You can actually put the app signs up here and that's just a shorthand for the same thing. So we get the same output at the bottom. Another difference here is instead of adder accessor, it's property. It's just a different term. And what's really cool about this is, just as a side, because we have a proper class here to show off, is you can use the tools that are, as part of the language, and start getting information about the class. We can see that the greeter has two properties, a name and a citation, and there's both strings. And you can see how much space this will take up on the, as memory, and you can see the hierarchy of the classes. My favorite feature that is a small one, but very fun, is that the two-proc thing is a little more powerful. So it's a period instead of a dot, and as everyone knows, that's 50% less ink. So you're saving stuff already. But what's really cool is that you can start chaining things. And so instead of just doing upcase, we can reverse and then upcase. You can also do things that take arguments. And so we can do split it off of every character, sort the characters, and then rejoin them. And without having to go up to blocks and text. And that's not a huge thing, but it's kind of nice. And I watched a documentary about how they fixed steelwork last night. It was riveting. But the real big difference, aside from those sort of superficial ones, is the type system. And so I want to spend a little time about that. And so if we look at this example here, we have a method that takes something and then calls the multiply method with the argument of two. And so if we pass in an integer here, if we ask what the type of the result is, it's going to be in 32. And this type of keyword is the compile time type. The distinction that I'm going to make there is to be made more clear later. And if we pass in the string high, the type of the result is string. And we can see here just like in Ruby, it doubles the string. What actually is going on under the hood is it's creating two copies of the method, one that takes a three, or one that takes in 32 as an argument and one that takes strings in argument. If we passed in a float, then there would be three copies of the method being made, one for each of the argument that's in the program. Where it gets more interesting though is how the union types work. And so here's a method that instead of taking different inputs, it has different outputs. And so some of the time it'll return the int 32 and some of the time it'll return a string. And so we see over here with the return type, the type of the compiled type is, is a union of int 32 and string. Now if we ask it what the class is, that's the runtime class. And so when we pass in something that is high enough, we get the integer out. The runtime class is int, but it's still a union type actually. If we pass in something that's too low, the runtime type is a string, but it's the compiled type is still the union of the two. So let's see what happens when you have that. As we saw in the past example, both integer and string implement that times method. And so we can, this still works here. So we multiply it by 2, we get 30, we get the string repeated twice. If however we try and use plus, things start to go wrong. Now what's happening here is any methods that you call downstream have to be on every member of the union type. And while there is a plus on string, there isn't one that is plus with int 32 as the argument. And so this program fails to compile. This is a compile time error. And so we can figure, okay, so what can we do about this? Well one thing we can stop, maybe our first thought is let's not return a string, and maybe that'll work. But now we're getting a different error. What happened here is that now we don't have a multiplication method on nil. Of course, just like in Ruby, if the condition doesn't match, it returns nil. And we knew that, but we didn't expect it. And what this actually is a compile time error that prevents all the places that you've seen in Ruby of undefined method on nil, all of those sorts of errors can be checked at compile time. And some languages have special syntax for dealing with nil. What's interesting here is this just falls out of the automatic union typing that is going on here. So how do we actually deal with this? So one way we can do it is say only do this if it's not nil. And so this works, because any code that's inside the if, it can know that it's not going to be evaluated at compile time and let it go on through. So that's kind of nice. If you don't want to do it like that and you like I know what this is going to be all the time, you can do implicit, you can do explicit casting. And that works. You can also say not nil. And this is kind of gross and long on purpose because it to sort of discourage its use, because if you do have a mistake and you say, oh, I know that this is not going to be nil. Now you get a runtime error and then you lose all of those advantages of the type system. But what's really cool about this is nowhere in here, except for this implicit casting at the bottom, were we talking about any types? It just figured them all out at compile time. And some people say, oh, so it's optional typing. And it's not, I don't know my terminology. I'm not a language expert, but I would say it's not optional typing, because the language I see that do that, they don't care either way. They just, you give up the constraints if you don't say the type. This, everything is always typed. You just don't have to say it. Inference, type inference. Yeah. Thank you. Another cool thing you can do is method overloading. So this is a very contrived example, but it's not that uncommon from some methods in ActiveRecord and such, which split off the arguments that you give it and do some ascertations. This is fairly contrived admittedly, but what's cool in Crystal is you can, if you do want to say the types, you can say the types and then it knows which method to go to at runtime. So one of the things here, so this should work, like if this was in Ruby, this would work. And so we have this, you know, base class that we inherit from. And, you know, of course, you know, it's better to prefer composition over inheritance, but sometimes you use inheritance. And the reason this is failing is because the compile time type here of the pet is seen to be as animal plus any of its children. But animal itself does not include the talk method, because it's just sort of an abstract class. And so what you can do here is use the abstract keyword and that will, you're saying like, I will never instantiate the base class. I promise I'll never do that. And then everything works. Another thing you can do if you're, you want to, you know, be explicit about your interfaces, you can say abstract, deaf, talk. And this will be the same now, but if you forget to implement the talk method on one of them, it'll compile, it'll throw an error right there and you can see exactly what you forgot to do. The only thing that we kind of, the types kind of get in the way a little bit is with containers. So you see here we have an array of arrays. And this first one, the type is array of array of the union of character and integer. And so if we make a mistake and put them in the other order of our pairs, this one still works because it's the union type inside. And we also run into all the same problems of having to have a method that's on all the different types. Crystal provides a thing called a tuple, which is present in many languages but not, it's a foreign concept in Ruby. And what this is, the type now is an array of the tuple of int 32 and character. And this is position specific. And so with that, if we try and put something in backwards, that doesn't work because the tuple of type int and then car is not the same as the type of car and then tuple and int. And this one also works very fine because it knows the type can only be that one type, everything compiles fine. One sort of downside though of all this typing is that you can't just make an empty array because it wants to know the memory sizes of how to lay stuff out in RAM. And so you either have to say of int 32 or as you've seen over here, this array with the parentheses, you can do it equals int 32 array int 32 new. And this is how generics work in a language. If you're familiar with generics from other languages, you can define your own classes to take a parameterized type as a thing. This is my next question. What nails do carpenters hate hammering? Very good. It is fingernails. So you've seen that Gitter and Setters, the property macro. The way this is done is with just code that looks like this. You have a little like a template language to iterate over things and so we just, for every of the names that are passed in, we do a little bit of work here because you can pass in some other things that are sort of inconsequential. And then we define methods. And this is how the Gitter can go from name and age to be the same as this. And you can do a lot of things with the macros. You can operate on the absolute syntax tree. You can transform part of the language. It's actually really cool. One of the other neat things is you can shell out during compile time. And so this example uses back text to shell out and get the current date. And this actually gets burned into the program. So you can see when you make it and run it immediately of the same dates and then as you iterate it over time the build stays the same but the current version changes as time goes on. And you can imagine really cool things you can do here. So there isn't really an ORM for the language yet. But you can imagine a compile time it connects, looks at the schema and then starts populating methods. And so that's really cool but also what's really cool is the kind of shark that make good carpenters. Hammer heads, I heard someone. Also this build right here, this is thematic. So one of the things I worked on is my first project to get to learning the language was write the Postgres driver for the language. And what I was really surprised with is how easy it was to link against C code. I had looked at the linking stuff in Ruby and it was kind of always off-putting with the x-stik comp stuff and you have to write a lot of C. This is actually all you have to do. And so this example right here if it works is actually linking against libpq on my machine, connecting to the Postgres that's running on my machine and executing a query. And this is the total amount of code start to finish that is required to do that. You say this is a lot of types right here but you're just saying how to get stuff in and out of C and it works. And you can say like change it up, ask me the Postgres version that I'm running, maybe generate U, generate V4, generate UUID and all of this is executing queries on my local Postgres. And the fact that it's like this little amount of code really was one of the first things that impressed me about the language. Looking at how the build steps work there's a lot of different steps which are interesting but beyond the scope of this talk. You can see the linking step here and then my binary here is linking against libpq. Another thing that it links against right now is libpcre for doing all the regular expressions. And this we're not going to go through it step by step because there's a lot here but some of the other cool things about linking against C, a very common pattern is to see methods signature pass in a pointer to something, have it fill in the data and then you deal with that. This has sort of a nicety to take care of that for you and accentuate a new variable and it also works with instance variables. So this actually right here is the entire method for running a regular expression. It compiles the regular expression, it studies it to make it optimizations and then here's where all the capture groups end up. And so that's pretty cool. I recently had new gutters installed in my house and the carpenter said it was on the house. I kind of beat the punchline for that one. I apologize. One of the things with performance being such a key part of the language that's really cool is that all the old tools of profiling C code, perf on Linux, instruments on OS 10 work out of the box. And so these are, you can see here, here's the types, you know, the pointer class parameterized with UNT8. You can see individual methods being called. You don't have to worry about like instrumenting detrace, which I have still never figured out how to do. It's really complicated. And LLDB works fine. All these old tools just really work. You can drill down, you can see the assembly, you can see, you know, where your time is being spent. With all these construction jokes, I was kind of worried that I would screw a lot of them up. But I really think I'm nailing it. So some things that I wanted to put in here that was hard to put in and also, you know, make it make sense. Just a little grab bag here is structs are interesting. Unlike the Ruby ones, they're actually the same as classes except they're only allocated on the stack. And so you can't change, once you create it, you can't change any of the values, but it can be much more efficient for those sorts of use cases. And you can sort of, it's easy to go back and forth between the two and you can really reduce the memory footprint of your programs by using that. All of the IO in the language is a vented. And a lot of the things, you saw the string interpolation earlier, what that's actually doing is creating an IO object and a buffer and concatting it in. So it's actually, you know, very, very performant. And it's stealing some ideas from popularized by Go. So there's a code form that are built in that you can run as part of your editor to automatically have, you know, code form out of the same way across all your projects. The concurrency model is also inspired by Go. It's, you know, channels and coroutines. Currently, though, I must admit there is no parallelism. So you can have concurrent code, but it's still only executing on one processor. It's still, the language is not yet 1.0, but that's going, coming along. And if you're interested in installing this, giving a try, I really welcome it. If you have any questions, please reach out this crystalling.org slash docs has installation instructions for Mac, Linux, what have you. And it was in a conversation last night just to finish things up. We're talking about like our home, hometowns and stuff. And I did grow up in a small town in Illinois. And, you know, it was very, you know, you know, a few hundred, like a hundred people, 120 in my class, my mom's house, there's like sheep and goats. It's a very small thing. And there's this one guy who we always pinned, you know, being a small town, we pinned all our hopes and dreams on. His name was Justin. And we always like, Justin's going to go great places. And, you know, he was, you know, he graduated high school early. He went on to college, got a degree, road scholar, went off to England. But then we all lost track of him and, you know, didn't hear from him for years. And I caught up with him just the other, just the other couple months when I was visiting Niagara Falls. And there's like a, I guess, you know, not a sea world, but some sort of aquatic park there. And I go up and I see a guy working there and you'll never guess who it was. It wasn't Justin, it was someone else. But I saw another guy I kept walking. And then there, I saw the baby, the baby dolphin exhibit. There he was, like feeding the dolphins. And I said, Justin, what's the matter with you? Like, you know, we always, our whole town, we put all our dreams on you. And I understand that that's a lot of burden to put on one person. But, you know, you're, you know, feeding, you know, dolphins. Like what, you know, what went wrong? And he said, well, I don't know. I think you're giving me a lot of trouble. I really think I'm serving a youthful purpose. Thank you.