Go - one language you should try
CC Attribution - NonCommercial - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Grzesik, Andrzej
Or why you should only write an eighth of the code. You live and breathe Most of the things you do with a computer involve it. How many tiny little http-related utils have you already created? Is it time to stop? By no means, we all do it. I'd just like to encourage you to write the next one in Go. It's a fun little language, which feels like a cross-breed between C (pointers!) and ruby (concise, powerful syntax). But how much? Why, yet another language, but my perl/python/.. does all the things? Well, it does. But go has a few things that make it super sweet, is web-scale and real fun to use! Or at least come and listen how did we get rid of 87% of our codebase in a day :-)
 I think it should be working. So hello and welcome to my session about a language called Go. I'm really happy to see you. I think, well, I hope the coffee is good. I've had just one so far. Who here is enjoying NDC for their first time? Me as well. It's my first time at NDC in Oslo. It's my second time in Oslo because I have a friend living here. So it's amazing to be here. It's a lovely city. Well, the weather is very generous to me as well, again, which is also amazing. And this talk is about a funny language called Go funny. As in, it brings fun. It's not nothing to be joked about because you can do very serious things with it. If you have any questions, of course, well, you know, try to raise your hands. I'll try to notice you and I'll try to repeat the question that you have and maybe even answer. So starting with a bit about myself. Well, you could describe me as a Java developer in a dotnet and a primarily in the dotnet conference talking about totally a non-dotnet and not JVM language, a bit out of place. But, well, to give myself a bit of a background, I come from Kraków in Poland. I now live in London. I run a conference called Geekon. Also have been involved in the community as in running the Polish Java user group doing, well, founded Kraków Hadoop user group, which now is called Data Kraków because, well, Data Science is much more popular. Apart from, well, interested in all the usual software engineering things that you would expect for example, one thing that needs to be mentioned is Software Craftsmanship Kraków. It's a group which you would expect to be about testing and software craftsmanship and we founded that in 2010. It's actually a group in which we read computer science papers. So every two weeks, we pick a paper. Well, people read it before and then we come in, meet and discuss it for give or take two hours. So it's a very well different thing to what people usually connect with with Software Craftsmanship, but I think it's worth to be noted because we've had over 100 meetups so far. Anyway, me, described in, trying to describe myself in a single sentence as a developer going deeper. So if something works, I'm usually suspicious. Why is it working? This shouldn't be like that. It shouldn't compile, which means I like to go deeper and deeper and deeper and deeper. Well, with all of the time that it requires. One disclaimer, my opinions are my own. You can find it on LinkedIn. Who do I work for? But this talk is not connected to my employer in any way, of course, because they are very brand protective, which means they don't want me to mention their name. That's their choice. If you have any questions, shoot or try to find me after the talk. If you have any questions during the talk and you would like to raise your hand, I would love to answer. So, GoalLang. It's a free and open source language. As in free beer, you can well download it from the internet and use it and you don't have, as of now, at least I haven't heard that, you don't have to worry about a large database company suing you for using that. So, it's open source, so, again, you don't have to worry. I haven't seen a legal department that would give people problems because of their attempts to use Goal. It's BSD license, so that should be okay in most places. Of course, there might be some extremes. I'm not a lawyer. It comes from Google, so it has been invented. Google uses it. At least that's what they say because they've never worked for Google, so I have no idea what does it look like internally. But it comes from there to solve a couple of problems. Who here has written some C or C++ in their lives? Yeah. There are some, let's call them inefficiencies or problems or minds or, well, 10,000 ways to shoot yourself in the foot very effectively blowing the whole leg and half your hip off in those languages. Goal is nice, as in it allows you to save yourself from some of the problems. It takes some of the power away, and at first I thought that it's very limiting. That was my first attempt. It feels like I can't do all the things that I used to be able to. Am I really going to be able to be productive in this language? Then it turned out, I'm not really missing all those features that much because I can still get the job done, and usually there are less bugs and there's less code. Go is fast, as in the whole. One of the key goals in creating that language has been speed. Speed in compilation. You might have seen compilation processes for large C code bases that can take a day or at least a couple of hours. Go, I haven't seen really long go compile times. Go compiles really, really fast. The whole tool chain is very fast, which means you can have very rapid development cycles, which means you get feedback often. You can run your tests. You don't have to wait a day for a software deployment manager and their team to try to attempt to configure the thing and run CMake, DMake, your flavor of make and wait for it to happen. Go has a mascot as every single, well, self-worthy open source project. It needs some graphic designers to help it. So for a go, go for is the mascot. And if you're already asleep, you're thinking about lunch or some of the awesome stuff that you can see in the exhibition hall. I really loved the VR experience there. It's a mix between C++ and Ruby because of the syntax, because of the power and because of how low level go gets. So if you're already asleep or getting the play with it tonight, I really encourage you to. It's super easy to start with. You just need to download the tool chain and then you can start. You don't need to download a specific operating system, a specific IDE, a specific something. Just the go distribution for your machine of choice and a text editor and you're good to go. So, well, I always get questions about who uses go. What companies use go? Can I use some big brands to encourage my place to use it? Well, Google obviously as the inventors of the language, well, eBay, for some of, that might be a good thing, for some of you it might be a bad. Dropbox, well, Bitbucket now, Atlassian, I think. Government okay. So that's a government entity. They use go the language and the great thing about UK gov is that some of their go usage is open source. And I can only say some because I don't know of all of their go usage, but government UK open source is a lot of their currently written software, which means you can actually, this is good enough for the UK government. This is the link to GitHub. Have a look. It's serious stuff running on go used by a government. That's a very good political argument for some of the discussions. Talker, of course, some other things. The Wiki address has a much longer list of users. There is a lot of companies in London which use go and experiment with go. I can give you a short story about a company that just happens to be in my area called Not on the High Street. I went there, I think a year ago to do a talk about go the language because some of the developers were curious and just a week ago I learned that I already started using that in production. That was nice. To fill that story completely, how did I learn about go? Well, I heard that Google has open sourced a language, created this language and I was just curious to start. I couldn't find a reason. And then we were doing effectively a router, an HTTP router in Java. Which means if you're doing any software in Java, it tends to grow into thousands of lines. So our software had, I think, well, 10,000 of lines plus a couple of hundred of XML lines plus, of course, you had to use Tomcat and other things. And at one point I thought maybe we should take a step back. Maybe something is a bit wrong in here because the amount of dependencies, the amount of things or crap that you need to install to get it to essentially route HTTP requests and serve very simple things, it feels a bit too high. So we rewrote that into go and we ended up with around one-eighth of the code. And we got a single binary and that was it. And that felt really awkward because, well, at least me coming from Java ecosystem, I'm used to bloated software sometimes in the verbosity. And then in this language, well, this is everything. So we've shown it to other people, well, okay, show me the code. That's readable. That looks like Ruby. I don't really understand all of the tiny details. But those are details. Where is the rest of it? No, no, no. That's all. That is impossible. Because as I said, it was around one-eighth of the code and that was our first, well, serious project that we did for eBay in 2013 in code language. And that's, well, then we started having go as a regular piece in our tool chain. I do not encourage you to rewrite all your software into go. That's never the solution. It's a great language for some usages. Well, for some usages, it's not perfect for everything because I still believe there is no silver bullet which obviously translates into I'm an engineer, not a consultant because then I would try to sell you mine. Where do I use it? All kinds of network-related middleware. Yes. All kinds of anything that needs to deal with sockets, well, HTTP traffic, analyzed root, do something with that, go is super pleasant to use it, to use that. I know that there is a lot of companies that use go for microservices that wouldn't have been my first choice because I personally prefer languages with more, well, with a richer type system because then you can reuse the domain language that you will create in one application in the other, which means I would probably tend to favor Scala right now. But there is a lot of go usage in microservices space and people are very happy with that because the applications in go, you can create them quickly and you can run them quickly and they usually behave quite well, which means a lot of the overhead that I mentioned you don't have to go through. And I mentioned Scala because I like Scala the language at first it helps because learning curve is quite steep. Go has a much, much nicer, much more approachable learning curve. Just to answer the question that usually happens. Where not? Well, user interfaces, web applications, well, you can't write them in go. I haven't seen a go to JavaScript transpiler just yet. It doesn't mean that there doesn't exist one. It's only that I haven't seen it. It's a back end development language. It's really good there. But I've been talking for a couple of minutes now and I think it's time for, well, we have to go through some code. So, Mandatory, hello world, because of course we have to, let's make it even larger. Yay. So, you have, well, a package declaration. That's obvious what it does. We import FMT. So, we import a namespace of another package that we will be using a function from. And then we have, well, we use a function from that. You can notice that it starts with an uppercase. That's a convention in go. Anything that you want to export within a package has to have a start with an uppercase. Let's try to run it. So, go, build, main. That's done. And go run main. Oh, sorry. Yay. That was fast. So, why is main not uppercase? Because main, that's a really good question. That's a catch. Main is this one special thing that you start your applications with. If you notice any similarity with a usual main function that's prevalent, that's present in many other languages, that's exactly your intuition guides you well. Main is this one special package in your source tree that is supposed to contain the entry point for your application. So, if we look at the directory structure here, well, there is bin, there is PKG, there is SRC, under SRC, well, there is, you can have different packages. And if you have any dependencies, they will end up here, but we'll discuss, I'll talk about it later. If you want to create an application, the default would be that it would sit in a package called main, and all of the other stuff should be your dependencies. So, if you want to have a number of applications, well, you will have a number of projects with different main directories, and all of the other things will be your dependencies, which encourages you to externalize and then think about how you structure your software. So, just a convention. So, we've seen a hello world. Why do I like go? Coming back to that point, well, no runtime dependencies. What do I mean by that? I mean that I get, oops, I think I want to be here. So, this main, this binary has everything that's needed. It only prints a hello world, and somebody could say that it's a bit large that it takes two megabytes to just print nothing, well, almost nothing. Just a hello and you see this very important message, but then it takes two megabytes. The answer is go links everything statically. So, you can take the binary, you can deploy it to all of your servers, and you don't have to worry about missing dependencies. Everything is contained there, which means your release management becomes trivial because you just need to well take a binary and deploy it to a number of machines. Your dependency, your library management becomes super easy, super pleasant. Your operations people will probably most probably be very satisfied with such an approach because that will, that gives you simplicity and simplicity is what I really like in software. So, deployment, as we said, super easy, much more pleasant than C because we don't have to produce a lot of the artifacts that we would sometimes have to worry cache for the compiler to optimize our enterprise completion process. And you've seen that I've compiled this tiny amount of code using a go command, and I mentioned something called the go tool chain. And now let's talk about the tool chain. Let's give it a bit of a look. So, if I type go, I will see that go is a tool for managing go source code. Yay. The commands are, so the built in, the built in commands, the things that are built into the basic tool chain, the thing that you download from the Internet, so anybody using go language, anybody being able to compile, you can safely assume they can build. They can show documentation for package or symbols. They can format and run a formatter. You can also generate. You can install dependencies. You can download dependencies. You can list packages. You can run. You can test. You can print your current version because obviously you'll need to do that. Being able to get to manage dependencies, being able to run your tests out of the box, that's usually a pretty good start. No other things are necessary. That's all built in. To be fair, what will do tests look like? Well tests are just simple programs that are supposed to have an exit code of zero in any decent software, piece of software. Well, that's a convention that they follow. But then they allow you, they already give you something that you can test your source, your code with. You can build and you can manage dependencies, which means you can specify dependencies that sit, for example, on GitHub and this tool can download. And we'll see that a bit later. So the go command. We've seen that in action. And I mentioned go format. Authors of go decided that there are certain discussions in the software industry not really worth having in most of the context. One of them is formatting. So in terms of go, tabs versus spaces doesn't exist. I know it's a great flamer for having a beer over, but with the go language you are supposed to be using tabs and all break lines or new lines characters will be converted into semi-colon so you don't have to use them. So the way you place your returns actually matters. That also means that every single piece of go software should look the same. It's encouraged, it's highly encouraged to run go format after every save in your editor and it's a very easy thing to configure. That also means that analyzing software becomes a much easier job because you can make certain assumptions about what does the source code look like. How is it shaped? Because everybody's source is shaped the same. And that also means that when you're reading somebody else's go you don't have to why is this curly brace sitting in a new line and there is a comment in between. No, no, no. There is one way to do that and everybody follows that. This is more or less what it is. I'm saying more or less because how Keynote decided to format my text is a different story. But another thing, another great thing that I like about go is that it's very explicit about the types it uses. This is not supposed to give you an introduction. How do I start with go with absolutely everything because I assume you are very intelligent people. You can read, you can follow the tutorials online on your own. I wanted to tell you why do I find go as a very good and very pleasant language and what features actually make me still like coding it in it after three years. I did the first proper commercial project in it. So the types have the width, their size in it. So you don't have to worry or wonder how many bytes does an int take. No, that's in the name. Is it a signed, is it an unsigned, that's in the name. What is it? No, it's all built in. For those of you who still program and see that might not be a problem but for people, for example, coming from Java or some other languages, that's a problem. If there is an architecture change happening in between or you're programming to a different set of devices, well, an int 32 is always an int 32. This is what it is. This is how wide it is. You don't have to worry whether the default for that platform is 16, 14, 32 or something else. That problem is solved. Which means your interfaces, especially for something that deals with bytes and some really low level funny bits are very explicit, are easy to follow and are easy to understand. A bit of syntax, well, you can declare a variable and you can assign to it or you can declare and assign at the same time and you don't have to specify types sometimes because go compiler can infer that, well, another poke at Java which still can't figure out what type of things is, even though it knows very well. If you want to print a length of string, you do, you call a function len with the arguments of the string that you want length of. Which means string is unlike some other languages, string is not an object here. So it won't or a class, it won't have methods like you would expect it to. Which is just the way it decided to. It has some other consequences but we'll see them in a moment. And now let's have a look at maps because one maps here have quite a nice feature which is, which we'll see in a moment. So I declare a map which is a map of from string to bull, nothing fancy, I initialize it with two values. And then I try to, in this very line, I try to access a key that's not set in there. And instead of getting a null like some other, some languages would give you, you get false. And false is a zero value for bullion. So there is a concept of zero values or default values which, what is the initial value of a variable if you didn't bother or you didn't declare it. That means that all variables unless declared otherwise, you know what to expect. For ints that would be zero, for flows that would be zero, for strings that would be an empty string, for larger structs that would be a null. But it also gives you this tiny little perk that if you want to access a key inside the map, you don't have to check like so many times we have whether it exists in the map and then if it doesn't insert it and then set it to a value. No, you can assume it exists and then operate it on it as if. Which means if you want to have a map with counters, you can just say map of the key and just increment it. Because go will make sure that if it wasn't there and you access that, that's a zero, you don't need to store that. But if you actually change that, sure, it will be there, store that one as you would expect. Which saves you a lot of lines across many, many projects. Of course, I know it's a tiny detail but it's really helpful. And then structs. Because go uses structs, it doesn't have classes which have like Java, like Scala, like probably C sharp classes. They decided to go with structs as in constructs that have, that are just a list of fields. And you can initialize them this way. So just pass the arguments or you can use named arguments and then the order doesn't matter. For a lot of reasons, having named arguments is really helpful because it just helps readability, especially in the public sections of your APIs. And then you can call methods. Well, you can cast a variable to an interface and then you can call methods but let's see interfaces. So we have a type that is called square that has just one variable inside called side. And we declared that there is a function that operates on squares that's called area. And it will return an in 32. Which, well, the area for that is quite obvious how it works. So we define a square and we can call area on the square. And now the question would become why? How is it that it works that way? Well. So the authors of Go decided that knowing what other people, how other people are going to use your code and having them to explicitly be able to say that import or extends or everything is a bit of a nuisance. And maybe not nuisance but it's tiring and it brings complexity into the world. And you by definition cannot foresee all of the possible usages of your type. So instead of restricting and formalizing and maybe putting that into concrete, putting your type hierarchy into concrete, you get structural typing. So if your class has methods that much type that somebody else declared, it means your class fulfills some other type. Which means if there is, I don't know, a Martian square that somebody has designed that just meets the square method, I can cast, well, me or they can cast my square into their square because the methods match. But that's it. That seems really awkward at first because how is it going to work? But then it turns out to be an extremely powerful feature of Go the language because it means that you get to use I.O. You get to use a lot of the libraries that the authors couldn't have foreseen what they can be used for just because the types match you can cast and then you can use them in your program. And that's a really, really, really nice feature. So where is it useful? As I said, I.O., yes. All of your domain class hierarchies. If your domain class has one function, another function, another function, it means that set of functions forms an interface. It means you can use that type as something specific. Which means if your domain class hierarchies are getting larger and larger and somebody wants to use it in a very peculiar or specific way, they usually can and they don't have to cast. They do have to cast it, but they don't have to introduce special marker interfaces into the whole type hierarchies. Which for languages like Java, Scala, anything else leads to, that forces ugly less and less specific, more and more generic hierarchies. So if you ever looked at what a particular array list or a particular hash map looks like, what type those extend, in Go you don't have to worry about that because it's only about the methods that you declare. If the signature fits and if the list of methods fits another interface, you can use one type as the other and that's it. That's helpful. And now let's look at some network programming because my person speaking here previously has talked about network and using network quite a lot. So let's have a look at an echo server. Well, this is how much code you need for an echo server. Of course it's a sample, so it will be short by definition. But this is it. You expose a listen address, you create a TCP listener, you accept connection and then, well, this is just a server that will copy whatever you sent to it and reply with the same. Quite silly, but just to show you how much code is needed. Because also it shows you another feature of Go language. You can see that when I try to listen, I get a channel and I get a second thing that's ERR. So the error thing is the error. If error is nil, that means that nothing bad happened, but if error wasn't nil, that means that something wrong happened and I have, well, I can examine. It's not nil, it will be the object that describes the unexpected situation. There is no exception. It's not that the flow of your program will be seriously altered, something will explode here and then you have an exception couple of stack traces below or to the left. Because why not? No, it's right in the same place because methods can return multiple things at the same time. So a TCP server, yay, good. Maybe we should actually give it a try because there is a something peculiar about that server that I wanted you to have a look at. So. Let's try to print. Now we have an echo server running on port 4,000, so we'll just... That's what is expected. So you already see the problem. It's not really concurrent. So, well, how can we make it concurrent? Well, first by removing the format, we will build it. Oh. And now you see something about Go and its approach to coding. You cannot have... This way. So I imported and I haven't used package called FMT. Go is extremely strict about leaving and letting you have unused variables or imports in your code. It doesn't allow them. Just that. Which means if you're debugging with print statements because, well, that's still my most frequent way of debugging simple things, it will be a bit painful. But if you... In the large code bases that you usually work with, how many... How much of the source code is left unused? I don't know, but there is probably some. Go will try to eradicate and get rid of every single thing that it can safely say that hasn't been... And is not accessible in any way. Which is a really, really useful feature if you think about that in the context of, well, it's done at Google, which means the amount of software written is huge, which means you want to decrease... You want to remove all of the cognitive load that's needed to read the software that nobody ever actually runs. Because why would you waste your time on that? But we talked about an Echo server. Well, that's... So does the concurrent one? Does the normal one? Does the concurrent one? Does the normal one? Well, for people who didn't notice that, I just added this Go line here. What happens? What is the Go line? What does the Go instruction do? This way, without the Go instruction, I'm just calling a function called copy. Like you would, nothing magical happens. Single thread, no concurrency whatsoever. Whereas when I have Go, I actually run it in a Go routine. So I make that function be called concurrently and then this flow can continue. And where that will happen is something that goes runtime will manage. So Go routines, lightweight threads. When you spawn them, the idea is that you can spawn as many Go routines as you want. As in they are extremely light, their stack will be light. There is no one-to-one mapping between a Go routine and an operating system thread. So you don't have to worry that if you start anything more than, I don't know, eight on a desktop, only eight will make sense. No, this is not how you are supposed to think about that because Go routines are how you structure your software. And that's quite orthogonal to how your hardware, underlying hardware is going to run it. And you shouldn't have to worry about the hardware for most of the cases because in most cases you are there to solve a problem, which means express it with code and be able to run it. Go runtime will take care of that. That's, again, a normal function call without the Go instruction. And that's deferring it, that's running it in a separate Go routine. First question that comes to mind, well, how many threads will run? That's something that actually bit me and bit us at eBay at the very beginning of our history of Go. There is an environment variable called Go Max Brox, or there is a runtime parameter that you can observe and react to and change, which tells you how many concurrent Go routines can operate. It's usually useful to set it to something like your current number of hardware CPUs or cores because anything higher will obviously have the obvious problems. But that's something worth mentioning because it's biting so many people and it has and it will, because by default this value is set to one, which means only one can run at a time. So we can spawn functions that will operate on a different thread. Awesome. How do you make them talk together? Because that's only, well, that this is the necessary component. The answer to that is channels. Channels, as the concept come from a very important paper called CSP or communicating sequential processes by Mr. Hoar. I would think that some of you at least have heard. If you have some spare time, if you would like to talk computer science with your friends, try to read this paper, try to discuss it, go through it because it's a really awesome paper. It's so much different to some of the concepts that we primarily use in most languages popular right now. And in current world that's going more and more multi-core, multi-processes, multi-threaded. It makes things easier. And by making things easier it reduces complexity. So we don't have to worry about how things are orchestrated. Runtime will support that. You only have to make your implementation look nice. So Go uses a concept called channels. Channels are bits of memory. They are used to communicate between go routines. They have types. So you don't have to worry about what comes in or what comes out. Type safety is there. And with type safety because we talked about types, we know what they look like in memory because we know the width, we know how they, we know how they, well, exactly what they look like. We also can push other data into those channels from different applications if we agree on the byte order. And channels are also thread safe. So you don't have to do manual synchronization around using channels because channels will under the hood provide you with thread safety. You don't have to worry about explosions. You make a channel by, well, this instruction. That's, you make a channel of a variable. Then we have a channel. There is, there are two types of channels in Go. One type is called buffered. The other one is called unbuffered. One is unbuffered. Unbuffered channels. So channels that don't have a buffer, which means, well, they are unspecified in their size. They are synchronous and they will wait when you try to read from an empty one. Basic syntax, well, you've seen how you make a channel. You push things into a channel with this funny arrow operator or you read from a channel and you can assign it to a variable. And you can see, you can also get this extra variable whether something was actually there. Because if you were reading from an empty channel, you will get the zero variable, the zero variable chest as I described it with maps. But if you'd like to have a distinction whether the zero that you read was because the channel was empty or because that's actually what was in the channel, you can use that extra variable there. Some bits of code. You, of course, have to pass channel as an argument to a function because, well, it has to be able to communicate. This simple piece of code, well, this piece of code will just put a random integer into the channel and then another function will try to, will read it and then we'll reply with, well, received something. Absolutely trivial, nothing fancy in here. Just the basics so that you know more or less how it works. And as I said, that's not cool yet. The cool thing about channels apart from, well, passing variables and passing data all the time is that you can use them to coordinate. And you can, well, what you can do is make a channel and then have a function that will close that channel or write anything into that and another function will try to read from a channel, which means the function that tries to read from an empty channel will have to wait and it will wait and it will wait and it will wait and then when you close or write anything that doesn't, it doesn't have to make any sense, then that will progress, which means having, well, coordinating two functions becomes super easy. If you share that channel across many functions, then all of the functions that are waiting for a channel when you close it will be able to progress. How many, you can of course do it with mutixes, but why? Something called a latch, you can also express with channels, of course, there is some work that the worker is going to work on and so on and so on and so on. What can you imagine a latch with? You know what a horse race looks like. You know how it starts, there is this very fancy gate to which all of the horses have to enter and then it's all released and then all of the horses start at once. This is the same concept actually in here. So you spawn a number of workers, you spawn, well, as many of them as you want and they will do the work after they manage to read something from the latch. So once that is closed or they can read something from here, well, they will be able to progress. When is it important? When is that fun? When you want to, I don't know, each of the workers that you prepare has to read some configuration, how it has to be able to, well, initialize themselves in a certain way, maybe, I don't know, maybe make a TCP connection, maybe make an SSH connection, make, I don't know, it really depends on your use case, but this is a very, very frequent construct in many of the servers that we've written. It helps and the fact that it's only, I don't know how many lines, but not too many. How many lines would that be in your language? I can hear some whispers, I don't know what they say, but, of course, it depends on the language. That's a very good answer, but if you were to try to code it in Java, that would be a lot, as in a lot. It certainly wouldn't fit on the screen in a readable way. I can promise you that. Generators, another nice thing that Go has, you probably have used an SQL database, you probably heard of sequences or a way to have, well, sequential or non-sequential, but unique numbers in a piece of software. How can you make that in Go? It's, again, trivial. So if you need some uniqueness, if you need something to govern over that, well, you can use a Go routine. And the good thing is you use this funny for construct, so you write the current version of the counter or your randomly generated version of the value into the channel and then, well, generate another one. The great thing is it's lazy. So it only actually, this is only executed when the value is needed, which means you don't have to worry about pre-generating all of the random values in the world or about the sizing, no, no. This Go routine will only be called upon when it's needed, which means having a sequential number generator that can be used across all of your Go routines on a single machine becomes very easy. Of course, the problem becomes very complicated if you want to have a number of machines or a whole cluster or a number of clusters in different data centers, but this problem is beyond, this problem spans many run times, which means it's beyond what a programming language should solve by default. But if you're still on a single machine, this gives you a generator. You can, of course, do other stuff in here. Also, if you want to have a single, I don't know, file interface or a single database connection, you can use that construct as well. Multiple channels at once, because, well, it is good we've read from one channel, but what if there is a situation in which I want to read from a channel, well, maybe there is this connection that will give me something, maybe there is this connection that will give me something, how can I express that? Well, Go has a select statement, which will just, it will advance and it will execute the code that's associated with whichever case happens first. So you don't have to worry about expressing that with ifs or doing nested loops with, or while, or, well, yeah, looping and checking if something is available in the channel over and over, it's available as a construct, which means you don't have to worry. Providing a default, there is a construct for that, and there is a timeout built in. How many times have you written a read from a socket or from somewhere, and then forgotten about the timeout? I have done that many, many times. This still doesn't solve that problem, because if I forget to put that in, I will forget, but it's easy to specify it and it's built into the construct, so there is nothing extra that I have to use that will be taken care of and that will be guarded by the runtime built in. Services. So if assuming your software has, you're doing a microservice based application or just a service based application and you want to create some services and the service has to stay available, but then comes the problem of how do we shut down in a graceful way? Because that's a nice way to shut things down, especially if you have connections to other services so that you don't leave them hanging, so that things don't have to timeout, so that you don't waste resources. Well, you can create a service and, well, spawn it and wait for it to do all the work, and then again, you can use the channel to finish all the work, to signal that you have, well, either completed your work or you're ready to die, which means you can use a quitting kind of notification like in here. So make a channel, well, do the work for three days or any amount of time that you need. You do the cleanup and then you, well, you might report, this is, well, just sample so it returns, it prints out to system out that you're done with the cleanup and then you quit. And then when you have quit and the cleanup has happened, well, your governing piece of code can finish, exit in a nice way and you're done. Buffered channels, because I mentioned that there are unbuffered channels, we skip the buffered ones for a reason. They are asynchronous. They will return a zero element when empty and they will only wait when they are full. So a buffered channel, a queue with a bounded size, your intuition guides you well. I've been talking about channels for more or less 15 minutes. Somebody would ask, are channels the ultimate gold, well, hammer, the silver, the golden bullet, whichever mythology you want to follow? And of course, well, the fact that you can express a lot of the problems with channels doesn't mean that you should. So Go also has the usual constructs, right? Like mutexes, like locks, like atomic operations. And those are screenshots from Go documentation that's available online about packages, about sync and sync atomic packages. So those functions, those instructions are built into the, well, already available to you. You don't have to write them yourself, which means you don't have to create a double nested locking or some other idioms that you hope that they work, but they really don't. It's all, they're available for you. And last thing, if memory serves me well, are ranges. So a way of operating over channels or slices, which is a go way of sync arrays from a programmatic point of view. And the thing is, you can treat both in a single way. So you can treat a slice or you can treat a channel similarly, and you can just treat it, well, put that into the range instruction so you can do a for loop over each. And then you don't have to learn two different syntaxes because those things are look the same and operate the same, which again makes your software nicer to read, makes everything, well, makes life better. Packages, well, I mentioned that Go has packages when I showed you the package declaration. When I see what's available, I will see that there is a bin directory, there is a package directory that will also generate things for specific architectures, which should lead you to a question, what about other architectures? What is the architecture support model with Go? Well, by default, if I compile a program, a piece of software on a Mac, I can put it, well, give it to a different Mac and it will run just fine. Of course it will not run on the Windows, of course it will not run on a Linux, but if I compile it on a Linux, I can get that binary because, again, static linking and ship it to a bunch of other Linux boxes and it will work, which is quite amazing. Can I cross compile? Of course. Can I do other funny things while compile against sources that have some C integration? Yes, of course. And I mentioned, somebody even asked about packages and dependencies and I mentioned that Go already has a tool for that and I can put imports that pointed packages that hover somewhere in the Internet. And that's actually a very funny thing because it's not specified in the language. So there is, there is, how Go tools should resolve that, but it's assumed that Go tools will be able to resolve addresses like that. So if we go to here and we uncomment this B. And then we do go get and we hope that, oops, Google code doesn't like us anymore. Oh, well. What Go get would do is get the code from Google code if Google code would actually play with us today. It would download all the sources, it would download, well, the whole package. So if you're used to binary packages being shipped around with tools like Maven, with tools like Ant, with other tools of choices, then Go does not the case. What you will download is the source code. So if you want to examine how something has been written, you will get to see exactly that. What it also means, you will download the source code with tests, assuming the tests are there. So you can run their tests if you suspect a bug. If you want to see the documentation, documentation is part of the source code, it's embedded, which means you get to see it as well. Which is an absolutely amazing concept if you're in a company that values open source software and it makes working with proprietary libraries very awkward. But, well, luckily, in my history, I haven't had a situation so far that I had to connect to a very proprietary library without having access to source code in Go. Maybe because the language and the ecosystem are quite young, maybe the mentality has changed, maybe the other environments are more frequent to exhibit such behavior. So Go gets, well, we've tried to run it, it didn't work that well, so we'll skip that part. What looks bad? Well, if you want to have JSON structures and JSON kind of binding, the way that you can express that in Go looks a bit ugly to me. I'm not a huge fan of the syntax or because it connects your type definitions with how you should parse your data. It links two things together. It also means that the structure of your JSONs starts to live in your source code, which means you can't change one without the other, which is not the luckiest of choices. On the other hand, there are quite popular libraries that allow JSON and other format bindings for many languages out there, JavaScript, most probably.NET, which means, well, that's something people look for. Before you leave, before I say thank you and do you have any questions, if you wanted to learn Go, if you wanted to learn something more, of course, there is the excellent website which has a lot of tutorials. It has some of the tutorials you can actually write code and run them through your browser. But if you'd like to do it the classical way, get a book. This is the book I would recommend. It's written by, well, you can see the authors here, but I would say that it's quite amazing. It's very comprehensive. It's exactly as thick as your Kindle is or, well, I haven't seen the paper version because I don't buy them anymore, but this will be my book of choice. And last thing, what ID's can you write, should you write Go in? Well, pick your favorite text editor. You don't really need anything fancy. If you like Visual Studio Code, it has excellent Go support, including all of the additional tools that you can use like Linting, like import or automatic importing, like automatic formatting on save. You can have that all in Visual Studio Code. I started writing Go with Sublime and I like it. Well, I love Sublime for that. You can, of course, do it in Vim. You can do it in Atom. You can do it in most of the other ID's out there as well. Because the language is very simple because the syntax doesn't have any special cases. It's not the type system is, again, simple, which means creating tools doesn't look that complex. But then all of the complexity shouldn't be in the software in how it gets written because it's not the smartest people who write the code. It's about the problem that gets to be solved. So with that, I will ask you, well, try to download Go, have some fun, and Go code. And if you have any questions, just try to wave your hand. Yeah, there is a question. Yeah, so handling errors by looking at return codes, yes, the error variable that was returned from some of the instructions is if it's nil, if it's empty, that means that there is no error. If it's not nil, it should have the error on information in it. It's not error codes as in integers comparing that to things. You can use types. Well, there is a type system for your benefit here. But yeah, this is the approach here. How do you protect from errors that are not thought about or nil or inference exception or the equivalent or something like that? So how can I protect myself from errors that somebody didn't think about? So if I ignore it, well, my software will explode the same way other pieces of software will explode. Because, well, if it's the second parameter, somebody forces you to use it. Yeah. But I mean, let's say in Java, you would probably around some critical stuff have tried something and then catch everything and at least log it and try to be ready to process the next request or whatever if something goes wrong. So how would you handle that? Well, there is a way which I don't have that example in the slides, but you don't have to assume if there is a tiny error in one of the small go routines that something really not important that will crush your application. No, there is a way to protect yourself from that, of course, but it's just not in the slides. ID support, well, we've covered. Debugging is also possible. C integration, well, how many minutes do we have? Three. Is anybody interested in C integration? No. No. No. Good. So with that, I'll say thank you. Enjoy lunch, enjoy coffees, enjoy all the great sponsors and everything else in the conference. It was my pleasure to see you and, well, experience also and I'll be available if you want to have any more conversations. Thanks. There is this voting machine at the end. If you can please press the green button that is Aftertaste to start voting. Just do 1-0-0.
 I think it should be working. So hello and welcome to my session about a language called  Go. I'm really happy to see you. I think, well, I hope the coffee is good. I've had  just one so far. Who here is enjoying NDC for their first time? Me as well. It's my  first time at NDC in Oslo. It's my second time in Oslo because I have a friend living  here. So it's amazing to be here. It's a lovely city. Well, the weather is very generous to  me as well, again, which is also amazing. And this talk is about a funny language called  Go funny. As in, it brings fun. It's not nothing to be joked about because you can do very  serious things with it. If you have any questions, of course, well, you know, try to raise your  hands. I'll try to notice you and I'll try to repeat the question that you have and  maybe even answer. So starting with a bit about myself. Well, you could describe me  as a Java developer in a dotnet and a primarily in the dotnet conference talking about totally  a non-dotnet and not JVM language, a bit out of place. But, well, to give myself a bit  of a background, I come from Kraków in Poland. I now live in London. I run a conference called  Geekon. Also have been involved in the community as in running the Polish Java user group doing,  well, founded Kraków Hadoop user group, which now is called Data Kraków because, well,  Data Science is much more popular. Apart from, well, interested in all the usual software  engineering things that you would expect for example, one thing that needs to be mentioned  is Software Craftsmanship Kraków. It's a group which you would expect to be about testing  and software craftsmanship and we founded that in 2010. It's actually a group in which  we read computer science papers. So every two weeks, we pick a paper. Well, people read  it before and then we come in, meet and discuss it for give or take two hours. So it's a very  well different thing to what people usually connect with with Software Craftsmanship,  but I think it's worth to be noted because we've had over 100 meetups so far. Anyway,  me, described in, trying to describe myself in a single sentence as a developer going  deeper. So if something works, I'm usually suspicious. Why is it working? This shouldn't  be like that. It shouldn't compile, which means I like to go deeper and deeper and  deeper and deeper. Well, with all of the time that it requires. One disclaimer, my opinions  are my own. You can find it on LinkedIn. Who do I work for? But this talk is not connected  to my employer in any way, of course, because they are very brand protective, which means  they don't want me to mention their name. That's their choice. If you have any questions,  shoot or try to find me after the talk. If you have any questions during the talk and  you would like to raise your hand, I would love to answer. So, GoalLang. It's a free  and open source language. As in free beer, you can well download it from the internet  and use it and you don't have, as of now, at least I haven't heard that, you don't have  to worry about a large database company suing you for using that. So, it's open source,  so, again, you don't have to worry. I haven't seen a legal department that would give people  problems because of their attempts to use Goal. It's BSD license, so that should be  okay in most places. Of course, there might be some extremes. I'm not a lawyer. It comes  from Google, so it has been invented. Google uses it. At least that's what they say because  they've never worked for Google, so I have no idea what does it look like internally.  But it comes from there to solve a couple of problems. Who here has written some C or  C++ in their lives? Yeah. There are some, let's call them inefficiencies or problems  or minds or, well, 10,000 ways to shoot yourself in the foot very effectively blowing the whole  leg and half your hip off in those languages. Goal is nice, as in it allows you to save  yourself from some of the problems. It takes some of the power away, and at first I thought  that it's very limiting. That was my first attempt. It feels like I can't do all the  things that I used to be able to. Am I really going to be able to be productive in this  language? Then it turned out, I'm not really missing all those features that much because  I can still get the job done, and usually there are less bugs and there's less code.  Go is fast, as in the whole. One of the key goals in creating that language has been speed.  Speed in compilation. You might have seen compilation processes for large C code bases  that can take a day or at least a couple of hours. Go, I haven't seen really long go compile  times. Go compiles really, really fast. The whole tool chain is very fast, which means  you can have very rapid development cycles, which means you get feedback often. You can  run your tests. You don't have to wait a day for a software deployment manager and their  team to try to attempt to configure the thing and run CMake, DMake, your flavor of make  and wait for it to happen. Go has a mascot as every single, well, self-worthy open source  project. It needs some graphic designers to help it. So for a go, go for is the mascot.  And if you're already asleep, you're thinking about lunch or some of the awesome stuff that  you can see in the exhibition hall. I really loved the VR experience there. It's a mix  between C++ and Ruby because of the syntax, because of the power and because of how low  level go gets. So if you're already asleep or getting the play with it tonight, I really  encourage you to. It's super easy to start with. You just need to download the tool chain  and then you can start. You don't need to download a specific operating system, a specific  IDE, a specific something. Just the go distribution for your machine of choice and a text editor  and you're good to go. So, well, I always get questions about who uses go. What companies  use go? Can I use some big brands to encourage my place to use it? Well, Google obviously  as the inventors of the language, well, eBay, for some of, that might be a good thing, for  some of you it might be a bad. Dropbox, well, Bitbucket now, Atlassian, I think. Government  okay. So that's a government entity. They use go the language and the great thing about  UK gov is that some of their go usage is open source. And I can only say some because I  don't know of all of their go usage, but government UK open source is a lot of their currently  written software, which means you can actually, this is good enough for the UK government.  This is the link to GitHub. Have a look. It's serious stuff running on go used by a government.  That's a very good political argument for some of the discussions. Talker, of course,  some other things. The Wiki address has a much longer list of users. There is a lot  of companies in London which use go and experiment with go. I can give you a short story about  a company that just happens to be in my area called Not on the High Street. I went there,  I think a year ago to do a talk about go the language because some of the developers were  curious and just a week ago I learned that I already started using that in production.  That was nice. To fill that story completely, how did I learn about go? Well, I heard that  Google has open sourced a language, created this language and I was just curious to start.  I couldn't find a reason. And then we were doing effectively a router, an HTTP router  in Java. Which means if you're doing any software in Java, it tends to grow into thousands of  lines. So our software had, I think, well, 10,000 of lines plus a couple of hundred  of XML lines plus, of course, you had to use Tomcat and other things. And at one point  I thought maybe we should take a step back. Maybe something is a bit wrong in here because  the amount of dependencies, the amount of things or crap that you need to install to  get it to essentially route HTTP requests and serve very simple things, it feels a bit  too high. So we rewrote that into go and we ended up with around one-eighth of the code.  And we got a single binary and that was it. And that felt really awkward because, well,  at least me coming from Java ecosystem, I'm used to bloated software sometimes in the  verbosity. And then in this language, well, this is everything. So we've shown it to other  people, well, okay, show me the code. That's readable. That looks like Ruby. I don't really  understand all of the tiny details. But those are details. Where is the rest of it? No,  no, no. That's all. That is impossible. Because as I said, it was around one-eighth of the  code and that was our first, well, serious project that we did for eBay in 2013 in code  language. And that's, well, then we started having go as a regular piece in our tool chain.  I do not encourage you to rewrite all your software into go. That's never the solution.  It's a great language for some usages. Well, for some usages, it's not perfect for everything  because I still believe there is no silver bullet which obviously translates into I'm  an engineer, not a consultant because then I would try to sell you mine. Where do I use  it? All kinds of network-related middleware. Yes. All kinds of anything that needs to deal  with sockets, well, HTTP traffic, analyzed root, do something with that, go is super  pleasant to use it, to use that. I know that there is a lot of companies that use go for  microservices that wouldn't have been my first choice because I personally prefer languages  with more, well, with a richer type system because then you can reuse the domain language  that you will create in one application in the other, which means I would probably tend  to favor Scala right now. But there is a lot of go usage in microservices space and people  are very happy with that because the applications in go, you can create them quickly and you  can run them quickly and they usually behave quite well, which means a lot of the overhead  that I mentioned you don't have to go through. And I mentioned Scala because I like Scala  the language at first it helps because learning curve is quite steep. Go has a much, much nicer,  much more approachable learning curve. Just to answer the question that usually happens.  Where not? Well, user interfaces, web applications, well, you can't write them in go. I haven't  seen a go to JavaScript transpiler just yet. It doesn't mean that there doesn't exist one.  It's only that I haven't seen it. It's a back end development language. It's really good  there. But I've been talking for a couple of minutes now and I think it's time for, well,  we have to go through some code. So, Mandatory, hello world, because of course we have to,  let's make it even larger. Yay. So, you have, well, a package declaration. That's obvious  what it does. We import FMT. So, we import a namespace of another package that we will  be using a function from. And then we have, well, we use a function from that. You can  notice that it starts with an uppercase. That's a convention in go. Anything that you want  to export within a package has to have a start with an uppercase. Let's try to run it. So,  go, build, main. That's done. And go run main. Oh, sorry. Yay. That was fast. So, why is  main not uppercase? Because main, that's a really good question. That's a catch. Main is  this one special thing that you start your applications with. If you notice any similarity  with a usual main function that's prevalent, that's present in many other languages, that's  exactly your intuition guides you well. Main is this one special package in your source  tree that is supposed to contain the entry point for your application. So, if we look  at the directory structure here, well, there is bin, there is PKG, there is SRC, under  SRC, well, there is, you can have different packages. And if you have any dependencies,  they will end up here, but we'll discuss, I'll talk about it later. If you want to create  an application, the default would be that it would sit in a package called main, and  all of the other stuff should be your dependencies. So, if you want to have a number of applications,  well, you will have a number of projects with different main directories, and all of the  other things will be your dependencies, which encourages you to externalize and then think  about how you structure your software. So, just a convention. So, we've seen a hello  world. Why do I like go? Coming back to that point, well, no runtime dependencies. What  do I mean by that? I mean that I get, oops, I think I want to be here. So, this main,  this binary has everything that's needed. It only prints a hello world, and somebody  could say that it's a bit large that it takes two megabytes to just print nothing, well,  almost nothing. Just a hello and you see this very important message, but then it takes  two megabytes. The answer is go links everything statically. So, you can take the binary, you  can deploy it to all of your servers, and you don't have to worry about missing dependencies.  Everything is contained there, which means your release management becomes trivial because  you just need to well take a binary and deploy it to a number of machines. Your dependency,  your library management becomes super easy, super pleasant. Your operations people will  probably most probably be very satisfied with such an approach because that will, that gives  you simplicity and simplicity is what I really like in software. So, deployment, as we said,  super easy, much more pleasant than C because we don't have to produce a lot of the artifacts  that we would sometimes have to worry cache for the compiler to optimize our enterprise  completion process. And you've seen that I've compiled this tiny amount of code using a  go command, and I mentioned something called the go tool chain. And now let's talk about  the tool chain. Let's give it a bit of a look. So, if I type go, I will see that go is a  tool for managing go source code. Yay. The commands are, so the built in, the built in  commands, the things that are built into the basic tool chain, the thing that you download  from the Internet, so anybody using go language, anybody being able to compile, you can safely  assume they can build. They can show documentation for package or symbols. They can format and  run a formatter. You can also generate. You can install dependencies. You can download  dependencies. You can list packages. You can run. You can test. You can print your current  version because obviously you'll need to do that. Being able to get to manage dependencies,  being able to run your tests out of the box, that's usually a pretty good start. No other  things are necessary. That's all built in. To be fair, what will do tests look like?  Well tests are just simple programs that are supposed to have an exit code of zero in any  decent software, piece of software. Well, that's a convention that they follow. But  then they allow you, they already give you something that you can test your source, your  code with. You can build and you can manage dependencies, which means you can specify  dependencies that sit, for example, on GitHub and this tool can download. And we'll see  that a bit later. So the go command. We've seen that in action. And I mentioned go format.  Authors of go decided that there are certain discussions in the software industry not really  worth having in most of the context. One of them is formatting. So in terms of go, tabs  versus spaces doesn't exist. I know it's a great flamer for having a beer over, but with  the go language you are supposed to be using tabs and all break lines or new lines characters  will be converted into semi-colon so you don't have to use them. So the way you place your  returns actually matters. That also means that every single piece of go software should  look the same. It's encouraged, it's highly encouraged to run go format after every save  in your editor and it's a very easy thing to configure. That also means that analyzing  software becomes a much easier job because you can make certain assumptions about what  does the source code look like. How is it shaped? Because everybody's source is shaped  the same. And that also means that when you're reading somebody else's go you don't have  to why is this curly brace sitting in a new line and there is a comment in between. No,  no, no. There is one way to do that and everybody follows that. This is more or less what it  is. I'm saying more or less because how Keynote decided to format my text is a different story.  But another thing, another great thing that I like about go is that it's very explicit  about the types it uses. This is not supposed to give you an introduction. How do I start  with go with absolutely everything because I assume you are very intelligent people.  You can read, you can follow the tutorials online on your own. I wanted to tell you why  do I find go as a very good and very pleasant language and what features actually make me  still like coding it in it after three years. I did the first proper commercial project  in it. So the types have the width, their size in it. So you don't have to worry or  wonder how many bytes does an int take. No, that's in the name. Is it a signed, is it  an unsigned, that's in the name. What is it? No, it's all built in. For those of you who  still program and see that might not be a problem but for people, for example, coming  from Java or some other languages, that's a problem. If there is an architecture change  happening in between or you're programming to a different set of devices, well, an int  32 is always an int 32. This is what it is. This is how wide it is. You don't have to  worry whether the default for that platform is 16, 14, 32 or something else. That problem  is solved. Which means your interfaces, especially for something that deals with bytes and some  really low level funny bits are very explicit, are easy to follow and are easy to understand.  A bit of syntax, well, you can declare a variable and you can assign to it or you can declare  and assign at the same time and you don't have to specify types sometimes because go compiler  can infer that, well, another poke at Java which still can't figure out what type of  things is, even though it knows very well. If you want to print a length of string, you  do, you call a function len with the arguments of the string that you want length of. Which  means string is unlike some other languages, string is not an object here. So it won't  or a class, it won't have methods like you would expect it to. Which is just the way  it decided to. It has some other consequences but we'll see them in a moment. And now let's  have a look at maps because one maps here have quite a nice feature which is, which we'll  see in a moment. So I declare a map which is a map of from string to bull, nothing fancy,  I initialize it with two values. And then I try to, in this very line, I try to access  a key that's not set in there. And instead of getting a null like some other, some languages  would give you, you get false. And false is a zero value for bullion. So there is a concept  of zero values or default values which, what is the initial value of a variable if you  didn't bother or you didn't declare it. That means that all variables unless declared otherwise,  you know what to expect. For ints that would be zero, for flows that would be zero, for  strings that would be an empty string, for larger structs that would be a null. But it  also gives you this tiny little perk that if you want to access a key inside the map,  you don't have to check like so many times we have whether it exists in the map and then  if it doesn't insert it and then set it to a value. No, you can assume it exists and  then operate it on it as if. Which means if you want to have a map with counters, you  can just say map of the key and just increment it. Because go will make sure that if it wasn't  there and you access that, that's a zero, you don't need to store that. But if you actually  change that, sure, it will be there, store that one as you would expect. Which saves  you a lot of lines across many, many projects. Of course, I know it's a tiny detail but it's  really helpful. And then structs. Because go uses structs, it doesn't have classes which  have like Java, like Scala, like probably C sharp classes. They decided to go with structs  as in constructs that have, that are just a list of fields. And you can initialize them  this way. So just pass the arguments or you can use named arguments and then the order  doesn't matter. For a lot of reasons, having named arguments is really helpful because  it just helps readability, especially in the public sections of your APIs. And then you  can call methods. Well, you can cast a variable to an interface and then you can call methods  but let's see interfaces. So we have a type that is called square that has just one variable  inside called side. And we declared that there is a function that operates on squares that's  called area. And it will return an in 32. Which, well, the area for that is quite obvious  how it works. So we define a square and we can call area on the square. And now the question  would become why? How is it that it works that way? Well. So the authors of Go decided  that knowing what other people, how other people are going to use your code and having  them to explicitly be able to say that import or extends or everything is a bit of a nuisance.  And maybe not nuisance but it's tiring and it brings complexity into the world. And you  by definition cannot foresee all of the possible usages of your type. So instead of restricting  and formalizing and maybe putting that into concrete, putting your type hierarchy into  concrete, you get structural typing. So if your class has methods that much type that  somebody else declared, it means your class fulfills some other type. Which means if there  is, I don't know, a Martian square that somebody has designed that just meets the square method,  I can cast, well, me or they can cast my square into their square because the methods match.  But that's it. That seems really awkward at first because how is it going to work? But  then it turns out to be an extremely powerful feature of Go the language because it means  that you get to use I.O. You get to use a lot of the libraries that the authors couldn't  have foreseen what they can be used for just because the types match you can cast and then  you can use them in your program. And that's a really, really, really nice feature. So  where is it useful? As I said, I.O., yes. All of your domain class hierarchies. If your  domain class has one function, another function, another function, it means that set of functions  forms an interface. It means you can use that type as something specific. Which means if  your domain class hierarchies are getting larger and larger and somebody wants to use  it in a very peculiar or specific way, they usually can and they don't have to cast. They  do have to cast it, but they don't have to introduce special marker interfaces into the  whole type hierarchies. Which for languages like Java, Scala, anything else leads to,  that forces ugly less and less specific, more and more generic hierarchies. So if you ever  looked at what a particular array list or a particular hash map looks like, what type  those extend, in Go you don't have to worry about that because it's only about the methods  that you declare. If the signature fits and if the list of methods fits another interface,  you can use one type as the other and that's it. That's helpful.  And now let's look at some network programming because my person speaking here previously  has talked about network and using network quite a lot. So let's have a look at an echo  server. Well, this is how much code you need for an echo server. Of course it's a sample,  so it will be short by definition. But this is it. You expose a listen address, you create  a TCP listener, you accept connection and then, well, this is just a server that will  copy whatever you sent to it and reply with the same. Quite silly, but just to show you  how much code is needed. Because also it shows you another feature of Go language. You can  see that when I try to listen, I get a channel and I get a second thing that's ERR. So the  error thing is the error. If error is nil, that means that nothing bad happened, but  if error wasn't nil, that means that something wrong happened and I have, well, I can examine.  It's not nil, it will be the object that describes the unexpected situation. There is no exception.  It's not that the flow of your program will be seriously altered, something will explode  here and then you have an exception couple of stack traces below or to the left. Because  why not? No, it's right in the same place because methods can return multiple things  at the same time. So a TCP server, yay, good. Maybe we should actually give it a try because  there is a something peculiar about that server that I wanted you to have a look at.  So. Let's try to print.  Now we have an echo server running on port 4,000, so we'll just...  That's what is expected. So you already see the problem. It's not really concurrent. So,  well, how can we make it concurrent? Well, first by removing the format, we will build  it. Oh. And now you see something about Go and its approach to coding. You cannot have...  This way. So I imported and I haven't used package called FMT. Go is extremely strict  about leaving and letting you have unused variables or imports in your code. It doesn't  allow them. Just that. Which means if you're debugging with print statements because, well,  that's still my most frequent way of debugging simple things, it will be a bit painful. But  if you... In the large code bases that you usually work with, how many... How much of  the source code is left unused? I don't know, but there is probably some. Go will try to  eradicate and get rid of every single thing that it can safely say that hasn't been...  And is not accessible in any way. Which is a really, really useful feature if you think  about that in the context of, well, it's done at Google, which means the amount of software  written is huge, which means you want to decrease... You want to remove all of the cognitive load  that's needed to read the software that nobody ever actually runs. Because why would you  waste your time on that? But we talked about an Echo server. Well, that's... So does the  concurrent one? Does the normal one? Does the concurrent one? Does the normal one? Well,  for people who didn't notice that, I just added this Go line here. What happens? What  is the Go line? What does the Go instruction do? This way, without the Go instruction,  I'm just calling a function called copy. Like you would, nothing magical happens. Single  thread, no concurrency whatsoever. Whereas when I have Go, I actually run it in a Go  routine. So I make that function be called concurrently and then this flow can continue.  And where that will happen is something that goes runtime will manage. So Go routines, lightweight  threads. When you spawn them, the idea is that you can spawn as many Go routines as you want.  As in they are extremely light, their stack will be light. There is no one-to-one mapping  between a Go routine and an operating system thread. So you don't have to worry that if  you start anything more than, I don't know, eight on a desktop, only eight will make sense.  No, this is not how you are supposed to think about that because Go routines are how you  structure your software. And that's quite orthogonal to how your hardware, underlying  hardware is going to run it. And you shouldn't have to worry about the hardware for most  of the cases because in most cases you are there to solve a problem, which means express  it with code and be able to run it. Go runtime will take care of that. That's, again, a normal  function call without the Go instruction. And that's deferring it, that's running it  in a separate Go routine. First question that comes to mind, well, how many threads will  run? That's something that actually bit me and bit us at eBay at the very beginning of  our history of Go. There is an environment variable called Go Max Brox, or there is a  runtime parameter that you can observe and react to and change, which tells you how many  concurrent Go routines can operate. It's usually useful to set it to something like your current  number of hardware CPUs or cores because anything higher will obviously have the obvious problems.  But that's something worth mentioning because it's biting so many people and it has and it  will, because by default this value is set to one, which means only one can run at a  time. So we can spawn functions that will operate on a different thread. Awesome. How  do you make them talk together? Because that's only, well, that this is the necessary component.  The answer to that is channels. Channels, as the concept come from a very important paper  called CSP or communicating sequential processes by Mr. Hoar. I would think that some of you  at least have heard. If you have some spare time, if you would like to talk computer science  with your friends, try to read this paper, try to discuss it, go through it because it's  a really awesome paper. It's so much different to some of the concepts that we primarily  use in most languages popular right now. And in current world that's going more and more  multi-core, multi-processes, multi-threaded. It makes things easier. And by making things  easier it reduces complexity. So we don't have to worry about how things are orchestrated.  Runtime will support that. You only have to make your implementation look nice. So Go  uses a concept called channels. Channels are bits of memory. They are used to communicate  between go routines. They have types. So you don't have to worry about what comes in or  what comes out. Type safety is there. And with type safety because we talked about types,  we know what they look like in memory because we know the width, we know how they, we know  how they, well, exactly what they look like. We also can push other data into those channels  from different applications if we agree on the byte order. And channels are also thread  safe. So you don't have to do manual synchronization around using channels because channels will  under the hood provide you with thread safety. You don't have to worry about explosions.  You make a channel by, well, this instruction. That's, you make a channel of a variable.  Then we have a channel. There is, there are two types of channels in Go. One type is called  buffered. The other one is called unbuffered. One is unbuffered. Unbuffered channels. So  channels that don't have a buffer, which means, well, they are unspecified in their size.  They are synchronous and they will wait when you try to read from an empty one. Basic syntax,  well, you've seen how you make a channel. You push things into a channel with this funny  arrow operator or you read from a channel and you can assign it to a variable. And you  can see, you can also get this extra variable whether something was actually there. Because  if you were reading from an empty channel, you will get the zero variable, the zero variable  chest as I described it with maps. But if you'd like to have a distinction whether the  zero that you read was because the channel was empty or because that's actually what  was in the channel, you can use that extra variable there. Some bits of code. You, of  course, have to pass channel as an argument to a function because, well, it has to be  able to communicate. This simple piece of code, well, this piece of code will just put a random  integer into the channel and then another function will try to, will read it and then  we'll reply with, well, received something. Absolutely trivial, nothing fancy in here.  Just the basics so that you know more or less how it works. And as I said, that's not cool  yet. The cool thing about channels apart from, well, passing variables and passing data all  the time is that you can use them to coordinate. And you can, well, what you can do is make  a channel and then have a function that will close that channel or write anything into  that and another function will try to read from a channel, which means the function that  tries to read from an empty channel will have to wait and it will wait and it will wait  and it will wait and then when you close or write anything that doesn't, it doesn't have  to make any sense, then that will progress, which means having, well, coordinating two  functions becomes super easy. If you share that channel across many functions, then all  of the functions that are waiting for a channel when you close it will be able to progress.  How many, you can of course do it with mutixes, but why? Something called a latch, you can  also express with channels, of course, there is some work that the worker is going to work  on and so on and so on and so on. What can you imagine a latch with? You know what a  horse race looks like. You know how it starts, there is this very fancy gate to which all  of the horses have to enter and then it's all released and then all of the horses start  at once. This is the same concept actually in here. So you spawn a number of workers,  you spawn, well, as many of them as you want and they will do the work after they manage  to read something from the latch. So once that is closed or they can read something  from here, well, they will be able to progress. When is it important? When is that fun? When  you want to, I don't know, each of the workers that you prepare has to read some configuration,  how it has to be able to, well, initialize themselves in a certain way, maybe, I don't  know, maybe make a TCP connection, maybe make an SSH connection, make, I don't know, it  really depends on your use case, but this is a very, very frequent construct in many  of the servers that we've written. It helps and the fact that it's only, I don't know  how many lines, but not too many. How many lines would that be in your language? I can  hear some whispers, I don't know what they say, but, of course, it depends on the language.  That's a very good answer, but if you were to try to code it in Java, that would be a  lot, as in a lot. It certainly wouldn't fit on the screen in a readable way. I can promise  you that. Generators, another nice thing that Go has, you probably have used an SQL database,  you probably heard of sequences or a way to have, well, sequential or non-sequential,  but unique numbers in a piece of software. How can you make that in Go? It's, again,  trivial. So if you need some uniqueness, if you need something to govern over that, well,  you can use a Go routine. And the good thing is you use this funny for construct, so you  write the current version of the counter or your randomly generated version of the value  into the channel and then, well, generate another one. The great thing is it's lazy.  So it only actually, this is only executed when the value is needed, which means you  don't have to worry about pre-generating all of the random values in the world or about  the sizing, no, no. This Go routine will only be called upon when it's needed, which means  having a sequential number generator that can be used across all of your Go routines  on a single machine becomes very easy. Of course, the problem becomes very complicated  if you want to have a number of machines or a whole cluster or a number of clusters in  different data centers, but this problem is beyond, this problem spans many run times,  which means it's beyond what a programming language should solve by default. But if you're  still on a single machine, this gives you a generator. You can, of course, do other  stuff in here. Also, if you want to have a single, I don't know, file interface or a  single database connection, you can use that construct as well. Multiple channels at once,  because, well, it is good we've read from one channel, but what if there is a situation  in which I want to read from a channel, well, maybe there is this connection that will give  me something, maybe there is this connection that will give me something, how can I express  that? Well, Go has a select statement, which will just, it will advance and it will execute  the code that's associated with whichever case happens first. So you don't have to worry  about expressing that with ifs or doing nested loops with, or while, or, well, yeah, looping  and checking if something is available in the channel over and over, it's available as  a construct, which means you don't have to worry. Providing a default, there is a construct  for that, and there is a timeout built in. How many times have you written a read from  a socket or from somewhere, and then forgotten about the timeout? I have done that many,  many times. This still doesn't solve that problem, because if I forget to put that in,  I will forget, but it's easy to specify it and it's built into the construct, so there  is nothing extra that I have to use that will be taken care of and that will be guarded  by the runtime built in. Services. So if assuming your software has, you're doing a microservice  based application or just a service based application and you want to create some services  and the service has to stay available, but then comes the problem of how do we shut down  in a graceful way? Because that's a nice way to shut things down, especially if you have  connections to other services so that you don't leave them hanging, so that things don't  have to timeout, so that you don't waste resources. Well, you can create a service and, well,  spawn it and wait for it to do all the work, and then again, you can use the channel to  finish all the work, to signal that you have, well, either completed your work or you're  ready to die, which means you can use a quitting kind of notification like in here. So make  a channel, well, do the work for three days or any amount of time that you need. You do  the cleanup and then you, well, you might report, this is, well, just sample so it returns,  it prints out to system out that you're done with the cleanup and then you quit. And then  when you have quit and the cleanup has happened, well, your governing piece of code can finish,  exit in a nice way and you're done. Buffered channels, because I mentioned that there are  unbuffered channels, we skip the buffered ones for a reason. They are asynchronous. They  will return a zero element when empty and they will only wait when they are full. So  a buffered channel, a queue with a bounded size, your intuition guides you well. I've  been talking about channels for more or less 15 minutes. Somebody would ask, are channels  the ultimate gold, well, hammer, the silver, the golden bullet, whichever mythology you  want to follow? And of course, well, the fact that you can express a lot of the problems  with channels doesn't mean that you should. So Go also has the usual constructs, right?  Like mutexes, like locks, like atomic operations. And those are screenshots from Go documentation  that's available online about packages, about sync and sync atomic packages. So those functions,  those instructions are built into the, well, already available to you. You don't have to  write them yourself, which means you don't have to create a double nested locking or some  other idioms that you hope that they work, but they really don't. It's all, they're available  for you. And last thing, if memory serves me well, are ranges. So a way of operating  over channels or slices, which is a go way of sync arrays from a programmatic point of  view. And the thing is, you can treat both in a single way. So you can treat a slice  or you can treat a channel similarly, and you can just treat it, well, put that into  the range instruction so you can do a for loop over each. And then you don't have to  learn two different syntaxes because those things are look the same and operate the same,  which again makes your software nicer to read, makes everything, well, makes life better.  Packages, well, I mentioned that Go has packages when I showed you the package declaration.  When I see what's available, I will see that there is a bin directory, there is a package  directory that will also generate things for specific architectures, which should lead  you to a question, what about other architectures? What is the architecture support model with  Go? Well, by default, if I compile a program, a piece of software on a Mac, I can put it,  well, give it to a different Mac and it will run just fine. Of course it will not run on  the Windows, of course it will not run on a Linux, but if I compile it on a Linux, I  can get that binary because, again, static linking and ship it to a bunch of other Linux  boxes and it will work, which is quite amazing. Can I cross compile? Of course. Can I do other  funny things while compile against sources that have some C integration? Yes, of course.  And I mentioned, somebody even asked about packages and dependencies and I mentioned  that Go already has a tool for that and I can put imports that pointed packages that  hover somewhere in the Internet. And that's actually a very funny thing because it's not  specified in the language. So there is, there is, how Go tools should resolve that, but  it's assumed that Go tools will be able to resolve addresses like that. So if we go to  here and we uncomment this B. And then we do go get and we hope that, oops, Google code  doesn't like us anymore. Oh, well. What Go get would do is get the code from Google code  if Google code would actually play with us today. It would download all the sources,  it would download, well, the whole package. So if you're used to binary packages being  shipped around with tools like Maven, with tools like Ant, with other tools of choices,  then Go does not the case. What you will download is the source code. So if you want to examine  how something has been written, you will get to see exactly that. What it also means,  you will download the source code with tests, assuming the tests are there. So you can run  their tests if you suspect a bug. If you want to see the documentation, documentation is  part of the source code, it's embedded, which means you get to see it as well. Which is  an absolutely amazing concept if you're in a company that values open source software  and it makes working with proprietary libraries very awkward. But, well, luckily, in my history,  I haven't had a situation so far that I had to connect to a very proprietary library without  having access to source code in Go. Maybe because the language and the ecosystem are  quite young, maybe the mentality has changed, maybe the other environments are more frequent  to exhibit such behavior. So Go gets, well, we've tried to run it, it didn't work that  well, so we'll skip that part. What looks bad? Well, if you want to have JSON structures  and JSON kind of binding, the way that you can express that in Go looks a bit ugly to  me. I'm not a huge fan of the syntax or because it connects your type definitions with how  you should parse your data. It links two things together. It also means that the structure  of your JSONs starts to live in your source code, which means you can't change one without  the other, which is not the luckiest of choices. On the other hand, there are quite popular  libraries that allow JSON and other format bindings for many languages out there, JavaScript,  most probably.NET, which means, well, that's something people look for. Before you leave,  before I say thank you and do you have any questions, if you wanted to learn Go, if you  wanted to learn something more, of course, there is the excellent website which has a  lot of tutorials. It has some of the tutorials you can actually write code and run them through  your browser. But if you'd like to do it the classical way, get a book. This is the book  I would recommend. It's written by, well, you can see the authors here, but I would  say that it's quite amazing. It's very comprehensive. It's exactly as thick as your Kindle is or,  well, I haven't seen the paper version because I don't buy them anymore, but this will be  my book of choice. And last thing, what ID's can you write, should you write Go in? Well,  pick your favorite text editor. You don't really need anything fancy. If you like Visual  Studio Code, it has excellent Go support, including all of the additional tools that  you can use like Linting, like import or automatic importing, like automatic formatting on save.  You can have that all in Visual Studio Code. I started writing Go with Sublime and I like  it. Well, I love Sublime for that. You can, of course, do it in Vim. You can do it in  Atom. You can do it in most of the other ID's out there as well. Because the language is  very simple because the syntax doesn't have any special cases. It's not the type system  is, again, simple, which means creating tools doesn't look that complex. But then all of  the complexity shouldn't be in the software in how it gets written because it's not the  smartest people who write the code. It's about the problem that gets to be solved. So with  that, I will ask you, well, try to download Go, have some fun, and Go code. And if you  have any questions, just try to wave your hand. Yeah, there is a question.  Yeah, so handling errors by looking at return codes, yes, the error variable that was returned  from some of the instructions is if it's nil, if it's empty, that means that there is no  error. If it's not nil, it should have the error on information in it. It's not error  codes as in integers comparing that to things. You can use types. Well, there is a type system  for your benefit here. But yeah, this is the approach here.  How do you protect from errors that are not thought about or nil or inference exception  or the equivalent or something like that? So how can I protect myself from errors that  somebody didn't think about? So if I ignore it, well, my software will explode the same  way other pieces of software will explode. Because, well, if it's the second parameter,  somebody forces you to use it. Yeah. But I mean, let's say in Java, you would probably  around some critical stuff have tried something and then catch everything and at least log  it and try to be ready to process the next request or whatever if something goes wrong.  So how would you handle that? Well, there is a way which I don't have  that example in the slides, but you don't have to assume if there is a tiny error in  one of the small go routines that something really not important that will crush your  application. No, there is a way to protect yourself from that, of course, but it's just  not in the slides. ID support, well, we've covered. Debugging  is also possible. C integration, well, how many minutes do we have? Three.  Is anybody interested in C integration? No. No. No. Good.  So with that, I'll say thank you. Enjoy lunch, enjoy coffees, enjoy all the great sponsors  and everything else in the conference. It was my pleasure to see you and, well, experience  also and I'll be available if you want to have any more conversations. Thanks.  There is this voting machine at the end. If you can please press the green button that  is Aftertaste to start voting. Just do 1-0-0.
Go_-_one_language_you_should_try_-_Andrzej_Grzesik_0_59.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_60_539.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_540_1319.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_1320_3215.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_3216_7967.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_7968_8255.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_8256_9563.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_9564_14579.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_14580_17039.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_17040_17087.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_17088_17291.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_17292_18191.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_18192_18527.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_18528_18623.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_18624_20591.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_20592_20843.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_20844_22607.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_22608_22655.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_22656_23339.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_23340_25571.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_25572_25619.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_25620_33335.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_33336_43559.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_43560_43655.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_43656_43799.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_43800_43847.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_43848_43943.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_43944_43991.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_43992_44135.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_44136_44183.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_44184_44231.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_44232_44363.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_44364_44411.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_44412_44531.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_44532_44735.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_44736_45335.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_45336_45527.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_45528_45635.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_45636_48059.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_48060_60407.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_60408_69935.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_69936_70895.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_70896_74555.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_74556_74651.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_74652_74699.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_74700_74831.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_74832_74879.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_74880_74951.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_74952_74999.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_75000_75395.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_75396_75443.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_75444_79055.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_79056_80075.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_80076_80639.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_80640_80963.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_80964_84947.png Go_-_one_language_you_should_try_-_Andrzej_Grzesik_84948_85181.png