Summarized using AI

Go and Ruby `by Eleanor McHugh

Eleanor McHugh • September 29, 2011 • New Orleans, Louisiana • Talk

In this session at RubyConf 2011, Eleanor McHugh presents an exploration of the Go programming language, particularly comparing it to Ruby. The talk emphasizes Go as a statically-compiled systems language designed for creating scalable applications while maintaining type safety and dynamic-like features using type inference. The following key points are discussed:

  • Introduction to Go: McHugh introduces Go, mentioning its open-source nature, the supportive community including contributors from Google, and its structural design focused on readable code.
  • Comparing Ruby and Go: The speaker contrasts Ruby's dynamic typing and flexibility with Go's static typing, demonstrating how both languages can achieve similar functionality although using different approaches. An analogy is drawn comparing Ruby's type system to quantum mechanics, emphasizing the variability and unpredictability of types in Ruby as opposed to Go's more rigid structure.
  • Key Features of Go: The session covers several core features of Go including:
    • CSP-based Concurrency: How Go's Goroutines allow for efficient concurrency management without blocking operations.
    • Memory Handling: Discussions regarding the allocation of memory using structs and interfaces to create type-safe applications.
    • Testing and Benchmarking: Introduction to gotest, Go's testing framework, which allows developers to easily write performance tests and benchmarks within their codebase.
    • Interoperability: McHugh touches on CGO, a tool for linking C libraries, allowing Go to work with existing C code.
  • Code Examples: Several examples are presented, illustrating the syntax and operational differences between Go and Ruby. These include simple programs, structure definitions, and benchmarks. The session emphasizes Go's testing and debugging capabilities through practical examples, particularly highlighting Go's unique reflection capabilities and concurrency model.
  • Practical Applications and Tools: The discussion also showcases real-world applications of Go, touching on areas such as systems programming, error handling, and integration with Ruby. McHugh demonstrates how to implement common programming paradigms in Go, effectively drawing parallels to Ruby's idioms, which helps familiarize Rubyists with Go’s syntax and concepts.

Conclusion: The talk concludes with the assertion that Go provides numerous innovative features for developers familiar with Ruby, specifically in terms of structured systems programming, concurrent operations, and efficient memory management. Attendees leave with a fundamental understanding of Go, better equipped to explore this powerful language in their development projects.

Go and Ruby `by Eleanor McHugh
Eleanor McHugh • New Orleans, Louisiana • Talk

Date: September 29, 2011
Published: December 13, 2011
Announced: unknown

Go is a statically-compiled systems language geared to developing scalable and type-safe applications whilst leveraging type inference to approximate the light touch of a dynamic language. It could be characterised as the static-typing world's response to Ruby. In this session we're going to explore the Go language, its tool-chain and idioms such as CSP-based concurrency and dynamically inferred interfaces to see how they influence the design of Go applications. We'll compare these to equivalent Ruby idioms where they exist, model Go-style concurrency in pure MRI Ruby, and look at interoperability between the two languages. Along the way we'll meet gotest (Go's testing and benchmarking framework), CGO (for linking to C libraries), goinstall (the remote package installer) and Go's powerful reflection and type manipulation features. There'll be a good mix of Go and Ruby code so that by the end of the session you'll be comfortable reading Go source code, have a basic feel for developing with the language and the necessary background to start using Go components in your dev projects.

RubyConf 2011

00:00:17.160 good afternoon New Orleans I've always wanted to say that um I'm going to talk to you today about um go and booy and
00:00:27.800 possibly little flying sources symbols in the middle I will probably run out of time for um my name's Elena i l all over
00:00:36.680 the internet as F Ela and I'm a dropped out open source developer with a 2-year-old so if anybody in this room is
00:00:44.239 petrified of programming languages especially low level ones I'm a stay-at home mom and I can do them so get
00:00:52.879 over here's a little bit about me um some of the things lurking in here are song titles from very obscure bands so I
00:00:59.559 apologize for that um I also apologize for the fact that if
00:01:04.760 your English is not your first language I talk very very fast when I get very very nervous and for everybody who
00:01:12.240 hasn't got absolutely perfect 2020 Vision there's a lot of code and it would all be too small
00:01:17.720 so um I've been hanging around in the movie world for about a decade now and
00:01:23.000 uh most of the stuff I like to play with is the sort of stuff that people don't normally think of for Ruby
00:01:28.560 click and this is the appropriate disclaimer click so okay so um I gave a
00:01:37.119 talk earlier this year called go it's not just for Google um and I got a nice email from Rob Pike after we saw the
00:01:43.680 video of him he said you made me cry we do want people to use our
00:01:50.439 language and I thought well fine I will continue talking about it then so this one should yeah next
00:01:57.240 one I don't know if I'm going to get through any of what I want to through today but anyway uh this is Gordon the
00:02:02.439 goer uh he's kind of cuter than Glend the rabbit but it's a whole plan n sort
00:02:07.600 of inoke thing and uh he lives at Google he's got about 134 non-g gooogle
00:02:14.280 employees who have contributed to his codebase he's fully open source and um
00:02:21.560 he's a language that has a language spec that's being implemented rather than a
00:02:27.160 standardized committee that's trying to figure out what the spec should be so this actually means the spec is readable and very
00:02:33.160 short fire this is a very simple example of a go program um I have decided to set all
00:02:40.400 of these slides going on half second timers because uh they just show you what you should actually think about uh
00:02:48.159 I've got so many versions of this slide deck up and it's probably the best documentation for how to learn to write
00:02:53.400 go programs if you're rubyist but the more that I look at them the less I can think of to say when I've got them going
00:02:59.440 so this is is a very simple program there's some constants and some variables and some printing and it's all
00:03:04.720 very unexciting you're canting work
00:03:10.159 out um go is a very small language and I was going to dwell on both the keywords
00:03:15.239 and the data types but I'm not going to we're going to skip that so this is more useful to us the
00:03:23.159 comparison between go and Ruby um people actually think well a lot of people who
00:03:28.280 come from a dynamic languages background get petrified as statically typed languages and also think that compiled
00:03:34.879 languages all going to be a pain like C++ Etc and go is actually a very sweet little language that isn't really that
00:03:41.840 different to Ruby once you get into it
00:03:47.519 yeah so first we're going to talk about type in Ruby because then I'm going to talk about type and go and not enough
00:03:54.360 people understand type in Ruby in the first place to understand type in other languages and how it can be like Ruby
00:04:00.519 so yeah stupid little diagram demonstrates how most people think that type Works in
00:04:07.799 movie me message comes in hits instance works up the class hierarchy pulls in
00:04:13.159 stuff from modules it's complete lie because for one thing classes themselves
00:04:18.560 are instances and can change so if I do this as it really is I'd have branches all over the place all with super
00:04:25.680 classes so an easy way of thinking about typing
00:04:32.919 Ruby is to think we have an instance class and an inherited class possibly and we have an expressed type that's
00:04:39.639 also combined that comes from a set of modules that we can mix in and this expressed type thing is actually going
00:04:45.000 to be key to understand as type and go here's a simple example of R be doing
00:04:51.680 some of this type stuff um class inherits from another class A Class
00:04:57.440 calling some super class methods all very
00:05:06.919 exciting last time I gave this talk was by Skype call to lonar and uh off the off the top of my
00:05:15.120 head I just said you know Ruby type is like quantum mechanics because it is the moment you blink it's
00:05:20.280 changed um or is like something more useful that came out last night talking to EV Phoenix Ruby type is time variant
00:05:30.440 so you never actually know the type of an object you just know that you're on the right time sequence for the object I
00:05:35.560 started off as a physicist that I know things MD ways but now go type system tries to solve
00:05:43.280 all the problems that computer scientists perceive in the kind of type systems that we as ruers love and it
00:05:49.240 fails so but it only fails if you happen to spend two years making it perform
00:05:55.720 strange experiments as a rubyist so to a Python program you wouldn't go down this
00:06:00.759 food you wouldn't get there um so I like to refer to with a TM and clearly
00:06:05.919 defined areas of doubt and uncertainty because they're very clearly defined they're far
00:06:12.120 away yeah all type in go ultimately device
00:06:18.520 from a memory layout um even things that don't actually have a memory layout the
00:06:23.720 compilers still insist on setting aside a bite for storage for them which is actually really annoying when you want to create typ have any
00:06:30.520 representation um I'm not going to how you do that but it's just the first hack I actually
00:06:36.160 thought of when go was released was oh can I create a structure type that has no storage and according to language you
00:06:42.039 can but then it say bite which is very annoying because effectively that's a garbage connection problem isn't it so
00:06:48.639 anyway you've got a memory layout and you've got a method set which is what we normally just call a bunch of methods on class and you've got a static type
00:06:56.039 that's the combination of the two of those but you've also got a thing called type embedded where you can stick a stru
00:07:01.680 type inside another stru type which is the exact opposite of the way you do inheritance in
00:07:06.840 C++ you don't because you can't override the embeded type you can only make it disappear which is quite an interesting
00:07:13.680 type system by way this is a simple example of a type you can anything there
00:07:20.599 are 13 base types in go and you can turn any one of them into a user type just by declaring a type that uses that type as
00:07:26.800 in memory layer and then you can deare any old methods you feel like on it uh this is example of declaring a method on
00:07:33.080 pointer which means you can only use this method with pointers to that typ you can also declare it on the type
00:07:39.360 itself fire I think I might put the wrong
00:07:47.639 delay right this is a slightly more substantial example this is actually creating a type that actually uses a
00:07:53.840 slice of the previous type as its underlying memory layout a slice is just
00:07:58.919 basically mutable array that lives in memory that's got a little header that's a pointed to the array and some
00:08:05.039 information about length and capacity so you can chop around the content of the array and shrink and and and grow the
00:08:11.919 apparent array without having to reallocate the underlying memory or have to do any point of math um none of this
00:08:19.360 is particularly interesting it's just it's some code I've got luring in a project so next
00:08:24.919 one and this is an example of program that just uses that and prints out for Stuff
00:08:30.000 um there are some bizar shortcuts together I mean syntactically I particularly like this this one because
00:08:38.360 the you can Define either a bottom bound or a top Bound for a slice that you're
00:08:44.080 playing with and then it would just do everything from zero to the top bound or from the bottom bound to the end of the
00:08:50.120 slice which takes away having to keep right um L whatever minus one to
00:08:55.399 calculate what the actual index of the last thing in the slice is fire away
00:09:01.000 uh this is an example of struct of using a struct to embed the previous type in another type so a vector basically will
00:09:08.560 take a buffer and then do some other stuff on top it's not very exciting but just shows the point this is where we
00:09:14.720 get into more interesting stuff um this is called an interface an interface is just a method
00:09:21.200 set it says anything that's got this set of methods on it will comply with this interface and then you can write loads
00:09:27.959 of codes in term of the interface but you never specify that something implements that interface type inference
00:09:34.279 takes care of that so and this thing here that's currently in red this is
00:09:40.160 what's called the blank interface that's that's any type that does that has any
00:09:45.839 method set at all or no methods so that matches all of the basic types as well the built-in types we're going to meet
00:09:51.279 that quite a lot later because I'm going to go into how goes reflection system works okay next one um this is just an example of
00:09:58.160 creating um one instance of a one type that actually complies with that interface next one
00:10:04.800 and this is another one that complies with the same interface so one holds integers and the other holds floating point in a slide next slide and this is
00:10:12.920 an example of the fact that you only have to declare a variable as the interface type and then you can use both of those types interchangeably in that
00:10:20.000 and call the methods on them so it starts to it's basically You' started to get a reasonable duct typing but a duct
00:10:27.120 typing with a bounded type set
00:10:34.200 next the main point about this is computer scientists are a lot happier with Go's approach to duct typing than
00:10:40.240 they are with Ruby's approach to duct typing because when you blink and go things don't change in the
00:10:45.760 background without a lot of work whereas in Ruby there's no guarantee they won't change in the background by
00:10:52.839 way um this is actually constructed as a set of lightning talks because I've got so much stuff I don't know how much of
00:10:58.839 it I can you get through and and I couldn't really think of what I wanted to cut so um I'm quite famous in the
00:11:06.680 Ruby world for the fact I never write tests I just use IRB and and for years
00:11:13.639 and years and years people thought I just hated testing and I don't I really love testing it's just I like to do interactive testing um when I'm writing
00:11:21.279 code and go I don't have an interactive mode there's no equivalent of IRB it's a
00:11:26.800 compiled language um people working on just in time recompilation to give you a
00:11:33.079 sort of a faked way of doing it but it's a clunky tool at present so I tend to write unit tests which is um different I
00:11:42.120 actually enjoy it as well that's the weird thing by way um so we're going to start off we're going to Define us
00:11:47.959 something uh in this case I've defined an equals method on the buffers because I'm going to want to check in my tests
00:11:53.760 where two buffers are equal next um what you've got going on here is
00:11:59.440 just a stupid little test and Go's testing framework is well it's a testing tool not a framework it's
00:12:05.760 called go test and you basically write a whole bunch of tests in a file and they're marked out by having tests as
00:12:11.760 the first four letters of the function names and it just compiles that up into a program and runs it now what's going
00:12:18.199 on I've got quite a lot of CLI stuff going on here but I'm not going to dwell on too much of it um Go's got a really
00:12:24.360 nice switch statement that's very very similar to the way to the case statements in Ruby um in the sense that
00:12:30.639 every single case is itself evaluatable so I'm and you have to in go
00:12:36.959 you have to explicitly fall through to the next case unlike in C where you just naturally drop through and have to prevent yourself um little things like
00:12:44.680 that make it a much safer language for systems programming um than C but anyway
00:12:50.360 skip on to oh before we skip on will it go yes it is um also up here this thing
00:12:57.000 buffer if you remember buffer was defined as a of integers and all constants in go are
00:13:04.120 ideal that means at compile time the compiler will work out whether they're ins Floats or whatever without you
00:13:09.639 having to specify what they are very often um and this is basically just how you would create a vector type that
00:13:15.959 happen to contain a buffer type that happens to be a slice of those numbers so it's it's quite similar to the way in
00:13:22.199 which you would just declare a ra in moving but with a bit of extra boiler PL plate in there so f one um to run test
00:13:29.800 you have to have a makeer file um this is something that's going out of the language hopefully over the next few
00:13:35.040 months but at present all of Go's tool chain relies on you writing make files and
00:13:40.560 there unnecessary really um so skip on now this is a slightly more ex more
00:13:47.760 complicated example because um this is benchmarking um go test provides you
00:13:54.160 with benchmarking out of the box but it's got a very strange way of doing it um completely not the way that Ryan has
00:14:01.079 implemented benchmarking your mini desk so um Rob Pikes is the opinion that you
00:14:06.360 only really know need to know in benchmarks whether something runs for less than a second or not so and this
00:14:13.279 this down here this variable n is actually defined in the benchmarking um Library it tries running
00:14:20.279 each Benchmark with that set to one if it gets a stupidly small number then it just tries to run it until the machine
00:14:25.959 Falls over uh and cuts the test at a second and if it gets a number bigger than a second it says that's the answer
00:14:31.440 that's the Benchmark um and I tend to write benchmarks for nearly everything because it's quite good fun seeing that function
00:14:37.720 call takes two nanc on average and things like that it's a very high resolution Benchmark Library
00:14:43.680 want and this is just what it looks like when you at the console and you run it
00:14:48.880 see uh next all right um one of the The Perennial arguments in the go Community
00:14:56.639 uh constant argument in fact is go doesn't have Exceptions there is you know I mean
00:15:01.839 people use exceptions all the time they're great one um for anybody who's in ay talk I mean exceptions are a great
00:15:07.560 one but go doesn't have an exception mechanism except that's not really
00:15:12.800 true right next one um this basically is all you need to
00:15:17.920 know to say Implement catch and throw catch and throw is very simple to implement in go because Go's got first
00:15:24.279 class functions which happen to be well they're closes and on top of that it's also got a defer mechanism which will
00:15:31.319 call that thing as it unwinds the stack so um in this case I mean I'm at the top
00:15:38.279 I'm throwing a panic I'm just saying this system should die now um and I'm
00:15:44.000 doing it with a NE value because obviously um I don't want to send information I just want to get back to the first thing that's willing to catch
00:15:50.880 a throw uh I'm not sure this would be safe in real world code but um and a catch is
00:15:57.600 quite fascinating because you have this deferred function and then you call the function that you might
00:16:03.279 want to catch and then it calls Whatever and ever and ever you build a staty um
00:16:08.720 and when it comes back up on the way out you just ask it am I recovering from something have I got something that's
00:16:14.240 been passed back up the stack I should care about and in this case I check to see if it's nil and if it's not nil
00:16:19.720 which means it's a genuine Panic by something in in the runtime I check it back up again um but otherwise I just
00:16:25.639 say okay fine cut the stack on right there let's just get get on with what we're doing so catch all is just that
00:16:32.399 taken one step further throws Panic is actually quite a useful little testing thing because there's no built-in
00:16:39.600 support in go test for saying did this thing Panic or not but there doesn't
00:16:45.079 have to be because I mean it's like seven or eight lines of code and the fascinating thing here of course is I'm passing in a I'm passing in a a function
00:16:53.360 but the Deferred function there is itself a closure so where I set b equals true there get some value come out for
00:17:00.120 recover that actually changes the return value that comes out of that function so
00:17:05.280 it's nice it's sort of it's very lispy in those ways
00:17:13.400 next it never used to have all of these pretty red bits I put them in because when you're trying to present the kind of sessions I do over a Skype phone call
00:17:20.679 with no video the thought of trying to say to people well look I'm pointing at this right now when there's three there were
00:17:26.919 361 slides when I was giving this I was like um that's not going to work is it so okay follow on to the next
00:17:34.039 one now this is how to implement a stack do so I'm going to go through this one
00:17:40.919 in quite a bit of detail because it gets into some bits that I don't play with anywhere else in this presentation but
00:17:46.200 um firstly amongst the standard packages there's a runtime package that allows you to actually introspect the
00:17:52.280 runtime um and there's this nice little function called callers that will figure out all
00:17:58.080 of the callers to the the function that you're currently in um given um a stack
00:18:03.679 pointer it will just give you back a whole pile of addresses for where those function entry points up and um you can
00:18:09.080 if you want actually just recall them which um I haven't demonstrated here that would be two slides rather than one
00:18:14.919 but um here all I'm doing is I say well I know what these program counters are can you tell me if this was a function
00:18:20.600 if it was a function can you tell me what ly in a source file it was and then I'll just print that information out so
00:18:26.080 I'll get my stack Trum and you it's very easy to to sort of build
00:18:32.960 all of this instrument your programs at runtime to do all kinds of clever stuff based on error conditions that would be
00:18:39.440 easy to do in Ruby as well but would be very difficult to do in say C++ or Java
00:18:44.919 so uh we skip on oh one other thing I want to say before that um up here this
00:18:50.919 four clause four is the only Loop construct that exists in go and in this case because I've got a
00:18:58.880 slice of information it understands that it can give me each item in the slice in in turn so it's a it's a sort of a four
00:19:05.960 person's enumerator um skip up this is the stuff I spend most of my
00:19:12.640 time actually talking to people about because I seem to be the only person who's actually obsessed with the reflection system in go
00:19:19.080 um yeah five one
00:19:24.880 yeah okay um this lovely bit of code here here is how you allocate a random
00:19:31.559 allocate a piece of memory knowing uh a particular object that already exists
00:19:37.080 you can allocate another one that's like it and this took me about two months to figure out because the reflection system was a moving Target for most of last
00:19:43.919 year um and it just basically so all that this is doing is giving me a way of
00:19:49.120 being able to create either slices or maps at runtime without knowing what
00:19:54.320 type of slice or map they are before that code path is entered um trying to do this in C would be
00:20:01.840 impossible um without doing an awful lot of very horrible Jerry mandering that has nothing to do with the actual
00:20:07.200 implementation of C's by binary interface you can do this sort of stuff in Java but it's just it's very very
00:20:13.559 slow and it's moderately slow slow and go so so this is an example of then testing
00:20:20.600 that out as you can see I'm using the th the fro Panic function I defined earlier
00:20:26.000 just to see whether or not it will work and if it won't work say this should work it doesn't so I
00:20:33.520 one duplicate is a little more interesting because I had a I had an actual thing I was working on where I
00:20:38.760 needed to be able to duplicate an existing item but I didn't want to have to write the code full of the 13 basic
00:20:44.520 types exist in in r in go and then to have to keep reimplementing it for every other type and go doesn't have any kind
00:20:51.240 of generics mechanism so the only way to attack that is to use reflection uh so this will quite happily
00:20:57.360 figure out it will create a buffer using the previous allocate function and then it will figure out exactly how to trans
00:21:04.200 data from one buffer into another to copy across your data without caring about what the type is um quite a lot of
00:21:11.000 these things are slowly making their way into the runtime as generic functions so we've got a generic copy function and
00:21:17.120 things like that that only care the types match between the parameters but at the time I wrote this that didn't
00:21:23.120 didn't actually work for many of the cases I had so um
00:21:30.360 yeah the F the bit of code I'm going to go into now is consider is was considered for some time the most dangerous piece of code in existence um
00:21:37.840 and I got an awful lot of very rude comments from people who came from a a static typing background about how you
00:21:43.080 should never do this but sometimes a bit buffer really is just a bit buffer sometimes I want to look at Raw memory
00:21:49.120 and I want to do something with that raw memory and I don't really want to have a type system getting in the way um you
00:21:55.039 don't have use cases for that in day-to-day programming but I do a lot of work involving vir machine design so I'm
00:22:00.440 often trying to Curry bits between different types for different purposes um that I have I'm the only
00:22:07.720 person who understands the transform I'm trying to do in that particular context yep and so I created this package called
00:22:15.200 raw um it has um I think it's um it's called Random
00:22:20.360 Access right is the official name of it um but I I release it under a dual license in hopes that somebody will need
00:22:26.360 this for a computer game someday and would therefore licensed to close Source version which is called read and reap
00:22:31.880 because basically it it just this is the closest to true unsafety that go can do
00:22:38.320 um what I'm doing here is I'm defining the concept that there's something uh that there's an interface called a memory block and all I care about with a
00:22:45.159 memory block is that whatever object I I want to treat as a memory block understands how to create a bite slice
00:22:51.480 and that is actually a shortcut for Bea code I'm going to show in a minute so
00:22:56.559 bear in mind I'm going to show you some that's specific to certain kind to the reflection system but at the same time
00:23:03.080 I'm also going to show a shortcut that allows you as the person using the library to implement your own way of
00:23:09.240 doing it that's more efficient for your actual runtime type so for example if I
00:23:15.000 have a say I have a a string of 32 pit floating Point um a l of 32 pit floating
00:23:20.159 Point numbers and I decide I want to do this the reflection system will take about a thousand times longer to run the
00:23:26.039 code for doing it than if I just write my own bite slice of the 32-bit looing Point numbers
00:23:32.840 so and we're going to play with uh we're going to see something that's that's core to the way in which rub um go
00:23:39.679 handles both slices and strings and that's the concept of a slice header or a string header these are actually
00:23:45.400 obscured in the language itself you only ever see this thing as a reference to
00:23:50.440 the underlying data but the reflection system allows you to treat them as first class types in their own right so F away
00:24:00.480 there are several several interesting idioms going on here firstly you'll notice there are multiple return values
00:24:06.960 um go is a language that allows for multiple return
00:24:12.559 values that was kind of an idea that was sexy to me sort of like in the early ' 90s when languages didn't have early
00:24:18.279 multiple return values but it it's not really very exciting in the modern world but it's
00:24:25.159 it's it's a selling point to some people I understand um more interesting is this up here the
00:24:32.399 second line is actually a type switch um and it's a an example of how to do a
00:24:41.200 type switch with reflection as opposed to do a direct type switch normally in go you would just you would have um
00:24:47.559 whatever your variable is and then you'd have dot bracket and type in there and then you could use cases that were each
00:24:53.039 of the actual randine types that you knew about but with reflection instead you ask what the actual
00:24:58.840 kind of the thing is and it comes back with whether it's a slice or interface um and all I'm really doing there is I'm
00:25:05.720 creating a new slice header I'm saying well I understand that this slice already exists so I'm going to create a
00:25:12.159 new header that's got the pointer in it at everything that I can manipulate and then this thing up here
00:25:17.640 unsafe pointer it looks like it's a function called but actually that's an instruction to the compiler that says by
00:25:23.080 the way turn off type checking in this portion allow this pointer to point to anything that I ask it to later so I
00:25:30.600 want and this is well I thought this was a thing of beauty when I wrote
00:25:37.480 it this is true of nearly every piece of code I've ever written I thought it was a thing of beauty at the time I wrote it I apologized to the whole world for this
00:25:44.799 um but basically this this this beauty just says there are two known cases in which I know I do not have to use
00:25:51.840 reflection to create a bite slice from any any arbitary type that comes in if
00:25:58.399 it actually is a slice of bites I don't have to do it and also if it complies
00:26:03.600 with the interface I already defined memory block now that means that because Go's got a a bounded package scheme
00:26:10.360 where you can only see stuff inside your package unless it's exported that would make it you'd have the same problems you
00:26:15.960 have as in in Java where you can't retrofit functions on without explicitly saying so while doing it this way any
00:26:22.520 person on the planet who wants to implement a bite slice method for whatever purpose probably for a
00:26:28.559 legitimate purpose like turning some string into a slice of bites I can now
00:26:34.840 reuse their work whenever that type is chucked into this Library by any program without anybody having to tell anything
00:26:41.880 to do it so that's where type influence starts to feel a lot more like Ruby um
00:26:48.080 so yeah the most the most dangerous thing here oh this is this is it I love
00:26:54.080 this um on the previous let's get back to the previous slide for a second if it would do
00:26:59.760 it sorry there's a lot of slides there and they got Auto Tim is in the minutes very on the previous slice slide I
00:27:07.039 actually found out what a bite slice was with a one liner in which I just asked at one time what the type of of a a
00:27:12.360 slice of bite is with that piece of information which is just a 32-bit number so you could stick any 32-bit
00:27:18.640 number in there in theory although there's only a finite set of types that would be understood by the one time um I
00:27:24.399 can now just say you remember that header that I had um well pretend that
00:27:30.120 header is a bite slice create something that would be appropriate for a bite slice oh and by the way because I need
00:27:36.799 the runtime signature to match to fire it out just change the typ so it really is a slice of
00:27:42.919 bite and then return it um this is a really stupid example
00:27:49.039 because actually I can't really think of anybody other than me who would want this piece of code way it is but it means that if for other purposes there
00:27:55.000 are are purposes in all kinds of lowlevel operating systems stuff where you would want this I mean I I've
00:28:00.480 seen an awful lot of C code when I used to work at at that level that basically was trying to do this to void pointers
00:28:07.440 which just takes away every type guarantee completely in the entire code paath all right next
00:28:14.039 one that's a valid line of go that's my defense this is well the go statement
00:28:21.360 itself is how you launch off a go routine and a go routine is a self- scheduling co- routine that blocks on iO
00:28:27.880 and moves to a new thread when it's blocking so that it doesn't block the rest of your program they're very very
00:28:33.760 cheap because they have a 4K slack uh stack because they're built on plan nine threads and this here is a thoroughly
00:28:41.640 valid completely useless function call it's got no content in the function
00:28:46.960 body but um it's it's a valid function call so I couldn't resist it and then of course I had to put a comment at the end
00:28:52.480 to get the yourself in or I'd have had to V code and it would have rolled over the line it wouldn't look pretty so fin
00:29:00.840 off this is this is the sort of this is a very silly example this is the one the code in here oh no it's now the set one
00:29:08.000 of two pieces of code in here I've stolen from other people this I've stolen from the go Community there's another one in a minute I've stolen from
00:29:13.159 the Ruby Community um this is basically a random number generator but it's not a
00:29:18.679 random number generator how you might normally think of them because this
00:29:23.919 basically down here a select statement is basically you can set up a whole pile of of different IO streams and it will
00:29:31.240 randomly pick which one to look at next until it finds one that has IO coming in
00:29:38.440 and it's very random um as a result of that the
00:29:44.360 easiest way to generate a random string of ones and zeros is to create something called a channel um and channels are
00:29:50.720 basically just Pathways between two separate go routines and just Chuck zeros and ones
00:29:56.600 down the channel but I don't want to specify myself what the randomness of that is so I just say
00:30:04.120 decide for yourself pick a zero or one which is kind of cool I mean when I
00:30:10.880 first saw this bit of code this this was written by a guy called Andrew Gerard who's one of the um Google go team and
00:30:17.399 when I saw this bit of code I thought why have I never thought doing random numbers that way before why do I always
00:30:22.760 sit down in my mercing twist or something stupid like that when I could just you know so this is actually quite
00:30:28.440 quite an interesting up here I then just print out whatever the next value is that sat on that channel and this is a
00:30:35.840 blocking Channel this is synchronous IO that's going on here because there's no buffer underneath the
00:30:42.399 channel and so I'm manually polling yeah that's may not be how I
00:30:49.039 want my IO to always work so next slide so this is the same thing but this is an asynchronous
00:30:55.519 oops I didn't mean to put a skip in there if you can get it back on the next one I'd appreciate it the previous one
00:31:01.000 I'd appreciate it you may have to stop the presentation
00:31:06.799 at that point I think in my defense there's over 400 slides so getting all of my timers right
00:31:12.760 is not you know so if that one we can stick on this one right what we've got
00:31:19.519 going on here we're creating um an asynchronous channel that can hold up to 16 values so it will slurp 16 of a time
00:31:26.600 out of this down here and that just means that obviously it frees up on the amount of polling you might do I'm no
00:31:32.000 longer checking on a limit and then I might do another one where I decided I
00:31:37.200 wasn't even going to ask for 16 numbers out anyway but anyway um that's all there is to actually doing synchronous a
00:31:43.919 synchronous IO in go it's exactly like having pipes between processes on a Unix box and just using select Calles in that
00:31:51.320 context right next one oh and that four at the bottom was just to create an infinite Loop so
00:31:58.880 um this takes it a little bit further because sometimes you might want to actually write other stuff that wants to
00:32:05.080 take a signal source and wait until the signal source is finished so a signal source is in this sense is a
00:32:13.200 closure that I've just you know said is a type because you can do you can
00:32:18.440 basically functions Etc you combine them as userdefined types as well um all this
00:32:24.720 really does I mean it just effectively this just implements the equivalent of thread it's not very exciting so next
00:32:31.320 one this is a all of this example is building towards map
00:32:36.639 produce um map reduce with with with reflection so that it's arbitary map
00:32:42.519 reduce so you just have to use the one map reduce engine don't have to keep reiting it for stuff and um we got
00:32:49.000 several things going on here now the great thing about having functions as first class types themselves is that then you can Define methods to apply to
00:32:55.639 the function so that's a apply at the top Tak some parameters and then cause the
00:33:01.200 function itself that is in the that is the the memory representation of the type to then go off and do the work and
00:33:06.679 it pumps the the value out onto the channel that you pass in as one of the parameters um so it's very very easy to
00:33:13.000 build filter chains just by defining types and then embedding types inside each other um the each at the bottom is
00:33:19.039 just a really bad way of implementing a ruby style iterator
00:33:24.120 next combination is slightly more interesting because effectively I've just said anything that's got that
00:33:30.240 function signature takes two parameters and gives one back can really be treated as being a reducer so that's a natural
00:33:37.600 reduce step in a map reduce pipeline um down here you can see that we've got a
00:33:43.559 go routine this is a closure now I had an argument with somebody Meetup in
00:33:49.600 Scotland about this who was an llang fan this is a closure this shares State at
00:33:54.679 the point at which it's created with everything before that it's inherited all the environment down from before it
00:34:00.080 that means if I have several of these in parallel they all share the same state which is you know shared memory ah there
00:34:07.760 are actually a lot of problems where that's useful where you want to share state but you want to share state in a bounded way um which is the problem
00:34:14.359 really with shared memory and Unix it's most of the implementations aren't that bounded and what's Happening Here is
00:34:19.879 this is going off and it will run a whole load of different iterations and pump a whole pile of values out onto a
00:34:26.079 channel and pull them out a transformation is even simpler because really a transformation is just taking
00:34:31.720 one value and turn it into another one so I I've just implemented a whole B bunch of combinator math theory in like
00:34:37.320 four slides which you could do in Ruby but you couldn't do in C and this is
00:34:43.040 this is the real point of of go that you no longer have to think to yourself that systems programming means I'm going to
00:34:48.560 spend the next three months of my life writing boiler plate I can actually do systems programming the way I do Ruby
00:34:53.720 programming so and for those who really love test driven development it even comes with a testing tool you poor bited
00:35:00.240 SS and and obviously the great thing about a transformation is a transformation is
00:35:06.240 is quite useful as part of a map um operation so we'll skip on from that because that's just doing the same as
00:35:12.119 the previous but with different stuff and in here you can see there's one really ugly thing with first class
00:35:19.359 functions um there's no literal type to express them so you have to always cast
00:35:25.960 um a Lambda to actually be of the right type that you're trying to use it in I
00:35:31.359 think this is so ugly but um finding a good syntax is for for this has actually
00:35:36.880 proved very very difficult so it may be a wart that stays there for a long long time skip
00:35:42.280 up and here's just a little program that basically uses the previous to just go off and compute some sums and it's not
00:35:49.240 very exciting right okay this this is basically a piece of code I showed off
00:35:55.079 last year in the concurrency session I did with the Le who and um people keep saying well you know Ruby
00:36:02.319 concurrency sucks and in many ways it does global thread loocks and things like that but you can do exactly the
00:36:08.720 same idiom as you as I just demonstrated in go in Ruby because you've already got two tools in the standard Ruby library
00:36:14.680 for doing it you if you import thread uh sorry wrong language requireed
00:36:21.040 thread um and use thread local variables you can just bind Atomic cues to threads
00:36:27.560 so the following video code is going to demonstrate that this is all going to be available online hopefully when slides share stops
00:36:33.880 being pissy about uploading from here and then you can read all of this it's actually designed to read offline mostly
00:36:39.280 um can we skip Papa page maybe two
00:36:45.880 pages right maybe three yeah oh maybe four it should say
00:36:51.400 that's it um how many people use spread groups some
00:36:58.520 that's good because to be honest most times when I ask that question people say what are thread groups um because
00:37:04.760 people just don't seem to use this this side of Ruby very much um sometimes if you've got a group of
00:37:10.800 threads you want to be able to say I want to send something to every thread except me that's in the group and other times you just want to be able to uh
00:37:17.920 find a particular thread so all of this is just some boiler plate to do that but the important thing for the example is
00:37:24.079 obviously we're using sockets and threads by one
00:37:30.839 it wouldn't be one of my sessions if it didn't do this all right now the important thing here I've actually
00:37:37.160 optimized this since I showed this code last year is all you have to do is when you initialize a thread is bind an
00:37:46.480 atomic Q to a thread variable and just never change the thread variable and then you've got an
00:37:53.040 atomic Q which is exactly the same as a channel in go
00:37:58.079 so once you've done that you can then allow people to send messages to the thread in their normal boring code and
00:38:05.160 then you can quite happily go off and you can encue all of those messages and that's all taken care of under the hood
00:38:11.319 without you having to care about it automically so you won't have any sort of race conditions crop up from that and
00:38:18.640 this with a code just demonstrates how to then bind uh an IO Loop to a thread
00:38:23.920 variable so that now I can send messages to any random piece of IO that happens to be bound in
00:38:30.839 um I simplified this this example slightly because this used to be the default parameter to the method was the
00:38:36.960 actual thread creation um because I quite like doing things like that at times because it's
00:38:42.240 quite fun but and it allows you to stick your own IO Handler in if you do it that way that doesn't necessarily even have
00:38:48.240 to be threaded so you could sort of use the same pattern with a vent machine or things like that but for this it's sort of it's a bit of a digression from the
00:38:54.040 point really um and basically all you then have to have is a loop that's going
00:38:59.480 somewhere that just DQ's items off the off the que and the DQ is actually a
00:39:05.280 blocking operation so that thread isn't going to waste processor Cycles running a pointless uh polling Loop while it's
00:39:12.240 waiting for things to come in and it just shuts it out on a socket and I quite like just closing sockets in the
00:39:17.640 places where I actually use them so right next one
00:39:22.920 um this is a chat server um I'm not going to talk about the code in any great detail except that I've got three
00:39:28.680 thread groups which means I can move a connection between being a receiver transmitter or deceased or I can have a
00:39:35.480 deceased transmitter uh or transmitter that's a receiver for example um and obviously
00:39:41.640 you have to register things up and you have to pass stuff about it's very ex unexciting Skip it's got
00:39:47.440 typo that's a bracket where it shouldn't have been um the important thing with this is
00:39:54.640 actually having a run method because otherwise you're never going to launch the thread that's the actual background listening thread that manages the thread
00:40:00.760 groups to take the other threads that do the io um and obviously simp clean up right
00:40:07.960 F okay um I'm how are we doing for time uh the next talk is supposed to
00:40:14.680 start in oh you're reading my mind aren't you all right well good artists imitate
00:40:22.720 great artists steal ridiculously and BG like um
00:40:28.040 go doesn't really aim to displace C from the world of programming it's just nobody who's ever programmed in go would
00:40:34.000 ever want to touch C again you know um so but we need to live in a
00:40:41.280 world that's got CA libraries and go is statically compiled and statically bound
00:40:47.359 so we've got some problems about how we can actually interface with those C libraries so five off um we've got a
00:40:54.760 basic we've got a tool called cgo and cgo can allow you to bind in any Dynamic
00:41:00.520 shared library on your system and then you can just wrap it up in a way that's
00:41:05.839 very goike next the mate file back there was necessary but boring um this is from
00:41:11.640 a project I've got going on because I wrote a I started out to write my own SQL like three rapper because I didn't like any
00:41:17.680 of the three that existed and then I ended up apparently taking all of them and rewriting all of them as well and
00:41:23.920 then somebody decided they would make it public um which which I'm still not happy about because people might actually use this code in a reliable
00:41:30.200 setting which I was never the intent um what we've got going on here we've got a fake package
00:41:37.119 called C that doesn't really exist and only the cgo tool understands that and
00:41:42.920 we can put any number of C statements in the preceding comment
00:41:48.480 before that statement and it'll quite happily compile them into your code of when it's compiling up to be able to use
00:41:53.520 the library um in this case I don't really have to do anything except incl include the header you can actually get at C types
00:42:01.800 directly by saying they are C types that they're part of the C package but you're only ever supposed to access them via
00:42:08.359 pointers for obscure reasons that I often forget about um ignore um it
00:42:13.839 doesn't seem to be a problem with basic types but pointers to big things go A bit funny at times I think it's an alignment issue um and down here we've
00:42:21.040 got some error handling because I don't normally talk about error handling because I don't like go standard error handling idium which is to return an OS
00:42:27.200 ER value um but it's lowle code you sometimes have to return errors next
00:42:33.480 page but what we got going on over here is I defined some constants um those constants all exist in the in the the
00:42:42.119 SQL light library but they're all a bunch of defines and the defines don't turn up in your go code which is
00:42:49.720 something that has to be improved on I think before this is really going to be a major commercial success at all um but
00:42:57.520 you've got some fun fun things you can do I mean there's a map with some text and this is how you the standard error
00:43:04.079 idiom is that you define a string method on your error values and then they automatically will print themselves out
00:43:09.839 in format statements when you want to print stuff next page this is where it gets a bit more interesting because here I'm carrying
00:43:17.599 together well carrying isn't quite the right word but I'm messing around with some C strings to turn Go's idea of
00:43:23.520 strings which your utfa into C idea of strings so I can sort of open files by file name and so forth and you can see
00:43:30.559 these statements here these are all C function calls that are in line and are
00:43:35.800 able to access um variables that I've already defined are compatible with C in
00:43:41.680 the in as part of the structure Etc next one and over here you can see I can
00:43:47.880 use Go's ER recovery me panic recovery mechanism just the
00:43:53.400 same way I would in a normal go program to recover from errors in C programs um next
00:44:00.119 one and here's just uh this is a there's a header missing there that should have
00:44:05.640 come up first but anyway this is um not code that works because it turns out I don't have Ruby Doh on my MacBook
00:44:12.040 because my MacBook is not my normal Ruby development machine um but this is basically how you more or less how you
00:44:18.920 would load the Ruby interpreter into a go program so as to then drive Ruby from
00:44:26.559 go so skip on yes that's just an example of what it
00:44:32.920 would actually look like passing in movie code with normal C API stuff next slide there's some homework that goes
00:44:38.960 with this I was talking to Evan last night about uh whether rubinius really
00:44:44.200 is inventable as just a standard CA library and apparently it isn't yet because they want to clean API and if
00:44:50.599 you know the sort of thing it will never happen because we don't care you know because nobody ever does it anyway but
00:44:56.880 um um I would recommend that if you want to find out how cgo Works a great project would go be to go off and test
00:45:02.839 how to actually get Ruby loaded into a go program um because it will be hard work it's it's quite a substantial API
00:45:10.680 skip on and this is where you can find out more golang.org is where you can get the
00:45:16.480 language hhg goang is where everybody hangs out on Twitter um that pledgie
00:45:21.760 account is where you can help keep me unemployed for another year so that I can work on this mad stuff
00:45:27.480 um I've got some projects on GitHub um for somebody with such a long history in the Ruby World hardly any of them have
00:45:32.599 anything Ruby related because um all of my Ruby code turns up in talks normally
00:45:37.720 but I've got some actual useful stuff to go and the slides are available there which is actually slides share so it
00:45:43.599 will have reasonable download bandwidth there's about 406 of them for this but that's because of the color coding so I
00:45:49.640 think it's about 70 in reality but anyway um if you want to find out more about go then quite happily come and
00:45:54.960 corner to me with beer and um I finished before the next one's
00:46:00.160 going to go on in fact 45 minutes and 10 seconds I think is the fastest I've ever delivered
00:46:06.040 this so so thank you very much for your time and
Explore all talks recorded at RubyConf 2011
+55