 Okay, so this talk is about the Go language. I gave this talk in Bucharest earlier this year, and it was called an introduction to Go, and people told me it was like such a boring title that I should have a more interesting funny title, and they suggested let's get ready to Go, so I renamed it to let's get ready to Go, and yeah, apparently some people were confused about this thinking that this was like some other kind of talk, and not a talk about the Go language. Anyway, so a little bit about me, I'm a Deviant developers in 2005. As a Deviant developer, I first started maintaining some electronic packages because I'm an electronic engineer. I then organized several dev comps, particularly I was the core organizer of dev comp 8 in Argentina, and this year I'm also part of the core organizers of the comp 15 in Germany, because in between I moved from from Argentina to Germany. I work as a site reliability engineer at Google since 2012, and I've been mostly a Python programmer for more than 10 years, but I've been writing Go code since February, so I'm not an expert, but the intention of this talk is to give an introduction and let people know what things they are going to encounter when they try to learn Go. Of course, it's a 45-minute talk. It's not like you are going to leave this room being a Go programmer, right? I hope nobody expects that. It's just an introduction so that you have a basic idea of what the language looks like and the things that you can do with it seen mostly from the point of view of a Python programmer. So a bit of history, Go is a very young language. It was created in 2007 by some famous people. Robert Grissmer is less known, but probably many of the people in this room know about Rob Pike and Ken Thompson. They are like the oldest of Unix, C, and many other things that are the foundation of what we are doing. And the goal when they created the Go language was to create a language that was similar to C, but that incorporated all the good things that had been discovered or developed since then. So when C came up, it was a revolution, right? Because before that, people were writing assembler. And it's been going on and being a great language for a long time, but now it's time for something that's created this century and not last century. So what Go is not? Go is not an interpreted language. It's compiled. It's not a replacement for Python. I say I come from Python and I have this feeling that before I used to do everything with Python, and it's not like you will do everything with Go. There are certain things that are better suited to do with Go, and there are certain things that are better suited to do with a scripting language, an interpreted language that is faster. When you need to just do a quick prototype, you do not want to use the whole thing just for a quick prototype. It's not the answer to every programming need. And it's not very well named. So this is kind of weird, right? It comes. So Go was developed, the people that developed Go worked for Google, and I find it a bit surprising that they decided to name their language Go, which is something that you can't Google for, right? If you Google Go, who knows what you will get as a result? So if you need to Google stuff for the Go language, what you use is use Go lang, right? The key word is not Go, it's Go lang. And that works fine. So you can get documentation, stack overflow answers, blog posts, everything includes the Go lang string, because otherwise it doesn't work. So what Go is, it's an open source compile language. It's this century C. That's what it's intended to be. It's intended to be the 21st century C. And it's designed for concurrency, it has garbage collection, it has unicode support, it has some dynamic typing. Well, so it has all these new things, while at the same time it tries to keep the philosophy of C. Some nice things about Go, the compiler catches a lot of errors. This is particularly compared to interpreted languages, but also compared to the C compiler. The compiler, I don't know, if you declare a variable and don't use it, the compiler tells you, hey, you declare a variable and you didn't use it. Maybe there's something wrong there. And things like that. Usually the compiler is right when it catches errors. Sometimes you say, okay, I had this variable, I will use it later. Why do you complain? But yeah, you can just comment out the line. It comes with a very full set of libraries with lots of functionalities that are already there, so you don't have to develop them yourself. It has native concurrency support, I will talk a little bit more about that. And for people that like the quickness of an interpreted language, there's the goal playground, which is like an interactive web page where you can write some code and execute it and see it executed there without needing to compile it yourself. If you don't have the tools installed, you can just go there and start playing around the beat without having to worry of having all the packages. And also, it's good when you are sending code back and forth, if you put stuff in the playground, you can then create a shareable link. So you send it to someone saying, I have this code and I don't know why it doesn't work, can you help me? You send them the link and then this person finds, oh, yeah, you forgot to do this or that. And they send you the link with the fix. So this is very good for exchanging code with people on the Internet. So what does Go look like? This is a very simple Go program for people that come from C that's going to look familiar. So package main means that this is where the main function is going to be, then import fmt, it's bringing in the package that will allow printing on the screen. Then this sum, no, I don't know how it is. Yeah. Some column equals zero is the pseudo dynamic typing that Go has. So what's happening there is that Go is seeing that zero is a number and assigning some this type. So it's not only that we are assigning zero to the variable, we are also assigning the type. What will not happen is if we later on try to assign a string there, it will fail because some is an integer. So we are excused from declaring the type, but the type will stay, right? We can't just change and say, oh, now I want some to be eight. No, it can't. So it does the type declaration for us, but then the type stays. The same for the for loop. The for loop is exactly the for loop from Z except without the parenthesis. And then at the end, this just brings it on the screen. So that seems like very similar to see and very nice and okay, but there are some quirks because I didn't have any types there and it didn't look weird, but the types are declared exactly the other way around that they are declared in C. So instead of in star C, which is a pointer to an integer, it's first the variable name and then start int. So the idea is that you read this out loud. C is a pointer to an integer. And that's how the order goes. Or the same for arrays, which in Go are called slices, but you can think of them as arrays. A is an array of bytes. So it goes the other way around. Then when you are dealing with visibility, the case of the first letter of a function defines if a function is private or public. There's no public or private keyword. It's just the case of the first letter. So if you suddenly change your mind and want to export the function that you are not exporting, you have to rename it to have the first letter be uppercase and change all your code so that whatever calls it, now calls the uppercase version. And it has error handling, but it takes a while to get used to it because it's kind of strange. I will show some code soon. Interfaces. Go does not have objects in the Java sense, but it does have something that it's almost like objects. What you have is you have structs or types. It doesn't need to be a struct. It can be just a simple type. And you associate methods to those structs or types. You can even associate methods to like int. You can associate methods to any type you want. Doesn't need to be a type you declared. It can be any type you want. You can associate methods to it. And then polymorphism is done through this interface. So you can declare an interface and it's done through these interfaces, but you don't declare that a struct or a class or because there's no class. You don't declare that these things are of that type. If they follow the interface, they just are of that type. This is something that it's only possible because it's compiled. It wouldn't be possible in an interpreter language, but being that it's compiled, it's like if it has all the needed things to be part of the interface, it just is. You don't have to declare these follow this interface. You just have to make it follow the interface. Okay, so I have more snippets here. Are they readable from the back? I think they are, but yeah, okay. So maybe should I stand here? So the first function, because it starts with a lower case, it's private, right? It's a private function because it starts with lower case h. It receives a string and returns a bull. So what comes after the parameters is what the function returns. Yeah, the rest is just showing some of the functions available in the strings package. Then the next function is a function that is associated to a type. So the parenthesis that comes before the name of the function, this KC key config parenthesis, is the type to which this function is associated. So this is a method of the key config class, right, speaking in Java terms. And KC is the name that you will use to access the instance, right? So what in Java is this and what in Python, it's usually self that you can rename to whatever you want. It's this KC here and you can name it whatever you want. And this one, because it starts with a uppercase K, it's an exported function. And then in the last one, we have the error handling that I mentioned. It's weird. So what's happening here is that the first function that is in the first line, file stat, returns two things. The first thing is the file information that the function is wanting to use. And the second thing is an error. So what you do is you check if the error is nil or it's not nil. So if it's nil, it means everything went right. And if it's not nil, it means something failed. And you have to handle the error. And this function returns a boolean and an error. So what you do is if whatever you call return an error, you also return an error. Usually you add more information, but it depends. So you can add more information to that error that you are returning. In this case, it's not adding more information. I picked a simple piece of code. But it can go much more complicated. The problem that I see with this, that takes a while to get used to, at the end you get used to it, but it takes a while, is that for every call that might return an error, you have to check the error. If you come from Java or Python, you are used to just putting a try and doing all the stuff there that might fail and afterwards catching whatever exceptions you might have to catch. But in this case, for every call you need to check, did this return an error, did this return an error, did this return an error. Yeah, so it takes a while to get used to. But in the end, it's very simple. So you just check every error. And sometimes it makes sense because depending on what is the error, you may want to do different things. So it's not that it doesn't make sense, it just takes some time to get used to it. So concurrency, this is one of the things that I said, like Go, it's designed for concurrency. The main way of doing concurrency in Go is using Go routines, which are like core routines, but special. And you can start any function that you have in your code. You can just start it with the Go keyword. And it will become a Go routine. And what this means is that it will run on a separate thread, but it's a very lightweight thread. It's not a full thread as we normally think of, but it's very lightweight and very cheap. So you can start many, many Go routines in parallel and it will not make your computer try. Then there's channels to synchronize the Go routines. So you can send information to a routine and receive information from the routine using the channels. And the basic idea behind this is you don't share the data by sharing memory between threads, which is what gives so many headaches regarding concurrency. But rather, you share the data by sending it or receiving it. So reading or writing from the routines, but not sharing memory. Because sharing memory has been proven to be really hard to do right. So this is very easy. You should send the data, receive the data, and it's very easy to get right. So before I go into that, I wanted to do a small demo. Are there any questions up to now? Do we have someone with a mic if there are any questions? Okay, apparently not. So I will go do a small demo. Let's see how that goes. Let's start first with the usual thing. Instead of printing Hello World, this is DevCon 15, the biggest DevCon. Okay. So this is like the basic quest of Go programs. To build it, what did I call the directory? This is 15 Go. So Go build example.go. This will build binary. The Go compiler is really fast. And this is one of the features of the compiler that it's really fast. I'm not a particular fan of the compiler being fast because normally you compile a bunch of times and you execute many more times. But whatever. For the designers, it was really important that the compiler was fast. So it's really fast. So there we have our Hello World. Now let's do something a bit more interesting. So first, I'll print a random number. So there are two randoms. There's math run and there's script run. So for script things, you want to use the real random. For just printing a random number on the screen, you don't need to do all the script things. But I think it makes sense because the script random is harder to use because it's script. So there. Let's see how that goes. Yeah. What do you think will happen when I execute this again? Same random number? Why? Yeah. I need to see this user random generator. Otherwise, it doesn't work. So here's where you say, okay, so how do I see this user random generator? There's a lot of documentation. This is a good thing. So in golang.org-package, you have all the packages that are included with the language. And I'm importing math, sorry, math run. So let's open that. And here it says that there's this seed function. Where is it? Seed here. So we need to seed it in order to get real random. So seed. So what will I seed it with? Time. So, well, okay. Let's go faster here. Okay. If I do this, let's just do it. So what's happening there? The same second gets the same to the random generator. So instead of Unix, we want Unix, nano. I would have shown the spec for time, but I want to also show other things. So yeah. So now it's working. Yeah. It's a random between 10 numbers. You won't expect to have more than that randomization. Okay. So now I want to show some go routines. Because we have limited amount of time, it will be a very simple go routine. It will not do anything useful. But just to show how it works. So it will first print that it's starting and then print that it's done. And in between, I'll make it sleep a random amount of time. Sleep takes a duration. Let's go look at the sleep. So sleep takes a duration. Here is the spec from sleep. And here there's an example, but it doesn't work with the random number. I will need to cast the random number so that it's a duration. So I think it's time.duration 100 times time dot millisecond. Possibly got it right there. We will see when the compiler complains. So now, so I have this function that starts, does something for some amount of time and then says I'm done. Right? Let's pretend this function actually does something useful, like parse a file and then store the result somewhere else or whatever. And then I will do four, four, five times so that it fits on the screen. Is it clear what I'm doing? What do you think will happen? The deadline should come back in random order. Yes. What happened? I didn't wait. Exactly. Because I didn't wait, they were started and then the program finished and they didn't have time to do anything. So let's wait a little bit more. Let's wait one second. Here we can use time. Second. There. So I started them in order, but they got done in a random order, right? Because they took different amount of time. Well, so as I said, this is a very useless example, but it just shows how easy it is. It's like any function, this function, the slipper function didn't have anything saying this is a function that will be inside the thread or anything. It's just any function that you can start as a go routine and then it's concurrent. Then you need to make sure that you wait for it, but that depends on whatever you are doing. You can also like send data and receive data. Shall we do that? Do we have time? I don't know. Are there any questions? I don't want to eat all the time with the demo if there are no questions. Wait, wait, wait for the mic, please. There. My question is how do you do that with a normal function? Just omit the word go. Sorry, there's too much. I don't understand. One, two, three, four. How do you do that with a normal function? It's just a normal function. That's why I don't understand the question. So I just created a function and then here I use the go keyword to make it thread it. The go keyword is for... The go keyword starts a go routine. If you add this keyword, it becomes a go routine. There is no other way to call the function. Yeah, I could just... So if I call it without the go keyword, it just does it in order. How do you do a modeling of interdependencies between the different threads that you have fired up? Can you repeat the question talking slower? How do you model interdependencies between the different threads that are fired up? I mean, how do you communicate with each other? There was a channel, right? So that's what you were mentioning in the beginning. Yeah, okay. Let me see. I don't want to go... It's a lot of code, but... So I will look for the example so that I don't have to type on the example. But first, I will introduce this site, like tour.go.lang.org. It's like a tutorial. So if you... After this talk, you feel like you would like to learn how to code and go. This tutorial is recommended and it has some part about concurrency. So let's go look at the example there, because otherwise it's a lot of typing. So here, can you read from there? Should I make the font larger? I don't know how to, but I will try. Yeah, there. Okay. So this is a channel. C is a channel. So this function receives the channel to which it has to write. It's a channel to which it will write. And it does the sum of a lot of integers and by the end, it sends the sum to the channel. Like this arrow notation means that the sum is sent to the channel. And then in the main function, so the channel is created with this make keyword. And there are two go routines called summing half of the array and receiving the same channel. So they both have to write to the same channel. There are some. And then this method receives using the, so it just changes where the channel is, right? So it's the same arrow thing, but on one side, the channel is on the left and on the other side, the channel is on the right. And so in this case, you are receiving from the channel into these two variables. Yes. And we can run it from here. And sorry. And they are like, it has the sum of both channels and the result of the summing both numbers. For, this is also like, not a very useful example. It's just an example to understand channels. But the idea is that if you have workers that need to do something and at the end, they have a result, you just give them the channel and when they are done, they send the data to the channel. And on the other side, you read from the channel and when you read from the channel, you wait until there's information there. So that's like the way it is done automatically by the operation of reading from the channel. Yes. So they are usually synchronized because you are reading. Other questions? You're firing off to go routines at that point. There's no guarantee which order they'll complete in, is there? No. So the x and y could end up being unlikely, but it could be minus five and 17. Yes. Yeah, they could be. In this case, it doesn't happen, but yes. Yes. There's no guarantee. Okay. So let's go back to the presentation. Oh, no. Okay. So the state of going devian. You can get install go long and you have the whole developing environment installed. You will have this go build command that I've been using and all the libraries to build go packages. There's DH go long. Yeah. So this state, this stats is from May. There are probably more reverse build dependencies by now, but I compiled a number in May and there were 53 reverse build dependencies from DH go long. So there are 53 packages that are using DH go long to build. There's a guide. If you want to package a go package, there's a guide from the team, the package go team, and the package go contains all the team maintain packages, which are most of the 53 packages are maintained by the go team. And if you want to package go packages, I invite you to also be part of the team. Makes sense to do it together and not separate. Yeah. So basically, devian is ready to go. And yeah. That's basically it. And please have more questions. Are all go binaries still statically linked? Yes. Is that not a problem for devian, especially in the realm of security support? It's one of the main reasons I have not touched go is it does not seem ready for deployment that is not Google style. We build everything every time we ship. It seems like goes not suitable for distributions at the present moment in time. Yes, I agree. I don't have a better answer. I agree with you. All I did question about versioning. I mean, all libraries are usually in versioned. So we pick the current version at random and it stays as is in devian. I'm sorry. I don't understand you. I mean, because in go, you don't version your libraries. It's also a problem for devian because we put a git hash in the package version and it's difficult to know if the version is up to date. If you pick a good version or not a good version, maybe there is a bug. We don't really know. Is that something that will change in the future? Many go projects are using rendering because of that. Yes. So maybe a better solution would be to say it was a bad idea to tell everybody that you don't need to put a version number on library. Please use version number instead. Well, yes, but you need to convince people to use a version number. Yeah, but I mean, I agree. It would be a good idea to have version numbers. So go has a version number. It's the libraries that don't have a version number or not all of them, but some of them. And I agree. It's not a good idea because it's hard to just go with the git date or commit version or whatever depending on whoever uses what. But yes, you need to convince people that it's a good idea to use versions. And I don't think I have the power to do that. Other questions? We have five more minutes for questions. Not actually a question, just a comment. In Go 1.5, they do have shared libraries now. So the very latest version of Go has shared libraries. Okay. It's possible to statically compile everything anymore. No more questions? All right, then I guess we are ready to go. Thank you.