 It's self-hosted, it's nice, at least it was for me when I was able to work a little bit on the farsight and the lights. So it says number equals 42, it's gonna be 42, we bring the class, it's gonna be an in32, would in something like Java. So it's not that kind of type, it equals an array with one and two, and then you shovel something at the end of the year. Like, you have an array, you initialize it with the same two integers, you shovel an integer, and say, you know, it's a pretty bum, but it says no for a little matches, array in 32, shovel an array. What I'm just telling you is, you cannot shovel a string into an array initializing your integers and strings for a short minute or two. The stuff that you want to put there, so you can say, it's an array, declare a type that it's gonna be, it's gonna have eventually. Ruby has a lot of, it tries to follow the same methodology of Ruby Java, being easy for the programmer. The programmer, that's kind of the mentality as well, but it's not the same language. So now that we understand the type system, nothing's for you with compile time, as usually compile languages do. So let's look at this example in Ruby, and again, I'm sorry if you're not familiar with Ruby, but I think it's co-discipline of that. It's called string size, takes a string and just calls size in it and prints what that size is. In Ruby, if I do that and pass in a string, it will give me the number of characters in the string, which is fine. If I pass in nil, and here I pass in nil exclusively, but this could be a variable that holds nil, you get any finite size for the nil class. This is a pretty common error if you have ever worked with Ruby using this a lot. You get a nil error right in your face. Sometimes you'll know where it comes from, sometimes it won't happen in runtime, because that's how it will be worked. If we try the same thing in Crystal, the syntax is again the same. Have a method, string size, takes a string and just prints it out. It will explode if you say finite size for nil. Pretty much the same error, but you'll get it in compile time. So no chance of pushing this up to production or any other source of environment. The error is pretty much, is a lot larger than this. Crystal brings us back trace of where your nil may be coming from. So it tries to figure out where the nil to try to help you out, something that Ruby does not have, and it's pretty useful. So going back to the example that we had with the array, so let's see what we want to do. We have an array, we say it's a union type of string, and in 32, so we can put strings and integers there, that's fine. And now we want to print a state out, so we know that the last element of the array is going to be string, because we're doing it. And we're going to take it out and print the size. In Ruby this would just work, so that's fine. In Crystal it does not. It says, and you find that size for in 32, and now it even tries to even help you more and say the compile time is the type that I think that you have for this array is in 32 union with string. So what is actually saying is that this array can be either of ints or strings, so you can now call size of it, because ints do not have the method size. It's not only because I cannot make sure that this last element is going to be a string, even though looking at this example you know it is, in general you cannot be for that. However, Crystal allows you to make sure that it's a string, and then it allows you to call size of it. So the way you do it is you take the last element, you call this a string in it, then you are sure that it's a string, so you can call any string method size. Even though the array is the union type of both. This is like a pretty smart way that Crystal has for you to do these operations, even though you have a Trojanus array you can call methods for one of those types. So moving on, we have C-vibes. My experience with Ruby, and again sorry, I have a Ruby background, so I may compare a lot with Ruby, but C-vibing in Ruby, then every time I look at it, it's pretty daunting. It's not very easy to get started, in my opinion. Most of the times you need to write C, which again I'm not very comfortable with, and you need to know Ruby's C implementation. The struts, the methods it uses, that's what you're going to have to use. There's a project in Ruby called Fiddle, which looks nicer, like has a DSL link in use, even though it's not like a native citizen to the language at all. In Crystal, this is what we have here, the A to I function that comes from libc, and you just declare libc, and then you have the header of the function, and you can use it in your regular Crystal code. That's it. Shitting a little bit, because libc is already in the standard level of Crystal, so you can just use it like that. If it was a library that's not the standard level of Crystal, for any other C-library, or LLDM compatible for that matter, you can just use this redline as you would call a redline. It prompts you, or what's your name, give you the name, and it works, and it's a string. The one thing to note on the Crystal code, if you can see well, is that you actually have to call string.new on what you get back from your redline, and that's because if you look at the header there, it's a pointer. So that's what the C function returns, it's a pointer, and Crystal will mess that. It has a new choose of pointers, and it can capture a pointer into an actual string in the language. So pointers exist. They are not something you should be using in your regular day-to-day use of the language. It's something you can use to make the transition from C to the language, but not something you should be using otherwise. It uses this kind of stuff, so they were, I think, pretty smart in doing it to leverage a lot of the things that the C community has already done. So, for instance, the garbage collector, and I think still to this point, is not implemented at all in Crystal. They just took one that was implemented in C, even though it might not be the best one. It works, yeah, it's been working for a few times, just because that. So it's something that you know you need, but you don't want to care about right now, and give them the opportunity to work on some other stuff. And if not that, with a few things, and over the course of that, re-implementing some of the stuff to be more specific to Crystal, but it gives us the power to not have to worry about some things we don't want to. Crystal has, as a lot of times we do, is the generics. So again, looking at Ruby, if you would have, like, so I have a class full that has a natural reader, that's a gather together, an infrastructure that takes the value and just initializes it. Pretty simple. In Ruby I can just create a full of integers, and I get the value I call the absolute of it. I get one, it works. If I do the same thing with the character, I get the ASCII value of this word. So Ruby, we're very fan of the typing thing, and everything kind of just works. In Crystal it's a little bit different. So if I do it, like, the same thing has just changed from what Crystal calls it. They have getters, setters, and properties, instead of actually reading the characters and actually accessing Ruby. It also has the office script kind of thing, where in the initialized structure of the class, you don't have to say value, and then inside of the body say addValue equals value, which is kind of annoying to be honest. Like, you can just do addValue there, and it just works. But if I try to do the same thing now, instantiated it with an integer, and then instantiated it with a character, and that's on it, it's kind of great. The error has changed a little bit over time, but it's still going to break. Here it says I cannot infer the type of this variable value of foo. So it's like, but it does not allow you to do something like this. You cannot call this method with different types and everything. So one way to work around it is like, oh, you cannot infer the type, then let me tell you the type. Let's say value is in it. Well, now it breaks because it says there's no overload for foo.new, there's no structure for the type character, because it's a name. So you can, like, if that's all you knew, if there were no generics, we're going to see how it's going to look a little bit, or the next slide actually, is like, you would be stuck. Like, there would be no way out of this. Or it could be an union, and you have the problems we talked about with unions before, where, like, when you call a method, it has to satisfy all of the types in the union. So the way to do that with generics is, just say it's a foo of t, t is a generic variable, and just say value will be the one defining what t is. That's what that means. So now I can do foo of integer, and so that value will define that the foo is actually a foo of integer, and that works. So this is what internally hashes and arrays use in order to have this functionality where you can create an array of whatever you want, and not every array that you create are going to be, like, this massive union type of everything you ever use in an array. Each array is independent. It's expected behavior, but, like, this is how it works. Another variable feature that I find in Crystal is method overloading. So you can define the... So in Ruby, you cannot have two methods with the same name, basically. They have the same name, even if they have different arrays. Different arrays, I mean, like, they're not, it's not in the word. Ruby's going to complain. In Crystal, you can have the same name for a method, but if it has a different array, or if it has a different type signature, it's considered a different method. Another thing is what in Crystal they call yieldness, which is kind of a strange name, but it means that it's somewhere in the code you're going to yield to a block. So this is something also a little bit specific to Ruby, but it means that you... So in Ruby, you have implicit closures that you can pass the method, and if you're using those, then it's a different method, again, because it's like you're having an extra argument, even though it's implicit. So let's look at an example. So the Ruby example is that whole thing, and it's just a method, even though you can't see the specifics, it doesn't really matter as well. So this is handling three different situations for a method called sum. So one, you take the strings, you convert them to each of them, another, you just take an integer and you just print that out. Not very useful, but it shows the example I'm going to show, and the other, you take the sum of two anythings, and you just try to call plus of them. So it might bring some situations, but in general, that's what it was going to do. The same thing in Ruby is much more complex. You have to take a variable number of arguments and then do a switch statement on that. And if it's two arguments, then do something. Or if it's two arguments, see if they're both strings, if they are something, if not some of them. If it's one, do something else, that'll raise an error. So it's not, like, great. People have had a lot of ways to work around it, and it's mostly okay, but it's a feature I enjoy in languages in general, that and path matching, which Crystal does not have, but it would be great. So this is also something that I don't think is ever going to happen in Ruby, but if you want to try it out in Ruby Lite syntax, you can try Crystal. Talk a little bit about how Crystal handles concurrency. There's a couple ways you can do it. There's, of course, there's mutexes and there's semaphores and all that kind of stuff. It's in there, but I'm not sure you're going to want to do that, which I would. So one thing they did not too long ago is that they kind of borrowed their concurrency model from Go a little bit. So they tried to mimic what Go does. At least it's a DI. I don't know about the internal, but I'm pretty sure they're not the same. But the API way the Go channels work is similar to the way that the Crystal channels work. So in Crystal, I have the example of Go, and if my code is terrible, I'm sorry, I have no idea what I'm doing there. But Ruby likes a little bit. Let's go with the Go first. You have the main function. You have makeChannelStrange, so I'm assuming you create a channel for strings. And before receive, then because this is mostly, I think, how it goes, Crystal is slightly different, but it's similar if you kind of squint your eyes. So you see, I created channelStrange.new, so creating a channel for strings. Same thing, spawn. So spawn is going to create that just as it acts a little bit different. And then I'm creating beforeReceive and channelReceive. So because channelReceive will return the message, I can just print that. ForReceive, same thing, channelReceive will go to the... Crystal is not parallel yet, so it's running on... You can never see the aftersand in Crystal. And you can call... So this is the exact same code I have in Crystal, but before the beforeReceive, I have a fire.yield, and that means, hey, if anyone's waiting to do some work, they can, which the spawn crowd, the spawn just pick it up and say, hey, I have some work to do, and it prints before send, it sends the message. Once it sends the message, the other thread will start from where it started, from the yield, so it will print beforeReceive and then it will print the message. If I wanted to see the aftersand, I didn't have a fire yield after ShadowReceive, so the last instruction would be a fire yield. That means, okay, I'm just gonna... So I'm just gonna wait here for someone else to finish whatever and work to implement their channels in Crystal. So something that you don't have would be anything like this, but I find it's interesting. So kind of wrapping it up here, this was a bit fast, but this thing in Crystal is called Charts, which would be called Charts, or we would call libraries or something like that. So yeah, we try to find a strange name for libraries for some reason, but in Crystal there are called Charts. You have a Chart there, and there's a Chart YAML, so the Charts project is the dependency manager, and you have the Chart YAML, it's a YAML file, you just declare dependencies, you have your production dependencies, it's pretty standard that thing, and then you just use it, you require it there. The one thing that is interesting about it, I think, is that it's decentralized. So there is no... I don't know if next year, yeah, still, or like there's no Ruby Charts, and they don't want it to be, like, it all works on GitHub for now, and Bitbucket. So being decentralized has some, like, issues that you have to work with that probably you don't think about a lot when you have a decentralized place where you can push all your libraries, and the biggest one, I think, is discovery. So finding libraries, it's kind of hard. There's no place where you can look, there's no official place where you're like, hey, this is where the real Charts are. There's none of that. So when I first started working with Crystal a little bit, there was really nothing. So I committed this website, which, sorry, I know, one of the first in production, in Crystal, and called Crystal Charts. It's pretty early, but it did a job. It uses GitHub Search API to look for projects, and you're going to see the problem here, to look for projects for which Crystal is the main language. Because as far as I know, there's people here that can correct me. That was the only way to search for things in GitHub. And the problem here is that it's too full. So for one, you can have a natural library. That Crystal is not the main language. It's not going to show up. Or the other way around. You can have an app that is mostly Crystal, but it's not a library, and it will show up. So it hasn't been too much of a problem so we have some ways of starting it. By default, it's started by stars, and the ones that have more and more stars are usually libraries and good ones. So it's not because of the old ones yet, but it might be something they will have to address sooner or later. Not sure. So there's this. Someone made it more beautiful. It's pretty much the same thing. It has the same functionality, and this thing, Crystal Shires XYZ, you can put that up. Well, again, you can see Crystal is there. Crystal is not really a library, but it's the language, but it's mostly written in Crystal, so it shows up there as the main one. There's Kamal, which is the signature thing. Amethyst is kind of the same thing. You even have Awesome Crystal, which you familiar with, Awesome Dash, whatever, projects. Amethyst of other nice Crystal things. But it's up there as one of the major libraries. You can see the issues here. Yeah, so that was pretty much it. Thanks, and ask me questions I'll be happy to take.