== Writing an App with Go - Instructors: Gustavo Niemeyer == {{{#!irc === ChanServ changed the topic of #ubuntu-classroom to: Welcome to the Ubuntu Classroom - https://wiki.ubuntu.com/Classroom || Support in #ubuntu || Upcoming Schedule: http://is.gd/8rtIi || Questions in #ubuntu-classroom-chat || Event: App Developer Week - Current Session: Writing an App with Go - Instructors: niemeyer http://pad.ubuntu.com/ep/pad/view/ro.vJnRUh5vWNI/latest [20:00] Logs for this session will be available at http://irclogs.ubuntu.com/2011/09/09/%23ubuntu-classroom.html following the conclusion of the session. [20:01] Hello everyone! [20:01] Sorry for interrupting the amazing set of questions zoopster :) [20:02] So, I'm here to talk about how to develop apps in Go today [20:02] This is the Go language not the game board obviously [20:02] http://golang.org [20:02] I'll be using an Etherpad over the conversation to put content [20:03] Please follow up here: [20:03] http://pad.ubuntu.com/ep/pad/view/ro.vJnRUh5vWNI/latest [20:03] nigelb, pleia2: Can we have that in the topic? [20:04] Please feel free to ask any questions as I go.. I'll be happy to talk [20:04] I don't have a specific script in mind, so I'll be happier to solve doubts and to talk to you than to be in a monologue presenting the language [20:04] There's plenty of material online to follow, and I'll be providing some pointers [20:04] So let's make the most of our time here to exchange ideas and solve questions [20:05] So [20:05] My name is Gustavo Niemeyer, and I'm responsible for the area of Amazing And Unknown Projects at Canonical [20:06] Was pushing Landscape for several years, and then when it started to get well known I moved to the Ensemble project [20:06] https://landscape.canonical.com, https://ensemble.ubuntu.com [20:06] Now Ensemble is getting well known, but I think I'll stick for a little longer ;-) [20:07] Little more than a year and a half ago I started playing with Go in my personal time [20:07] Not really expecting much [20:07] I've been doing that with every other language for a while.. Haskell, Erlang, Java, etc [20:07] Python was the last language to hook me up for a long time as the "preferred whenever possible" choice [20:08] After I started some projects with Go, though, I started to really appreciate what was there [20:08] It didn't really hook me up for any _specific_ feature, though [20:08] What's most amazing about it is really the sum of the parts [20:08] In fact, it's a pretty simple language [20:08] So most aspects you'll see there will be a "Ah, but that's done elsewhere too" moment [20:08] and that's surely the case [20:09] The detail is precisely that it's putting all of those things in _one_ language [20:09] In a very nice to digest fashion [20:09] For instance, [20:09] Go is statically compiled, but has good reflection capabilities [20:09] It also has what I like to call "static duck typing".. [20:10] If you've used Python or similar languages before, you know what I mean by that.. [20:10] In Python, you just provide a value to a function, say, and expect that the function will handle it correctly [20:11] So any method that has, say, a read( ) method, can be provided to a method that calls value.read() [20:11] In Go, there are interfaces [20:11] But they're not like interfaces in languages like Java, for instance [20:11] if you declare an interface like this: [20:11] type Validator interface { IsValid() bool } [20:12] You can use that to declare a function.. [20:12] func MyF(v Validator) { println(v.IsValid()) } [20:12] and any objects at all that define such a method can be used [20:12] they don't have to _declare_ that they implement the Validator interface.. they simply do as long as they have the right methods [20:13] ... [20:13] Anyway [20:13] That's called structural typing, btw.. if you fancy CS [20:13] A few other factors of the top of my head.. [20:13] Go is [20:13] - Garbage collected [20:14] - Capable of producing good tracebacks [20:14] - Debuggable with gdb [20:14] - Has an easy to use module/package system [20:15] Hmm.. lots of leavers :) [20:15] Maybe I should get into some action. [20:15] Let's get it working then. [20:16] First thing, you'll need to install the language [20:16] It's available in Oneiric [20:16] If you're using an older release, there is a PPA available [20:16] Supporting down to Lucid [20:16] sudo add-apt-repository ppa:gophers/go [20:17] sudo apt-get update [20:17] sudo apt-get install golang [20:17] Just the last command for Oneiric [20:17] Now, let's produce a hello world example.. [20:17] I'll guide you towards having a sane environment that you can evolve from, rather than just a quick and dirty one [20:18] So, create a directory: [20:18] mkdir ~/gopath [20:18] and export the variable: [20:18] export GOPATH=~/gopath [20:18] This instructs goinstall that you want to be using that directory for installing programs and packages [20:19] Now, let's create a source directory for our program [20:19] mkdir -p ~/gopath/src/example.com/mycmd [20:19] cd ~/gopath/src/example.com/mycmd [20:20] When you host your source code, you'll have only that last bit withing the revision control, usually [20:20] the example.com is just namespacing the import.. it'll become more clear as we go on [20:21] So, you're now within that directory [20:21] Let's type the following on that file (on the fly! ugh) [20:21] package main [20:21] import "fmt" [20:21] func main() { [20:21] fmt.Printf("Hello world\n") [20:21] } [20:21] Put that within a main.go file [20:22] The name is actually not important [20:22] Now, if you type this command: [20:22] goinstall example.com/mycmd [20:22] You should get mycmd within ~/gopath/bin/mycmd [20:22] Try to execute it [20:23] Congratulations! [20:23] You've just run your first Go program :-) [20:23] Let's go a bit further to understand what we're doing [20:23] Still within ~/gopath/example.com/mycmd [20:24] Let's create a second file called util.go [20:24] and type this within it: [20:24] package main [20:24] func Hello() { [20:24] println("Hello there!") [20:24] } [20:25] Now, edit your main.go, and replace the Printf(...) with this: [20:25] Hello() [20:25] and try the command again: [20:25] goinstall example.com/mycmd [20:26] You'll get an error regarding "fmt" not used.. simply remove the line import "fmt".. [20:26] and try again [20:26] Anyway.. the point I'm trying to make is this: [20:26] All files within a single package in Go are part of the same namespace [20:27] You can name files as you wish [20:27] They're just organizational [20:27] Now, let's get a bit fancier.. [20:27] Let's introduce a package [20:27] Later we'll be playing with concurrency a bit too.. [20:28] So.. let's create our package directory [20:28] mkdir -p ~/gopath/src/example.com/mypkg [20:28] cd ~/gopath/src/example.com/mypkg [20:28] Again, same idea [20:28] Files are just for organization.. [20:28] Let's name ours as hello.go [20:29] Open hello.go within mypkg and put this content there: [20:29] package mypkg [20:29] func Hello(ch chan string) { [20:30] println("Hello", <-ch) [20:30] println("Hi as well", <-ch) [20:30] } [20:30] Let me copy & past locally to follow [20:31] Alright.. [20:31] We have a package! [20:31] One very interesting detail: [20:31] This package is within its own namespace.. [20:32] We can only access Hello() because it starts with a capital cased letter [20:32] This is the way Go differentiates private from exported variables, constants, functions, methods, etc [20:32] In all of those cases, capital case == exported [20:32] At first this feels a bit strange, but it has a pretty interesting consequence: [20:33] Every _usage_ of any of those things makes it clear if what's being used is public or not [20:33] So.. let's go.. [20:33] Go back to our command [20:33] cd ~/gopath/example.com/mycmd [20:33] And type this new code in there: [20:33] Within file main.go, that is: [20:33] package main [20:34] import "example.com/mypkg" [20:34] func main() { [20:34] ch := make(chan string) [20:35] go mypkg.Hello(ch) [20:35] ch <- "Joe" [20:35] ch <- "Bob" [20:35] } [20:35] If I didn't screw up, you can run this now: [20:36] goinstall example.com/mycmd [20:36] and then [20:36] ~/gopath/bin/mycmd [20:36] Try that out [20:37] I made a mistake, which I'll mention in a bit, but first let's go over what just happened [20:37] We imported the package "example.com/mypkg" [20:38] This causes goinstall to look for this package, *download* it if necessary, compile, and install it [20:38] You can check that this is indeed the case by listing: ls ~/gopath/pkg/*/* [20:39] You should get a mypkg.a inside it [20:39] This is your package example.com/mypkg compiled into binary form [20:40] Then, we've called the Hello() function within it [20:40] But we haven't simply called it [20:40] The "go" keyword we've used ahead of the function call instructs the compiler that the function call should be put in the background [20:40] So mypkg.Hello() was running concurrently with your main() function [20:41] Then the statement [20:41] println(..., <-ch) [20:41] Will block in the channel receive expression (<-ch) before a value is available for consumption [20:41] which is exactly what we did next in main() [20:41] ch <- "Joe" sends a value [20:42] The mistake I made in that case, is that the main() function is not waiting for the concurrently running function to terminate [20:42] There are tricks that may be used for this, such as [20:42] select{} [20:43] Then, in case you wanted to actually publish that code to be easily consumable, [20:43] you could put the code within Launchpad or Github [20:43] Exactly as it is [20:43] Just put the content of "mypkg" for instance within the trunk of a project launchpad.net/mypkg [20:43] And people will be able to "goinstall launchpad.net/mypkg" [20:44] So.. that's a quick introduction to the language.. [20:44] But there's a _lot_ more to talk about it [20:44] unfortunately I cna't type that fast and we don't have as much time :) [20:44] So I'll provide some resources [20:44] And open to questions [20:45] The main site is the key documentation point: [20:45] http://golang.org [20:45] There's _very_ good introductory documentation there.. [20:45] I recommend the Getting Started, Tutorial, and Effective Go, in that order [20:45] You should be quite proficient after that [20:45] Well.. or able to use it at least.. [20:46] Proficiency comes with practice [20:46] I'm one of the external contributors of the language as well, so I'll be happy to answer deeper questions which I'm happy to be familiar with in case you have any [20:46] So, that was it.. please shoot the questions.. [20:47] Or maybe not.. :-) [20:49] Alright.. I guess I'm alone in here. :-) [20:49] Thanks for attending, and please drop me a message if you have questions. [20:50] #go-nuts in this same server is also a good place to talk about it. [20:50] I'll be happy to answer questions in the -chat as well}}}