 Hi, everyone. I'm Kat. I'm a software engineer, and I've doubled in a few languages over the years, probably as most of the people. I did a ferment of Java. I did a bit of Bash, did a bit of Ruby. But I've been a PHP developer predominantly for the last seven or so years. So this used to be my first language. And I still very much enjoy writing PHP. But I picked up Go two or three years ago as my second main language, and I kind of got hooked. These days, it's actually my main language at work. I no longer do PHP full-time. I work at Monza, and we're building a modern bank fully in Go. But I'm not here just to tell you how awesome Go is. This is after all a PHP conference, so it wouldn't be fair. But hopefully, you'll get a good idea of what Go is like. And what I'm hoping to do is convince you to learn more than one language. And I want to show you how this can change you as a programmer and make you a better programmer. Based on my experience with switching from PHP to Go and then for a bit back to PHP. So you might be thinking, what the hell, Cat? PHP solves all my problems. Well, what does it really? Sometimes developers who only know one language will try to do everything in that one language. And sometimes that can cause you unnecessary grief. There might be a better tool out there, but how would you know about it if you don't know about it simply? So just like you wouldn't use a screwdriver to hammer a nail into a wall, maybe you shouldn't try to use PHP for everything under the sun. Like, it's not a multi-tool. Sometimes it is in fact called the double-cloth hammer, where it sort of does a lot of things okay, but sometimes there might be a better thing out there. That's okay, no language is perfect. But that doesn't mean that you should just stick to the good old hammer for everything. Sometimes you'll do just fine, but sometimes you'll just really limit what you can do. So learning another language is just like adding a new tool to your tool books. The more tools you have, the more things you can do. And you can do things the right way. And it's a really great way to learn new concepts and new ideas and for how to solve things. And we see this in languages themselves. Languages borrow ideas from each other all the time. And like most of the things, most of the tools in PHP have been inspired by things in Ruby, for example, like Composer. And PHP used to be procedural, and then Java popularized object-oriented programming and then PHP became object-oriented. So it's really worth keeping an eye out on other languages just to keep up to date with the latest trends. So let's have a look at Go. It's sometimes called Golang. The actual name is Go. Golang is just kind of a way to help you Googling for stuff because if you Google for Go, don't try that. It's gaining in popularity now, but it's actually six, seven years old. Go 1 was released in 2012. We're now at Go 1.11, and Go 2 is in the works, Generics being one of the main features that are remote to be shipped with it. It was written at Google by the three gentlemen here, Robert Griesmer, Rob Pike, and Ken Thompson. So pretty big names in computer science. Go is compiled as statically typed language. It's a little bit like C, but with the nice things, like memory management and garbage collection. So you don't have to allocate memory yourself. It's great. And one of the main selling points of Go is the built-in concurrency, which we'll of course look at in a minute. The biggest difference between PHP and Go are of course the mascots, the logos and the derived mascots. It's gophers versus elephants. They come in lots of different shapes and sizes. I have a small sample here. I actually managed to get a matching set now. The width of the gopher and the elephant is about the same, but gophers are about 20 to 25% tallers, and the eye size is obviously the biggest differentiator. I'm only kidding. One of the biggest differences is how you run Go apps versus how you run PHP apps. PHP's an interpreted language, so you need something like a server with a PHP interpreter on it to run your program, because that interpreter needs to take the code, interpret it, translate it into byte code, and run it for you. So that translation into machine code will happen on the fly as you're executing your program. Go on the other hand is a compiled language, which means that you first compile the program for the right architecture, and then you just run it like any other binary on your system. There is nothing else that you need to run a Go program. Why is this important? Because it affects the speed. Compiled languages are generally faster than interpreted languages for the obvious reason that you do the work of translating it upfront, translating it into machine code upfront, so you don't do it at one time. So here I have some benchmarks for a simple hello world application written in Go, Node, and PHP. These are fairly old. I think it's PHP 5.6 and Go 1.4, but sort of the trend these days is about the same, so that's why I didn't necessarily bother updating this. So on the left, it's Nginx serving a static file. Nginx is written in C, so obviously it's the fastest. And you can see that the first two columns on the left are compiled languages. It's Nginx and C and Go. Node.js is impressively close to Go, though. Then we have HHVM and Vanilla PHP. Vanilla PHP on this graph is about two and a half times slower than Go, just under two K requests per second. These are just some benchmarks that I found on the internet. I haven't reproduced them myself, but that was exactly the feeling that I had when I started using Go, that it just felt so much faster. And PHP is sort of interpreted and it's built for the speed of development. Go is compiled and it's built for runtime speed. That was the primary driver behind everything. Go compiles is sometimes just a few milliseconds or seconds, it's rarely a minute. So it doesn't really slow down development either. So let's have a look at some Go code. This is a twist on the classic Hello World program. So we have a string. Hello, is it something you're looking for? And let's say we want to print out T or me at random. So you can see where this is going. The syntax is obviously different to PHP. The format of Go apps is standard across all Go applications. There's just one right way to structure a Go apps and that's it. Whether you like it or you hate it, you just have to stick with it. And there was a tool called the Go formator that does this for you on every save. So literally any Go program that you take from GitHub is gonna have the exact same structure with curly brackets on the same line. So you just save all that time arguing about tabs versus spaces. Go use this tabs but you can do soft spaces. Or which line does the bracket go on? Which is really cool. Yes. The very famous saying is that Go formator is the tool that everybody hates but nobody wants to go without the Go formator. So it's like a love and a hate relationship. But you get used to it pretty quickly. For me, it took me about three weeks to kind of get my eyes used to the Go format. So in Go, you need to declare the package at the top. It's a little bit like namespaces in PHP or like modules in Ruby. And then we need to declare the libraries from the standard packages or from any other libraries that your code will use. Luckily there is a tool called Go imports that will do this for you on the fly. So you don't have to type this out by hand. And then you have our main function. Every Go program has to have a main function. You might have noticed that there is no public or private in front of it. Go has a simple convention that functions, except for main, but functions that start with lower case letters are sort of like private functions visible just inside the package. And then functions starting with the capital letter are visible outside of the package as well. Except for main, main is always global. And this is true for function names and also variable names. And this is how we declare a variable. Each variable has a type in Go and you can't type Jaggle. It's strongly typed language. This is actually the long way of declaring a variable, var, name, and type. There's also a shorter way and Go will automatically work out the type of that variable based on the value that you're giving it. So here we are creating an array of two strings, me and T, and Go will automatically work out that this is an array of two strings and that's the actual type. And you kind of end up doing this most of the time when you code in Go. So say we want to print out five of those sentences in a row. So we have our for loop and notice that there's no brackets around it, unlike in PHP. There is also no semicolons at the end of the lines. So there is a little bit less visual debt which some people are really passionate about. But yeah, some people could argue that this is a little bit cleaner because it doesn't have the braces in the semicolons. So let's run our program. We get five sentences as expected with the random mu or T. So to do that we can call Go run which is again a tool that you get when you install Go. And that will run our program but it will not actually output the binary for us. So if we want to create a binary then we have to call something called Go build or Go install. And this will output a binary file as shown here in red. So this was compiled on Linux. So it's just a standard Linux binary. And then you just run it like any other binary, dot slash lionel and you get the same result. So I mentioned already using Go run and Go build and Go install and Go FMT formator. And these are just some of the very, very many tools that you get with Go out of the box. And I think this is where Go wins over a lot of the languages because it's such an easy setup. It's the setup where you get everything you might need out of the box when you install Go and if you're on the Mac, you just do brew install Go and that's it. In PHP, if you want to install PHP unit you have to get the extension somehow in your system and you have to tweak the any file and you have to set it up and then the PHP unit XML file. So there is a bit more work and you kind of have to do this for every single project. And so it gets a bit tedious, a bit boring. Whereas with Go, once you've got Go installed on your systems, those tools work globally for all your projects. So it's just install once, use all the time for everything. You get a formator, you get a linter, you get tools for testing, you get a Godoc, which is a documentation tool. You get all the tools for running your program and you also even get tools for profiling your program out of the box. So when I first started using Go, I was like, oh my God, this is amazing. So one of the things that used to trip people up and this is about to change in Go, so I still left this slide in but this is kind of how it is until now but we're actively moving away from this and it's this notion of the Go path and you might have heard some rumors about how people are confused about it. So that was the idea. Initially, the Go had an idea that all your code, all your Go code will live on the same space on a disk and the whole dependency management where the Go get tool pulling down your dependencies, that was based on the fact that that tool knows exactly where to pull those dependencies because it kind of has a knowledge of the structure on your disk. So that was the official way of developing in Go. With PHP, obviously you can put your files anywhere as long as the server knows where the document root is. So there was this special environment variable, there is still called Go path, which you basically just pointed at directory where all your projects would live and then inside this directory there would be three other subdirectories, source, bin and package and source is where all your code would go. So then obviously then to avoid name clashes you had to vendor somehow the paths so the very standard convention in Go was to just use something like your GitHub or GitLab project prefix to make sure that all those paths for all your Go apps are unique. So here I've got two examples. I could have two programs named the same name but because they would have different the purple bit which is the GitHub or GitLab path Go would see them as two different projects. So that's how it used to be and you kind of had, there was a hacky way around it to be able to move files around but that was the designed way. I personally didn't mind, a lot of people hated this because it was such a change from all the other languages. For me, actually for the first time ever all my projects were organized on disk so I kind of liked it. But GoPath is going away. In Go 1.11 and really I think it's scheduled to go into Go 113 which is gonna be released around August this year. There's gonna be this thing called modules which is a proper way of managing your dependencies and this was long awaited. Go for a long time didn't really have a solution for dependency management other than the very basic Go get. So people started writing open source tools which were kind of like Composer but in modules is like Composer taken a step ahead as well. If you imagine for a second that you could run your PHP apps just with a simple command called PHP. So if you did PHP, your file and something would happen which obviously you can run scripts like this then the PHP tool would automatically run Composer install for you if it detected that it has a Composer JSON file and that's essentially what modules do. If modules have a list of modules, the file, then the Go run or Go build tool will automatically pull your dependencies, make sure they're up to date, make sure they match the checksum file which is the equivalent of the log file in PHP and do all of that for you. So you don't even have to, how many times have you forgotten to run Composer install? Basically that problem goes away. So there are a lot of quirks under the hood. Modules are like entirely based on Semver so they rely on everybody using Semver properly which we'll see how it goes. So there's a lot of quirks under the hood but that's basically the idea. You will be able to download the dependencies from Mirrors, they will be authenticated and so on and so forth. There's also a really cool thing that they made so I mentioned in the meantime before this happened there were a lot of open source dependency managers built for example, GoDep and so modules will be able to automatically import all your dependencies from your depth file and translate it into modules and I think they support nine other common dependency managers. So that's pretty cool. So the migration shouldn't be painful in theory. So what kind of apps can you build with Go? I tend to think of Go as a box of Legos that you're given. So you can kind of build anything you want but you gotta figure it out yourself or figure out a lot of that yourself. I see PHP more like the ready-made sets that you're given so they're a little bit more limited but you get a nice instruction manual and off you go. Both languages are great for web apps. They're great for APIs. You can use PHP or Go to write command line apps or even like bash scripts. PHP for me excels at the web level. Like if you just need to quickly write a website I would probably use PHP. Whereas with Go, Go is great for anything slightly lower level that doesn't need a UI in my opinion. So things like infrastructure components, servers, load balancers, proxies, you can even write as server and Go to run your PHP scripts. All sorts of things that don't have a UI and they need to be fast. So let's move on to the reason why so many people start looking at Go and that is concurrency. But before we dive into concurrency and Go, let's quickly remind ourselves what the difference is or is there a difference between concurrency and parallelism and what does it actually mean? So as a PHP dev, you rarely or in my case, never come across concurrency in your apps. Really wasn't a thing back in the day. So you can use a PHP extension called pthreads which probably most people heard of. I've met one person in seven years who actually successfully used it in production. Nobody really does. There are also frameworks like React PHP or AMP. I've never really played around or had to use them for work. So I don't really know how good they are, but because they're frameworks, they're not really built into the language, it's not something that you're likely to come across. PHP traditionally is written with single-threadedness in mind. So it's just less common to come across concurrency than in Go. Go has been designed with concurrency in mind and it's outright promoted to you as a developer. So like I said with PHP, because we're using extensions or frameworks, it might be even a little bit slower than Go which just has it built in. So it wasn't until it started doing Go that I actually realized concurrency parallelism, what is the difference? And is it the same thing? Turns out it's not quite. So concurrency as a concept basically means that two threads can run in parallel. And parallelism is the actual act of running two threads in parallel. So it basically means that in theory, if two threads can make progress, your design is concurrent, but unless they're actually running at the same time, it's only concurrent, it's not parallel. So the difference kind of comes out depending on how many cores your machine has, for example. If you were to take a concurrent program and run it on a single core, then it would be a concurrent design, but it would be not parallel. But if you take a four-core machine and run the same program there and it's designed with concurrency in mind, then in theory you can run it on all four cores simultaneously so it can have four threads running at the same time, and that's both concurrent and parallel. So just to show you a silly example, and I've stolen that example from one of Rob Pike's talks, this is basically a bunch of gophers running around burning books, as they do. So this is a concurrent design. We have one gopher loading the books, one gopher taking them to the incinerator, one of them loading them and burning them, and then one taking the empty trolley back. So in theory, this is a concurrent design because all four gophers can do their work at the same time. Like in the ideal world, all four of them will be busy at the same time. But you could also have just one gopher doing their job. Like if they sort of get backed up, for example, the one loading the books isn't doing the job fast enough, then the rest of them might start being idle because they're waiting. So at this point, you're kind of losing that parallelism. The design is still concurrent, but if you only have one gopher running at the same time, then we don't have parallelism anymore. And then you could also take that set of four gophers and multiply it, and you could have sort of meta concurrency where you just multiply a concurrent design and you get even more things. So in general, we talk about concurrency and go because it's just the general form of parallelism and it focuses more on the theory and the design rather than the actual under the hood things. So it's a subtle difference, but I thought it was interesting and I thought it would be worth clarifying. So one of the most appealing things about Go is how easy it is to make, to write concurrent programs in Go. Basically it boils down to three keywords, the built-in Go keyword, GoRoutines and Channels. So a GoRoutine is not exactly a separate process, it's not a separate Unix thread. They call it the lightweight thread of execution and it's sort of mapped to OS threads. It's all managed by the Go runtime so you don't have to do any of the management yourself. GoRoutines use the same address space so they share the same memory. So you need to be careful about synchronizing the memory between synchronizing access to memory from different GoRoutines. So it's kind of like just with any concurrent design or concurrent program. Here's how you create a GoRoutine. You just put the Go keyword in front of it and it's that simple. So this function will now go off and get executed in a separate lightweight thread of execution. Here's a simple example of using GoRoutines. Say we want to print out hello world but we want to print out hello five times by the main thread and world five times by a GoRoutine, a separate GoRoutine. So you define a function called say which just takes a word and loops through it five times, prints it out, fairly simple. And then in the main function we call it twice. So once for hello, once for world. But on the first line, we put the Go keyword in front of it and that will make Go execute this function in the separate thread. And this is non-blocking, which means that as soon as we go past the Go line, the line that says Go say, it will just move on to the next one. It doesn't wait for the Go line to finish. So it's completely non-blocking. So the two calls will in theory be executed at the same time. And you get an output like this, looks legit. So you get two words printed in random order by each of the GoRoutines. And then if you run it multiple times, you get a slightly different output every time, as expected. So that's because the two threads are actually running concurrently and so without any deliberate synchronization between them, the order just will be completely random. So here you can see the example difference. And where hello is printed last, hello is getting printed by the GoRoutine that is running alongside the main routine. So that means that the main GoRoutine in the second column has terminated already while the GoRoutine was still running. And it doesn't wait for the GoRoutine to finish, it just finishes itself. And that's not ideal because you can end up with zombie GoRoutines, for example. And then you have no control over them. It's literally kill minus nine at this point. So to make sure that you don't exit until all the GoRoutines are done, you can use something called a sync group. So you declare it and then you add one for each one of the GoRoutines that you're creating. So it's basically just a pool of tokens that you're handing out. And then you kick off a function and then Go supports anonymous functions and closures. So it's just a simple example. And then in there we use a special defer keyword. So we say defer weight group done. And now basically it's a bit like finally in PHP, it basically just makes sure that the weight group done is will be executed no matter what before we exit the main function. So it's really handy for things like making sure that you always close the file handles or that you release a mutex or tell the weight group that you're done after your function. So then we call say from the Go function and from the main function itself. And then we call weight group weight. And that will basically make the main thread weight until that GoRoutine says it's done. So it shows you that analyzing this little example shows you that analyzing concurrent programs can be a little bit tricky because things may deliberately sometimes happen at random. Sometimes you genuinely don't care. And sometimes you expect things to be executed in sequentially or in some kind of order. There are also other constructs like mutexes for synchronizing access to memory. But luckily a lot of the native Go functionality is safe for concurrent use out of the box. So you don't really need to spend too much time on that. And if you use the standard concurrency patterns that kind of becomes second nature. So it's not as scary as it sounds. Go also has a race condition detector built in into its tool chain so you can even use that. And even better way to provide synchronization in your Go programs is to use channels. You can think channels as pipes or queues. It's kind of the same idea. So if you share a pipe or a queue or a channel between the two Go routines you can just send messages and receive messages. So that's how you can make them talk. So channels in Go are first class citizens. It's a type just like a string or an integer. Channels are also typed. So each channel has a type assigned to it so that the values that you can put in have to be of that type only. So you can have a channel of integers or a channel of strings and you wouldn't be able to put a string on the channel of integers. So channels can also be bi-directional so they can both send and receive or it can be sent only or receive only. By default sending or receiving data on the channel is a blocking operation. So the program will wait until something comes out of the channel or gets sent to a channel. So that means that if a Go routine is waiting to receive something from a channel it will just pause and wait until something appears on that channel and is ready to be received. So this allows us to synchronize Go routines without using explicit things like mutexes or weight groups or any complicated conditionals and it kind of makes your programs look and be a lot more clean. So we can declare channels just like we declare variables in Go. So here I have a variable called messengers and it's a channel of strings. Before I can use this channel to send messages I need to actually create it, not just declare it. So we actually have to make it and there is a special keyword called make that will actually initialize it. So the channels can be buffered or unbuffered as well so you can sort of put a size limit for how many values you can put in a channel before it starts erroring or they can be unbuffered which means unlimited in and out. So then if we wanted to send some data on a channel there is a special keyword in Go which is the sort of rocket, sorry not the rocket but it's kind of like the rocket operator. It's just an arrow. So you point the arrow, the general rule is that the arrow points in the direction of data flow. So if you want to put something on a channel you just point the arrow at the channel and you give it a value. And then if you want to receive a value you kind of do it the other way around so you point the arrow away from the channel and then here we can just assign it straight to the variable called message and then Go will work out that the message is of type string. So how can we implement something more typical in Go like a worker pull pattern which is pretty standard in Go. It's really standard in concurrent programming in general. So basically what a worker pull pattern is it means that instead of having one thread just turn through tasks or input variables and do something with them you can have more than one so say five or six or however many you want do the same thing at the same time. So they will just execute it the same function at the same time. So that means we can speed things up and process things a lot faster because rather than just doing it in sequentially you can have a four, five, six times speed up. So to create the channel, whoops, we declared at the top. So we create a channel of tasks and then just assume task is some random type doesn't really matter here. So we have a jobs channel now and then at the bottom here it's a special construct the for range in Go and that means that it will iterate over the values in a channel and either take them out or print them in put them into a channel. So if I go back in here the middle bit is basically say we've defined some kind of limit for how many workers we wanna say so here I've just used a limit variable but could be five could be any number for the number of the amount for that number of workers that we wanna have we basically kick off a Go routine so the Go keyword and we just say that iterate over the jobs channel, pick up a task and then do something with that task. So every single one of those functions would call the do function in its own Go routine but it will have a different task. So then the last square here is we need to actually remember to put the tasks on the channel because the first two is just create a channel and then pass it into the Go routines to start to be ready to start picking up tasks. So the last box is actually assuming we have some kind of array or slice of tasks to be done we iterate over that and then we just load each task on the jobs channel and then as soon as we load those tasks on the channel the Go routines will start kicking in and start processing them so it doesn't wait until we're done putting the tasks in it will just happen as soon as the first task is available on the channel. Which also means you don't know which one of the workers is gonna pick it up so if you had five in here it could be any one of those fives that will get to the first task first and then you don't actually know what order they will be picked up in. So hopefully you can see that concurrent designs let you really speed things up and process things faster. So for me it was just the ease of picking it up in Go and looking into concurrent and event-driven designs that it was one of the reasons why I really enjoyed learning Go so much. You can obviously try the frameworks in PHP but I think a language that just outright promotes this to you and makes it so easy to use it's just a much nicer way of learning concurrent programming. So my intention wasn't really to tell you that Go is better than PHP or PHP is better than Go they're just different and you should think about what you wanna build first and which language will help you solve the problem in the most elegant way or the most efficient way or a way that makes the most sense for your business. I think generally in this day and age we need to be getting smarter as programmers and we need to find ways to optimize our processing with the ever-increasing loads on our systems. Like these days it's not uncommon to be processing tens of thousands of requests per second and we just need to come up with ways to handle that load. So exploring other language just gives you the benefit of just discovering all the different other patterns that other languages might use to deal with similar problems. And I genuinely think that as we're reaching the limits of hardware improvements Moore's law is kind of now no longer applying and language optimizations itself like we've kind of reached the limit of how much we can optimize PHP 7. So I think the focus will really be on making the programs concurrent because that's the one thing that we didn't really do much with yet in PHP. So you see things like that popping up on Twitter and then you hear about things like SWALL which is a production grade asynchronous programming framework for PHP which looks and feels and is scary just like writing go in PHP. So it's really impressive. So if you're curious, check it out. I think those types of things will become mainstream very, very shortly. Even in PHP 8 we're thinking about doing JIT so just in time compilation to kind of have a little bit of PHP compiled not just everything interpreted. We already do some of it, obviously it's not as simple but we're looking to now make PHP even more compiled than interpreted. So obviously I ended up comparing the two languages quite a lot as I was going along. So here are just some of my favorite things about each. I still think that PHP is at least for me just super quick and easy to just bash something out. Especially if it's not a concurrent thing or if you don't care about concurrency in that case it's just simple. If I can just write a simple sequential program I'll probably just do it in PHP. I like that PHP has a lot of mature frameworks and they're all well established like we kind of as a community have a logging framework to go to so monologue or composer which is the dependency manager and all the well established frameworks. And there was a lot of really mature projects out in the ecosystem. PHP is pretty widespread. There's tons of docs, tons of tutorials online so it's really easy to get help. It's not surprising, PHP's been around for 20 years so we have a lot of materials and a lot of good practices in place. And PHP 7 was really a huge leap forward in terms of how mature the language feels sort of getting rid of some of the nonsense that we had previously and obviously the big speed improvements like 30% out of the box is pretty significant. And I also love the ability to enforce types in PHP. I've never been a fan of type juggling so I really like that you can do that now in PHP. But there are also quite a few things that I liked about Go. I love the strong types from the start like I said. It just to me feels less prone to errors and a good habit to use types. Just less surprises along the way. What's known as the idiomatic Go which is kind of the way to write Go programs. It really encourages you to keep things simple, like simple and stupid. And there is a lot of object calisthenics sort of a lot of inspiration from there in the idiomatic Go. I love the error checking policy and I'll come back to that in a second. I like that Go has multiple return values because I no longer have to figure out if I should return an array with different fields or pass a million DTOs everywhere. You can just return multiple values in Go functions which is pretty handy because you can return a value and an error and if the error is not nil then you know something's gone wrong. It just simplifies that sort of detection and that flow. Like I said, love the built-in concurrency. It's really fun to play around with it. Love the tooling. I'm excited about modules because that will be the one missing puzzle that Go didn't have for a very long time. Go is super easy to set up and run. Like I said, just brew install or whatever your package, your distribution is. I like the wider range of applications in Go. I feel like you can build anything in Go from a web server to a website. There is a templating language that you can use. There's HTML templates but you can also do all the stuff under the hood that PHP maybe wouldn't feel like the right thing to use. And I'm really impressed with the speed and how much faster it is than PHP. And that's probably always gonna be the case because it's a compiled language so naturally probably always gonna be like that. Some of my not-so-favorite things or what I think could be a little bit better about each, PHP is supposed to Go feels a little bit more inconsistent. Obviously a 20-year-old language versus six, seven-year-old language, that's fair enough. I think we've all heard of the fractal of bad design article which lists the million things that are wrong with PHP. I'm pretty sure in 10 years' time there will be articles like that about Go. PHP kind of allows you to do stupid things sometimes and get away with it. It lets you leave dead code around because it's an interpreted language. The PHP interpreter doesn't have the ability to check ahead if a variable that you're trying to reference is defined if something's used or not. Go because it's compiled, you've got the analyzer and it can work out if you've declared a variable that is never referenced. And Go will actually not compile if you have dead code around which is really annoying to start with. If you're used to just prototyping in PHP and sort of half-finishing something and you know PHP is gonna complain about it and throw a million warnings but you carry on regardless, can't do it and go. It would just not compile, it will refuse, point blank. You cannot get used to it and then surprisingly, you then start writing correct programs to start with but that's a big difference. PHP, again, some people say it feels a little bit more verbose because of the brackets and everything. And I kind of really wish PHP had multiple return values. It really makes life simpler in many cases. Go on the other hand, like I said before, less mature ecosystem. It has a few good frameworks around but it lacks those well-established mature, tried-and-trusted, battle-tested frameworks. There are a few go-tos but not as many as in PHP. And dependency managers, like I said, we had to wait till now. It was a bit of a bumpy ride. And the final thing is kind of, as you do Go, you'll see that in PHP you have a lot of helper functions, a lot of wrapper functions. There's like a billion functions to manipulate strings. Go doesn't have as many and that was a deliberate design choice by the Go creators because sometimes doing a for loop is way more efficient and faster than calling a designated function that under the hood does the same thing. So the Go creator's kind of went for speed and that sometimes means that you have to be a little bit more verbose in your programs or you have to write the sugar yourself. So sometimes I was thinking like, oh God, like do I really have to write this myself? I would just use this and that in PHP. But that's the trade-off. So an even more interesting observation for me was noticing some things that I started doing in PHP once I've spent some time in Go land. So as a result, I'm definitely more mindful of keeping things simple and clean, even if the language isn't forcing me to. I also became way more strict with types even before we had types introduced in PHP. It's just second nature now. I never liked type juggling, so I make this explicit in all my PHP 7 programs looking forward to type properties, class properties in 7.4, so that will kind of complete the circle. I tend to use shorter and more sensible names. If I have a class that sits in the controller's namespace, do I really need to call it controller as well? Like we do this a lot for ID, like sort of easier searching through IDE, but in theory, if you already know it's in that namespace, maybe you don't need that. Certainly Go is a big, big no for enterprise-style naming. So here's an example from Rob Pike's talk where he sort of gives a Java example, Java Enterprise, and it just finishes with Dear God, Make It Stop. I just love that. Yeah, it's, yeah, I can't even read this. It extends things three times. Public static, listenable feature, chain, function, something, something, extends, extends, yeah. Certainly none of that in Go. Error-handling. Basically the main message from Go is handle your errors first, and that's like rule number one. So the things on the left is what I used to do before I switched to PHP quite often, and if I was to explain this, I couldn't even tell you what is going on because it's like an if and else and an if inside, and you kind of see that in PHP that it just becomes those nested if and else letters or just becoming a nightmare. The code on the right does exactly the same thing, but it's so much easier. Basically, if the name is empty, you return false. If the name is not a string, you return false, otherwise you return true. So it's probably a name validator or something like that, but it's just so much easier to explain. And the difference is essentially you focus on the error cases and you handle them first as soon as they happen. So as soon as something is in right, you just return. You don't carry on. You don't like go through your code and collect a list of errors and then eventually spit it all up. So you basically just, the main benefit is that you don't run into the risk of doing something you wouldn't accidentally wanna do if there are errors already. So I really like this fail fast approach, which is kind of the standard way of writing go-ups. Also gives you the benefit of just having two lines of sight as opposed to three. So another programmer, including your future self, in six months time when you're glancing through your program, it's just easier to understand and that's part of the object calisthenics as well. So if you've never heard of that, I highly recommend looking into that because a lot of the calisthenics are just incorporated and go from the start. So obviously go didn't invent this, but it was go that made me apply it a lot more. And then I now do the same thing in PHP. Using interfaces and go. If you design your domain well in go and then you leverage, you can leverage the power of interfaces to do things like DDD and hex architecture really, really well in go. And then that in turn makes your code safer to change, easier to change, more extensible and all the goodness that comes with DDD and hex architecture and all of that. So the difference is that go's interfaces are implicit. So in go you think of something, if something has a rather than something is a, then a has an interface X. So if a struct in go, struct is a little bit like object has methods ABC, then it implements interface X. But if an object in PHP would more, you would think more like if the object is of type X, then it should have methods ABC. So go kind of reversed it and does it sort of back to front or the other way around. And the sort of most curious things is that you don't actually declare interfaces in go explicitly, it just works it out under the hood. Like if it sees a struct and it sees that that struct implements types, then it would just know that that implements that interface and then everywhere you wanna inject an interface, it would just work. Like go will just work all of that under the hood. So there's no explicit declaration. So here's a simple example, a shape interface which has an area function. And then we also declare a type called circle, which is a struct, so kind of like an object. And then we define an area function which the circle struct implements, so that's the receiver. So in go you can declare the receiver of a function and that's like putting that function in the class of the circle. And so go at this point knows that circle implements the shape interface because it has the same function. If you just renamed the functions or if you suddenly renamed the function in the interface that link would be broken. So in PHP obviously you have to be explicit. You have to say that class circle implements interface shape. So another side benefit of that is it makes refactoring easier because obviously there's less things to rename or redeclare. Like if you get your design right in go apps you can just shuffle things around, you can rename things but it will just work without having to then pair up the interfaces again with the implementations. So I think that learning go has made me a better programmer for sure. I think knowing more than one programming language really gives you more than one worldview on some problems and you can share ideas across languages. It goes without saying that it makes you more employable these days. These days rarely anyone is just a PHP developer. You're probably expected to at least know some JavaScript but it makes you more employable if you can do go or Java or whatever else as well. And it just feels great to have another tool under your belt. Like it really expands your horizons. You get into new communities, you make new friends. So I really encourage you to go out today and learn whatever programming language you wanted to look into next doesn't have to be go. And this talk obviously wouldn't be complete without briefly mentioning the two communities. So I think both of them are great. I think this talk is proof that there is no reason that you should limit yourself to just one community. And there is no reason that you can't exist in both. So the PHP community rocks and we have many, many conferences. I think this is James and Jeremy at PHP Bulgaria a few years ago, which was really fun. But Go is kind of quickly catching up though. The main Go conference which has been running for five years now is called GopherCon and that used to be in Denver this year. It's in San Diego for the first time. So they're moving it around. So Go conferences have been happening for about five years. And since then, they've exploded and they are now popping up all over the world. Actually Joanna and Sam, the people who are behind this conference, they also organized GopherCon UK, used to be called Golang UK. So it's happening usually in August. So again, if you're interested, check it out. I think the tickets are already on sale. And there is also GopherCon EU, which this year is in Tenerife. Last year it was in Iceland and it was really, really cool. There's Dot Go in France. There is a GopherCon in Brazil, and India and Canada is just all over the place now. There is one in New York City as well. There is something called Gopher Palooza in San Francisco. Just all sorts of things. In London as well, if you're local, check out the London Gophers Meetup. It's a monthly meetup on Go, like PHP London. I think there is quite a few. There's definitely Go in Bristol. I think there was Go in Cardiff. I'm pretty sure there will be popping up more and more. So a lot of people sort of say, okay, what would you recommend if I wanted to get started with Go? So I've just put a bunch of links and talks. Golang.org, which is the main website for Go, really kind of has it all. It has a blog. It has a tour of Go. It even has something called the Playground. And the Playground is really cool because it lets you just try out Go code in your browser without even installing it, which is really cool. And then later on, imagine PHP docs where you could just run a function right there and then after looking at the docs and tweak the params and see how it reacts. That's essentially Go Playground. So it's really, really cool. You're starting out and even as you're doing Go for years and years and years. So Go by Example is another website which is kind of like a tour of Go. It just takes you through some examples. Talks on the right. Concurrency is not parallelism. I've already mentioned that. That's the talk by Rob Pike. It's really, really good. I think it's only 20 minutes long, so it's worth a watch. Simplicity is complicated. It's another talk by Rob and it just talks a lot about how writing simple Go apps is actually really, really hard and kind of gives you some ideas for how to achieve that. If you're into containers and if you wanna see a Docker-like container built on stage in 20 minutes, then Liz Rice has a really, really good talk on that. She builds a container and go from scratch in 20 minutes which really explains the basics of how containers work under the hood and how they interact with the operating system. And then she did another talk which is building a debugger from scratch in Go again in 20 minutes, both really good talks. So I've put links to those. I will tweet out the link to the slides so don't worry about pictures. And with that, I hope you enjoyed the rest of the conference. Thanks so much for listening. The slides will be out. They are already online. Please give me feedback on Joinedin. And if you have any questions, I've left lots of time for comments, but feel free to just grab me. I'll be here for the rest of the day and at the social. So thank you very much. Yes, yeah, go for it. So if anybody wants to ask a question, looking for hands. I have actually two questions if it's possible. One is Go has a lot of package out of the box, right? Is it possible to update the only one or you have to update the whole language? And another question is we can think about replacing a Rabit MQ message system with a Gorotin. Thank you. For the first, so I'll start with the second one. So actually the first one. So the question was you have a lot of packages in Go and can you just import one, not all of them? I want to update just one package. For example, the sync package. I have to upgrade all the language or I can just upgrade the sync package. You can upgrade the sync package. So actually the sort of Go on your system is going to be all the tooling that will let you run Go apps but actually the source code for Go itself will be, so the native Go packages like the HTTP and log and everything that is built into Go, that will be tied to the version of Go on your system. So if you have Go 111, then you'll have that version of the sync package. If you have Go 1.8, you'll have that version. And then if you're using third party packages or like the Go 1.x packages, which are not in the Go core but sort of endorsed by the Go creators, then you can choose the version. And again, depending on whether you're using Go get or one of the open source dependency managers or modules these days, there's different ways to lock them. But in theory, from the Cogor, it's just like PHP. So like if you have PHP 7, you will just have PHP 7 version of the strings functions. So second question was, remind me, oh, RabbitMQ. I probably wouldn't replace the entire queuing system with your Go, because if you remember, the Go routines are mapped to OS threads, so you can actually run out of memory and like your program will just might not have enough memory to just hold all the data in memory. I think rewriting something like RabbitMQ. I think RabbitMQ is Erlang, isn't it? So it's already a concurrent, very solid language. I think rewriting something like a queuing system in Go makes sense. I don't think it's a replacement for a queuing system, because also queuing systems have all the retries and everything, all of that is built into Rabbit or whatever you're using, ETLs, all of that stuff, that you wouldn't get with the Go routine. I mean, you could try. I don't think you would work in production. Yeah, no worries. Any other questions? Do you have a question? An editor for Windows for the Go language? Yes, JetBrains have a GoLand. I think it was called GoLand, now it's GoLand. So if you're into PHPStorm, there is a Go equivalent. Visual Studio Code has a Go plugin, which is really, really good. Atom has a Go plugin, Sublime has a Go plugin, everything has a Go plugin, so yeah. Thank you. You discussed about parallelism. I was curious about if you would want to scale more than one machine, have more connected does-goes, have any frameworks that help moving things outside of just one application and having more? I mean, I'm pretty sure there are load balancers in such written in Go, like traffic, I can never pronounce this, but there are things written in Go that kind of act like load balancers and they will route traffic. Because at this point if you're scaling horizontally, you're kind of looking more at infrastructure and request routing, things like Envoys or LinkerD, that kind of thing, and then your Go service will just have to be completely stateless and kind of generic that any request can hit any service. So you can have multiple Go services running. If you're using Kubernetes, you can have as many Go apps as containers running, or you can just spin up as many, like you can basically just kick off as many binaries as you wanted to, and they can all be up at the same time and they can all listen for requests. And then it's just a matter of what you're using to actually spread the load. But yeah, entirely possible. No different to PHP though, like same principles, yeah. Thanks for a really good talk. Thank you. I've been a bit nervous about using Go. I've heard a rumor that if you have too much exposure to it, you end up looking and acting like a gopher. Is there any truth in that statement? I was gonna say, do I look like a gopher yet? Sort of, like you definitely start applying more of Go in PHP. Like you're kind of trying to, or start like just even without thinking, bringing all those like the way that you would write a Go program, you're gonna start doing this in PHP. I don't know, personally, I think I'm just a lot more open to like different communities. I'm certainly don't plan to move away from PHP. And like I'm not just sort of saying, oh, now I'm all Go and no PHP. I think both of them are still perfectly valid. Like 80% of the web is powered by PHP. So, PHP's not going away anywhere. But I think it's actually interesting because I gave this talk for the first time two years ago and Go and PHP were really different. And now like this year and end of last year has shown that they're actually quite, sort of PHP's quite merging towards Go. And that's kind of hardware language limitations that we've hit. So I think it might actually, I think learning Go now will allow you to learn concurrency patterns that you will then in a year or two years time, you'll see them in PHP and then you won't be surprised. So get a head start. Thanks, that was great answer. Okay, any more questions? Just looking. Oh, yeah. Hiya. You didn't mention about unit testing for Go. So do you have any pointers or how difficult or easy it is to unit testing? Yeah, so Go has kind of two main types of tests. It will be unit tests and benchmarks, which is really cool that benchmarks are built into Go. So unit tests are just like in PHP, like same principles. They are built into the Go toolbox, so you just go Go test package name or whatever and they will just run the tests. Every time you compile your program, it will run through any tests that it finds. So tests are underscore test.go files and they usually sit next to your actual Go files. So all the tools will kind of know that this is a test file, they will run it as part of the compilation and then you can just run them on your own with Go test. And then benchmarks is just a different kind of tests where you can execute the same test until you converge on the result. And we're talking about like a million iterations, five million iterations. So in PHP, you just write a loop around your PHP test and you'll be like executed a million times and then get the average runtime. Whereas with Go that's built into the testing framework. So actually it spits you out all the stats for like this was the average, this was the longest, this is the variability, all sorts of things. So you can actually analyze programs for efficiency a lot better in Go, like a lot easier in Go. So yeah, you can kind of just get benchmarking stats as well and it's out of the box. Thank you. Do you have anything like a B-hat or cucumber for Go? So BDD framers, not that I'm aware of. In general, I think the reason why I'm not aware of that much is because you don't really use them that much or at least I don't use them in anything that I built so far with Go because usually you do microservices in Go and they are actual microservices. They're very simple. So I never had a need to use them as much. I don't know if cucumber or gherkin as a language supports Go, I haven't checked. But in general, I think you rarely write sort of full blown Go apps that would require something like this or if you, I don't know, like it's definitely possible but I think if I was writing something like a load balancer I'm not sure if I'd even use that or if I would just base it on the tests because the tests, the unit tests and you can kind of build integration tests with the unit testing framework. So yeah, but I haven't checked if gherkin actually supports Go. If you didn't mention anything about object oriented programming, so classes and so on, is it a limitation of the language how to deal with that? So Go is technically object oriented because you can have sort of receiver, like receivers on the functions. It's just not as obvious as in PHP. It doesn't have classes and objects but structs are kind of like objects. Packages are kind of like classes or basically classes are like a meta concepts that just exists when you sort of assign receivers to functions and then you know, like you know that out of the 10 functions declared in the file, five of them can only be executed on a struct. So it kind of exists as a concept but not quite. I haven't found it that limiting because again, it forces you to just keep your programs simple. Like in PHP, if you really stick to the, you know, class shouldn't have more than 200 lines, you end up with a lot of very simple classes and that sometimes to me felt like almost an overkill. So Go kind of, if you, Go encourages you to keep your files and your packages fairly small and then at that point, sometimes if you have a class that does one thing on me, then that kind of just becomes your package or your file. So it's different, but I didn't feel it's, I didn't like miss OO and Go. Initially, yes, because initially, like Go also has pointers. So you kind of get slightly confused between instructs and pointers and when do you use what? But over time, I think it just starts to make sense.