<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Dave Cheney</title>
	<atom:link href="http://dave.cheney.net/feed" rel="self" type="application/rss+xml" />
	<link>http://dave.cheney.net</link>
	<description>History, Economics and Technology</description>
	<lastBuildDate>Tue, 21 May 2013 22:31:03 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Go 1.1 performance improvements</title>
		<link>http://dave.cheney.net/2013/05/21/go-1-1-performance-improvements</link>
		<comments>http://dave.cheney.net/2013/05/21/go-1-1-performance-improvements#comments</comments>
		<pubDate>Tue, 21 May 2013 00:03:14 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[go1.1]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=440</guid>
		<description><![CDATA[This is the first in a series of articles analysing the performance improvements in the Go 1.1 release. It has been reported (here, and here) that performance improvements of 30-40% are available simply by recompiling your code under Go 1.1. For linux/amd64 this holds true for a wide spectrum of benchmarks. For platforms like linux/386 and [...]]]></description>
				<content:encoded><![CDATA[<p>This is the first in a series of articles analysing the performance improvements in the Go 1.1 release.</p>
<p>It has been reported (<a href="http://talks.godoc.org/code.google.com/p/go.talks/2013/go1.1.slide#30">here</a>, and <a href="http://golang.org/doc/go1.1#performance">here</a>) that performance improvements of 30-40% are available simply by recompiling your code under Go 1.1. For <code>linux/amd64</code> this holds true for a wide spectrum of benchmarks. For platforms like <code>linux/386</code> and <code>linux/arm</code> the results are even more impressive, but I&#8217;m putting the cart before the horse.</p>
<p><em>A note about gccgo</em>. This series focuses on the contributions that the improvements to the <em>gc</em> series of compilers (<code>5g</code>, <code>6g</code> and <code>8g</code>) have made to Go 1.1&#8242;s performance. <em>gccgo</em> benefits indirectly from these improvements as it shares the same runtime and standard library, but is not the focus of this benchmarking series.</p>
<p>Go 1.1 features several improvements in the compilers, runtime and standard library that are directly attributable for the resulting improvements in program speed. Specifically</p>
<ul>
<li>Code generation improvements across all three <em>gc</em> compilers, including better register allocation, reduction in redundant indirect loads, and reduced code size.</li>
<li>Improvements to inlining, including inlining of some <code>builtin </code>function calls and compiler generated stub methods when dealing with interface conversions.</li>
<li>Reduction in stack usage, which reduces pressure on stack size, leading to fewer stack splits.</li>
<li>Introduction of a parallel garbage collector. The collector remains mark and sweep, but the phases can now utillise all CPUs.</li>
<li>More precise garbage collection, which reduces the size of the heap, leading to lower GC pause times.</li>
<li>A new runtime scheduler which can make better decisions when scheduling goroutines.</li>
<li>Tighter integration of the scheduler with the <code>net</code> package, leading to significantly decreased packet processing latencies and higher throughput.</li>
<li>Parts of the runtime and standard library have been rewritten in assembly to take advantage of specific bulk move or crypto instructions.</li>
</ul>
<h2>Introducing <em>autobench</em></h2>
<p>Few things irk me more than unsubstantiated, unrepeatable benchmarks. As this series is going to throw out a lot of numbers, and draw some strong conclusions, it was important for me to provide a way for people to verify my results on their machines.</p>
<p>To this end I have built a simple <code>make</code> based harness which can be run on any platform that Go supports to compare the performance of a set of synthetic benchmarks against Go 1.0 and Go 1.1. While the project is still being developed, it has generated a lot of useful data which is captured in the repository. You can find the project on Github.</p>
<p><a href="https://github.com/davecheney/autobench">https://github.com/davecheney/autobench</a></p>
<p>I am indebted to Go community members who submitted benchmark data from their machines allowing me to make informed conclusions about the relative performance of Go 1.1.</p>
<p>If you are interested in participating in <code>autobench</code> there will be a branch which tracks the performance of Go 1.1 against tip opening soon.</p>
<h2>A picture speaks a thousand words</h2>
<p>To better visualise the benchmark results, <a href="https://twitter.com/ajstarks">AJ Starks</a> has produced a wonderful tool, <em>benchviz</em> which turns the dry text based output of <code>misc/benchcmp</code> into rather nice graphs. You can read all about <em>benchviz</em> on AJ&#8217;s blog.</p>
<p><a href="http://mindchunk.blogspot.com.au/2013/05/visualizing-go-benchmarks-with-benchviz.html">http://mindchunk.blogspot.com.au/2013/05/visualizing-go-benchmarks-with-benchviz.html</a></p>
<p>Following a tradition set by the <code>misc/benchcmp</code> tool, improvements, be they a reduction in run time, or an increase in throughput, are shown as bars extending towards the right. Regressions, fall back to the left.</p>
<h2>Go 1 benchmarks on <code>linux/amd64</code></h2>
<p>The remainder of this post will focus on <code>linux/amd64</code> performance. The <code>6g</code> compiler is considered to be the flagship of the <em>gc</em> compiler suite. In addition to code generation improvements in the front and back ends, performance critical parts of the standard library and runtime have been rewritten in assembly to take advantage of SSE2 instructions.</p>
<p>The data for the remainder of this article is taken from the results file <a href="https://github.com/davecheney/autobench/blob/master/linux-amd64-d5666bad617d-vs-e570c2daeaca.txt">linux-amd64-d5666bad617d-vs-e570c2daeaca.txt</a>.</p>
<p><a href="http://dave.cheney.net/wp-content/uploads/2013/05/linux-amd64-go1.png"><img class="alignright size-full wp-image-446" alt="linux-amd64-go1" src="http://dave.cheney.net/wp-content/uploads/2013/05/linux-amd64-go1.png" width="1024" height="1500" /></a></p>
<p>The <code>go1</code> benchmark suite, while being a synthetic benchmark, attempts to capture some real world usages of the main packages in the standard library. In general the results support the hypothesis of a broad 30-40% improvement. Looking at the results submitted to the <em>autobench</em> repository it is clear that <code>GobEncode</code> and <code>Gzip</code> have regressed and issues <a href="https://code.google.com/p/go/issues/detail?id=5165">5165</a> and <a href="https://code.google.com/p/go/issues/detail?id=5166">5166</a> have been raised, respectively  In the latter case, the switch to 64 bit <code>int</code>s is assumed to be at least partially to blame.</p>
<h2>net/http benchmarks</h2>
<p>This set of benchmarks are extracted from the <code>net/http</code> package and demonstrated the work that Brad Fitzpatrick and Dmitry Vyukov, and many others, have put into <code>net</code> and <code>net/http</code> packages.</p>
<p><a href="http://dave.cheney.net/wp-content/uploads/2013/05/linux-amd64-http.png"><img class="alignright size-full wp-image-448" alt="linux-amd64-http" src="http://dave.cheney.net/wp-content/uploads/2013/05/linux-amd64-http.png" width="1024" height="850" /></a></p>
<p>Of note in this benchmark set are the improvements in <code>ReadRequest</code> benchmarks, which attempt to benchmark the decoding a HTTP request. The improvements in the <code>ClientServerParallel</code> benchmarks are not currently available across all <code>amd64</code> platforms, as some of them have no support for the new runtime integration with the <code>net</code> package. Finishing support for the remaining BSD and Windows platforms is a focus for the 1.2 cycle.</p>
<h2>Runtime microbenchmarks</h2>
<p>The final set of benchmarks presented here are extracted from the <em>runtime</em> package.</p>
<p><a href="http://dave.cheney.net/wp-content/uploads/2013/05/linux-amd64-runtime.png"><img class="alignright size-full wp-image-449" alt="linux-amd64-runtime" src="http://dave.cheney.net/wp-content/uploads/2013/05/linux-amd64-runtime.png" width="1024" height="2650" /></a></p>
<p>The <code>runtime</code> benchmarks represent micro benchmarks of very low level parts of the <code>runtime</code> package. </p>
<p>The obvious regression is the first <code>Append</code> benchmark. While in wall time, the benchmark has increased from 36 ns/op to 100 ns/op, this shows that for some <code>append</code> use cases there has been a regression. This may have already been addressed in tip by <a href="https://codereview.appspot.com/9360043/">CL 9360043</a>.</p>
<p>The big wins in the <code>runtime</code> benchmarks are the amazing new <code>map</code> code by khr which addresses <a href="https://code.google.com/p/go/issues/detail?id=3885">issue 3886</a>, the reduction in overhead of channel operations (thanks to Dmitry&#8217;s new scheduler), improvements in operations involving <code>complex128</code> operations, and speedups in <code>hash</code> and <code>memmove</code> operations which were rewritten in 64bit assembly.</p>
<h2>Conclusion</h2>
<p>For <code>linux/amd64</code> on modern 64 bit Intel CPUs, the <code>6g</code> compiler and runtime can generate significantly faster code. Other <code>amd64</code> platforms share similar speedups, although the specific improvements vary. I encourage you to review the benchmark data in the <em>autobench</em> repository and if you are able, submit your own results.</p>
<p>In subsequent articles I will investigate the performance improvement Go 1.1 brings to <code>386</code> and <code>arm</code> platforms..</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2013/05/21/go-1-1-performance-improvements/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Go 1.1 tarballs for linux/arm</title>
		<link>http://dave.cheney.net/2013/05/20/go-11-tarballs-for-linux-arm</link>
		<comments>http://dave.cheney.net/2013/05/20/go-11-tarballs-for-linux-arm#comments</comments>
		<pubDate>Mon, 20 May 2013 00:45:49 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[arm]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=436</guid>
		<description><![CDATA[For the time poor ARM fans in the room, I&#8217;ve updated my tarball distributions to Go 1.1. These tarballs are built using the same misc/dist tool that makes the official builds on the golang.org download page. You can find the link at the Unofficial ARM tarballs for Go item at the top of this page. [...]]]></description>
				<content:encoded><![CDATA[<p>For the time poor ARM fans in the room, I&#8217;ve updated my <a href="http://dave.cheney.net/unofficial-arm-tarballs">tarball</a> distributions to Go 1.1. These tarballs are built using the same <a href="https://code.google.com/p/go/source/browse#hg%2Fmisc%2Fdist"><code>misc/dist</code></a> tool that makes the official builds on the <a href="https://code.google.com/p/go/downloads/list">golang.org</a> download page.</p>
<p>You can find the link at the <a href="http://dave.cheney.net/unofficial-arm-tarballs">Unofficial ARM tarballs for Go</a> item at the top of this page. Please address any bug reports or comments to me directly.</p>
<p>There are also a number of other ways to obtain Go 1.1 appearing on the horizon. For example, if you are using Debian Sid, Go 1.1 is available now. This version has been imported into Ubuntu Saucy (which will become 13.10), although at this time it remains in the <q>proposed</q> channel.</p>
<p>Rest assured I will not be shy in announcing when Go 1.1 has wider availability in Ubuntu.</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2013/05/20/go-11-tarballs-for-linux-arm/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go and Juju at Canonical slides posted</title>
		<link>http://dave.cheney.net/2013/05/11/go-and-juju-at-canonical-slides-posted</link>
		<comments>http://dave.cheney.net/2013/05/11/go-and-juju-at-canonical-slides-posted#comments</comments>
		<pubDate>Sat, 11 May 2013 04:45:40 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[canonical]]></category>
		<category><![CDATA[juju]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=426</guid>
		<description><![CDATA[This month I had the privilege of presenting a talk at the GoSF meetup to 120 keen Gophers. I was absolutely blown away by the Iron.io/HeavyBit offices. It was a fantastic presentation space with a professional sound and video crew to stream the meetup straight to G+. The slides are available on my GitHub account, but a [...]]]></description>
				<content:encoded><![CDATA[<p>This month I had the privilege of presenting a talk at the GoSF meetup to 120 keen Gophers.</p>
<p>I was absolutely blown away by the Iron.io/HeavyBit offices. It was a fantastic presentation space with a professional sound and video crew to stream the meetup straight to G+.</p>
<p>The slides are available on my GitHub account, but a more convenient way to consume them is Gary Burd&#8217;s fantastic talks.godoc.org site.</p>
<p><a href="http://talks.godoc.org/github.com/davecheney/gosf/5nines.slide#1">http://talks.godoc.org/github.com/davecheney/gosf/5nines.slide#1</a></p>
<p>If you&#8217;re interested in finding out more about the Juju project itself, you can find us on the project page, <a href="https://launchpad.net/juju-core/">https://launchpad.net/juju-core</a>/ or #juju / #juju-dev on IRC.</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2013/05/11/go-and-juju-at-canonical-slides-posted/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Curious Channels</title>
		<link>http://dave.cheney.net/2013/04/30/curious-channels</link>
		<comments>http://dave.cheney.net/2013/04/30/curious-channels#comments</comments>
		<pubDate>Tue, 30 Apr 2013 00:12:42 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[channels]]></category>
		<category><![CDATA[csp]]></category>
		<category><![CDATA[golang]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=399</guid>
		<description><![CDATA[Channels are a signature feature of the Go programming language. Channels provide a powerful way to reason about the flow of data from one goroutine to another without the use of locks or critical sections. Today I want to talk about two important properties of channels that make them useful for controlling not just data [...]]]></description>
				<content:encoded><![CDATA[<p>Channels are a signature feature of the <a title="Go Programming Language" href="http://golang.org/">Go programming language</a>. Channels provide a powerful way to reason about the flow of data from one goroutine to another without the use of locks or critical sections.</p>
<p>Today I want to talk about two important properties of channels that make them useful for controlling not just data flow within your program, but the flow of control as well.</p>
<h2>A closed channel never blocks</h2>
<p>The first property I want to talk about is a closed channel. Once a channel has been closed, you cannot send a value on this channel, but you can still receive from the channel.</p>
<pre>package main

import "fmt"

func main() {
        ch := make(chan bool, 2)
        ch &lt;- true
        ch &lt;- true
        close(ch)

        for i := 0; i &lt; cap(ch) +1 ; i++ {
                v, ok := &lt;- ch
                fmt.Println(v, ok)
        }
}</pre>
<p>In this example we create a channel with a buffer of two, fill the buffer, then close it.</p>
<pre>true true
true true
false false</pre>
<p>Running the program shows we retrieve the first two values we sent on the channel, then on our third attempt the channel gives us the values of <code>false</code> and <code>false</code>. The first <code>false</code> is the zero value for that channel&#8217;s type, which is <code>false</code>, as the channel is of type <code>chan bool</code>. The second indicates the open state of the channel, which is now <code>false</code>, indicating the channel is closed. The channel will continue to report these values infinitely. As an experiment, alter this example to receive from the channel 100 times.</p>
<p>Being able to detect if your channel is closed is a useful property, it is used in the range over channel idiom to exit the loop once a channel has been drained.</p>
<pre>package main

import "fmt"

func main() {
        ch := make(chan bool, 2)
        ch &lt;- true
        ch &lt;- true
        close(ch)

        for v := range ch {
                fmt.Println(v) // called twice
        }
}</pre>
<p>but really comes into its own when combined with <code>select</code>. Let&#8217;s start with this example</p>
<pre>package main

import (
        "fmt"
        "sync"
        "time"
)

func main() {
        finish := make(chan bool)
        var done sync.WaitGroup
        done.Add(1)
        go func() {
                select {
                case &lt;-time.After(1 * time.Hour):
                case &lt;-finish:
                }
                done.Done()
        }()
        t0 := time.Now()
        finish &lt;- true // send the close signal
        done.Wait()    // wait for the goroutine to stop
        fmt.Printf("Waited %v for goroutine to stop\n", time.Since(t0))
}</pre>
<p>Running the program, on my system, gives a low wait duration, hence it is clear that the goroutine does not wait the full hour before calling <code>done.Done()</code></p>
<pre>Waited 129.607us for goroutine to stop</pre>
<p>But there are a few problems with this program. The first is the <code>finish</code> channel is not buffered, so the send to <code>finish</code> may block if the receiver forgot to add <code>finish</code> to their <code>select</code> statement. You could solve that problem by wrapping the send in a <code>select</code> block to make it non blocking, or making the <code>finish</code> channel buffered. However what if you had many goroutines listening on the <code>finish</code> channel, you would need to track this and remember to send the correct number of times to the finish channel. This might get tricky if you aren&#8217;t in control of creating these goroutines; they may be being created in another part of your program, perhaps in response to incoming requests over the network.</p>
<p>A nice solution to this problem is to leverage the property that a closed channel is always ready to receive. Using this property we can rewrite the program, now including 100 goroutines, without having to keep track of the number of goroutines spawned, or correctly size the <code>finish</code> channel</p>
<pre>package main

import (
        "fmt"
        "sync"
        "time"
)

func main() {
        const n = 100
        finish := make(chan bool)
        var done sync.WaitGroup
        for i := 0; i &lt; n; i++ { 
                done.Add(1)
                go func() {
                        select {
                        case &lt;-time.After(1 * time.Hour):
                        case &lt;-finish:
                        }
                        done.Done()
                }()
        }
        t0 := time.Now()
        close(finish)    // closing finish makes it ready to receive
        done.Wait()      // wait for all goroutines to stop
        fmt.Printf("Waited %v for %d goroutines to stop\n", time.Since(t0), n)
}</pre>
<p>On my system, this returns</p>
<pre>Waited 231.385us for 100 goroutines to stop</pre>
<p>So what is going on here? As soon as the <code>finish</code> channel is closed, it becomes ready to receive. As all the goroutines are waiting to receive either from their <code>time.After</code> channel, or <code>finish</code>, the <code>select</code> statement is now complete and the goroutines exits after calling <code>done.Done()</code> to deincrement the <code>WaitGroup</code> counter. This powerful idiom allows you to use a channel to send a signal to an unknown number of goroutines, without having to know anything about them, or worrying about deadlock.</p>
<p>Before moving on to the next topic, I want to mention a final simplification that is preferred by many Go programmers. If you look at the sample program above, you&#8217;ll note that we never send a value on the <code>finish</code> channel, and the receiver always discards any value received. Because of this it is quite common to see the program written like this:</p>
<pre>package main

import (
        "fmt"
        "sync"
        "time"
)

func main() {
        finish := make(chan struct{})
        var done sync.WaitGroup
        done.Add(1)
        go func() {
                select {
                case &lt;-time.After(1 * time.Hour):
                case &lt;-finish:
                }
                done.Done()
        }()
        t0 := time.Now()
        close(finish)
        done.Wait()
        fmt.Printf("Waited %v for goroutine to stop\n", time.Since(t0))
}</pre>
<p>As the behaviour of the <code>close(finish)</code> relies on signalling the close of the channel, not the value sent or received, declaring <code>finish</code> to be of type <code>chan struct{}</code> says that the channel contains no value; we&#8217;re only interested in its closed property.</p>
<h2>A nil channel always blocks</h2>
<p>The second property I want to talk about is polar opposite of the closed channel property. A nil channel; a channel value that has not been initalised, or has been set to <code>nil</code> will always block. For example</p>
<pre>package main

func main() {
        var ch chan bool
        ch &lt;- true // blocks forever
}</pre>
<p>will deadlock as <code>ch</code> is <code>nil</code> and will never be ready to send. The same is true for receiving</p>
<pre>package main

func main() {
        var ch chan bool
        &lt;- ch // blocks forever
}</pre>
<p>This might not seem important, but is a useful property when you want to use the closed channel idiom to wait for multiple channels to close. For example</p>
<pre>// WaitMany waits for a and b to close.
func WaitMany(a, b chan bool) {
        var aclosed, bclosed bool
        for !aclosed || !bclosed {
                select {
                case &lt;-a:
                        aclosed = true
                case &lt;-b:
                        bclosed = true
                }
        }
}</pre>
<p><code>WaitMany()</code> looks like a good way to wait for channels <code>a</code> and <code>b</code> to close, but it has a problem. Let&#8217;s say that channel <code>a</code> is closed first, then it will always be ready to receive. Because <code>bclosed</code> is still <code>false</code> the program can enter an infinite loop, preventing the channel <code>b</code> from ever being closed.</p>
<p>A safe way to solve the problem is to leverage the blocking properties of a nil channel and rewrite the program like this</p>
<pre>package main

import (
        "fmt"
        "time"
)

func WaitMany(a, b chan bool) {
        for a != nil || b != nil {
                select {
                case &lt;-a:
                        a = nil 
                case &lt;-b:
                        b = nil
                }
        }
}

func main() {
        a, b := make(chan bool), make(chan bool)
        t0 := time.Now()
        go func() {
                close(a)
                close(b)
        }()
        WaitMany(a, b)
        fmt.Printf("waited %v for WaitMany\n", time.Since(t0))
}</pre>
<p>In the rewritten <code>WaitMany()</code> we <code>nil</code> the reference to <code>a</code> or <code>b</code> once they have received a value. When a nil channel is part of a <code>select</code> statement, it is effectively ignored, so <code>nil</code>ing <code>a</code> removes it from selection, leaving only <code>b</code> which blocks until it is closed, exiting the loop without spinning.</p>
<p>Running this on my system gives</p>
<pre>waited 54.912us for WaitMany</pre>
<p>In conclusion, the simple properties of closed and nil channels are powerful building blocks that can be used to create highly concurrent programs that are simple to reason about.</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2013/04/30/curious-channels/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What is the zero value, and why is it useful ?</title>
		<link>http://dave.cheney.net/2013/01/19/what-is-the-zero-value-and-why-is-it-useful</link>
		<comments>http://dave.cheney.net/2013/01/19/what-is-the-zero-value-and-why-is-it-useful#comments</comments>
		<pubDate>Fri, 18 Jan 2013 22:15:53 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=324</guid>
		<description><![CDATA[Let&#8217;s start with the Go language spec on the zero value. When memory is allocated to store a value, either through a declaration or a call of make or new, and no explicit initialization is provided, the memory is given a default initialization. Each element of such a value is set to the zero value for its type: false for booleans, 0 for integers, 0.0 for [...]]]></description>
				<content:encoded><![CDATA[<p>Let&#8217;s start with the <a href="http://golang.org/ref/spec#The_zero_value">Go language spec on the zero value</a>.</p>
<blockquote><p>When memory is allocated to store a value, either through a declaration or a call of <code>make</code> or <code>new</code>, and no explicit initialization is provided, the memory is given a default initialization. Each element of such a value is set to the <i>zero value</i> for its type: <code>false</code> for booleans, <code>0</code> for integers, <code>0.0</code> for floats, <code>""</code> for strings, and <code>nil</code> for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.</p></blockquote>
<p>This property of always setting a value to a known default is important for safety and correctness of your program, but can also make your Go programs simpler and more compact. This is what Go programmers talk about when they say <em>&#8220;give your structs a useful zero value&#8221;</em>.</p>
<p>Here is an example using <code>sync.Mutex</code>, which is designed to be usable without explicit initialization. The <code>sync.Mutex</code> contains <a href="http://golang.org/src/pkg/sync/mutex.go?s=697:745#L8">two unexported integer fields</a>. Thanks to the <em>zero value </em>those fields will be set to will be set to <code>0</code> whenever a <code>sync.Mutex</code> is declared.</p>
<pre>package main

import "sync"

type MyInt struct {
        mu sync.Mutex
        val int
}

func main() {
        var i MyInt

        // i.mu is usable without explicit initialisation.
        i.mu.Lock()      
        i.val++
        i.mu.Unlock()
}</pre>
<p>Another example of a type with a useful <em>zero value</em> is <code>bytes.Buffer</code>. You can decare a <code>bytes.Buffer</code> and start <code>Read</code>ing or <code>Write</code>ing without explicit initialisation. Note that <code>io.Copy</code> takes an <code>io.Reader</code> as its second argument so we need to pass a pointer to <code>b</code>.</p>
<pre>package main

import "bytes"
import "io"
import "os"

func main() {
        var b bytes.Buffer
        b.Write([]byte("Hello world"))
        io.Copy(os.Stdout, &amp;b)
}</pre>
<p>A useful property of slices is their <em>zero value</em> is <code>nil</code>. This means you don&#8217;t need to explicitly <code>make</code> a slice, you can just declare it.</p>
<pre>package main

import "fmt"
import "strings"

func main() {
        // s := make([]string, 0)
        // s := []string{}
        var s []string

        s = append(s, "Hello")
        s = append(s, "world")
        fmt.Println(strings.Join(s, " "))
}</pre>
<p>Note: var s []string is <i>similar</i> to the two commented lines above it, but not identical. It is possible to detect the difference between a slice value that is <em>nil</em> and a slice value that has <em>zero length</em>. The following code will output <i>false</i>.</p>
<pre>package main

import "fmt"
import "reflect"

func main() {
        var s1 = []string{}
        var s2 []string
        fmt.Println(reflect.DeepEqual(s1, s2))
}</pre>
<p>A surprising, but useful, property of nil pointers is you can call methods on types that have a nil value. This can be used to provide default values simply.</p>
<pre>package main

import "fmt"

type Config struct {
        path string
}

func (c *Config) Path() string {
        if c == nil {
                return "/usr/home"
        }
        return c.path
}

func main() {
        var c1 *Config
        var c2 = &amp;Config{
                path: "/export",
        }
        fmt.Println(c1.Path(), c2.Path())
}</pre>
<p>With thanks to <a href="https://plus.google.com/u/1/100144763948435845718" rel="nofollow">Jan Mercl</a>, <a href="https://plus.google.com/u/1/109937363154511097852" rel="nofollow">Doug Landauer</a>, <a href="https://plus.google.com/u/1/100350950314702566738" rel="nofollow">Stefan Nilsson</a>, and <a href="https://plus.google.com/u/1/114584453838689084704" rel="nofollow">Roger Peppe</a> from the wonderful <a href="https://plus.google.com/u/1/communities/114112804251407510571" target="_top">Go+</a> community for their feedback and suggestions.</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2013/01/19/what-is-the-zero-value-and-why-is-it-useful/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using screen for lazy dot files</title>
		<link>http://dave.cheney.net/2013/01/15/using-screen-for-lazy-dot-files</link>
		<comments>http://dave.cheney.net/2013/01/15/using-screen-for-lazy-dot-files#comments</comments>
		<pubDate>Tue, 15 Jan 2013 04:41:16 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Useless Trivia]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[screen]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=313</guid>
		<description><![CDATA[I have a lot of shell accounts; on my laptops and workstations, on my ARM build boxes, on remote servers, and so on. I don&#8217;t make a lot of customisations to my login shell as the lowest common denominator of OS X, FreeBSD and various Linux distros has trained me to live with what is on the [...]]]></description>
				<content:encoded><![CDATA[<p>I have a lot of shell accounts; on my laptops and workstations, on my ARM build boxes, on remote servers, and so on. I don&#8217;t make a lot of customisations to my login shell as the lowest common denominator of OS X, FreeBSD and various Linux distros has trained me to live with what is on the host.</p>
<p>I do have two exceptions, <code>bash</code> and <code>screen</code><sup>1</sup>. Handling my <code>screen</code> config is easy; just <code>scp</code> my <code>.screenrc</code> file to the new host. Handling the small number of changes to my <code>bash</code> setup is more involved as <code>bash</code> has several places it looks in (<code>.bashrc</code>, <code>.bash_profile</code>, sometimes just <code>.profile</code>) and those files may already exist on the host.</p>
<p>Recently I&#8217;ve been experimenting with the idea of using <code>screen</code> to handle this customisation, which reduces the amount of configuration data copied to a new host to a single new file. Here is a sample <code>.screenrc</code> from an ARM FreeBSD build box.</p>
<pre>startup_message off
vbell off

# Window list at the bottom.
hardstatus alwayslastline "%{wk}%-w%{Gk}[%n %t]%{wk}%+w%=%{Ck}%M%d %c%{-} %{=r} ${USER}@%H"

# who needs .bashrc ?
shell bash
setenv PS1 "\[\e]0;\u@\h: \w\a\]\h(\w) % "
setenv GOROOT /u/go                           
setenv GOPATH $HOME
# yup, screen can expand shell vars
setenv PATH $PATH:$GOROOT/bin:$GOPATH/bin 

autodetach on
term xterm-color
termcapinfo xterm ti@:te@</pre>
<p>Combined with <code>ssh $HOST -t -- screen -R -D</code>, this makes setting up a new machine very simple.</p>
<hr />
<p>1. Note to haters. I know that alternatives like <code>zsh</code> and <code>tmux</code> exist, but <em>neither</em> are installed by default on any mainstream distro, so until they are, I don&#8217;t care. At any rate, these suggestions probably apply equally well to your chosen shell and screen multiplexer.</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2013/01/15/using-screen-for-lazy-dot-files/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Go, the language for emulators</title>
		<link>http://dave.cheney.net/2013/01/09/go-the-language-for-emulators</link>
		<comments>http://dave.cheney.net/2013/01/09/go-the-language-for-emulators#comments</comments>
		<pubDate>Wed, 09 Jan 2013 10:23:15 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[emulation]]></category>
		<category><![CDATA[retrocomputing]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=259</guid>
		<description><![CDATA[So, I hear you like emulators. It turns out that Go is a great language for writing retro-computing emulators. Here are the ones that I have tried so far: trs80 by Lawrence Kesteloot I really liked this one because it avoids the quagmire of OpenGL or SDL dependencies and runs in your web browser. I had a little trouble getting [...]]]></description>
				<content:encoded><![CDATA[<p>So, I hear you like emulators. It turns out that Go is a great language for writing retro-computing emulators. Here are the ones that I have tried so far:</p>
<h1><a href="https://github.com/lkesteloot/trs80">trs80</a> by <a href="https://plus.google.com/u/1/100123330484223031699">Lawrence Kesteloot</a></h1>
<p>I really liked this one because it avoids the quagmire of OpenGL or SDL dependencies and runs in your web browser. I had a little trouble getting it going so if you run into problems remember to execute the <code>trs80</code> command in the source directory itself. If you&#8217;ve used <code>go get github.com/lkesteloot/trs80</code> then it will be <code>$GOPATH/src/github.com/lkesteloot/trs80</code>.</p>
<p><a href="http://dave.cheney.net/2013/01/09/go-the-language-for-emulators/screenshot-from-2013-01-09-210519" rel="attachment wp-att-262"><img class="alignright size-full wp-image-262" alt="trs80" src="http://dave.cheney.net/wp-content/uploads/2013/01/Screenshot-from-2013-01-09-210519.png" width="577" height="592" /></a></p>
<h1><a href="https://github.com/remogatto/gospeccy">GoSpeccy</a> by <a href="https://github.com/remogatto">Andrea Fazzi</a></h1>
<p>GoSpeccy was the first emulator written in Go that I am aware of, Andrea has been quietly hacking away well before Go hit 1.0. I&#8217;ve even been able to get GoSpeccy running on a Raspberry Pi, X forwarded back to my laptop. Here is a screenshot running the <a href="http://pouet.net/prod.php?which=54076">Fire104b</a> intro by <a href="https://plus.google.com/u/1/106356964679457436995/posts">Andrew Gerrand</a></p>
<p><a href="http://dave.cheney.net/2013/01/09/go-the-language-for-emulators/screenshot-from-2012-09-19-08_04_24" rel="attachment wp-att-260"><img class="alignright size-full wp-image-260" alt="GoSpeccy on a Raspberry Pi" src="http://dave.cheney.net/wp-content/uploads/2013/01/Screenshot-from-2012-09-19-08_04_24.png" width="1366" height="768" /></a></p>
<h1><a href="https://github.com/scottferg/Fergulator">Fergulator</a> by <a href="https://github.com/scottferg">Scott Ferguson</a></h1>
<p>Like GoSpeccy, Fergulator shows the power of Go as a language for writing complex emulators, and the power of <code>go get</code> to handle packages with complex dependencies. Here are the two commands that took me from having no NES emulation on my laptop, to full NES emulation on my laptop.</p>
<pre>lucky(~) sudo apt-get install libsdl1.2-dev libsdl-gfx1.2-dev libsdl-image1.2-dev libglew1.6-dev libxrandr-dev
lucky(~) % go get github.com/scottferg/Fergulator</pre>
<p><a href="http://dave.cheney.net/2013/01/09/go-the-language-for-emulators/screenshot-from-2013-01-09-210856" rel="attachment wp-att-264"><img class="alignright size-full wp-image-264" alt="Fergulator" src="http://dave.cheney.net/wp-content/uploads/2013/01/Screenshot-from-2013-01-09-210856.png" width="1366" height="768" /></a></p>
<h1><a href="https://github.com/remogatto/sms">sms</a> by <a href="https://github.com/remogatto">Andrea Fazzi</a></h1>
<p>What&#8217;s this? Another emulator for Andrea Fazzi ? Why, yes it is. Again, super easy to install with <code>go get -v github.com/remogatto/sms</code>. <del>Sadly there are no sample roms included with <code>sms</code> due to copyright restrictions, so no screenshot.</del> <strong>Update:</strong> Andrea has included an open source ROM so we can have a screenshot.</p>
<p><a href="http://dave.cheney.net/2013/01/09/go-the-language-for-emulators/screenshot-from-2013-01-10-082450" rel="attachment wp-att-307"><img class="alignright size-full wp-image-307" alt="sms" src="http://dave.cheney.net/wp-content/uploads/2013/01/Screenshot-from-2013-01-10-082450.png" width="1366" height="768" /></a></p>
<p><b>Update:</b> Several Gophers from the wonderful <a href="https://plus.google.com/communities/114112804251407510571">Go+ community</a> commented that there are still more emulators that I haven&#8217;t mentioned.</p>
<ul>
<li><span style="line-height: 13.999999046325684px;"><a href="https://github.com/jteeuwen/dcpu">dcpu</a> by <a href="https://plus.google.com/u/1/115138137251576973974" target="_top">Jim Teeuwen</a>, an implementation of Notch&#8217;s DCPU specification.</span></li>
<li><a href="https://github.com/nictuku/chip-8">chip-8</a> by <a href="https://plus.google.com/u/1/116078268286389936989" target="_top">Yves Junqueira</a>, which implements the <a href="http://en.wikipedia.org/wiki/CHIP-8">CHIP-8 virtual machine</a> used in some mid 1970&#8242;s home consoles.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2013/01/09/go-the-language-for-emulators/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Testing Go on the Raspberry Pi running FreeBSD</title>
		<link>http://dave.cheney.net/2012/12/31/testing-go-on-the-raspberry-pi-running-freebsd</link>
		<comments>http://dave.cheney.net/2012/12/31/testing-go-on-the-raspberry-pi-running-freebsd#comments</comments>
		<pubDate>Mon, 31 Dec 2012 05:12:57 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[go-golang-raspberrypi]]></category>
		<category><![CDATA[golang]]></category>
		<category><![CDATA[raspberrypi]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=219</guid>
		<description><![CDATA[This afternoon Oleksandr Tymoshenko posted an update on the state of FreeBSD on ARMv6 devices. The takeaway for Raspberry Pi fans is things are working out nicely. A few days ago a usable image was published allowing me to do some serious testing of the Go freebsd/arm port. So, what works? Pretty much everything [root@raspberry-pi [...]]]></description>
				<content:encoded><![CDATA[<p>This afternoon Oleksandr Tymoshenko <a href="http://kernelnomicon.org/?p=246">posted an update</a> on the state of FreeBSD on ARMv6 devices. The takeaway for Raspberry Pi fans is things are working out nicely. A few days ago a <a href="https://plus.google.com/u/1/103860539990722557379/posts/a2GxCrR1hpM">usable image was published</a> allowing me to do some serious testing of the Go <code>freebsd/arm</code> port.</p>
<p>So, what works? Pretty much everything</p>
<pre>[root@raspberry-pi ~]# go run src/hello.go
Hello, 世界</pre>
<p>For the moment <code>cgo</code> and hardware floating point is disabled. I disabled <code>cgo</code> support early in testing after some segfaults, but it shouldn&#8217;t be too hard to fix. The <code>dist</code> tool is currently failing to auto detect<sup>1</sup> support for any floating point hardware.</p>
<pre>[root@raspberry-pi ~]# go tool dist env
GOROOT="/root/go"
GOBIN="/root/go/bin"
GOARCH="arm"
GOOS="freebsd"
GOHOSTARCH="arm"
GOHOSTOS="freebsd"
GOTOOLDIR="/root/go/pkg/tool/freebsd_arm"
GOCHAR="5"
GOARM="5"</pre>
<p>This could be because the auto detection is broken on <code>freebsd/arm</code>, but possibly this kernel image does not enable the floating point unit. I&#8217;ll update this post when I&#8217;ve done some more testing.</p>
<p>At the moment performance is not great, even by Pi standards. The SDCard runs in 1bit 25mhz mode, and I believe the caches are disabled or set to write though. The image has been stable for me, allowing me to compile Go, and various ports required by the build scripts.</p>
<pre>[root@raspberry-pi ~/go/test/bench/go1]# go test -bench=.
testing: warning: no tests to run
PASS
BenchmarkBinaryTree17    1        166473841000 ns/op
BenchmarkFannkuch11      1        83260837000 ns/op
BenchmarkGobDecode       5         518688800 ns/op           1.48 MB/s
BenchmarkGobEncode      10         225905200 ns/op           3.40 MB/s
BenchmarkGzip            1        16926476000 ns/op          1.15 MB/s
BenchmarkGunzip          1        2849252000 ns/op           6.81 MB/s
BenchmarkJSONEncode      1        3149797000 ns/op           0.62 MB/s
BenchmarkJSONDecode      1        6253162000 ns/op           0.31 MB/s
BenchmarkMandelbrot200   1        20880387000 ns/op
BenchmarkParse          10         250097600 ns/op           0.23 MB/s
BenchmarkRevcomp         5         279384200 ns/op           9.10 MB/s
BenchmarkTemplate        1        7347360000 ns/op           0.26 MB/s
ok      _/root/go/test/bench/go1        380.408s</pre>
<p>If you are interested in experimenting with FreeBSD on your Pi, or testing Go on <code>freebsd/arm</code>, please get in touch with me.</p>
<p><strong>Update:</strong> As of 6th Jan, 2013, benchmarks and IO have improved.</p>
<pre>BenchmarkGobDecode             5         482796600 ns/op           1.59 MB/s
BenchmarkGobEncode            10         226637900 ns/op           3.39 MB/s
BenchmarkGzip          1        15986424000 ns/op          1.21 MB/s
BenchmarkGunzip        1        2553481000 ns/op           7.60 MB/s
BenchmarkJSONEncode            1        2967743000 ns/op           0.65 MB/s
BenchmarkJSONDecode            1        6014558000 ns/op           0.32 MB/s
BenchmarkMandelbrot200         1        19312855000 ns/op
BenchmarkParse        10         238778300 ns/op           0.24 MB/s
BenchmarkRevcomp               5         307852000 ns/op           8.26 MB/s
BenchmarkTemplate              1        6767514000 ns/op           0.29 MB/s</pre>
<hr />
<p><sup>1.</sup> Did you know that Go automatically detects the floating point capabilities of the machine it is built on ?</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2012/12/31/testing-go-on-the-raspberry-pi-running-freebsd/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Andrei Alexandrescu on exceptions</title>
		<link>http://dave.cheney.net/2012/12/11/andrei-alexandrescu-on-exceptions</link>
		<comments>http://dave.cheney.net/2012/12/11/andrei-alexandrescu-on-exceptions#comments</comments>
		<pubDate>Tue, 11 Dec 2012 02:58:48 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[exceptions]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=210</guid>
		<description><![CDATA[Source: C++ and Beyond 2012: Andrei Alexandrescu &#8211; Systematic Error Handling in C++ Earlier today on the #go-nuts irc channel: 11:32 &#60; nsf&#62; http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C 11:32 &#60; nsf&#62; Andrei invents multiple return values and defer I have a great deal of respect for Andrei. I think whenever he speaks, you should listen. In watching this video I was [...]]]></description>
				<content:encoded><![CDATA[<p><video width="320" height="240" poster="http://media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling_512.jpg" controls="controls"><source src="http://media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling_mid.mp4" type="video/mp4" /><source src="http://media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling.webm" type="video/webm" /><object width="320" height="240" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://dave.cheney.net/wp-includes/js/tinymce/plugins/media/moxieplayer.swf" /><param name="flashvars" value="url=http%3A//media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling_mid.mp4&amp;poster=http%3A//media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling_512.jpg" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="true" /><embed width="320" height="240" type="application/x-shockwave-flash" src="http://dave.cheney.net/wp-includes/js/tinymce/plugins/media/moxieplayer.swf" flashvars="url=http%3A//media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling_mid.mp4&amp;poster=http%3A//media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling_512.jpg" allowfullscreen="true" allowscriptaccess="true" /></object></video></p>
<p>Source: <a href="http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C">C++ and Beyond 2012: Andrei Alexandrescu &#8211; Systematic Error Handling in C++</a></p>
<p>Earlier today on the <a href="https://botbot.me/freenode/go-nuts/">#go-nuts</a> irc channel:</p>
<blockquote><p>11:32 &lt; nsf&gt; http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C</p>
<p>11:32 &lt; nsf&gt; Andrei invents multiple return values and defer</p></blockquote>
<p>I have a great deal of respect for Andrei. I think whenever he speaks, you should listen. In watching this video I was struck by his excellent categorisation of some of the less common arguments for errors over exceptions:</p>
<ul>
<li>The exceptional path is slow (00:10:23). Facebook was using exceptions to signal parsing errors, which turned out to be too slow when dealing with loosely formatted input. Facebook found that using exceptions in this way increased the cost of parsing a file by 50x (00:10:42). No real surprise here, this is also a common pattern in the Java world and clearly the wrong way to do it. Exceptions are for the exceptional.</li>
<li>Exceptions require immediate and exclusive attention (00:11:28). To me, this is a killer argument for errors over exceptions. With exceptions, you can be in your normal control flow, or the exceptional control flow, not both. You have to deal with the exception at the point it occurs, even if that exception is truly exceptional. You cannot easily stash the first exception and do some cleanup if that may itself throw an exception.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2012/12/11/andrei-alexandrescu-on-exceptions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling_mid.mp4" length="750712629" type="video/mp4" />
<enclosure url="http://media.ch9.ms/ch9/31e0/0220c632-8fd7-490e-843e-c54caee331e0/CB2012AndreiAlexandrescuSystematicErrorHandling.webm" length="161056349" type="application/wordperfect" />
		</item>
		<item>
		<title>The Go Programming Language (2009)</title>
		<link>http://dave.cheney.net/2012/11/18/the-go-programming-language-2009</link>
		<comments>http://dave.cheney.net/2012/11/18/the-go-programming-language-2009#comments</comments>
		<pubDate>Sun, 18 Nov 2012 01:23:10 +0000</pubDate>
		<dc:creator>Dave Cheney</dc:creator>
				<category><![CDATA[Go]]></category>
		<category><![CDATA[History]]></category>
		<category><![CDATA[Photography]]></category>
		<category><![CDATA[go-golang]]></category>
		<category><![CDATA[golang]]></category>

		<guid isPermaLink="false">http://dave.cheney.net/?p=174</guid>
		<description><![CDATA[This month, Go turns three, and this is the video that started it all. As a testiment to skills of Pike, Thompson and Griesemer, the ideals presented in 2009 have survived virtually unaltered into the Go 1.0 release earlier this year. Rewatching this video recently I was reminded that when changes were required they were almost always to [...]]]></description>
				<content:encoded><![CDATA[<p>This month, <a href="http://blog.golang.org/2012/11/go-turns-three.html">Go turns three</a>, and this is the video that started it all.</p>
<p><iframe width="625" height="352" src="http://www.youtube.com/embed/rKnDgT73v8s?feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>As a testiment to skills of Pike, Thompson and Griesemer, the ideals presented in 2009 have survived virtually unaltered into the <a href="http://blog.golang.org/2012/03/go-version-1-is-released.html">Go 1.0 release earlier this year</a>. Rewatching this video recently I was reminded that when changes were required they were almost always to the standard library, which underwent constant revision (aided by the <code>gofix</code> tool) until the 1.0 code freeze. From my notes, the important language level changes were</p>
<ul>
<li><a href="http://www.youtube.com/watch?v=5kj5ApnhPAE">By early 2010</a>, semicolons had been removed from the written syntax (although still present implicitly inside the compiler).</li>
<li>The semantics of non-blocking send and recieve and channel closure were explored and altered a number of times before arriving at their final form.</li>
<li>Maps dropped the confusing <code>map[key] = nil, false</code> deletion form, replaced with more regular <code>delete(map, key)</code>, although some bemoaned the addition of another language builtin.</li>
<li>The constant literal syntax has been improved to make it clearer when constructing large constant literal forms.</li>
<li>Lastly, the builtin <code>error</code> type replaced the original <code>os.Error</code> interface type.</li>
</ul>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://dave.cheney.net/2012/11/18/the-go-programming-language-2009/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
