 So, hello everybody, please sit down. I would like to remind that you can join the contest for cool prizes tomorrow, and please vote for lighting talks on this section. Our next presenter is working for Redhead on OpenShift and Kubernetes, and he will tell us something about the benefits of transitioning from Java to Go. Please welcome. It's nice to see you, that so many of you are interested in switching from Java to Go. That's very comforting, on one hand. I hope that this many of you will be so interested in doing so after my presentation. Okay, so the title of my presentation is How a Java Dev Benefited from Transiting to Go, or in other words, that's Gopher versus Duke. I do hope you guys know both of the logos. There's no cool story behind Go logo, unfortunately, so I won't tell you anything. They just wanted to have something, and they come up with a Go for it. Okay, I'll try to speak at the beginning a little bit about the benefits from transitioning. Then I'll do a kind of short comparison of the languages, mostly focusing on what Go gives you versus what Java does not, and I'll try to summarize that thing. But before I start, let me tell you a little bit about myself. Why am I here in the first place? Why am I knowledgeable enough to speak about transitioning from one language to the other one? So, I've switched twice so far, where I really switch after working for a good couple of years from one language to the other. I first started with CC++ over 10 years ago. After working for a company about envoy-related stuff, I switched to Java technology, and I stayed with Java for over seven years. And then two years ago, Jirka Folta came to me asking if I would not want to work for Red Hat. Although initially that was supposed to be Robbie, thankfully it turned out to be Go in the end. So, there are two big switches that I've done in my life so far. And I've also pointed out that I know Python, and Python is with me since my university, so that would be almost 15 years in a year or something like that. Which is crucial because I have some dynamic languages interesting in my head, and certain things that I find useful in Go might come from my, let's say, affection to dynamic languages. And as it was pointed out earlier, I'm working on OpenShift for Red Hat. Okay, well, when I started first thinking about this presentation, what I'm going to say, what I like, what I don't like, I started thinking, but okay, that will be my opinion, but I would like to know what our folks think. And it appears that there are much more Java developers, or X kind of Java developers, in the OpenShift team that I've ever expected. So I ask them what they think about switching from Java to Go. So they wrote me, don't switch. I miss debugging, and now in my interfaces, and generics, and collections, and good logging frameworks, I miss machine-driven refactors that just worked. And that was when we were doing some really serious refactoring on the way. And it was like two weeks ago. All right, I asked more. So the other friend of mine wrote me this. I do think that Go format, I'll be talking about it in a minute, was a brilliant move. Having to never think about those issues has been awesome. Those of you who are using Eclipse and have automatic form letters might have a clue or might suspect what this might be. And one other wrote me, I miss it. There's plenty I miss about JVM. And what he says that he secretly loves Java, pretty much everyone says exactly the same thing. So having said that, how many of you is Java this? More than a half a room. How many of you have more than one year experience in Java? Okay, all of you. How many of you have more than five years experience of Java? Mostly. Mostly. Okay, that's nice. More than 10 years out of curiosity? There are a few. That's impressive. Awesome. Okay, but we're going to do Go. So what I like, and this is totally subjective opinion. This is what I like about Go. I really like the types. They're simple. They're expressive. There's no magic behind it. I like syntax of Go because it's variable. And it points you somewhere between Java, C, kind of like that. I really like the data structures. I'll be talking about that in a minute and interfaces about how they work. And this is a little bit of magic there. The concurrency. The concurrency is built into language. The concurrency, I would even say, is a first class citizen in the language, which is very crucial for building on top of that. There's built into the language testing framework or a package that is provided by the language. There's a garbage collection and memory management. That is familiar to pretty much every single Java developer, right? Hopefully. Okay. What I feel about Go is the package, the code organization. Go organize code similarly to what Java does. Java does is you usually do com.mycompany, that my super project, that my package, et cetera, et cetera. So Go is similar, but instead of mycompany.com, whatever, whatever, it uses the source repository name. So my package, if I put it up on GitHub, will be called GitHub.com slash, my nickname, that was a couple of slides before, slash name of my project, slash name of the package that I'm showing. So that is similar. So I kind of, the error handling, the error handling, I'll be showing that in a moment, is I still not sure if I like it or not. So I put it in neutral zone. And so that it's not superb and always, there are some quirks in Java. In Go, of course, in Java as well. So the biggest problems every single person will tell you about when you start working with Go is the dependency management. Strictly speaking, because there's none. And the other one I wrote out, the bugger. How many of you use Java the bugger? With Eclipse, right? Mostly, IntelliJ or whatever. So generally speaking, you know what I'm speaking about. It's so just like, and I'm attached to any single process that's running either as a single on or in a remote machine or whatever, right? So everybody, every single person I was speaking to, misses the bugger. And I can totally understand why. So having said that, let's jump in. I'll get that. Come down. I'll shut you down with this scarf. You're going to have two for your partner. OK. You know everybody knows that, right? The Hello World. You need to start with something. So in Java, you need to write tons of words, let's call it that way, to have the program print the Hello World for us. And then when I'm done with that, I need to do two magical commands to actually run it. I'm a CLI guy, so I'll do that. I don't want to hear that. Yeah, but in Eclipse you just press F11, F5 or whatever else and it just works. Nah, I don't buy it. You can't do Eclipse, F11 on production or on a server. That won't work, right? We all do CI, CD and stuff like that. I'm looking at everybody. So how it's done in Go. There's the package declaration. It won't allow you not to do it. It will be a compilation area if you don't provide one. There's the import section, similar to what you have in Java. Except that if you have multiple in Java, you'll have multiple import, the name, import, name. They were smart. You don't have to repeat the import word here. You'll just do import, open a bracket and then you name all the packages, close the bracket. That is handy. You don't have to report a couple of times. And there's the function name. Is it simple, right? Like fun, main, can I write compared to public class hello world, public static void mainstream. I never could remember the thing. Yes, there's Eclipse. I know it will do that for you. But I'm using very simple editor. There's like most of us who are working with Go are either using Vim or I'm personally using Sublime. But these are really simple. They don't do anything for you. Just simple auto-repeat, nothing. That's it. And there's more magic going on. How do I run it? I'll do go run main.go. That's it. There's no compilation, sort of. Go is smart enough that it will do that for me. So I don't have to. See? One again. I saved. I saved. I'm not going to count how many words I've saved in the upper. But I've saved at least one command during the compilation just to run it. Nice, isn't it? Okay. But you might ask why? Like there's like tons of languages out there, right? So there's a nice quote if you go to FAQ for the Golang, where they says, no major system language has emerged in over a decade. But over the time, the computing landscape has changed tremendously. So what they did? Let's build a new one. So the three guys, really smart one. I highly recommend either reading their books or watching their presentations. Really worth it. So Robert, Rob and Ken come up with the idea that they want to have new language. The new language has to be fast. By fast, I mean it needs to be super simple and super fast to create new applications. Why? The market is very demanding. We want to write software faster. And if I write software faster, I want to also compile faster, right? That's obvious. There's no type hierarchy in Go. And it's although Go is statically typed language, as I will show you in a minute, it is written in such a way that it gives you some freedom and it pretends to be lightweight language in those terms. They come up that the language definitely needs a good garbage collection and memory management. Whatever was done so far is okay, but we could do better. Why not? Always everybody says that, right? When somebody is trying to invent something new, it's like, I'm going to do it better this time. Yeah, as I mentioned before, the language has a built-in concurrency support. And it will target multi-core machines. Pretty regular, nothing fancy with that. Interferences, there are. There's no inheritance. It's... You can... I'll get back to that question. Once I will be talking about structures and interfaces, I'll try to address your question. But generally speaking, no, there's no inheritance. There are interfaces, but they work magically. So, the types. You could generally expect that a language will provide the usual type. So there's numeric types, which is int. There's int64. There's un and stuff like that. What you might find different from Java is that the order of definition is switched. You first define the name, then the type, and then the value. These are all valid variable declaration. So in the first one is the longest possible one. You're not going to use it. Trust me. It's too much writing. The second one, what it does, it's... Declare a variable named h. That will be an int. And then I'm assigning 35 to it. The third declaration, this is what you're going to use most often. Note there's a column before the equal mark. This means that I'm creating a variable declaring it at the same time. This is called the short declaration. A short variable declaration. What is cool about it, you don't have to specifically say, this will be an int, and then I'm assigning the int. The compiler is smart enough to know that this is what I'm assigning, will be the type of the variable. You don't have to do it manually. Java.7 did that with the diamond operator, kind of. So they went even further. On the right hand, there could be a function or a method or a structure, it doesn't matter. As long as the compiler can introspect the type, it will do that for you. There's one other quick about the variables in go. Is that you cannot have unused variables. Something that usually Java people will find out with PMD or textile. Go compiler does that. You cannot have unused variables. It will complain about unused variables. But there's a solution to that. There's the underscore. I'm assigning age to underscore, which means I'm tricking you that I'm going to use that one. So that's one option, or comment is the other option. The unused variables, error warning in compiler, also applies to imports. If go compiler will find out that you have unused import, it will complain the same way. But sometimes you want to have the import to happen just to have the initialization of the model to happen. Then you use, so you will find pretty often, if you go, for example, through origin or Kubernetes code, you will find modules being prefixed with a underscore. Additionally, there's RI, very simple, and maps, maybe little quirky, the syntax declaration is, but it's not that bad. Although this, if you try to do maps of maps, then it gets quirky. You need to spend a minute or two to figure out what is actually where, but you can't have the word ideal. Going further, I think I need to speed up. Type death. Do you know what type death was in the sea world? Could, generally speaking, declare your own type. So go does exactly the same. I can define that my type by size will be a float 64. Then I'm going to define some constants. The iota, that is cool stuff. Nobody has that one. No other language. You can use that to create nms. It will be first used. It will use number zero. And then each time it will be used. See, it is used in MB, in megabytes, gigabytes, you see this? It's empty, right? That's the magic of go. It will do that for you. It will, generally speaking, copy the last statement a couple of times. You don't have to do it manually. It will do that and create the nms for you. Speaking further, the RI. You use it as normally in Java you would. There's one additional structure that was introduced in go. Because by default Java RIs, go RIs are not modifiable. You cannot modify them. So there are slices. Slices is a direct access to a certain area of data of an RI. So for example, if I create a slice from my array one to three, that will be starting from first element up to three, but exclusive. The first one is inclusive. The third one is exclusive. To be easy. No, but this formula is used in other languages. If you're going to go play with Python, it is used over there. So there's nothing new. I think so. Yes, yes, yes, exactly. So this is a pattern that is generally applicable. Yes, slice. No, if you define a slice, you will access the slice by their indexes. So for this slice, index zero is the two. Index three. You can think of it as a substring as he told you. It's like a sub array. The name slice is just that. That basically means just that. Skipping fast forward. Conditionals. There's nothing magic about conditionals, except for one thing. As you see, there are no parentheses around condition. You can have them. Nobody will tell you not to. But go for matter, if you run the go for matter over your code, it will be removed. It's not needed. Even if you have multiple conditionals in an if, not needed. But the curly braces, they're always needed. Even more. The curly braces has to be at the same line the condition is. If you put the curly braces below it, it will be a compilation error. So, yeah. The second piece of code, what you can see is, you know, if you do for loop, you can use that variable inside of the loop and nowhere more. The variable declaration, condition, and incrementation. Here you can create and check immediately the variable. So, generally speaking, check a file. You get an error. You check if the error is not nil and you do something with the error. That means the error will not exist outside of the scope of this block. How it is used? For example, when you access a key in a map, that operation returns two values. The first one will be the actual value. The second one is whether the key exists or does not exist in a map. This is needed because sometimes default values, let's say, I'll say it differently, you're going to get here a default value always, even when the key did not exist. For example, if I have int from 1 to 10, and I'm going to get 11, 11 key, and I'm going to be expecting some value, I'm going to get zero, but the key was not found. The zero is not a proper value, so you should check that you're okay, actually, the existence of the key in a map. More or less, I hope that's clear. I'm going to throw you at you a couple more stuff like that. There's four loops, and that's it. There's no DUI. How many of you were doing this quirky exams that you need to switch from during your exam at the university? This is DUI. We wrote the DUI as a for loop, or differently, or the other side, right? Nobody does that. The Go creators come up with, we don't need DUI, because basically, whatever you need, you can do with a simple for loop. That's what I have. I have the for, which looks exactly the same like in Java, except for there's no parenthesis around the first line. Simple as that. There's a range operator. That's cool. There's nothing like that in Java, but there are stuff like that in Python, for example. This is what I like. This is what I was talking about. There are certain things that they did. They took from dynamic languages, Ruby, Python, and others, and they introduced it into Go. So this is one of the things. You can range over a map. This is generally speaking for each. Well, you're getting, with one operation, key and the value. What is tricky is that if you go through array, you're going to get two values as well. One will be the index, and the second will be the value. And if you don't assign the second value in the for loop over the array, you're going to get just the index. It's not a compilation error, because you can get just the first one. But you won't get the value. This is tricky. And I know that a couple of folks had some problems with it. Seriously? I'm going to skip QA. They can always catch me afterwards. The switch is simple. There's no magic in it. I'm going to speak faster. So the upper switch is normal like in everywhere else, except for one thing. Generally speaking in Java, what you do is that in every case, you do break at the bottom, right? Because you all know that, right? That the default behavior is, if you enter in a case, it will just go full through from that point. So Go does not do that. But if you want to have that behavior so that the case is an entry point and it will go full through all the cases, there's a keyword, fall through. But who used that? I personally, over more than 10 years, I haven't seen a code that is actually using that functionality. There were always breaks at the bottom. Okay, so that's one thing. The other thing, you can actually put the conditional laws inside of the case. This is not possible in Java, right? I think at least it wasn't two years ago when I... One other interesting construct is a type switch. You can check the type of a variable passed over an instance with a switch. One additional comment. It is very endiomatic and go to use switches instead of ill files. Very frequently. Function definition. I need to... Jesus. Too much of it talking. Cool thing. You can return multiple values. There's nothing like that in Java. I've always hated it. I did nasty hacks. What I did, it was like define an array of these things because then the first element is... It doesn't mean this, the second element means that and the third element means something different. That was so hacky and it was so bad and I shouldn't even speak aloud that I did that, but I did. Or you could create your own object. Seriously, I'm going to create an object just to return two values. Thankfully there's a key value that you can somehow hack over. I usually ended up creating my own type that allows me to pass two elements. Here I can pass as many as I want. Okay. Skipping further. Even more. If you define a function, you can name the parameters, right? That's what you do usually. But with go, I can even name the return variables. What it gives me is that I'm going to have those variables assign default values, which will be, for result, it will be an empty structure, for error it will be nil. And I'm going to use this, but here I'm finishing. I'm not even writing what I'm going to return. Go is smart. And it will take the last values of these two variables and it will put it for me here. But, oh, I don't know. Not frequently used. Since function are first class citizens in language, you can assign them to variables. How many times do you have to write just one function to satisfy an interface, to pass an object, to a function? Oh, my God. Okay. The thread is the runable. You just need to type run. Like thread, run. You need to type. Implements are runable. There's the almost anonymous class inside of it. Now you don't have to do that with here. I'm going to just pass the function whatever I want and how I want. And here's the error handling in go. There's no exception. Unfortunately. So this is what I think. I'm still not sure. Here the OS open path will return the file object and an error. And this is very idiomatic. You're going to find this tons of places. They're going to return either an object and an error or just an error to notify that something went wrong. And there's more cool stuff. The defer. That is awesome. How many times have you forgotten closing a file? Closing a socket? Closing connection to DB? Whatever. None of you? I don't believe you. I've done a couple of times for myself. So what they come up with is that right after I open a file I'm going to say defer. So put it for later. If I close. This will happen at the end of the function. And it will know how to close the file. Because it will just close this one. It doesn't matter how many returns I will have down the road. It will do that for me. Even more. You're going to have multiple differs inside a method. Yeah. I was given a hard limit. How many times? 24, 35. That means like a minute per slide. So the differs. This is a tricky. But by that later or earlier today is that they are executed and last in first out order. So you need to be careful with that. Structures. Okay. So you have classes in Go. You have classes in Java. You have structures in C. Or Pascal if you ever programmed that one. And this is generally speaking kind of like a class. You just define the field they want to have. And that's it. I'm going to create my structure with the new keyword. Or I'm going to just initiate it as an empty. The new keyword allocates memory and creates a pointer. Initialize it with zeros. And creates a pointer for me to my structure. Or you can just this and that. Go generally speaking initialize everything for me. So that's super cool. You don't have to worry about those. There are exceptions to the rule. The maps, channels, and so there's one more slices. Yeah. You need to use make because there are underlying structures that he needs to initialize for you. So the make keyword you're going to use that one a couple of times. Interfaces. That will be address your questions. Here's my interface. And this is how I implement the interface. See my struct implements the interface. You don't know how you don't because I'm not going to say because you have glasses. I can't say you're blind. That would mean but I will look carefully set string error. Fung set string error. That's it. This is how you implement interface and go. You just implement the methods that are named in an interface. And that's it. Now I can use my struct as in my interface. That's it. This is very crucial because you'll find a lot of small interfaces. One method, two methods from which we will actually compose. So there's no inheritance. You know what I can do? I can embed. You know how? I'm going to put either inside my structure the name of the interface as a variable then I will have to prepend the variable to access that or not even using that. And that means that I'll have the structure embedding inside of my structure. The same applies for interfaces. More or less. How many times? Five minutes? Yes, six. Okay. I'm going to go quickly through concurrency. That is the biggest problem and I have like six minutes to cover that. How many of you have problems with concurrency? Problems with writing proper concurrent code. I don't believe you. You're lying me again. So that is a pain in the ass, isn't it? So they come up with the slogan, do not communicate by sharing memory, instead share memory by communicating. They come up with something that is called goroutines and these are cheap. Trust me. These are super cheap. You can run 100,000 goroutines on your computer. You won't even feel that one. These are similar to goroutines in Python. It means that generally speaking if you run a goroutine and it will be blocked by I don't know IO, whatever, the goruntime will switch because there are not that many system threats as the goroutines there are. So it will be switching context between goroutines so that I can feel as you have that many power. And these are really, really cheap to launch. These cost a couple bytes on a stack. That's it. Nothing more. So how you run a goroutine? You prepend a function with the go keyword. That's it. It will close itself. You can do whatever you would with it. Quick skim through channels. Channels serve for synchronizing and go. You can have two types of channels. Channels can be unbuffered, which means whatever I send can be immediately available on the other end or they can be buffered. You can use the buffered one for synchronizing, creating some limiting throughput. But that's rare cases. Usually you use unbuffered, which means I have one goroutine going down, I have the other one goroutine. This goroutine is going to send. This goroutine is going to go, go, go, go. This one's guy waiting because I'm trying to send, but nobody is still, nothing is getting from the other goroutine. It goes, okay, it reaches, it reads. I am blocking this one and I can unblock this one. So you can use channel to synchronize. This is what was meant by the, yes, exactly. But these are very simple. In most of the cases, you'll end up using just the channels for your entire synchronization. That doesn't mean that Go does not have others, other primitives. There's a sync package. You can find some forwards, really advanced stuff. There's a sync atomic package that you can have atomic operation and lots of really good stuff there. But the problem is that in most cases, the channels will be enough for you. I can't even speak more. Here's a simple example. Here, I'm using a channel so that, because by default, if you run a goroutine in main, it will just exit. Doesn't matter. It won't wait for the goroutine. It's a different goroutine. If I want to have in main to wait for the goroutine to end, I'm generally speaking, I'm sending one to channel, and the main program is waiting for this channel to be received. It's a little bit quirky at the beginning to get used to reading and sending value to channels, especially if you're trying to send out, there are receive and send only channels, which makes a little bit complicated stuff. But as the name suggests, it's okay to use those. So sometimes there are multiple hours, and these are sometimes hard to parse. But on the other hand, it's really cool. The testing package. I thought that somebody was asking me something. The testing package, it is build and go. What you do is you write, let's say I have a main.go. You usually end up with main underscore task go. The tests are in the same directories as the main program. So there's no task source Java, like in Java, but you rather have both at the same place, which is handy. And they are not placed in the final binary. That's very important as well. How you write a test? You prepend your function with the test keyword, and you pass the testing.t, which has some values that you might use for logging, erring functions, and stuff like that. Yes, that was a pointer. I didn't have enough time, and I have like one minute left. This is the last part. I know I'm almost done. This is the last part. So this is what I don't like about go. This is Godep from our origin code. You want to guess how big the code is? How big this file is in origin? We have good couple dependencies inside of go. This file is 1600 lines long. It specifies the import path and the version, and we keep the entire subreport kind of like under our... If you go to the open ship dash origin repo, you'll find a Godep. That's a Godep.json file, and underneath you'll find underscore workspace. Underneath, you'll find all those packages that we've entered. That is so wrong. The debugger. One last thing, and I'll answer all the questions. The debugger. Yes, there is. Thanks, Derek Parker. Unfortunately, it's like GDB. So this is a session from a debugger. I was trying to launch one program and debug it. So as you see, it's very nasty. There's no something like Eclipse or stuff like that. That is so not cool. And the biggest problems are go routines. The go routines are super cool to write, but at the same time, they're super hard to debug. Having said that, thank you very much. If you have any questions, I'll be at the lobby or something like that. I can always ask more questions. Thank you, Maje. I have a quick announcement. There will be no lightning talks here, but there will be lightning talks in the D section. And you still have, I think, 10 minutes to go vote there.