tag:blogger.com,1999:blog-69832872024-03-12T20:59:07.106-07:00command centerrobhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comBlogger32125tag:blogger.com,1999:blog-6983287.post-30391535143915121302024-01-04T12:41:00.000-08:002024-01-04T12:41:14.732-08:00What We Got Right, What We Got Wrong<p><span style="font-family: georgia;"> </span></p><p><span style="font-family: georgia;">This is my closing talk (<a href="https://www.youtube.com/watch?v=yE5Tpp2BSGw" target="_blank">video</a>) from the GopherConAU conference in Sydney, given November 10, 2023, the 14th anniversary of Go being launched as an open source project. The text is interspersed with the slides used in the presentation.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia; font-size: medium;"><b>What We Got Right, What We Got Wrong</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>INTRODUCTION</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Hello.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Let me start by thanking Katie and Chewy for the giving me the honor of presenting the closing talk for the conference. And apologize for reading this from my script but I want to get the words right.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img border="0" data-original-height="2214" data-original-width="2986" height="295" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQvTZvSIAYokvx00Scs3gCg8rR2X74iruzto6wDM1Tth-ZeUPrEH01XM3NPwhLa62ga6pQlMMMzKXrsh3rP_BzOSL4eahGtRZw1LaESnDhmHFmot1OcEqsKsMr84KED9HO4m2F7VJcksZrE-U7WtacxMmXeRTeaveAIEvmHwvs36TOfSnbizPzzw/w400-h295/golang.org-2009.png" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">November 10, 2009</td></tr></tbody></table><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span><p></p><br /><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Today is November 10, 2023, the 14th anniversary of the launch of Go as an open source project.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">That day, at 3pm California time if memory serves, Ken Thompson, Robert Griesemer, Russ Cox, Ian Taylor, Adam Langley, Jini Kim and I watched expectantly as the site went live and the world learned what we had been up to.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Fourteen years later, there is much to look back on. Today I'd like </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">to take the opportunity to talk about some of the larger lessons </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">learned since that day. Even the most successful projects have </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">things that, upon reflection, could have been done better. And of </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">course, things that in hindsight seem to have been key to their </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">success.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Up front I must make clear that I am speaking only for myself, not </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">for the Go team and not for Google.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Go was and still is a huge effort by a dedicated team and a huge community, so if you agree with anything I say, thank them. If you disagree, blame me but please keep it to yourself 😃.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Given the title of this talk, many people might expect I'm going </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">to be analyzing good and bad things in the language. Of course I'll do some of that, but much more besides, for several reasons.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">First, what's good and bad in a programming language is largely a </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">matter of opinion rather than fact, despite the certainty with which many people argue about even the most trivial features of Go or any other language.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Also, there has already been plenty of discussion about things such as where the newlines go, how nil works, using upper case for export, garbage collection, error handling, and so on.<span class="Apple-converted-space"> </span>There are certainly things to say there, but little that hasn't already been said.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But the real reason I'm going to talk about more than the language is that that's not what the whole project was about. Our original goal was not to create a new programming language, it was to create a better way to write software. We had issues with the languages we were using</span></span><span style="font-size: 14px; font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">—</span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">everyone does, whatever the language</span><span style="font-family: georgia; font-size: 14px; font-variant-ligatures: no-common-ligatures;">—</span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">but the fundamental problems we had were not central to the features of those languages, but rather to the process that had been created for using them to build software at Google.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="225" src="https://lh7-us.googleusercontent.com/l1ERR57yyeKPWdSlzvKhKpmL2ZXk4cZwIplGY7fG3jyOwUFn8esWo79SE6Vh0IiFWiD-AfKyXYk2iC90ryJCqHtpQCZbsDwJUDftuf_jX_p_XtfPP04j-nkZ9LL2u-bQIx2Zykc_uFcmT9j0KifQyo6x9A=w400-h225" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures; text-align: left;">The first gopher on a t-shirt</span></td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The creation of a new language provided a new path to explore other ideas, but it was only an enabler, not the real point. If it didn't take 45 minutes to build the binary I was working on at the time, Go would not have happened, but those 45 minutes were not because the compiler was slow, because it wasn't, or because the language it was written in was bad, because it wasn't. The slowness arose from other factors.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And those factors were what we wanted to address: The complexities of building modern server software: controlling dependencies, programming with large teams with changing personnel, ease of maintainability, efficient testing, effective use of multicore CPUs and networking, and so on.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">In short, Go is not just a programming language. Of course it is a </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">programming language, that's its definition, but its purpose was to help provide a better way to develop high-quality software, at least compared to our environment 14 plus years ago.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And that's still what it's about today. Go is a project to make </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">building production software easier and more productive.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">A few weeks back, when starting to prepare this talk, I had a title </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">but little else.<span class="Apple-converted-space"> </span>To get me going, I asked people on Mastodon for </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">input. A fair few responded, and I noticed a trend in the replies: </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">people thought the things we got wrong were all in the language, </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">but those we got right were in the larger story, the stuff around </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">the language like gofmt and deployment and testing. I find that </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">encouraging, actually. What we were trying to do seems to have had an effect.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But it's worth admitting that we didn't make clear early on what </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">the true goals were. Perhaps we felt they were self-evident.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">To </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">address that shortcoming, in 2013 I gave a talk at the SPLASH </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">conference entitled, </span><i style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Go at Google: Language Design in the Service of Software Engineering.</i></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><i style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></i></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="425" src="https://lh7-us.googleusercontent.com/HCe4_dZBgS8SSYkp1xwH0U61SceRS-r1VHnHRxvmkIQUMbv98NEfVr9xWQKkQYiZFdvajhvIRBzoqRWPR9J_xSfktKplJoC7QM_b6VL1eSc3J6PNiSiBCH0YN1y2NF3m45HXdQomQBC5ddqppBgzXxQVcw=w640-h425" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Go at Google</td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span id="docs-internal-guid-656a738c-7fff-7c3e-5062-91ed31980467"></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">That talk and associated blog post are perhaps the best explanation of why Go happened.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Today's talk is something of a follow-on to the SPLASH talk, </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">looking back on the lessons learned once we got past building </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">the language and could apply ourselves to the bigger picture more broadly.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And so... some lessons.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">First, of course, we have:</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>The Gopher</b></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">It may seem an odd place to start, but the Go gopher is one of the </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">earliest factors in Go's success.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">We knew long before the launch </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">that we wanted a mascot to adorn the schwag - every project needs schwag - and Renee French offered to create one for us. We got that part absolutely right.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Here is a picture of the very first instance of the gopher plushie.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="640" src="https://lh7-us.googleusercontent.com/7vXoKLVuaUELhQt0WADJQGLRgS1_y__2nBoJwf00rWEn8cIzguqFbOXZwD41GpF_vB6YTUypWgvTrfNbJh-wWUJUzbpsyFrsku51eTElvW_0FWYrqoM_hQ9Bk1_Ts3u-Vd2HwWEjjKSB0UvEHH0OWplxbQ=w426-h640" style="margin-left: auto; margin-right: auto;" width="426" /></td></tr><tr><td class="tr-caption" style="text-align: center;">The gopher</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><br /></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And here is a picture of the gopher with the less successful first prototype.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="300" src="https://lh7-us.googleusercontent.com/7Ww-vBOulkzwtyGneS2DeN-HdAJrl76KpCRUcmVnc9s_i2GCBA-8Iub09owejoriSvWjOyAEtZOpDBxQuPczGqKJ8NdLX2Im5YY3yuBKJkSV_vKyX0M3sFtjRc1qEn_MzVnkHJQNW72Zp4sxJoFYoYdhSw=w400-h300" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures; text-align: left;">The gopher with his less evolved ancestor</span></td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><br /></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The Gopher is a mascot who serves as a badge of honor, even an </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">identifier for Go programmers everywhere.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">At this moment you are in a conference, one of many, called GopherCon.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Having a recognizable, funny creature ready to share the message from day one was vital to Go's growth.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Its goofy yet intelligent demeanor</span><span style="font-size: 14px; font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">—</span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">he can build anything!</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="268" src="https://lh7-us.googleusercontent.com/dNdOOpp-WS5SVwAqQfgsql5IlWtnboEWjdS0ZCoRVN660dbUybo5BA2MOB_AQDvyDJgnrPEXNirxBmn5R3P6jWRtQCLJ5nTXBW3FbnQWKKgUDQ3gBGGpjdDTehjl9NYdpJVwrxwll0Bf6NvcrRR4Dc3s9g=w400-h268" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Gophers building a robot (drawing by Renee French)</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-size: 14px;"><span style="font-family: georgia;">—</span></span><span style="font-family: georgia;">sets the tone for the community's engagement with the </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">project, one of technical excellence allied with real fun. Most </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">important, the gopher serves as a banner for the community, a flag to rally around, especially in the early days when Go was still </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">an upstart in the programming world.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Here's a picture of gophers attending a conference in Paris some </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">years back. Look how excited they are!</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="308" src="https://lh7-us.googleusercontent.com/z6o54Ge0CGMFldLyduYV1-4E_FTP14V4m_liRtC-Kk6GRidZMp6iJp7j6Oopu7gb5i8NfKO9ld0JsU1zDaKK0mHjbNrX3WsxuJ3STZti-Rh3YYnFLmYT1ifbMJ6oDymKFxKz6jdXW2IasGwHqLuRFQdygw=w640-h308" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Gopher audience in Paris (photo by Brad Fitzpatrick)</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">All that said, releasing the Gopher design under a Creative Commons Attribution license was perhaps not the best choice.<span class="Apple-converted-space"> </span>On the one hand, it encouraged people to remix him in fun ways, which in turn helped foster community spirit.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="360" src="https://lh7-us.googleusercontent.com/XCZwpWOvAmjdxPILuA0qRxnNFJnBwA4pA0zP7ZW-L9zO0xQck372VE8_Qsfzhs2EE0WLsMqLjPUg_MrgmyDDShGrpWZ_Bn3M7bx8tDQ0T2RbxgEO2qZDchw1G2H-j6T_NTQjojiB3V_96J_6zy_FuORzfw=w640-h360" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Gopher model sheet</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Renee created a "model sheet" to help artists work with him while </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">keeping him true to his spirit.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Some artists had fun playing with these characteristics and making their own versions of him; Renee and my favorites are the ones by the Japanese designer @tottie:</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-SKDh1LiCp-4fv2uflcgzEKpYr55gm262s8QqJNFSFOSr83AfCLYqy0Jb2ukMs-CyRO-HVGykw4jCxIxH55AYb8js49hHMh8T9XtbUzpC6j-HDJfKV8UXN8LLogm-B1cjtGTRK8qc8PoX64lsEwz1zaCmqkIWn-OQJk67e-LmT8KDowbeSOg3sQ/s2654/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1516" data-original-width="2654" height="229" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-SKDh1LiCp-4fv2uflcgzEKpYr55gm262s8QqJNFSFOSr83AfCLYqy0Jb2ukMs-CyRO-HVGykw4jCxIxH55AYb8js49hHMh8T9XtbUzpC6j-HDJfKV8UXN8LLogm-B1cjtGTRK8qc8PoX64lsEwz1zaCmqkIWn-OQJk67e-LmT8KDowbeSOg3sQ/w400-h229/Untitled.jpg" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">@tottie's gophers</td></tr></tbody></table><p></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">and game programmer @tenntenn:</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="320" src="https://lh7-us.googleusercontent.com/CUVhH12qbOL8GI_3X0QvP7YjH9NN91BGKjagEfrAhUlC4oOGGXItnka_sIPP3IOWP_FM_JcWM8g78J2EYKR8yVDu5K9UawjhsRjvFvdIJMiADIrkKii3T83CRnV7P0nSJSFts94n9i1fFrVIEPBeTx6tZQ=w320-h320" style="margin-left: auto; margin-right: auto;" width="320" /></td></tr><tr><td class="tr-caption" style="text-align: center;">@tenntenn's gopher</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But the "attribution" part of the license often resulted in frustrating arguments, or in false credit given to Renee for creations that were not hers and not in the spirit of the original. And, to be honest, the attribution was often honored only reluctantly or not at all. For instance, I doubt @tenntenn was compensated or even acknowledged for this use of his gopher illustration.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="225" src="https://lh7-us.googleusercontent.com/KZrk2URA2FoE8veKZVme44gkd7IYBunfsyM1k8eA6AFlrNqO-psuTaMqG3UOUmVuqE8gjgmpPTt6DOFX7nKAQk-HYluOp9tbvWjE01KxbkzLcWGkerZi3g2c2EQgeJOcCXA56eHh-fKDiPnG54kXu0UdaA=w400-h225" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">gophervans.com: Boo!</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">So if we were doing it over, we'd think hard about the best way to </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">make sure the mascot stays true to his ideals. It's a hard problem, </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">maintaining a mascot, and the solution remains elusive.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But on to more technical things.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>Done Right</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Here is a list of things that I think we got objectively right, </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">especially in retrospect.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Not every language project has done these things, but each was crucial to the ultimate success of Go. I'll try to be brief, because they will all be familiar topics.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>1.</b> Specification. We started with a formal specification. Not only </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">does that lock down behavior when writing a compiler, it enables </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">multiple implementations to coexist and agree on that behavior. A compiler alone is not a specification. What do you test the compiler against?</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="259" src="https://lh7-us.googleusercontent.com/2vxPLmSVO72PWo4h7i5SxZydZKgpApunogr52VEJwRHNL9JV9V-Mk0yH69vjY1ciPF1_seciItfyQluvKywn9PGelIF03zH4FWfBE-wnu7TMGHIaeCo3RoP3NnOnHXVYI1_j3B_cotdh_ivmyU8JhnnA5A=w640-h259" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr><tr><td class="tr-caption" style="text-align: center;">The specification, as seen on the web<br /></td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Oh and by the way, the first draft of the specification was written </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">here, on the 18th floor of a building on Darling Harbour in </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Sydney. We are celebrating Go's birthday in Go's home town.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>2.</b> Multiple implementations. There are multiple compilers, all </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">implementing the same spec. Having a spec makes this much easier to achieve.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><br /></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Ian Taylor surprised us when he sent mail one day informing us that, having read our draft spec, he'd written a compiler himself.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>Subject: A gcc frontend for Go</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>From: Ian Lance Taylor</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>Date: Sat, Jun 7, 2008 at 7:06 PM</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>To: Robert Griesemer, Rob Pike, Ken Thompson</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: courier; font-size: x-small;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>One of my office-mates pointed me at http://.../go_lang.html .<span class="Apple-converted-space"> </span>It</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>seems like an interesting language, and I threw together a gcc</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>frontend for it.<span class="Apple-converted-space"> </span>It's missing a lot of features, of course, but it</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: courier; font-size: x-small;"><span class="Apple-converted-space"> </span>does compile the prime sieve code on the web page.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">That was mind-blowing, but many more have followed, all made possible by the existence of a formal specification.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicO9e4BbHSZiS9EPn_5jYRkTOiEMimgXR667bKKDIJHdp2Gm96WgK11N23TYE6duBMP4j0zxexnFRjGk_ITVrhyphenhyphenP2zJ8ZLJzBSFu0Wk1bYz_1AjuZtPG7S4fXQvls9v1yZSsKWWM9hpX-WneJY2lSEEsY0FneqJeXq_4PP7BvNnPCFOXqSfNgcDw/s828/Untitled%202.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="654" data-original-width="828" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicO9e4BbHSZiS9EPn_5jYRkTOiEMimgXR667bKKDIJHdp2Gm96WgK11N23TYE6duBMP4j0zxexnFRjGk_ITVrhyphenhyphenP2zJ8ZLJzBSFu0Wk1bYz_1AjuZtPG7S4fXQvls9v1yZSsKWWM9hpX-WneJY2lSEEsY0FneqJeXq_4PP7BvNnPCFOXqSfNgcDw/w200-h158/Untitled%202.jpg" width="200" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Lots of compilers</td></tr></tbody></table><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span><p></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Having multiple compilers helped us refine the language and polish the specification, as well as providing an alternative environment for others less enamored with our Plan-9-like way of doing business.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">(More about that later.)</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Today there are lots of compatible implementations, and that's great.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>3.</b> Portability. We made cross-compilation trivial, which allowed</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">programmers to work on whatever platform they liked, and ship to whatever platform was required. This may be easier with Go than with any other language.<span class="Apple-converted-space"> </span>It's easy to think of the compiler as</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">native to the machine it runs on, but it has no reason to be.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Breaking that assumption is powerful and was news to many developers.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFK0jhjCUomSXuROX42M0PcdpMc0NmxkfQIqNek_dt6ePPvUTaCHMcZbZdlo-6qXZI-8zgfMfEeAtKmVuSvLfbvO4abXX6ns9hxyoAp53arLZ1jr6j6gFN6j2rHBosUNP2UTj__rw3aaGz8BU12DzfAZa8e45nvQlOy77z3hxO34JoJ2gTdfIsNg/s2368/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1456" data-original-width="2368" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFK0jhjCUomSXuROX42M0PcdpMc0NmxkfQIqNek_dt6ePPvUTaCHMcZbZdlo-6qXZI-8zgfMfEeAtKmVuSvLfbvO4abXX6ns9hxyoAp53arLZ1jr6j6gFN6j2rHBosUNP2UTj__rw3aaGz8BU12DzfAZa8e45nvQlOy77z3hxO34JoJ2gTdfIsNg/w400-h246/Untitled.jpg" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Portability</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><b style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">4.</b><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> Compatibility. We worked hard to get the language in shape for</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">version 1.0, and then locked it down with a compatibility guarantee. Given what a dramatic, documented effect that made on Go's uptake, I find it puzzling that most other projects have resisted doing this.<span class="Apple-converted-space"> </span>Yes, there's a cost in maintaining strong compatibility, but it blocks feature- itis and, in a world in which almost nothing else is stable, it's delightful not to have to worry about new Go releases breaking your project.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS5xASfv6sTVSZhDliz8zXe1GTUPw8Sdzip8aQHIyDfFft2SUwSRMsdCjIFR7o1UagxS3EmSMlBsFnu8QEL7KtkkwtsEYFekayW1QV_DKCXu-wIZLTIarmKPYERzBwmXmFMDcfTSbOOpYYttNdp9pcqDxaS_ydvJqbkDfKZNTIo-45A5ZGLhO5Ew/s2600/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1590" data-original-width="2600" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhS5xASfv6sTVSZhDliz8zXe1GTUPw8Sdzip8aQHIyDfFft2SUwSRMsdCjIFR7o1UagxS3EmSMlBsFnu8QEL7KtkkwtsEYFekayW1QV_DKCXu-wIZLTIarmKPYERzBwmXmFMDcfTSbOOpYYttNdp9pcqDxaS_ydvJqbkDfKZNTIo-45A5ZGLhO5Ew/w640-h392/Untitled.jpg" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The Go compatibility promise</td></tr></tbody></table><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span><p></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>5.</b> The library. Although it grew somewhat as an accident, as there was no other place to install Go code at the beginning, the existence of a solid, well-made library with most of what one needed to write 21st century server code was a major asset. It kept the community all working with the same toolkit until we had experience enough to understand what else should be made available. This worked out really well and helped prevent variant libraries from arising, helping unify the community.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_8S6Q1M6_8R7Zt7IZZKz5wwkzrv6DrSIIB8wRhArmfBcJwlw7JPjwDY9dPou3jB3DOZfzbvrop4T6Bmoyf2foW08f5jwIg7PNhU4NM0Hb2FhebCFliwGUQrxMnqYvcp75RlnEmmmOPNwTn4jSEaFJKG3WNe2XMp1p2dThGR-fzTjB-CHKd742ag/s2452/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1614" data-original-width="2452" height="211" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_8S6Q1M6_8R7Zt7IZZKz5wwkzrv6DrSIIB8wRhArmfBcJwlw7JPjwDY9dPou3jB3DOZfzbvrop4T6Bmoyf2foW08f5jwIg7PNhU4NM0Hb2FhebCFliwGUQrxMnqYvcp75RlnEmmmOPNwTn4jSEaFJKG3WNe2XMp1p2dThGR-fzTjB-CHKd742ag/w320-h211/Untitled.jpg" width="320" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The library</td></tr></tbody></table><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><br /></span><p></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>6.</b> Tools. We made sure the language was easy to parse, which enabled tool-building. At first we thought we'd need an IDE for Go, but easy tooling meant that, in time, the IDEs would come to Go. And along with gopls, they have, and they're awesome.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="237" src="https://lh7-us.googleusercontent.com/Orj-e3cQVo4pM6a9qWzsYqdCR4etcTgsLKCqTJ8N9c4ghr-mMH6jX-6PtOVrVmbI08O8PwCS-AyA37h2n3epwZ4Hx5UDO3FfIZn94TjcS_qxSlhXMsWBOz8-Eu2tn0KnyiiYSw_KRwpvTFBpy0xMnN7HBw=w400-h237" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Tools</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We also provided a set of ancillary tools with the compiler, such </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">as automated testing, coverage, and code vetting. And of course the go command, which integrated the whole build process and is all many projects need to build and maintain their Go code.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYd5UCtfFG80mmI2RFLBUFJmiyibsKJHS3_kJpwBxwDO3borgrsdz-h2a0vX2fkkfjLD5BtUQA1uuWoZ-VPRn7B6AkJSNcVZZ_V1CNmJSkVtygGLM0Xm5AIEV46rpCfwKY5eK1fDkFWTMX8EPeMXQisPYMJtXxmagpXMGHIc_dT6hyphenhyphennTiJVuu2zg/s2030/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1346" data-original-width="2030" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYd5UCtfFG80mmI2RFLBUFJmiyibsKJHS3_kJpwBxwDO3borgrsdz-h2a0vX2fkkfjLD5BtUQA1uuWoZ-VPRn7B6AkJSNcVZZ_V1CNmJSkVtygGLM0Xm5AIEV46rpCfwKY5eK1fDkFWTMX8EPeMXQisPYMJtXxmagpXMGHIc_dT6hyphenhyphennTiJVuu2zg/w400-h265/Untitled.jpg" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Fast builds</td></tr></tbody></table><p></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Also, it didn't hurt that Go acquired a reputation for fast builds.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>7.</b> Gofmt. I pull gofmt out as a separate item from tools because </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">it is the tool that made a mark not only on Go, but on the programming community at large. Before Robert wrote gofmt (which, by the way, he insisted on doing from the very beginning), automated formatters were not high quality and therefore mostly unused.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"></p><p class="p2" style="-webkit-text-stroke-width: 0px; color: black; font: 400 medium Times; letter-spacing: normal; margin: 0px; orphans: 2; text-align: left; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><p></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="-webkit-text-stroke-width: 0px; font-family: Times; letter-spacing: normal; margin-left: auto; margin-right: auto; orphans: 2; text-decoration-color: initial; text-decoration-style: initial; text-decoration-thickness: initial; text-transform: none; widows: 2; word-spacing: 0px;"><tbody><tr><td style="text-align: center;"><img height="222" src="https://lh7-us.googleusercontent.com/Dn_sduXHfRgwt578c4UxtjDb3_TKMZ06_AeYp0myRMjtdD5r5qxka3Jcu7YaZ8VF7iIfrESYFdDVE-2YRXFW-mnDdHiKF1_VDWXFZiUMNyTX_qRkacwc5eSDLBf01bATRXgof_j-xuk0fmBcUbx1TEFuQw=w400-h222" style="cursor: move; margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Gofmt proverb</td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Gofmt showed it could be done well, and today pretty much every language worth using has a standard formatter. The time saved by not arguing over spaces and newlines is worth all the time spent defining a standard format and writing this rather difficult piece of code to automate it.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Also, gofmt made countless other tools possible, such as simplifiers, analyzers and even the code coverage tool. Because gofmt's guts became a library anyone could use, you could parse a program, edit the AST, and just print byte-perfect output ready for humans to use as well as machines.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Thanks, Robert.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Enough with the congratulations, though. On to some more contentious topics.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><b>Concurrency</b></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Concurrency is contentious? Well, it certainly was in 2002, the </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">year I joined Google. John Ousterhout had famously written that </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">threads were bad, and many people agreed with him because </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">they seemed to be very hard to use.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="304" src="https://lh7-us.googleusercontent.com/BMVUWGXV637bSSUo6RaVnPuZJBJDsRP70IYNRP0HsvaPzPi3-Ovm9T6VMeop7HoZ1JaM96o4eoR4xNis9IyoqktyRsurr-fURWrOWktEJr8JCyVmz5V4Lwaobs9xHdsAhfRNoLgJsaF7SGeogqbHI-L8gw=w400-h304" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">John Ousterhout doesn't like threads</td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span id="docs-internal-guid-397e0f5c-7fff-73fb-9892-2f08655b91f6"></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Google software avoided them almost always, pretty much banning them outright, and the engineers doing the banning cited Ousterhout. This bothered me. I'd been doing concurrency-like things, sometimes without even realizing it, since the 1970s and it seemed powerful to me. But upon reflection it became clear that Ousterhout was making two mistakes. First, he was generalizing beyond the domain he was interested in using threads for, and second, he was mostly complaining about using them through with clumsy low-level packages like pthread, and not about the fundamental idea.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">It's a mistake common to engineers everywhere to confuse the solution and the problem like this. Sometimes the proposed solution is harder than the problem it addresses, and it can be hard to see there is an easier path. But I digress.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">I knew from experience that there were nicer ways to use threads, </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">or whatever we choose to call them, and even gave a pre-Go talk </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">about them.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="http://youtube.com/watch?v=hB05UFqOtFA" rel="nofollow" target="_blank"><img height="302" src="https://lh7-us.googleusercontent.com/GeRc6AtfheAKNQ8m31O0Y2s2TFLkZ39d8hadIjfzbenL_BwBktjznQiGpjkJpZppRRZorbGmITB1wI_dYxMZB1Ha4cyMR_gXgLjY5ZBfYbFlV01N3aLSHm2rYUWt0P6OQRz7xCl5HsLXyZcvw5jVwkPHvQ=w400-h302" style="margin-left: auto; margin-right: auto;" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Concurrency in Newsqueak</td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span id="docs-internal-guid-2b0289da-7fff-b00c-6572-21164181e508"></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">But I wasn't alone in knowing this; a number of other languages, </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">papers, and even books had been written about concurrent programming that showed it could be done well. It just hadn't caught on as a mainstream idea yet, and Go was born partly to address that. In that legendary 45-minute build I was trying to add a thread to a non-threaded binary, and it was frustratingly hard because we were using the wrong tools.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Looking back, I think it's fair to say that Go had a significant </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">role in convincing the programming world that concurrency was a powerful tool, especially in the multicore networked world, and that it could be done better than with pthreads. Nowadays most mainstream languages have good support for concurrency.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-iTVarT30e4zH1wpNyyXWtaImHDYQ9g7rhA_CFXvWrodamkus2jU4TelHvNpohapAPPOQfiXP9wwdnXqCjkGpR1FQ1PMgssZTIc8LUEjHUGFb9Swz1DMCOa6ch-UcsC3Zvv5LxWNvvKAL6C6pSulGhyphenhyphenyIrHOGPSu5LRmBuDZoRdOpb7W6qczqGw/s2412/Untitled.jpg" style="margin-left: auto; margin-right: auto; text-align: center;"><img border="0" data-original-height="1408" data-original-width="2412" height="234" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-iTVarT30e4zH1wpNyyXWtaImHDYQ9g7rhA_CFXvWrodamkus2jU4TelHvNpohapAPPOQfiXP9wwdnXqCjkGpR1FQ1PMgssZTIc8LUEjHUGFb9Swz1DMCOa6ch-UcsC3Zvv5LxWNvvKAL6C6pSulGhyphenhyphenyIrHOGPSu5LRmBuDZoRdOpb7W6qczqGw/w400-h234/Untitled.jpg" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Google 3.0<br /></td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Also, Go's version of concurrency was somewhat novel, at least in the line of languages that led to it, by making goroutines unflavored.<span class="Apple-converted-space"> </span>No coroutines, no tasks, no threads, no names, just goroutines. We invented the word "goroutine" because no existing term fit. And to this day I wish the Unix spell command would learn it.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">As an aside, because I am often asked about it, let me speak for a </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">minute about async/await.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">It saddens me a bit that the async/await model with its associated style is the way many languages have chosen to support concurrency, but it is definitely a huge improvement over pthreads.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Compared to goroutines, channels, and select, async/await is easier and smaller for language implementers to build or to retrofit into existing platforms. But it pushes some of the complexity back on the programmer, often resulting in what Bob Nystrom has famously called "colored functions".</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/" rel="nofollow" target="_blank"><img height="343" src="https://lh7-us.googleusercontent.com/KRFbbtCFJN8FJWTh0OJH3PW5ibMvqEd1Nzpkirk_ccdZ0T4QFhI_ADG6MbjhiAMu2_Yi1o-W1AIocWpECwi6g7V6UYf-JKECsWARTAutidgHeum3KR-yjFQp3Qhv99dnIuPfeJAPT_jMW0lrqdm9oOk1gw=w640-h343" style="margin-left: auto; margin-right: auto;" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;"><a href="https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/" rel="nofollow" target="_blank">What Color is Your Function?</a></td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">I think Go shows that CSP, which is a different but older model, </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">fits perfectly into a procedural language without such complication. I've even seen it done several times as a library. But its implementation, done well, requires a significant runtime complexity, and I can understand why some folks would prefer not to build that into their system. It's important, though, whatever concurrency model you provide, to do it exactly once, because an environment providing multiple concurrency implementations can be problematic. Go of course solved that issue by putting it in the language, not a library.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">There's probably a whole talk to give about these matters, but </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">that's enough for now.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">[End of aside]</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Another value of concurrency was that it made Go seem like something new.<span class="Apple-converted-space"> </span>As I said, some other languages had supported it before, but they were never mainstream, and Go's support for concurrency was a major attractor that helped grow early adoption, pulling in programmers that hadn't used concurrency before but were intrigued by its possibilities.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And that's where we made two significant mistakes.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="148" src="https://lh7-us.googleusercontent.com/OM6L9FABHYuZdskeZBIhwVjdH5L0zlOpdh-Iexvg8BOYDuGKhusFqsuB_WgeVgKNlhUj8lZN52r_BmTN5A5iC1ADQQgvqQui-MM-f1BeBcRJTNDkjAqmtW9o2n_e5q9ayHLRAZHov04ZUB18Es4k1ZOAaA=w400-h148" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Whispering gophers (Cooperating Sequential Processes)</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">First, concurrency is fun and we were delighted to have it, but the </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">use cases we had in mind</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">were mostly server stuff, meant to be done in key libraries such as net/http, and not everywhere in every program.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">And so when many programmers played with it, they struggled to work out how it really helped them.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">We should have explained up front that what concurrency support in the language really brought to the table was simpler server software.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">That problem space mattered to many but not to everyone who tried Go, and that lack of guidance is on us.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The related second point is that we took too long to clarify the </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">difference between parallelism - supporting multiple computations in parallel on a multicore machine - and concurrency, which is a way to structure code to do that well.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="133" src="https://lh7-us.googleusercontent.com/9G9ZFEqx9_ESzXDDlDN9lXBzYtYjNF0qwKN7ZDRmsEEd2DyEaWxLPQqWRggY3nWnPNWNzHnepHsy1QNkwuqte-IO5639pBUO8g6vmdCktQjl5Qgq9lhB3AXEc6UQzWUBaUl_x3UAypBYSVCnmuXh3sl60A=w400-h133" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;"><a href="https://www.youtube.com/watch?v=oV9rvDllKEg" rel="nofollow" target="_blank">Concurrency is not parallelism</a></td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Countless programmers tried to make their code faster by parallelizing it using goroutines, and were often baffled by the resulting slowdown. Concurrent code only goes faster when parallelized if the underlying problem is intrinsically parallel, like serving HTTP requests. We did a terrible job explaining that, and the result baffled many programmers and probably drove some away.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">To address this, in 2012 I gave a talk at Waza, Heroku's developer </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">conference, called, <a href="https://www.youtube.com/watch?v=oV9rvDllKEg" rel="nofollow" target="_blank">Concurrency is not Parallelism</a>. It's a fun </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">talk but it should have happened earlier.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Apologies for that. But the good point still stands: Go helped </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">popularize concurrency as a way to structure server software.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>Interfaces</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">It's clear that interfaces are, with concurrency, a distinguishing </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">idea in Go. They are Go's answer to objected-oriented design, in the original, behavior-focused style, despite a continuing push by newcomers to make structs carry that load.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Making interfaces dynamic, with no need to announce ahead of </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">time which types implement them, bothered some early critics, and still irritates a few, but it's important to the style of programming that Go fostered.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Much of the standard library is </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">built upon their foundation, and broader subjects such as testing </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">and managing dependencies rely heavily on their generous, "all </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">are welcome" nature.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">I feel that interfaces are one of the best-designed things in Go.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Other than a few early conversations about whether data should be included in their definition, they arrived fully formed on literally the first day of discussions.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="349" src="https://lh7-us.googleusercontent.com/_HpN7SQUWfsvyFOSIHTItIUWXwleQ_t0oE4vfG6WdiWlM8l5ur9xT4PE_kzkhqK3y7i2KXx4Xs9qlhtBAFU6ukx-3_H4GiTqBlRT8TtixDIkJWLpxYWVx8fgvwGRK6tCems5y2x6YKvkCEsd8_2OdLb1nA=w640-h349" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr><tr><td class="tr-caption" style="text-align: center;"><span id="docs-internal-guid-0b8d6292-7fff-4365-a25e-468ae0832111"><span style="background-color: white; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; vertical-align: baseline; white-space-collapse: preserve;"><span style="font-family: georgia; font-size: x-small;">A GIF decoder: an exercise in Go interfaces (Rob Pike and Nigel Tao 2011)</span></span></span></td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span id="docs-internal-guid-e503d169-7fff-a9be-a8c6-c61ce907ce97"></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And there is a story to tell there.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">On that famous first day in Robert's and my office, we asked the </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">question of what to do about polymorphism. Ken and I knew from C that qsort could serve as a difficult test case, so the three of us started to talk about how our embryonic language could implement a type-safe sort routine.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Robert and I came up with the same idea pretty much simultaneously: using methods on types to provide the operations that sort needed. That notion quickly grew into the idea that value types had behaviors, defined as methods, and that sets of methods could provide interfaces that functions could operate on. Go's interfaces arose pretty much right away.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbFJ-5NJ_QDF5NtzTqttnu5OdBBquGCPRmGEiEByyW96cuJeH_uqjQpb79689kdkcjWJvbTYXkkN4KXyAYL9irEKeyWeFzo-JAwOO9TKZtehp_TsfHkxTsKEFOHq-Q4zp7SInEaMg27onTGPCebTl6thtDZvU3fGYWX-tuKSk_WkXu2Om8aY510g/s2870/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1526" data-original-width="2870" height="341" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbFJ-5NJ_QDF5NtzTqttnu5OdBBquGCPRmGEiEByyW96cuJeH_uqjQpb79689kdkcjWJvbTYXkkN4KXyAYL9irEKeyWeFzo-JAwOO9TKZtehp_TsfHkxTsKEFOHq-Q4zp7SInEaMg27onTGPCebTl6thtDZvU3fGYWX-tuKSk_WkXu2Om8aY510g/w640-h341/Untitled.jpg" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">sort.Interface</td></tr></tbody></table><p></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">That's something that is not often not acknowledged: Go's sort is </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">implemented as a function that operates on an interface. This is </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">not the style of object-oriented programming most people were </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">familiar with, but it's a very powerful idea.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">That idea was exciting for us, and the possibility that this could become a foundational</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">programming construct was intoxicating.<span class="Apple-converted-space"> </span>When Russ joined, he soon pointed out how I/O would fit beautifully into this idea, and the library took place rapidly, based in large part on the three famous interfaces: empty, Writer, and Reader, holding an average of two thirds of a method each.<span class="Apple-converted-space"> </span>Those tiny methods are idiomatic to Go, and ubiquitous.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The way interfaces work became not only a distinguishing feature </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">of Go, they became the way we thought about libraries, and generality, and composition. It was heady stuff.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But we might have erred in stopping the conversation there.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">You see, we went down this path at least in part because we had </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">seen too often how generic programming encouraged a way of thinking that tended to focus on types before algorithms. Early abstraction instead of organic design. Containers instead of functions.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We defined generic containers in the language proper - maps, slices, arrays, channels - without giving programmers access to the genericity they contained. This was arguably a mistake. We believed, correctly I still think, that most simple programming tasks could be handled just fine by those types. But there are some that cannot, and the barrier between what the language provided and what the user could control definitely bothered some people.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">In short, although I wouldn't change a thing about how interfaces </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">worked, they colored our thinking in ways it took more than a decade to correct. Ian Taylor pushed us, from early on, to face this problem, but it was quite hard to do given the presence of interfaces as the bedrock of Go programming.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Critics often complained we should just do generics, because they </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">are "easy", and perhaps they can be in some languages, but the existence of interfaces meant that any new form of polymorphism had to take them into account. Finding a way forward that worked well with the rest of the language required multiple attempts, several aborted implementations, and many hours, days, and weeks of discussion. Eventually we roped in some type theorists to help out, led by Phil Wadler.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">And even today, with a solid generic model in the language, there are still lingering problems to do with the presence of interfaces as method sets.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5SS3786IKXJjs82x4-erKQdrijskx1rOwXBBVsefXsDLwZE5DDUJPRl9sMHzXc85WW8DY8qxQekd3JzuEKgUXqTvCBdpAcuVA8jn-vl_l8rfXoMCJ8_lP0dVmmlgy5lRVXf0yXVe8MPJ4XW6GlAmhsBJj0gpeJ4CpZZEmPR79RUdF9aLRjRWzPQ/s3016/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="552" data-original-width="3016" height="118" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5SS3786IKXJjs82x4-erKQdrijskx1rOwXBBVsefXsDLwZE5DDUJPRl9sMHzXc85WW8DY8qxQekd3JzuEKgUXqTvCBdpAcuVA8jn-vl_l8rfXoMCJ8_lP0dVmmlgy5lRVXf0yXVe8MPJ4XW6GlAmhsBJj0gpeJ4CpZZEmPR79RUdF9aLRjRWzPQ/w640-h118/Untitled.jpg" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">Generic sort specification</td></tr></tbody></table><p></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">The final answer, as you know, was to design a generalization of </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">interfaces that could absorb more forms of polymorphism, transitioning from "sets of methods" to "sets of types". It's a subtle but profound move, one that most of the community seems to be fine with, although I suspect the grumbling will never stop.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Sometimes it takes many years to figure something out, or even to figure out that you can't quite figure it out. But you press on.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">By the way, I wish we had a better term than "generics", which originated as the term for a different, data-structure-centric style of polymorphism. "Parametric polymorphism" is the proper term for what Go provides, and it's an accurate one, but it's an ugly mouthful. But "generics" is what we say, even though it's not quite right.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia;"><span style="font-variant-ligatures: no-common-ligatures;"><b>The Compiler</b></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><br /></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">One of the things that bothered the programming language community was that the early Go compiler was written in C. The proper way, in their opinion, was to use LLVM or a similar toolkit, or to write the compiler in Go itself, a process called self-hosting.<span class="Apple-converted-space"> </span>We didn't do either of these, for several reasons.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">First, bootstrapping a new language requires that at least the first </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">steps towards its compiler must be done in an existing language. For us, C was the obvious choice, as Ken had written a C compiler </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">already, and its internals could serve well as the basis of a Go </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">compiler. Also, writing a compiler in its own language, while </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">simultaneously developing the language, tends to result in a language that is good for writing compilers, but that was not the kind of language we were after.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The early compiler worked. It bootstrapped the language well. But </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">it was a bit of an odd duck, in effect a Plan 9-style compiler using </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">old ideas in compiler writing, rather than new ones such as static </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">single assignment.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">The generated code was mediocre, and the internals were not pretty.</span><span class="Apple-converted-space" style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"> </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">But it was pragmatic and efficient, and the compiler code itself was modest in size and familiar to us, which made it easy to make changes quickly as we tried new ideas. One critical step was the addition of segmented stacks that grew automatically. This was very easy to add to our compiler, but had we been using a toolkit like LLVM, the task of integrating that change into the full compiler suite would have been infeasible, given the required changes to the ABI and garbage collector support.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Another area that worked well was cross-compilation, which came directly from the way the </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">original Plan 9 compiler suite worked.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Doing it our way, however unorthodox, helped us move fast. Some people were offended by this choice, but it was the right one for us at the time.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="256" src="https://lh7-us.googleusercontent.com/rfL0OSI7StvNiafGcbDSiUrlI2rYep8MO4XD-IqhatdvmVE7bEzVXf-swzlY5hSUXNgPEbNhHCW6-0O7AZ4uDKeJmVffeXooYqI7kPIHGMp-xjoh7i2Y55dqozmUFlDFQRNcrVJdXzeLzX8zbejDpWG5PQ=w400-h256" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">The Go compiler architecture post Go 1.5</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">For Go version 1.5, Russ wrote a tool to translate the compiler </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">semi-automatically from C to Go. By then the language was complete, and concerns about compiler-directed language design were irrelevant. There are talks online about this process that are worth a look. I gave one talk at GopherCon in 2016 about the assembler, which is something of a high point in my lifelong quest for portability.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimGq0tHns5Y9_58sFB20zsiX2p3hVq8WOjzqYXXZmp2u_eOzUEDdiphs84V8JrUVaUc06eWS9T2GF81l77eY0XHkWXmaIS_srweJKKN1phwPZNawqTNUcoA1tkM9Xv31am_8vCVOqNsd0VOpMITgywSsanBCaiT1UMHe-2XlltxcNNVHEdBUq1vw/s2576/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1544" data-original-width="2576" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimGq0tHns5Y9_58sFB20zsiX2p3hVq8WOjzqYXXZmp2u_eOzUEDdiphs84V8JrUVaUc06eWS9T2GF81l77eY0XHkWXmaIS_srweJKKN1phwPZNawqTNUcoA1tkM9Xv31am_8vCVOqNsd0VOpMITgywSsanBCaiT1UMHe-2XlltxcNNVHEdBUq1vw/w400-h240/Untitled.jpg" width="400" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">The Design of the Go Assembler (GopherCon 2016)</td></tr></tbody></table><p></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We did the right thing by starting in C, but eventually translating </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">the compiler to Go has allowed us to bring to its development all </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">the advantages that Go has, including testing, tooling, automatic </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">rewriting, performance analysis, and so on. The current compiler </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">is much cleaner than the original and generates much better code. But, of course, that is how bootstrapping works.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Remember, our goal was just not a language, but much more.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Our unusual approach was in no way an insult to LLVM or anyone </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">in the language community. We just used the tool that best suited </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">our task. And of course, today there is an LLVM-hosted compiler for Go, and many others, as there should be.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>Project Management</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We knew from the start that to succeed, Go had to be an open source project. But we also knew that it would be more productive to develop in private until we had the key ideas figured out and a working implementation. Those first two years were essential to clarifying, free of distraction, what we were trying to achieve.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The transition to open source was a huge change, and educational. The input from the community was overwhelming. Engaging with the community took a lot of time and effort, especially for Ian, who somehow found time to answer every question anyone asked. But it also brought so much more. I still marvel at how quickly the Windows port arrived, done entirely by the community under the guidance of Alex Brainman. That was amazing.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">It took us a long time to understand the implications of the switch </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">to an open source project, and how to manage it.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">In particular, it's fair to say it took us too long to understand </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">the best way to work with the community. A theme throughout this talk is poor communication on our part - even as we thought we were communicating well - and a lot of time was wasted due to misunderstandings and mismatched expectations. It could have been better done.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">In time, though, we convinced the community, at least the part that stayed with us, that some of our ideas, although different from the usual open source way, were valuable. The most important were around our insistence on maintaining high code quality through mandatory code review and exhaustive attention to detail.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="297" src="https://lh7-us.googleusercontent.com/EM9rbPVLtezym_caYgRFi0ZfzLDCIBHMaBxS42GicnzjtGyPkl_dB74uqtSZa2qZcrudnsucXmQN47EuzIRiBW3GzgcapTJJHkqcCwpvKnp0f5fHYy4SVOOHGd7jct3mDp98GFMAKS_y6KXmL1wCLQaPuw=w400-h297" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Mission Control (drawing by Renee French)</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Some projects work differently, accepting code quickly and then </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">cleaning up once it's been committed. The Go project works the other way around, trying to get the quality first. I believe that's the more efficient way, but it pushes more work back on the community and they need to understand the value or they will not feel as welcome as they should. There is still much to learn here, but I believe things are much better these days.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">By the way, there's a historical detail that's not widely known. </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">The project has had 4 different content management systems: SVN, Perforce, Mercurial and then Git. Russ did a Herculean job of keeping all the history alive, so even today the Git repo contains the earliest changes as they were made in SVN. We all believe it's </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">valuable to keep the history around, and I thank him for doing the </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">heavy lifting.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">One other point. People often assume Google tells the Go team what to do. That's simply not true. Google is incredibly generous in its support for Go, but does not set the agenda. The community has far more input. Google has a huge internal Go code base that the team uses to test and verify releases, but this is done by importing from the public repo into Google, not the other way around. In short, the core Go team is paid by Google but they are independent.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>Package Management</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The process of developing package management for Go was not done well. The package design in the language itself was excellent, I believe, and consumed a large amount of time in the first year or so of our discussions. The SPLASH talk I mentioned earlier explains in detail why it works the way it does if you're interested.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">A key point was the use of a plain string to specify the path in </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">an import statement, giving a flexibility that we were correct in </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">believing would be important. But the transition from having only </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">a "standard library" to importing code from the web was bumpy.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="400" src="https://lh7-us.googleusercontent.com/qdkxLhGP5SGYw-vgB54RiqGJtEv2-PukXcGXvqYhWVz25QM_Aa0QyQUWLFONYd8uOvrOnOx2jxUJ75Lz0e7proBAVrMDnLPV3SVhfRcAEqVYqigWhd4vSYVXyPcZnIeqNiibzhSwWxW8hABFh_jDI1MYhw=w339-h400" style="margin-left: auto; margin-right: auto;" width="339" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Fixing the cloud (drawing by Renee French)</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">There were two issues.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">First, those of us on the core Go team early on were familiar with how Google worked, with its monorepo and everyone building at head. But we didn't have enough experience using a package manager with lots of versions of packages and the very difficult problems trying to resolve the dependency graph. To this day, few people really understand the technical complexities, but that is no excuse for our failure to grapple with those problems from the start. It's especially embarrassing because I had been the tech lead on a failed project to do something similar for Google's internal build, and I should have realized what we were up against.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><br /></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="273" src="https://lh7-us.googleusercontent.com/VY_aoD-8AaqPUOA4S5VOPLG5mUiSkgMTM3B4EUEJ_j4SdxbudG1shsRGnTe-AqEPFtuu6pEzeDCLSNvzWZ3afGRe5PY7muDLT_hKgMU78w9oCuXOAmvc5PGh_ra0-PQ5ENmK2s2O_hCKQyrXy4siliXEPg=w400-h273" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;"><a href="http://deps.dev">deps.dev</a></td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">My work on <a href="http://deps.dev">deps.dev</a> was a something of a penance.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Second, the business of engaging the community to help solve the dependency management problem was well-intentioned, but when the final design came out, even with plenty of documentation and writing about the theory, many in the community felt slighted.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="266" src="https://lh7-us.googleusercontent.com/LIqSeGgN3TE9ZTWbA7Z47ISmcBcDSnemtBpQ3jiookmTLfy7dWwi3ewK3Lnx4eEeXwVTCBvuk-B9aMnIXmwX5Nud78gmdC7FYjAMHkCieNAShoeYLPLuVAc75M3iCsGZyXGcmC_Ju567iu432TifJdcjGQ=w400-h266" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;"><a href="http://pkg.go.dev">pkg.go.dev</a></td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">This failing was a lesson to the team in how engagement with the community should really work, and much has improved since as a result.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Things are settled now, though, and the design that emerged is technically excellent and appears to be working well for most users. It just took too long and the road was bumpy.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>Documentation and Examples</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Another thing we didn't get right up front was the documentation. </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We wrote a lot of it, and thought we did a good job, but it soon </span></span><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">became clear that the community wanted a different level of </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">documentation than we expected.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="232" src="https://lh7-us.googleusercontent.com/_Yz8RnFyXvPbkx_Ze-3Uh47XMqRxzfFRKZdj1G8_01w36WxQGLZcA9oLHowHo2weeA0dSW3y4faFerQEjEadgm1giJJ1jaA7XWtw0pEDskTCtTgAIA0gCXwZunzy-DEKqemQZFyiPN0qDXBTnZD8K7VA2g=w400-h232" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Gophers fixing a Turing machine (drawing by Renee French)</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The key missing piece was examples of even the simplest functions. We thought that all you needed to do was say what something did; it took us too long to accept that showing how to use it was even more valuable.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="315" src="https://lh7-us.googleusercontent.com/adeTwrv9AgtHNZJypQBgKCb18ot3o24uTJko13zDpuf5rtsNDXiNeyEUK297_pj8a9DFXcUE0uEajthMvl0ThBHL44-KJ2OTBuNj6Vx7NRf-ueXklk5wy01Cr1dnwALtUFJv7EC5zNNQwuO_QOLNZeu2Eg=w640-h315" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr><tr><td class="tr-caption" style="text-align: center;">Executable examples</td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">That lesson was learned, though. There are plenty of examples in </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">the documentation now, mostly provided by open source contributors. And one thing we did very early was make them executable on the web. I gave a talk at Google I/O in 2012 that showed concurrency in action, and Andrew Gerrand wrote a lovely bit of web goo that made it possible to run the snippets right from the browser. I doubt that was the first time it had ever been done, but Go is a compiled language and many in the audience had never seen that trick before. The technology was then deployed to the blog and to the online package documentation.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;"><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="390" src="https://lh7-us.googleusercontent.com/aFHXWYuNyVZaZTaLwVvX3uidrrQW-2lbV-Xg9dZjaXbLiac4Unbgsf-l6h5T6YW6-XtKXVVNqaCPMa01nzuMe16No9E2tXA-Q0XTRi1KeWCMVugeHhnjQcPZkPrj31mdbm7UdDa5hVpbGcb5mWk15xkCCg=w640-h390" style="margin-left: auto; margin-right: auto;" width="640" /></td></tr><tr><td class="tr-caption" style="text-align: center;"><a href="https://go.dev/play/" rel="nofollow" target="_blank">The Go playground</a></td></tr></tbody></table><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span id="docs-internal-guid-b9e46eec-7fff-8f4a-c9ca-6c3710fbcd31"></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Perhaps even more important was its deployment to the Go playground, a freely available open sandbox for people to try things out, and even develop code.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><b>Conclusion</b></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We have come a long way.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Looking back, it's clear many things were done right, and they all helped Go succeed. But much could have been done better, </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">and it's important to own up to those and learn from them. There </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">are lessons on both sides for anyone hosting a significant open </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">source project.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">I hope that my historical tour of the lessons and their causes will </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">be helpful, and perhaps serve as a sort of apology/explanation for those who objected to what we were doing and how we were doing it.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><img height="400" src="https://lh7-us.googleusercontent.com/BWBPo-xXaifo9zq3Cspfqa6Ot4GjXf8dTKIvlbA1WQHuYNrbB3AeYh45OQo8Tf3fljo-clYT8mUVd-mDZgL5gYN9NOnKFXVAcyE0QPTKlxH0t9kFK4UOjPdzCqZnrs5Ao4c3YUkHhQYsEWtq0fAS-PRTyw=w400-h400" style="margin-left: auto; margin-right: auto;" width="400" /></td></tr><tr><td class="tr-caption" style="text-align: center;">GopherConAU 2023 mascot by Renee French</td></tr></tbody></table><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But here we are, 14 years after the launch. And it's fair to say that overall it's a pretty good place.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Largely because of the decisions made through the design and </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">development of Go as a way to write software - not just as a </span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">programming language - we have arrived somewhere novel.</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We got here in part because of:</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"></p><ul style="text-align: left;"><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">a strong standard library that implements most of the basics needed for server code</span></span></li><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">concurrency as a first-class component of the language</span></span></li><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">an approach based on composition rather than inheritance</span></span></li><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">a packaging model that clarifies dependency management</span></span></li><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">integrated fast build and testing tools</span></span></li><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">rigorous consistent formatting</span></span></li><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">a focus on readability over cleverness</span></span></li><li><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">a compatibility guarantee</span></span></li></ul><p></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And, most of all, because of the support of an unbelievably helpful and diverse community of Gophers.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span></p><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto;"><tbody><tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4juMexjG4kEsE4zT9mvxvSO_n8kbXjbb_x5WrfCje0FWe0hmFuvlEc0RYl4balyjwdEEulq-5mBaoJXAtF5F8Devq_s_q1j08g9iWcWOdVVfqQ1_8QxC2SJvaKMAnf9FUiN7CVpDMdfbXI2x9XvWFdaJutK-Ec7UnpWWQ97Drt9j1etydjTIqpg/s2922/Untitled.jpg" style="margin-left: auto; margin-right: auto;"><img border="0" data-original-height="1570" data-original-width="2922" height="344" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4juMexjG4kEsE4zT9mvxvSO_n8kbXjbb_x5WrfCje0FWe0hmFuvlEc0RYl4balyjwdEEulq-5mBaoJXAtF5F8Devq_s_q1j08g9iWcWOdVVfqQ1_8QxC2SJvaKMAnf9FUiN7CVpDMdfbXI2x9XvWFdaJutK-Ec7UnpWWQ97Drt9j1etydjTIqpg/w640-h344/Untitled.jpg" width="640" /></a></td></tr><tr><td class="tr-caption" style="text-align: center;">A diverse community (drawings by @tenntenn)</td></tr></tbody></table><p></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Perhaps the most interesting consequence of these matters is that Go code looks and works the same regardless of who's writing it, is largely free of factions using different subsets of the language, and is guaranteed to continue to compile and run as time goes on. That may be a first for a major programming language.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We definitely got that right.</span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Thank you.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><div class="separator" style="clear: both; text-align: center;"><br /></div><br /><div class="separator" style="clear: both; text-align: center;"><br /></div><br />robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-1895092628212827842023-12-06T01:56:00.000-08:002023-12-06T01:56:41.408-08:00Simplicity<p><span style="font-family: georgia;"><span><span style="font-size: 14px; font-variant-ligatures: no-common-ligatures;">In May 2009, Google hosted an internal "Design Wizardry" panel, with talks by Jeff Dean, </span></span></span><span style="font-family: georgia; font-size: 13px;">Mike Burrows, Paul Haahr, Alfred Spector, Bill Coughran, and myself.</span><span style="font-family: georgia;"><span style="font-size: 14px; font-variant-ligatures: no-common-ligatures;"> Here is a lightly edited transcript of my talk. Some of the details have aged out, but the themes live on, now perhaps more than ever.</span></span></p><p><span style="font-family: georgia; font-size: 14px; font-variant-ligatures: no-common-ligatures;">---</span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;"><br /></span></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Simplicity is better than complexity.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Simpler things are easier to understand, easier to build, easier to debug, and easier to maintain. Easier to understand is the most important, because it leads to the others. </span></span><span style="font-family: georgia; font-variant-ligatures: no-common-ligatures;">Look at the web page for google.com. One text box. Type your query, get useful results. That's brilliantly simple design and a major reason for Google's success. Earlier search engines had much more complicated interfaces. Today they have either mimicked ours, or feel really hard to use.</span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">That's google.com. But what about what's behind it? What about GWS? How you do you invoke it? I looked at the argument list of a running GWS (<a href="https://en.wikipedia.org/wiki/Google_Web_Server" target="_blank">Google Web Server</a>) instance. XX,XXX characters of configuration flags. XXX arguments. A few name backend machines. Some configure backends. Some enable or disable properties. Most of them are probably correct. I guarantee some of them are wrong or at least obsolete.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">So, here's my question: How can the company that designed google.com be the same company that designed GWS? The answer is that GWS configuration structure was not really designed. It grew organically. Organic growth is not simple; it generates fantastic complexity. Each piece, each change may be simple, but put together the complexity becomes overwhelming.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Complexity is multiplicative. In a system, like Google, that is assembled from components, every time you make one part more complex, some of the added complexity is reflected in the other components. It's complexity runaway.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">It's also endemic.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Many years ago, Tom Cargill took a year off from Bell Labs Research to work in development. He joined a group where every subsystem's code was printed in a separate binder and stored on a shelf in each office. Tom discovered that one of those subsystems was almost completely redundant; most of its services were implemented elsewhere. So he spent a few months making it completely redundant. He deleted 15,000 lines of code. When he was done, he removed an entire binder from everybody's shelf. He reduced the complexity of the system. Less code, less to test, less to maintain. His coworkers loved it.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But there was a catch. During his performance review, he learned that management had a metric for productivity: lines of code. Tom had negative productivity. In fact, because he was so successful, his entire group had negative productivity. He returned to Research with his tail between his legs.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">And he learned his lesson: complexity is endemic. Simplicity is not rewarded.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">You can laugh at that story. We don't do performance review based on lines of code.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But we're actually not far off. Who ever got promoted for deleting Google code? We revel in the code we have. It's huge and complex. New hires struggle to grasp it and we spend enormous resources training and mentoring them so they can cope. We pride ourselves in being able to understand it and in the freedom to change it.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Google is a democracy; the code is there for all to see, to modify, to improve, to add to. But every time you add something, you add complexity. Add a new library, you add complexity. Add a new storage wrapper, you add complexity. Add an option to a subsystem, you complicate the configuration. And when you complicate something central, such as a networking library, you complicate everything.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Complexity just happens and its costs are literally exponential.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">On the other hand, simplicity takes work—but it's all up front. Simplicity is very hard to design, but it's easier to build and much easier to maintain. By avoiding complexity, simplicity's benefits are exponential.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Pardon the solipsism but look at the query logging system. It's far from perfect but it was designed to be—and still is—the only system at Google that solves the particular, central problem it was designed to solve. Because it is the only one, it guarantees stability, security, uniformity of use, and all the economies of scale. There is no way Google would be where it is today if every team rolled out its own logging infrastructure.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But the lesson didn't spread. Teams are constantly proposing new storage systems, new workflow managers, new libraries, new infrastructure.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">All that duplication and proliferation is far too complex and it is killing us because the complexity is slowing us down.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We have a number of engineering principles at Google. Make code readable. Make things testable. Don't piss off the SREs. Make things fast.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Simplicity has never been on that list. But here's the thing: Simplicity is more important than any of them. Simpler designs are more readable. Simpler code is easier to test. Simpler systems are easier to explain to the SREs, and easier to fix when they fail.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Plus, simpler systems run faster.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Notice I said systems there, not code. Sometimes—not always—to make code fast you need to complicate it; that can be unavoidable. But complex systems are NEVER fast—they have more pieces and their interactions are too poorly understood to make them fast. Complexity generates inefficiency.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Simplicity is even more important than performance. Because of the multiplicative effects of complexity, getting 2% performance improvement by adding 2% complexity—or 1% or maybe even .1%—isn't worth it.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">But hold on! What about our Utilization Code Red?</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">We don't have utilization problems because our systems are too slow. We have utilization problems because our systems are too complex. We don't understand how they perform, individually or together. We don't know how to characterize their interactions.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The app writers don't fully understand the infrastructure.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The infrastructure writers don't fully understand the networks.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Or the apps for that matter. And so on and so on.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">To compensate, everyone overprovisions and adds zillions of configuration options and adjustments. That makes everything even harder to understand.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Products manage to launch only by building walls around their products to isolate them from the complexity—which just adds more complexity.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">It's a vicious cycle.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">So think hard about what you're working on. Can it be simpler? Do you really need that feature? Can you make something better by simplifying, deleting, combining, or sharing? Sit down with the groups you depend on and understand how you can combine forces with them to design a simpler, shared architecture that doesn't involve defending against each other.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">Learn about the systems that already exist, and build on them rather than around them. If an existing system doesn't do what you want, maybe the problem is in the design of your system, not that one.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">If you do build a new component, make sure it's of general utility. Don't build infrastructure that solves only the problems of your own team.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">It's easy to build complexity. In the rush to launch, it's quicker and easier to code than to redesign. But the costs accumulate and you lose in the long run.</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">The code repository contains 50% more lines of code than it did a year ago. Where will we be in another year? In 5 years?</span></span></p><p class="p2" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px; min-height: 16px;"><span style="font-family: georgia;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"></span><br /></span></p><p class="p1" style="font-feature-settings: normal; font-kerning: auto; font-optical-sizing: auto; font-size: 14px; font-stretch: normal; font-variant-alternates: normal; font-variant-east-asian: normal; font-variant-numeric: normal; font-variant-position: normal; font-variation-settings: normal; line-height: normal; margin: 0px;"><span class="s1" style="font-variant-ligatures: no-common-ligatures;"><span style="font-family: georgia;">If we don't bring the complexity under control, one day it won't be a Utilization Code Red. Things will get so complex, so slow, they'll just grind to a halt. That's called a Code Black.</span></span></p>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-59284881584003209712022-08-22T17:42:00.003-07:002022-09-05T19:08:50.812-07:00My black body story (it's physics).<p> I studied physics in university, and at one point asked a professor if I should learn German, because it seemed all the key texts of early 20th century physics were written by German-speaking physicists in German journals such as <i>Annalen der Physik</i>. But my prof assured me that was not needed, insisting that my own native language would serve me well. And he knew German, so his advice seemed sincere.</p><p>In the end he was right, but I still have an occasional pang of regret about never learning another language well enough. Wouldn't it be nice to read Einstein in the original? The <i>E</i>=<i>mc</i>² <a href="https://einsteinpapers.press.princeton.edu/vol2-trans/186" target="_blank">paper</a> is astonishing in its precision and brevity even in translation. (Although later physicists have criticisms of it, it remains a marvel). I did eventually pick up a bit of German, but not enough for Einstein.</p><p>Which brings me to <a href="https://en.wikipedia.org/wiki/Max_Planck" target="_blank">Max Planck</a>, who first quantized light, or so I was told.</p><p>By the third year of undergraduate physics, I had been taught the same derivation of the resolution of the <a href="https://en.wikipedia.org/wiki/Ultraviolet_catastrophe" target="_blank">"ultraviolet catastrophe"</a> at least three times. The classical (19th century) physics theory of a black body was clearly incomplete because the energy emitted was unbounded: higher and higher frequencies of light (the "ultraviolet") contributed ever more energy to the solution, leading to infinite energy regardless of the temperature (the "catastrophe"). By quantizing the light, Planck tamped down the runaway energy because as the frequency increased, the energy required to fill the quantized slots (photons) was no longer available, and the spectrum died down, as it does in the real world.</p><p>By the third or maybe fourth or fifth rendering of this story in class, I began to wonder: Why is the story always told this way? Why is the derivation always exactly the same? It almost seemed like a "just so" story, with the conclusion leading the analysis rather than the other way around. (But read on.) Or perhaps some pedagogue found a nice way to explain the theory to students, and that story was copied from textbook to textbook <i>ad infinitum</i>, eventually to become <i>the</i> story of the invention of quantum mechanics. In short, I was being taught a way to understand the physics, which is fine, but not how the ideas came to life, which left me wanting.</p><p>I wanted to investigate by going back to the original paper by Planck. But I couldn't read German, and as far as I knew there was no English translation of the original.</p><p>I visited my prof after class and asked him if he would help. He enthusiastically agreed, and we went off to the library to find the appropriate issue of <i>Annalen der Physik</i>. Fittingly, the paper was published in 1900.</p><p>Slowly, we—mostly he—worked our way through the paper. It was delightfully, completely, and utterly a 19th-century answer, not the 20th century one that was taught. Planck used thermodynamics, the jewel in the crown of 19th century physics, to derive the black body formula and create the 20th century. The argument was based on entropy, not energy. It had nothing to do, explicitly at least, with photons. But by focusing on the <i>entropy</i> of a set of indistinguishable oscillators at distinct frequencies, he could derive the correct formula in just a few pages. It was a <i>tour de force</i> of thermodynamic reasoning.</p><p>Why not teach us the historical derivation? The answer was now clear: This was a deep argument by a towering figure of 19th century physics, one that was beautiful but not a good fit for a 20th century, quantum-capable mind. Yes, Planck quantized the energy, but he did it as a mathematical trick, not a physics one. It was Einstein 5 years later, in his paper on the photoelectric effect, who made photons real by asserting that the quantization was not mere mathematics but due to a real, physical particle (or wave!). Us lowly students were being taught in a world that had photons already in place. Planck had no such luxury.</p><p>Another point I learned later, through the <a href="https://www.amazon.com/Subtle-Lord-Science-Albert-Einstein/dp/0192806726/" target="_blank">books</a> <a href="https://www.amazon.com/Inward-Bound-Matter-Forces-Physical/dp/0198519974" target="_blank">of</a> <a href="https://en.wikipedia.org/wiki/Abraham_Pais" target="_blank">Abraham Païs</a>, was that Planck knew the formula before he started. Using brilliantly precise experimental work by people in his laboratory, he recognized that the black body spectrum had a shape that he could explain mathematically. It required what we would now call quantization, a distribution over distinct states. In one evening, he found a way to derive that formula from the physics. It was not a matter of quantizing and finding it worked; quite the reverse. The analysis did in fact start from the conclusion, but not as we had been taught.</p><p>It's a lovely side detail that Einstein's Nobel Prize was for the photoelectric effect, not relativity as many assumed it would be at the time. The old guard that decided the prizes thought it was safe to give it to Einstein for his explanation, based on ideas by Planck, of a different vexing physics problem. That relativity stuff was too risqué just yet. In retrospect, making the photon real was probably Einstein's greatest leap, even though Planck and others of his generation were never comfortable with it. The Nobel committee got it right by accident.</p><p>To put all this together, what we learn through our education has always been filtered by those who came after the events. It can be easier to explain things using current ideas, but it's easy to forget that those who invented the ideas didn't have them yet. The act of creating them may only be well understood by stepping back to the time they were working.</p><p>I'm sorry I don't remember the professor's name. Our unpicking of the black body story was one of the most memorable and informative days of my schooling, and I will be forever grateful for it.</p><div><br /></div>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-65318726790146702212020-09-29T13:34:00.009-07:002020-10-02T13:49:50.317-07:00Color blindness<p><span style="font-family: Arial; font-size: 11pt; white-space: pre-wrap;">Color blindness is an inaccurate term. Most color-blind people can see color, they just don't see the same colors as everyone else.</span></p><span id="docs-internal-guid-dff89d18-7fff-456d-bfd8-1c99e13f78f7"><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">There have been a number of articles written about how to improve graphs, charts, and other visual aids on computers to better serve color-blind people. That is a worthwhile endeavor, and the people writing them mean well, but I suspect very few of them are color-blind because the advice is often poor and sometimes wrong. The most common variety of color blindness is called red-green color blindness, or deuteranopia, and it affects about 6% of human males. As someone who has moderate deuteranopia, I'd like to explain what living with it is really like.</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">The answer may surprise you.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">I see red and green just fine. Maybe not as fine as you do, but just fine. I get by. I can drive a car and I stop when the light is red and go when the light is green. (Blue and yellow, by the way, I see the same as you. For a tiny fraction of people that is not the case, but that's not the condition I'm writing about.)</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">If I can see red and green, what then is red-green color blindness?</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">To answer that, we need to look at the genetics and design of the human vision system. I will only be writing about moderate deuteranopia, because that's what I have and I know what it is: I live with it. Maybe I can help you understand how that impairment—and it is an impairment, however mild—affects the way I see things, especially when people make charts for display on a computer.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">There's a lot to go through, but here is a summary. The brain interprets signals from the eye to determine color, but the eye doesn't see colors. There is no red receptor, no green receptor in the eye. The color-sensitive receptors in the eye, called <i>cones</i>, don't work like that. Instead there are several different types of cones with broad but overlapping color response curves, and what the eye delivers to the brain is the </span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">difference</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> between the signals from nearby cones with possibly different color response. Colors are what the brain makes from those signals.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">There are also monochromatic receptors in the eye, called rods, and lots of them, but we're ignoring them here. They are most important in low light. In bright light it's the color-sensitive cones that dominate.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">For most mammals, there are two color response curves for cones in the eye. They are called warm and cool, or yellow and blue. Dogs, for instance, see color, but from a smaller palette than we do. The color responses are determined, in effect, by pigments in front of the light receptors, filters if you will. We have this system in our eyes, but we also have another, and that second one is the central player in this discussion.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">We are mammals, primates, and we are members of the branch of primates called Old World monkeys. At some point our ancestors in Africa moved to the trees and started eating the fruit there. The old warm/cool color system is not great at spotting orange or red fruit in a green tree. Evolution solved this problem by duplicating a pigment and mutating it to make a third one. This created three pigments in the monkey eye, and that allowed a new color dimension to arise, creating what we now think of as the red/green color axis. That dimension makes fruit easier to find in the jungle, granting a selective advantage to monkeys, like us, who possess it.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">It's not necessary to have this second, red/green color system to survive. Monkeys could find fruit before the new system evolved. So the red/green system favored monkeys who had it, but it wasn't <i>necessary</i>, and evolutionary pressure hasn't yet perfected the system. It's also relatively new, so it's still evolving. As a result, not all humans have equivalent color vision.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">The mechanism is a bit sloppy. The mutation is a "stutter" mutation, meaning that the pigment was created by duplicating the original warm pigment's DNA and then repeating some of its codon sequences. The quality of the new pigment—how much the pigment separates spectrally from the old warm pigment—is determined by how well the stutter mutation is preserved. No stutter, you get just the warm/cool dimension, a condition known as dichromacy that affects a small fraction of people, almost exclusively male (and all dogs). Full stutter, you get the normal human vision with yellow/blue and red/green dimensions. Partial stutter, and you get me, moderately red-green color-blind. Degrees of red-green color blindness arise according to how much stutter is in the chromosome.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Those pigments are encoded only on the X chromosome. That means that most males, being XY, get only one copy of the pigment genes, while most females, being XX, get two. If an XY male inherits a bad copy of the X he will be color-blind. An XX female, though, will be much less likely to get two bad copies. But some will get a good one </span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">and</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> a bad one, one from the mother and one from the father, giving them </span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">four</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> pigments. Such females are called tetrachromatic and have a richer color system than most of us, even than normal trichromats like you.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">The key point about the X-residence of the pigment, though, is that men are much likelier than women to be red-green color-blind.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Here is a figure from an article by Denis Baylor in an essay collection called </span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; text-decoration-skip-ink: none; vertical-align: baseline; white-space: pre-wrap;"><a href="https://www.amazon.com/Colour-Science-Darwin-College-Lectures/dp/0521496454" style="color: #1155cc; text-decoration-line: none;">Colour Art & Science,</a> edited by Trevor Lamb and Janine Bourriau, an excellent resource</span><span style="font-family: Arial; font-size: 11pt; white-space: pre-wrap;">.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 629px; overflow: hidden; width: 312px;"><img height="629" src="https://lh5.googleusercontent.com/_uUlaTOTL2VOjTaEK6VC1GQL3eJU1H3f_Sa6wMCzktahjUeA66egzEXBvA_9hE_JuF07MyYwF2SpHdv0ytjSQTecIExlZbv_qYs-pAIAAHv6QZv6oE3NiXTBNonoyQejE3NmZEIg" style="margin-left: 0px; margin-top: 0px;" width="312" /></span></span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">The top diagram shows the pigment spectra of a dichromat, what most mammals have. The bottom one shows the normal trichromat human pigment spectra. Note that two of the pigments are the same as in a dichromat, but there is a third, shifted slightly to the red. That is the Old World monkey mutation, making it possible to discriminate red. The diagram in the middle shows the spectra for someone with red-green color blindness. You can see that there are still three pigments, but the difference between the middle and longer-wave (redder) pigment is smaller.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">A deuteranope like me can still discriminate red and green, just not as well. Perhaps what I see is a bit like what you see when evening approaches and the color seems to drain from the landscape as the rods begin to take over. Or another analogy might be what happens when you turn the stereo's volume down: You can still hear all the instruments, but they don't stand out as well.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">It's worth emphasizing that there is no "red" or "green" or "blue" or "yellow" receptor in the eye. The optical pigments have very broad spectra. It's the </span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">difference</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> in the response between two receptors that the vision system turns into color.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">In short, I still see red and green, just not as well as you do. But there's another important part of the human visual system that is relevant here, and it has a huge influence on how red-green color blindness affects the clarity of diagrams on slides and such.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">It has to do with edge detection. The signals from receptors in the eye are used not only to detect color, but also to detect edges. In fact since color is detected largely by differences of spectral response from nearby receptors, the edges are important because that's where the strongest difference lies. The color of a region, especially a small one, is largely determined at the edges.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Of course, all animals need some form of visual processing that identifies objects, and edge detection is part of that processing in mammals. But the edge detection circuitry is not uniformly deployed. In particular, there is very little high-contrast detection capability for cool colors. You can see this yourself in the following diagram, provided your monitor is set up properly. The small pure blue text on the pure black background is harder to read than even the slightly less saturated blue text, and much harder than the green or red. Make sure the image is no more than about 5cm across to see the effect properly, as the scale of the contrast signal matters:</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 149px; overflow: hidden; width: 192px;"><img height="149" src="https://lh3.googleusercontent.com/3927UoIgyalKdIZwQnTHHE2YKxoMHilBWZfnD6LXIIAwZefhHJWbIgyA043dknzyOGyl8LcTR0Jxqi16LpLX6siBdha8s_IhqNfMPSe6XuerqiY5ODymG6SVVG-9B-p_szSIk1LE" style="margin-left: 0px; margin-top: 0px;" width="192" /></span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">In this image, the top line is pure computer green, the next is pure computer red, and the bottom is pure computer blue. In between is a sequence leading to ever purer blues towards the bottom. For me, and I believe for everyone, the bottom line is very hard to read.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Here is the same text field as above but with a white background:</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 149px; overflow: hidden; width: 192px;"><img height="149" src="https://lh3.googleusercontent.com/E3ibMjWZ7qUs0Gdx4u0jZYpFeTamQfe1ZQj8roPnw0dWxcGZWQp7q6BUuBcxWJ7bcg77pfCFQCwRoQuYcVubXahzbUja0vw4G98gDdq604Hk2XIl996hTxipRPo4kXeqHBcfhy_l=w195-h149" style="margin-left: 0px; margin-top: 0px;" width="192" /></span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Notice that the blue text is now easy to read. That's because it's against white, which includes lots of light and all colors, so it's easy for the eye to build the difference signals and recover the edges. Essentially, it detects a change of color from the white to the blue. Across the boundary the level of blue changes, but so do the levels red and green. When the background is black, however, the eye depends on the blue alone—black has no color, no light to contribute a signal, no red, no green—and that is a challenge for the human eye.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Now here's some fun: double the size of the black-backgrounded image and the blue text becomes disproportionately more readable:</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 298px; overflow: hidden; width: 384px;"><img height="298" src="https://lh3.googleusercontent.com/XnnbY9BKZzLqkEW4P4rEGCsdmkIx6cHOMNshR9mZQRxjt7pijzbbjfYunfrJgNTvHD_LOIsplXnPuZtms45DAYAGvQwperTdtfYXZZ_J2nOTR1OEa7Z8qcZUyBMDhTpk6a6ZjlPn" style="margin-left: 0px; margin-top: 0px;" width="384" /></span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Because the text is bigger, more receptors are involved and there is less dependence on edge detection, making it easier to read the text. As I said above, the scale of the contrast changes matters. If you use your browser to blow up the image further you'll see it becomes even easier to read the blue text.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">And that provides a hint about how red-green color blindness looks to people who have it.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">For red-green color-blind people, the major effect comes from the fact that edge detection is weaker in the red/green dimension, sort of like blue edge detection is for everyone. Because the pigments are closer together than in a person with regular vision, if the color difference in the red-green dimension is the only signal that an edge is there, it becomes hard to see the edge and therefore hard to see the color. </span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">In other words, the problem you have reading the blue text in the upper diagram is analogous to how much trouble a color-blind person has seeing detail in an image with only a mix of red and green. And the issue isn't between computer red versus computer green, which are quite easy to tell apart as they have very different spectra, but between more natural colors on the red/green dimension, colors that align with the naturally evolved pigments in the cones.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">In short, color detection when looking at small things, deciding what color an item is when it's so small that only the color difference signal at the edges can make the determination, is worse for color-blind people. Even though the colors are easy to distinguish for large objects, it's hard when they get small.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">In this next diagram I can easily tell that in the top row the left block is greenish and the right block is reddish, but in the bottom row that is a </span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">much</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"> harder distinction for me to make, and it gets even harder if I look from father away, further shrinking the apparent size of the small boxes. From across the room it's all but impossible, even though the colors of the upper boxes remain easy to identify.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><span style="border: none; display: inline-block; height: 138px; overflow: hidden; width: 192px;"><img height="138" src="https://lh5.googleusercontent.com/pd_IvLv0RnRM7vyM8FOmAaTI9Fk9dnwv89peRxQ0yHsAXm2iuOcGbdXVS2TIQfrw4IkLCkqeRgFjOKnMAwN2m26t51BA1dPNxooGcwcIk0U17p8ACg1nFM0NKqw0zPchsIKsccJ1" style="margin-left: 0px; margin-top: 0px;" width="192" /></span></span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Remember when I said I could see red and green just fine? Well, I can see the colors just fine (more or less). But that is true only when the object is large enough that the color analysis isn't being done </span><span style="font-family: Arial; font-size: 11pt; font-style: italic; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">only by edge detection</span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">. Fields of color are easy, but lines and dots are very hard.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Here's another example. Some devices come with a tiny LED that indicates charging status by changing color: red for low battery, amber for medium, and green for a full charge. I have a lot of trouble discriminating the amber and green lights, but can solve this by holding the light very close to my eye so it occupies a larger part of the visual field. When the light looks bigger, I can tell what color it is.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Another consequence of all this is that I see very little color in the stars. That makes me sad.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Remember this is about color, just color. It's easy to distinguish two items if their colors are close but their intensities, for example, are different. A bright red next to a dull green is easy to spot, even if the same red dulled down to the level of the green would not be. Those squares above are at roughly equal saturations and intensities. If not, it would be easier to tell which is red and which is green.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">To return to the reason for writing this article, red/green color blindness affects legibility. The way the human vision system works, and the way it sometimes doesn't work so well, implies there are things to consider when designing an information display that you want to be clearly understood.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">First, choose colors that can be easily distinguished. If possible, keep them far apart on the spectrum. If not, differentiate them some other way, such as by intensity or saturation.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Second, use other cues if possible. Color is complex, so if you can add another component to a line on a graph, such as a dashed versus dotted pattern, or even good labeling, that helps a lot.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Third, edge detection is key to comprehension but can be tricky. Avoid difficult situations such as pure blue text on a black background. Avoid tiny text.</span></p><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">Fourth, size matters. Don't use the thinnest possible line. A fatter one might work just as well for the diagram but be much easier to see and to identify by color.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">And to introduce one last topic, some people, like me, have old eyes, and old eyes have much more trouble with scattered light and what that does to contrast. Although dark mode is very popular these days, bright text on a black background scatters in a way that makes it hard to read. The letters have halos around them that can be confusing. Black text on a white background works well because the scatter is uniform and doesn't make halos. It's fortunate that paper is white and ink is black, because that works well for all ages.</span></p><br /><p dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;"><span style="font-family: Arial; font-size: 11pt; font-variant-east-asian: normal; font-variant-numeric: normal; vertical-align: baseline; white-space: pre-wrap;">The most important lesson is to not assume you know how something appears to a color-blind person, or to anyone else for that matter. If possible, ask someone you know who has eyes different from yours to assess your design and make sure it's legible. The world is full of people with vision problems of all kinds. If only the people who used amber LEDs to indicate charge had realized that.</span></p><br /></span>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-76584952625493330412020-04-04T15:19:00.000-07:002020-04-04T15:19:28.414-07:00Smiles<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13.2px;">(Another resurrected post from the my old Google+ stream, which appeared on or about Dec 6, 2011.)</span><br />
<span style="background-color: white; color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: 13.2px;"><br /></span>
<span style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;">For unknown reasons, someone asked me if had a copy of this file today. I didn't, but I remembered it was in dmr's home directory, and asked a friend there to find it. I remembered correctly. I don't know why it was touched in 1993, but the .v (mips object file) was created in late 1992. I leave the significance of that date as an exercise for the reader.</span><br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" /><br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" /><span style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;">By the way, sizeof(void) is illegal, so I'm unsure how it was compiled; my friend assures me the compilers from then didn't accept it either.</span><br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" /><br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" /><span style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;">Because G+ refuses to leave the indentation alone and screws up the ls formatting, I'm posting a screen grab here, but i'll include the source code, poorly formatted and rudely scrubbed of indentation, so you can play with the bytes. Just for fun, after the first screen grab I'll post a second screen grab of this post in edit mode before I hit save.</span><br />
<span style="font-size: 14.6667px;"><span style="font-family: Arial, Helvetica, sans-serif;"><br /></span></span>
<div class="main-content" style="font-size: 14.6667px; margin: 15px 0px;">
<span itemprop="text"><span style="font-family: Arial, Helvetica, sans-serif;">#include <u.h><br />#include <libc.h><br /><br />typedef int ☺☹☻;<br />typedef void ☹☺☻;<br />enum<br />{<br /> ☹☻☺ = sizeof(☺☹☻),<br /> ☻☺☹ = sizeof(☹☺☻),<br />};<br /><br />☹☺☻<br />main(☹☺☻)<br />{<br /> ☺☹☻ ☺☻☹;<br /><br /> for(☺☻☹=☻☺☹; ☺☻☹<☹☻☺; ☺☻☹++)<br /> print("☺☻☹ = %d\n", ☺☻☹);<br /> exits(☻☺☹);<br />}</span></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-uX7Xs-rYbg8/XokG6ph5AuI/AAAAAAAA8vw/2DNE73rSJ5o0FeLpsPirqbFGy1TUPo2CQCLcBGAsYHQ/s1600/s1.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" data-original-height="435" data-original-width="602" src="https://1.bp.blogspot.com/-uX7Xs-rYbg8/XokG6ph5AuI/AAAAAAAA8vw/2DNE73rSJ5o0FeLpsPirqbFGy1TUPo2CQCLcBGAsYHQ/s1600/s1.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-2LukP7dJgBs/XokHhbfPTNI/AAAAAAAA8v4/0EFcKUwrf0MMeH14iVma0yVkWDJAuKa3QCLcBGAsYHQ/s1600/s2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1010" data-original-width="522" src="https://1.bp.blogspot.com/-2LukP7dJgBs/XokHhbfPTNI/AAAAAAAA8v4/0EFcKUwrf0MMeH14iVma0yVkWDJAuKa3QCLcBGAsYHQ/s1600/s2.png" /></a></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-43196754805005368662020-01-26T21:20:00.000-08:002020-01-26T21:20:21.471-08:00UTF-8 turned 20 years old (in 2012)<span style="font-family: Arial, Helvetica, sans-serif;">(Another resurrected post from the my old Google+ stream, which appeared on or about Sep 4, 2012. Thirty years of age isn't too far off now.)<br /><br /><br />UTF-8 turned 20 years old yesterday.<br /><br />It's been well documented elsewhere (<a class="ot-anchor bidi_isolate" dir="ltr" href="http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt" jslog="10929; track:click" rel="nofollow" target="_blank">http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt</a>) that one Wednesday night, after a phone call from X/Open, Ken Thompson and I were sitting in a New Jersey diner talking about how best to represent Unicode as a byte stream. Given the experience we had accumulated dealing with the original UTF, which had many problems, we knew what we wanted. X/Open had offered us a deal: implement something better than their proposal, called FSS/UTF (File System Safe UTF; the name tells you something on its own), and do so before Monday. In return, they'd push it as existing practice.<br /><br />UTF was awful. It had modulo-192 arithmetic, if I remember correctly, and was all but impossible to implement efficiently on old SPARCs with no divide hardware. Strings like "/*" could appear in the middle of a Cyrillic character, making your Russian text start a C comment. And more. It simply wasn't practical as an encoding: think what happens to that slash byte inside a Unix file name.<br /><br />FSS/UTF addressed that problem, which was great. Big improvement though it was, however, FSS/UTF was more intricate than we liked and lacked one property we insisted on: If a byte is corrupted, it should be possible to re-synch the encoded stream without losing more than one character. When we claimed we wanted that property, and sensed we could press for a chance to design something <i>right</i>, X/Open gave us the green light to try.<br /><br />The diner was the Corner Café in New Providence, New Jersey. We just called it Mom's, to honor the previous proprietor. I don't know if it's still the same, but we went there for dinner often, it being the closest place to the Murray Hill offices. Being a proper diner, it had paper placemats, and it was on one of those placemats that Ken sketched out the bit-packing for UTF-8. It was so easy once we saw it that there was no reason to keep the placemat for notes, and we left it behind. Or maybe we did bring it back to the lab; I'm not sure. But it's gone now.<br /><br />I'll always regret that.<br /><br />But that's my only regret in this story. UTF-8 has made the world a better place and I am delighted to have been a facilitator in its creation.<br /><br />So tonight, please give a toast to a few quickly sketched boxes on a placemat in a New Jersey diner that today define how humans represent their text to be sent across international boundaries (<a class="ot-anchor bidi_isolate" dir="ltr" href="http://googleblog.blogspot.com/2012/02/unicode-over-60-percent-of-web.html" jslog="10929; track:click" rel="nofollow" target="_blank">http://googleblog.blogspot.com/2012/02/unicode-over-60-percent-of-web.html</a>), and especially to the X/Open folks for giving us the chance and the Unicode consortium and IETF for pushing it so successfully.<br /><br />Signed,<br />-rob<br />U+263A '☺' white smiling face</span><br />
<span style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;"><br /></span>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-48384970520450465562020-01-22T01:30:00.000-08:002020-01-22T15:10:08.397-08:00Unix Quiz answers<span style="background-color: white; color: #101010; font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">(Here's the next resurrected post, this time from Jun 8, April 30, 2012.)</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;"><br /></span>
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">A while back I posted the questions from the 1984 Unix/mpx Exit quiz:</span><span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;"> </span><a href="https://commandcenter.blogspot.com/2020/01/unix-quiz.html">https://commandcenter.blogspot.com/2020/01/unix-quiz.html</a><br />
<div style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px; margin-bottom: 1em;">
<div class="main-content" style="margin: 15px 0px;">
<span itemprop="text"><br />Here they are again, with annotated answers. The answers are in the form of the simplified pattern that the mpx exit program used to verify them.<br /><br />Note: I have never seen a correct set of answers posted on line except when they originated from this list. In other words, I don't believe anyone ever got all the questions correct, even with a web search engine. It may not even be possible.<br /><br />1. Q:The source code motel: your source code checks in, but it never checks out. What is it?<br />A:sccs<br />The Source Code Control System. The reference is to the Roach Motel.<br /><br />2. Q: Who wrote the first Unix screen editor?<br />A: irons<br />Ned Irons wrote a full-screen editor (the first?) at IDA in the 1960s and a Unix version, perhaps a translation, at Yale a few years later.<br /><br />3. Q: Using TSO is like kicking a {what?} down the beach.<br />A: dead whale<br />The quote is from Steve Johnson. For those of you who never experienced TSO, it's an accurate characterization.<br /><br />4. Q: What is the filename created by the original dsw(1)?<br />A: core<br />Setting the file's i-number using the switches on the front panel was the other half of its user interface.<br /><br />5. Q: Which edition of Unix first had pipes?<br />A: third | 3<br />Look it up.<br /><br />6. Q: What is <span style="font-family: "lucida grande mono550"; font-size: 14px;">=O=?</span><br />A: empire<br />Empire was a large-scale strategy game developed at Reed College and made a computer game by Peter Langston (and perhaps others?).<br /><br />7. Q: Which Stephen R. Bourne wrote the shell?<br />A: software | 1138 | regis<br />There were two people named Stephen R. Bourne working at SGI in the early 1980s. The one who wrote software (as opposed to designing hardware), who had worked in BTL Center 1138, or whose middle name was Regis: he wrote the shell.<br /><br />8. Q: Adam Buchsbaum's original login was sjb. Who is sjb?<br />A: sol & buchsbaum<br />Adam was one of many Unix room kids with parents who worked at the Bell Labs. Adam was unusual because his father was executive vice president but apparently didn't have enough clout to get his kid his own login.<br /><br />9. Q: What was the original processor in the Teletype DMD-5620?<br />A: mac & 32<br />The 5620 was the productized Blit. Trick question: most people thought the 5620, like the Blit, had a 68000 but it used the much less suitable yet more expensive BELLMAC-32.<br /><br />10. Q: What was the telephone extension of the author of mpx(2)?<br />A: 7775<br />The (2) here is important. Greg Chesson wrote mpx(2); I wrote mpx(8).<br /><br />11. Q: Which machine resulted in the naming of the "NUXI problem"?<br />A: series 1 | series one<br />The IBM Series/1 was big-endian. Swap the bytes of "UNIX", the first text printed as Unix booted.<br /><br />12. Q: What customs threat is dangerous only when dropped from an airplane?<br />A: belle | chess machine<br />Ken Thompson took Belle (the chess machine) to the Soviet Union for a tour. Well, he tried: the machine was impounded by U.S. customs and never left American soil. Ken's trip was not much fun.<br /><br />13. Q: Who wrote the Bourne Shell?<br />A: bourne<br />The only real gimme in the list. Feels like a trick question though.<br /><br />14. Q: What operator in the Mashey shell was replaced by "here documents"?<br />A: pump<br />Sometimes better ideas do win out.<br /><br />15. Q: What names appear on the title page of the 3.0 manual?<br />A: dolotta & petrucelli & olsson<br />This refers to System 3, two before System V. It always makes your technology seem more modern when you use Roman numerals.<br /><br />16. Q: Sort the following into chronological order: a) PWB 1.2, b) V7, c) Whirlwind, e) System V, f) 4.2BSD, g) MERT.<br />A: cagbef<br />Whirlwind is a ringer.<br /><br />17. Q: The CRAY-2 will be so fast it {what?} in 6 seconds.<br />A: infinite | np-complete | p=np<br />What can I say? The whole exercise was juvenile.<br /><br />18. Q: How many lights are there on the front panel of the original 11/70?<br />A: 52<br />We counted.<br /><br />19. Q: What does FUBAR mean?<br />A: failed unibus address register<br />It's really a register name on the VAX-11/780. Someone at DEC liked us.<br /><br />20. Q: What does "joff" stand for?<br />A: jerq obscure feature finder<br />Tom Cargill's debugger changed its name soon after we were pressured by management to change Jerq to Blit.<br /><br />21. Q: What is "Blit" an acronym of?<br />A: nothing<br />Whatever people thought, even those who insisted on spelling it BLIT, Blit was not an acronym.<br /><br />22. Q: Who was rabbit!bimmler?<br />A: rob<br />See Chapter 1 of The Unix Programming Environment for another theory.<br /><br />23. Q: Into how many pieces did Ken Thompson's deer disintegrate?<br />A: three | 3<br />During takeoff at Morristown airport, propeller meets deer; venison results.<br /><br />24. Q: What name is most common at USENIX conferences?<br />A: joy | pike<br />Sun Microsystems made these obnoxious conference badges that said, "The Joy of UNIX". We retaliated.<br /><br />25. Q: What is the US patent number for the setuid bit?<br />A: 4135240<br />Dennis Ritchie was granted the only patent that came out of Research Unix.<br /><br />26. Q: What is the patent number that appears in Unix documentation?<br />A: 2089603<br />I'm not a fan of this stuff. Look it up yourself.<br /><br />27. Q: Who satisfied the patent office of the viability of the setuid bit patent?<br />A: faulkner<br />At a time when software patents were all but unknown, Roger Faulkner demonstrated to a judge that the patent was sufficiently well explained by taking a Unix kernel without it and putting it in, given the patent text. A clean-room recreation, if you will.<br /><br />28. Q: How many Unix systems existed when the Second Edition manual was printed?<br />A: 10 | ten<br />It's right there in the introduction.<br /><br />29. Q: Which Bell Labs location is HL?<br />A: short hills<br />Easy for Labbers, not so easy for others. MH was Murray Hill.<br /><br />30. Q: Who mailed out the Sixth Edition tapes?<br />A: biren | irma<br />Packages from Irma Biren were very popular in some circles.<br /><br />31. Q: Which University stole Unix by phone?<br />A: waterloo<br />Software piracy by modem. I'm not telling.<br /><br />32. Q: Who received the first rubber chicken award?<br />A: mumaugh<br />I don't remember what this was about, and the on-line references are all about this quiz.<br /><br />33. Q: Name a feature of C not in Kernighan and Ritchie.<br />A: enum | structure assignment | void<br />K&R (pre-ANSI) was pretty old.<br /><br />34. Q: What company did cbosg!ccf work for?<br />A: weco | western<br />Western Electric. Chuck Festoon was created by Ron Hardin as a political statement about automated document processing.<br /><br />35. Q: What does Bnews do?<br />A: suck | gulp buckets<br />Obscure now, but this was a near-gimme at the time.<br /><br />36. Q: Who said "Sex, Drugs, and Unix?"<br />A: tilson<br />Mike Tilson handed out these badges at an earlier USENIX. They were very popular, although the phrase doesn't scan in proper Blockhead style.<br /><br />37. Q: What law firm distributed Empire?<br />A: dpw | davis&polk&wardwell<br />Peter Langston worked for this Manhattan law firm, whose computer room had a charming view of FDR Drive.<br /><br />38. Q: What computer was requested by Ken Thompson, but refused by management?<br />A: pdp-10 | pdp10<br />Sic.<br /><br />39. Q: Who is the most obsessed private pilot in USENIX?<br />A: goble | ghg<br />Cruel but fair.<br /><br />40. Q: What operating system runs on the 3B-20D?<br />A: dmert | unix/rtr<br />DMERT gives you dial tone. The D stands for dual, as in dual-processor for redundancy. In a particular Bell System way, it was an awesome machine.<br /><br />41. Q: Who wrote find(1)?<br />A: haight<br />Dick Haight also wrote cpio(1), which to my knowledge was the first Unix program that did nothing at all unless you gave it options.<br /><br />42. Q: In what year did Bell Labs organization charts become proprietary?<br />A: 83<br />And soon after, PJW appeared.<br /><br />43. Q: What is the Unix epoch in Cleveland?<br />A: 1969 & dec & 31 & 19:00<br />Easy.<br /><br />44. Q: What language preceded C?<br />A: nb<br />Between B and C was NB. B was interpreted and typeless. NB was compiled and barely typed. C added structs and became powerful enough to rewrite the Unix kernel.<br /><br />45. Q: What language preceded B?<br />A: bon | fortran<br />BCPL is not the right answer.<br /><br />46. Q: What letter is mispunched by bcd(6)?<br />A: r<br />This trick question was used to verify that a Unix knock-off was indeed a clean-room reimplementation. Or maybe they just fixed the bug.<br /><br />47. Q: What terminal does the Blit emulate?<br />A: jerq<br />Despite what Wikipedia claims at the time I'm writing this, the Blit did not boot up with support for any escape sequences.<br /><br />48. Q: What does "trb" stand for (it's Andy Tannenbaum's login)?<br />A: tribble<br />I honestly never knew why this moniker was applied to Andy (no, the other one), although I can guess.<br /><br />49. Q: allegra!honey is no what?<br />A: lady<br />Peter Honeyman is many things, but ladylike, no.<br /><br />50. Q: What is the one-line description in vs.c?<br />A: screw works interface<br />From the man page for the driver for the Votrax speech synthesizer.<br /><br />51. Q: What is the TU10 tape boot for the PDP-11/70 starting at location 100000 octal?<br />A: 012700 172526 010040 012740 060003 105710 012376 005007<br />It's in the book. There was a sad time when I not only had this memorized, it was in muscle memory.<br /><br />52. Q: What company owns the trademark on Writer's Workbench Software?<br />A: at & t communications<br />AT&T never could decide what it was to call itself.<br /><br />53. Q: Who designed Belle?<br />A: condon | jhc<br />Joe Condon, hardware genius, died just a few months ago. Belle was the first computer to achieve international master status, using (roughly speaking) Joe's hardware and Ken's software.<br /><br />54. Q: Who coined the name "Unix"?<br />A: kernighan | bwk<br />This one is well known.<br /><br />55. Q: What manual page mentioned Urdu?<br />A: typo<br />I miss the typo command and occasionally think of recreating it.<br /><br />56. Q: What politician is mentioned in the Unix documentation?<br />A: nixon<br />The Nixon era was a dark period for people maintaining time zone tables.<br /><br />57. Q: What program was compat(1) written to support?<br />A: zork | adventure<br />My memory is rusty on this one and I don't have the 6th Edition manual to hand.<br /><br />58. Q: Who is "mctesq"?<br />A: michael & toy & esquire<br />Michael Toy wrote rogue...<br /><br />59. Q: What was "ubl"?<br />A: rogue | under bell labs<br />... which Peter Weinberger renamed ubl when he imported it. The renaming made sense to anyone who worked at Murray Hill.<br /><br />60. Q: Who bought the first commercial Unix license?<br />A: rand<br />The RAND Corporation led the way.<br /><br />61. Q: Who bought the first Unix license?<br />A: columbia<br />Columbia University.<br /><br />62. Q: Who signed the Sixth Edition licenses?<br />A: shahpazian<br />He was the lawyer who literally signed off on the licenses.<br /><br />63. Q: What color is the front console on the PDP-11/45 (exactly)?<br />A: puce<br />That's what DEC called it. It's not puce at all, which is why it's a good trivia question.<br /><br />64. Q: How many different meanings does Unix assign to '.'?<br />A: lots | many | countless | myriad | thousands<br />Ken's favorite character on the keyboard.<br /><br />65. Q: Who said "Smooth rotation butters no parsnips?"<br />A: john & tukey<br />John Tukey discovered/invented the Fast Fourier Transform algorithm, coined the term "bit" for Claude Shannon, and of course uttered this unforgettable gem.<br /><br />66. Q: What was the original name for cd(1)?<br />A: ch<br />You answered chdir, didn't you? You were wrong.<br /><br />67. Q: Which was the first edition of the manual to be typeset?<br />A: 4 | four<br />The old phototypesetting process was much smellier than a modern printer.<br /><br />68. Q: Which was the first edition of Unix to have standard error/diagnostic output?<br />A: 5 | five<br />The idea came remarkably late. Also, back then shell scripts bound standard input to the script, not the terminal.<br /><br />69. Q: Who ran the first Unix Support Group?<br />A: maranzano<br />USG was a force for internal and commercial Unix development in AT&T.<br /><br />70. Q: Whose Ph.D. thesis concerned Unix paging?<br />A: ozalp & babaoglu<br />The name was well known; the trick was spelling it correctly when you were in a hurry to get home.<br /><br />71. Q: Who (other than the obvious) designed the original Unix file system?<br />A: canaday<br />Rudd Canaday was there at the beginning.<br /><br />72. Q: Who wrote the PWB shell?<br />A: mashey<br />John Mashey, inventor of the pump operator.<br /><br />73. Q: Who invented uucp?<br />A: lesk<br />In so doing, Mike Lesk created the job category of (amateur) network operations engineer.<br /><br />74. Q: Who thought of PWB?<br />A: evan ivie<br />Evan Ivie pushed on the Software Tools metaphor to instigate the Programmer's Workbench. It feels quaint now.<br /><br />75. Q: What does grep stand for?<br />A: global regular expressions print<br />I've read countless incorrect etymologies for 'grep'. It's just the ed command g/re/p. The reference here is the spelling on the original man page. That final 's' is key to getting this one right.<br /><br />76. Q: What hardware device does "dsw" refer to?<br />A: console & 7<br />The profound "delete from switches" program was in its purest form on the PDP-7 in the First Edition.<br /><br />77. Q: What was the old name of the "/sys" directory?<br />A: ken<br />Ken and...<br /><br />78. Q: What was the old name of the "/dev" directory?<br />A: dmr<br />... Dennis divided their work this way until the Seventh Edition.<br /><br />79. Q: Who has written many random number generators, but never one that worked?<br />A: ken | thompson<br />Sorry, Ken, but it's true and you know it.<br /><br />80. Q: Where was the first Unix system outside 127?<br />A: patent<br />The Bell Labs patent office truly benefited from automated document processing made possible in the early versions of Research Unix. I believe they started using it when the kernel was still in assembler.<br /><br />81. Q: What was the first Unix network?<br />A: spider<br />You thought it was Datakit, didn't you? But Sandy Fraser had an earlier project.<br /><br />82. Q: What was the original syntax for ls -l | pr -h?<br />A: ls -l>"pr -h"> | <"ls -l"<pr -h="" br="">Notation is important. Ken's introduction of the pipe symbol (not to be confused with the | of the pattern here) was a masterstroke.<br /><br />83. Q: Why is there a comment in the shell source /* Must not be a register variable */?<br />A: registers & longjmp<br />You should be able to understand this.<br /><br />84. Q: What is it you're not expected to understand?<br />A: 6 | 5 & process<br />What's amazing to me now is hard this was to understand, let alone to invent, yet within a few years we all realized it could be done almost trivially with setjmp and longjmp.</pr></span></div>
</div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande Mono550'; color: #000000}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-33634678476550993432020-01-19T11:52:00.001-08:002020-01-22T01:24:02.913-08:00Unix Quiz<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">(Here's another resurrected post from April 30, 2012. Answers in a followup.)</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;"><br /></span>
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;"><br /></span>
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">People objected that there was no Exit item on the main menu for the mpx program that put windows on the Blit; see </span><a class="ot-anchor bidi_isolate" dir="ltr" href="http://en.wikipedia.org/wiki/Blit_%28computer_terminal%29" jslog="10929; track:click" rel="nofollow" style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" target="_blank">http://en.wikipedia.org/wiki/Blit_(computer_terminal)</a><span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;"> (which mistakenly says it implemented cursor addressing when turned on - as if!) and </span><a class="ot-anchor bidi_isolate" dir="ltr" href="http://www.cs.bell-labs.com/cm/cs/doc/83/mpx.ps.gz" jslog="10929; track:click" rel="nofollow" style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" target="_blank">http://www.cs.bell-labs.com/cm/cs/doc/83/mpx.ps.gz</a><span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">. It seemed unnecessary, since you could just power cycle. Why clutter the menu? (Those were simpler times.)</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">After hearing too much complaining, I decided to implement Exit, but did it a special way. Late one night, with help from Brian Redman (ber) and Pat Parseghian (pep), I cranked out a set of trivia questions to drive the Exit control. Answer the question right, you can exit; get it wrong, you're stuck in mpx for a little longer. To make this worthwhile, the questions had to be numerous and hard, and had to be verified by the machine, so the quiz code included a little pattern matcher. It also had to be tiny, since the machine only had 256KB and the display took 100KB of that. (Those were simpler times.)</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">The response was gratifying. I'll never forget seeing someone, who shall remain nameless, a vociferous complainer about the lack of Exit, burble with excitement when he saw the menu item appear, only to crumble in despair when the question arrived. I forget which question it was, but it doesn't matter: they're all hard.</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">The questions were extended by lots of suggestions from others in the Unix lab, and then in 1984 they were handed out as a bloc in a trivia contest at the USENIX conference in Salt Lake City. To quote an observer, "The submission with the most correct answers (60) was from a team comprising David Tilbrook, Sam Leffler, and presumably others. Jim McKie had the best score for an individual (57) and was awarded an authenticated 1972 DECtape containing Unix Version 2. Finally, Ron Gomes had 56 correct answers and received an original engraved "Bill Joy" badge, which once belonged to Bill himself, from Sun Microsystems." That score of 57 was so impressive we hired Jim a little later, but that's another story.</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">How much Unix trivia do you know? Test your mettle; the questions appear below. This may be one of the hardest quizzes ever to originate outside of King William's College.</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">I've disabled comments because people will just send in spoilers. If you want to discuss or collaborate, do so elsewhere. I'll publish the computer-readable, pattern-matching answers here in a few days.</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">Good luck, and may your TU-10 never break your 9-track boot tape.</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">-rob</span><br />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<br style="font-family: Roboto, Arial, sans-serif; font-size: 14.6667px;" />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">1. The source code motel: your source code checks in, but it never checks out. What is it?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">2. Who wrote the first Unix screen editor?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">3. Using TSO is like kicking a {what?} down the beach.</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">4. What is the filename created by the original dsw(1)?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">5. Which edition of Unix first had pipes?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">6. What is </span><span style="font-family: "Lucida Grande Mono550"; font-size: 14px; font-variant-ligatures: no-common-ligatures;">=O=?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">7. Which Stephen R. Bourne wrote the shell?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">8. Adam Buchsbaum's original login was sjb. Who is sjb?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">9. What was the original processor in the Teletype DMD-5620?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">10. What was the telephone extension of the author of mpx(2)?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">11. Which machine resulted in the naming of the "NUXI problem"?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">12. What customs threat is dangerous only when dropped from an airplane?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">13. Who wrote the Bourne Shell?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">14. What operator in the Mashey shell was replaced by "here documents"?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">15. What names appear on the title page of the 3.0 manual?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">16. Sort the following into chronological order: a) PWB 1.2, b) V7, c) Whirlwind, d) System V, e) 4.2BSD, f) MERT.</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">17. The CRAY-2 will be so fast it {what?} in 6 seconds.</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">18. How many lights are there on the front panel of the original 11/70?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">19. What does FUBAR mean?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">20. What does "joff" stand for?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">21. What is "Blit" an acronym of?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">22. Who was rabbit!bimmler?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">23. Into how many pieces did Ken Thompson's deer disintegrate?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">24. What name is most common at USENIX conferences?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">25. What is the US patent number for the setuid bit?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">26. What is the patent number that appears in Unix documentation?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">27. Who satisfied the patent office of the viability of the setuid bit patent?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">28. How many Unix systems existed when the Second Edition manual was printed?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">29. Which Bell Labs location is HL?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">30. Who mailed out the Sixth Edition tapes?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">31. Which University stole Unix by phone?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">32. Who received the first rubber chicken award?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">33. Name a feature of C not in Kernighan and Ritchie.</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">34. What company did cbosg!ccf work for?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">35. What does Bnews do?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">36. Who said "Sex, Drugs, and Unix?"</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">37. What law firm distributed Empire?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">38. What computer was requested by Ken Thompson, but refused by management?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">39. Who is the most obsessed private pilot in USENIX?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">40. What operating system runs on the 3B-20D?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">41. Who wrote find(1)?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">42. In what year did Bell Labs organization charts become proprietary?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">43. What is the Unix epoch in Cleveland?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">44. What language preceded C?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">45. What language preceded B?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">46. What letter is mispunched by bcd(6)?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">47. What terminal does the Blit emulate?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">48. What does "trb" stand for (it's Andy Tannenbaum's login)?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">49. allegra!honey is no what?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">50. What is the one-line description in vs.c?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">51. What is the TU10 tape boot for the PDP-11/70 starting at location 100000 octal?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">52. What company owns the trademark on Writer's Workbench Software?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">53. Who designed Belle?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">54. Who coined the name "Unix"?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">55. What manual page mentioned Urdu?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">56. What politician is mentioned in the Unix documentation?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">57. What program was compat(1) written to support?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">58. Who is "mctesq"?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">59. What was "ubl"?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">60. Who bought the first commercial Unix license?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">61. Who bought the first Unix license?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">62. Who signed the Sixth Edition licenses?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">63. What color is the front console on the PDP-11/45 (exactly)?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">64. How many different meanings does Unix assign to '.'?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">65. Who said "Smooth rotation butters no parsnips?"</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">66. What was the original name for cd(1)?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">67. Which was the first edition of the manual to be typeset?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">68. Which was the first edition of Unix to have standard error/diagnostic output?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">69. Who ran the first Unix Support Group?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">70. Whose Ph.D. thesis concerned Unix paging?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">71. Who (other than the obvious) designed the original Unix file system?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">72. Who wrote the PWB shell?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">73. Who invented uucp?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">74. Who thought of PWB?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">75. What does grep stand for?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">76. What hardware device does "dsw" refer to?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">77. What was the old name of the "/sys" directory?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">78. What was the old name of the "/dev" directory?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">79. Who has written many random number generators, but never one that worked?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">80. Where was the first Unix system outside 127?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">81. What was the first Unix network?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">82. What was the original syntax for ls -l | pr -h?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">83. Why is there a comment in the shell source /* Must not be a register variable */?</span><br />
<span style="font-family: "roboto" , "arial" , sans-serif; font-size: 14.6667px;">84. What is it you're not expected to understand?</span><br />
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande Mono550'; color: #000000}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-78260268198829403972020-01-18T19:14:00.000-08:002020-01-18T19:14:10.585-08:00Old things made newA while back, Google Plus (google+?) lost its public face, removing from public view too much material. But Google, for all its faults, also has virtues, and it let me capture all my posts using its "takeout" feature before plus went negative.<br />
<br />I'm going to publish a few of the more worthwhile or at least fun ones here over the next little while.<br />
<br />
To get things going, here's a link I posted from September 30, 2011:<br />
<br />
<a href="http://www.marieclaire.com/fashion/trends/google-work-fashion" target="_blank">Fashion for Work at the Google Headquarters</a><br />
<br />
There's little merit and less verisimilitude in this, so file it under the fun category.<br />
<br />robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-34231620010517804752019-11-18T18:16:00.002-08:002019-11-18T18:25:58.027-08:00Computational reproducibility: Some challengesThere has been recent discussion about the <a href="https://www.nature.com/collections/prbfkwmwvz" target="_blank">reproducibility</a> of scientific results, with some unflattering conclusions. One <a href="https://www.insidehighered.com/news/2018/08/30/study-raises-new-questions-about-reproducibility-research" target="_blank">study</a> suggests only a 62% reproducibility rate.<br />
<br />
For some fields it's probably much worse. Any result that depends on computation is at great risk of continual change in its programming environment. A program written ten years ago has little chance of building today without change, let alone running or running correctly.<br />
<br />
This concern is not widespread, but it is growing. One indicator is the creation of the <a href="https://github.com/ReScience/ten-years" target="_blank">Ten Years Reproducibility Challenge</a>, which asks researchers to rerun their old code—ten years or more, very old by computing standards—and see if it still works.<br />
<br />
Can you even <i>find</i> your old code? That's a challenge all on its own.<br />
<br />
Any researchers out there with computational interests are encouraged to accept the challenge. The link above has details about how to proceed. The results are sure to be eye-opening. Even if you don't submit your results, the exercise will be valuable.<br />
<br />
While one can hope the results will not be as dismaying as some would predict, few would expect a happy outcome. It's worth taking a moment to consider why computational reproducibility is such a problem. Computational methods drift through continual change in systems, languages, libraries, approaches, even deployment techniques. Some of the change is necessary, as such addressing security issues caused bad library design; and some is truly enabling, such as the shift to networked servers; but much of the change can be put down to change for its own sake, better known as "progress".<br />
<br />
This topic was on my mind earlier this week because of the 10th anniversary of the announcement of the Go programming language as an open source project on November 10, 2009, and associated thoughts for the future. But perhaps the more important date is March 28, 2012, because that was the day that Go version 1.0 was announced.<br />
<br />
What makes Go 1.0 so important is that it came with a <a href="https://golang.org/doc/go1compat" target="_blank">promise</a> that users' programs would continue to compile and run without change for the indefinite future. That promise is an impenetrable bulwark against change for change's sake. Go 1.0 was far from perfect—there were many things that could have been done better, including several that we knew weren't as good as we wanted even at the time—but the promise of true stability more than compensated for any such weaknesses.<br />
<br />
Why don't more computational projects make guarantees like this? More languages, especially? Although no Go programs would be eligible for the Ten Year Challenge, the Seven Year Challenge would have a much higher chance of success for a Go program than one in most other languages.<br />
<br />
It's not just about promising compatibility, you have to deliver it. There have been countless times when a proposed change to Go would have been nice to accept, but would have broken existing programs, or at least had the potential to do so. The guardwall of true compatibility is constraining, but it is also enabling. It enabled the growth of the Go ecosystem, it enabled the community to prosper, it helped guarantee portability, and it reduced maintenance overhead to nearly zero for many programs.<br />
<br />
As the effort towards <a href="https://blog.golang.org/go2-here-we-come" target="_blank">Go 2.0</a> presses on, the compatibility promise remains. It's far too important to surrender, especially considering how far it has gotten things so far.<br />
<br />
Semantic versioning (<a href="https://semver.org/" target="_blank">semver</a>) helps, but it's not enough. It must be deployed in everything, tools included, and its compatibility properties strictly obeyed.<br />
<br />
So here's a Ten Year Challenge of my own: Dig out some ten-year-old code, if you can find some, and try to run it today. Do whatever is necessary to make it build and run again. If it's easy, great. If it's not, reflect on what the difficulties were, and what changes caused them, and whether those changes were worthwhile. Could they have been better managed?<br />
<br />
An even bigger challenge to system and language designers: Do a favor to your users and codify your compatibility rules. You may not be willing to be as rigid as the Go developers were, but you owe it to your community to be clear about what guarantees you do offer, and to honor them.<br />
<br />
If you do, perhaps ten years from now we can do this exercise again with better results.<br />
<br />robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-62729646852303534652019-01-23T21:27:00.002-08:002019-01-23T21:27:56.592-08:00Notes from a 1984 trip to Xerox PARCSomeone at work asked about this trip report I wrote long ago. I had not realized it was ever seen outside Bell Labs Research, but I now know it was. It's a bit of a time capsule now, and I was able resurrect it. Importing into Blogger was a bit of an ordeal that informs some of the points raised here, but other than that I make no comment on the contents beyond apologizing for the tone.<br />
<br />
<br />
<div class="page" title="Page 1">
<div class="layoutArea">
<div class="column">
<span style="font-family: 'Times'; font-size: 12.000000pt; font-weight: 700;">This Dorado is MINE, ALL MINE!
</span><br />
<span style="font-family: 'Times'; font-size: 12.000000pt; font-weight: 700;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt; font-style: italic;">Rob Pike</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt; font-style: italic;">April 29, 1984
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt; font-style: italic;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">A collection of impressions after doing a week’s work (rather than demo reception) at PARC.
Enough is known about the good stuff at PARC that I will concentrate on the bad stuff. The following may
therefore leave too negative an impression, and I apologize. Nonetheless...
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">Dorados work, and although most people at PARC now have their personal machine, it is hard to </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nd
a spare one for a visitor (e.g. me), and the allocation method is interesting. There are rooms full of Dorados
in racks, and each of</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">ce has a terminal in it. To connect a machine to a terminal, you make a connection at
the patch panel. There are just enough Dorados to go around, which makes it hard (but not impossible) to
</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nd a spare when one is needed. What seemed to be in shorter supply was the terminals. There is a terminal in every of</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">ce, but nothing like a terminal room. The presence of a visitor made it necessary to go to
the patch panel a couple of times a day (with muf</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fl</span><span style="font-family: 'Times'; font-size: 10.000000pt;">ed annoyance) to connect the temporarily vacant of</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">ce
to the vacant machine. It really seems to me that it would make more sense and involve less mechanism to
get a couple more machines and terminals, put them in a public place, and have the plug board there for
emergencies like machine failure. Personal or not, it’s too big a deal to get a machine.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">The idea of personal computers is an abreaction to time-sharing, with the unfortunate consequence
that personal computers (to be speci</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">c, D machines) look like personal time-sharing computers, albeit
without time-sharing software, an issue I’ll return to. The major issue is disks. Beside the plug board is a
white board divided into a grid of time-of-day cross machine-name. The machines have names because
they have disks; the reason you need the name is to get to a </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le you left there last time. Unfortunately,
Dorados need disks to run, because they must behave like Altos to run the crufty Alto software that performs vital services such as </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le transfer. The machine bootstraps by reading disk, not Ethernet. If this
were not the case, machine allocation could be done much more simply: you sit down at the (slightly
smarter) terminal you want to use, it </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nds a free Dorado, you log in to that and (if you care) connect, with
the Ethernet, to the disk you want.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">The machines run one program at a time, and that seems fundamental. When I had </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nished preparing a </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">gure with Draw, I had to exit Draw (‘‘Do you really want to quit? [Yes or No]’’ No. (I should write
the </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le.) ‘‘Name of </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le to write?’’ foo.draw ‘‘Overwrite the foo.draw that’s already there? [Yes or No]’’
Yes (dammit!). ‘‘Do you really want to quit? [Yes or No]’’ YES!!!!!!) to run the printing program. The
printing program then grabs the Dorado (running as an Alto) and holds it until the </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le is printed, which can
take quite a while if someone’s using the printer already. Once that’s accomplished, Draw can be started
again, but it won’t even accept a </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le name argument to start with. All the old state is lost.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">As another example, if there is a </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le on your local disk that I want to copy to my local disk (the standard way to look at a remote </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le, it seems), I must </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nd you in your of</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">ce and ask you to stop whatever you
are doing, save the state of your subsystem (Smalltalk, Cedar, etc.) and return to the Alto operating system.
Then, you run ftp on your machine, then go get a cup of coffee while I go to my machine and pull the </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le
across. On a related note, I spent an hour or so one morning looking for a working version of a program,
which eventually turned up on someone’s Alto. Copies of the </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">le didn’t work on my machine, though, so
whenever we needed to run it we had to </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nd the person and so on... Given the level of interaction of the
subsystems, the way PARC deals with </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">les and disks is striking.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;"><span style="font-size: 10pt;">Files are almost outside the domain of understanding at PARC. In fact, the whole world outside your
machine, Ethernet notwithstanding, is a forbidding world. I really got the feeling that their systems are so
big because they must provide everything, and they must provide everything because nobody out there provides anything, or at least it’s so hard to get to anyone helpful it’s not worth it. Smalltalk </span><span style="font-size: 10pt;">fi</span><span style="font-size: 10pt;">les are awkward,
but you can just (essentially) map the information into your address space and hold it there, whereupon </span></span><span style="font-family: Times, "Times New Roman", serif; font-size: 14px; font-variant-ligatures: no-common-ligatures;">it becomes remarkably easy to use. These subsystems are all like isolated controlled environments, little heated glass domes connected by long, cold crawlways, waiting out the long antarctic winter. And each dome is a model Earth.</span><br />
<span style="font-family: Times, "Times New Roman", serif; font-size: 14px; font-variant-ligatures: no-common-ligatures;"><br /></span></div>
</div>
</div>
<br />
<br />
<div class="page" title="Page 2">
<div class="layoutArea">
<div class="column">
<span style="font-family: 'Times'; font-size: 10.000000pt;">Using Smalltalk for a few days was interesting. The system is interactive to a fault; for example,
windows pop up demanding con</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">rmation of action and </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fl</span><span style="font-family: 'Times'; font-size: 10.000000pt;">ash incessantly if you try to avoid them. But overall, the feel of the system is remarkable. It is hard to describe how programs (if that is the right word) form.
The method-at-a-time discipline feels more like sculpting than authoring. The window-based browsers are
central and indispensable, since all that happens is massaging and creating data structures. A conventional
text editor wouldn’t </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">t in. I was surprised, though, at how often the window methodology seemed to break
down. When an incorrect method is ‘‘accepted,’’ messages from the compiler are folded into the text as
selected text, often at the wrong place. I found this behavior irritating, and would prefer a separate window
to hold the messages. The message in the code seemed to make it harder to </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nd the problem by cluttering
the text.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">A more interesting example occurred when I was half-way through writing a method and found I
needed information about another method. The browser I was in was primed with the information I needed,
but I couldn’t get at it, because the browser itself does not have windows. I could not leave the method I
was working on because it was syntactically incorrect, which meant I had to ‘‘spawn’’ a new browser. The
new browser remembered much of the state of the original, but it felt awkward to step away from a window
that had beneath it all the information I needed. A browser can only look at one method at a time, which is
annoying when writing programs, but if it had windows itself, this restriction could disappear.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">A similar problem is that, when writing a method, if a new method is introduced (that is, invented
while writing the caller), you must keep the missing method name in your head; the window that tells you
about it when you accept the method disappears when you say it’s O.K. The complexity of managing the
browser puts an undue strain on the programmer; I had an urge to make notes to myself on a scrap of paper.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">I missed grep. It’s not strictly necessary, because the browser does much of the same functionality,
but in a different way. To look for something, you look up its method; if you can’t remember the name, you
may have trouble. Experienced users clearly had no dif</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">culty </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nding things, but I felt lost without automatic tools for searching.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">Believe it or not, the response sometimes felt slow. I had to slow down frequently to let the event</span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">elding software catch up with me. For example, when making a rectangle for a new window, I could lose
as much as two inches off the upper left corner because of the delay between pushing a button and having it
detected. I therefore compensated, watching the cursor subconsciously to see that it was with me. The
obvious analogy is locking the keyboard.
</span><br />
<span style="font-size: 10pt;"><span style="font-family: Times, Times New Roman, serif;"><br /></span></span>
<span style="font-family: Times, Times New Roman, serif;"><span style="font-size: 10pt;">The language is strange but powerful; I won’t attempt a full critique here, but just comment on som</span><span style="font-size: 10pt;">e
peculiarities. The way defaults work in methods (isomorphic to procedures) is interesting, but necessary
because the generality of the design leads to argument-intensive methods. There are too many big words,
which stems partly from the lack of a grep (making it necessary to have overly descriptive names) and
partly from a desire to have the language look a little like English. For example,</span></span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;"> 2 raisedToInteger: 3
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">is perfectly readable, but chatty at best. Because all messages must be sent to a left operand, unary minus
didn’t exist. I complained and it appeared on Wednesday. The type structure is somewhat polymorphic,
but breaks down. For example, rectangles cannot have both scalars and points added to them, because the
message is resolved by the left operand of the message, not the left and right.
</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span>
<span style="font-family: 'Times'; font-size: 10.000000pt;">One philosophical point is that each window is of a type: a browser, a debugger, a workspace, a bit
editor. Each window is created by a special action that determines its type. This is in contrast to our style
of windows, which creates a general space in which anything may be run. With our windows, it is easy to
get to the outside world; the notion of Unix appears only when a Unix thing happens in the window. By
contrast, Smalltalk windows are always related to Smalltalk. This is hard to explain (it is, as I said, philosophical), but a trite explanation might be that you look outwards through our windows but inwards through
theirs.</span><br />
<span style="font-family: 'Times'; font-size: 10.000000pt;"><br /></span></div>
</div>
</div>
<div class="page" title="Page 3">
<div class="layoutArea">
<div class="column">
<span style="font-family: 'Times'; font-size: 10.000000pt;">A few years ago, PARC probably had most of the good ideas. But I don’t think they ran far enough
with them, and they didn’t take in enough new ones. The Smalltalk group is astonishingly insular, almost
childlike, but is just now opening up, looking at other systems with open-eyed curiosity and fascination.
The people there are absorbing much, and I think the next generation of Smalltalk will be much more modern, something I would </span><span style="font-family: 'Times'; font-size: 10.000000pt;">fi</span><span style="font-family: 'Times'; font-size: 10.000000pt;">nd always comfortable. However, it will probably be another model Earth.
</span><br />
</div>
</div>
</div>
<br /><br />
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande Mono550'; color: #000000}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-18969624762809793732018-02-24T15:36:00.001-08:002018-02-24T15:36:09.960-08:00CERN's iPod-like control devices, from 1973A recent dig through some old papers uncovered <a href="https://drive.google.com/open?id=1M8PVrZlRFeiA5dFnQ2R-oZ88nsTZ0Ajy" target="_blank">this</a> CERN memo from 1973 describing controls for the Proton Synchrotron being built at the time. I visited the control room some years later and saw the controls in action, installed on a room-hugging curved console reminiscent of a NASA mission control room. I was so impressed by the devices I asked for a copy of the documentation, written by (one assumes) their designers, F. Beck and B. Stumpe.<br />
<br />
These are like the ur-controls for the iPod and (later) iPhone, but anticipate the music player by almost three decades. In fact, the CERN knob is better than the click wheel: It is programmable to be smooth, indexed, or with variable turning resistance and spring return. It was inspirational to feel how it responded when turned in the various modes.<br />
<br />
Apple is very good at commercializing ideas, but big research institutions such as CERN, erstwhile Xerox PARC and Bell Labs excel at creating the ideas themselves.<br />
<br />This memo was from a different time, in more ways than one.<br />
<br />robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-25264165466055164662017-12-06T17:49:00.000-08:002017-12-06T21:13:03.249-08:00Error handling in Upspin<span style="font-family: "georgia" , "times new roman" , serif;">The </span><a href="https://upspin.io/" style="font-family: Georgia, "Times New Roman", serif;" target="_blank">Upspin</a><span style="font-family: "georgia" , "times new roman" , serif;"> project uses a custom package, </span><a href="https://godoc.org/upspin.io/errors" target="_blank"><span style="font-family: "trebuchet ms" , sans-serif;">upspin.io/errors</span></a><span style="font-family: "georgia" , "times new roman" , serif;">, to represent error conditions that arise inside the system. These errors satisfy the standard Go </span><a href="https://golang.org/pkg/builtin/#error" target="_blank"><span style="font-family: "trebuchet ms" , sans-serif;">error</span></a><span style="font-family: "georgia" , "times new roman" , serif;"> interface, but are implemented using a custom type, </span><a href="https://godoc.org/upspin.io/errors#Error" target="_blank"><span style="font-family: "trebuchet ms" , sans-serif;">upspin.io/errors.Error</span></a><span style="font-family: "georgia" , "times new roman" , serif;">, that has properties that have proven valuable to the project.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Here we will demonstrate how the package works and how it is used. The story holds lessons for the larger discussion of error handling in Go.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;"><b>Motivations</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">A few months into the project, it became clear we needed a consistent approach to error construction, presentation, and handling throughout the code. We decided to implement a custom errors package, and rolled one out in an afternoon. The details have changed a bit but the basic ideas behind the package have endured. These were:</span><br />
<br />
<ul>
<li>To make it easy to build informative error messages.</li>
<li>To make errors easy to understand for users.</li>
<li>To make errors helpful as diagnostics for programmers.</li>
</ul>
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">As we developed experience with the package, some other motivations emerged. We'll talk about these below.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;"><b>A tour of the package</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">The </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/errors" target="_blank">upspin.io/errors</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> package is imported with the package name </span><span style="font-family: "trebuchet ms" , sans-serif;">"errors"</span><span style="font-family: "georgia" , "times new roman" , serif;">, and so inside Upspin it takes over the role of Go's standard </span><span style="font-family: "trebuchet ms" , sans-serif;">"errors"</span><span style="font-family: "georgia" , "times new roman" , serif;"> package.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">We noticed that the elements that go into an error message in Upspin are all of different types: user names, path names, the kind of error (I/O, permission, etc.) and so on. This provided the starting point for the package, which would build on these different types to construct, represent, and report the errors that arise.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">The center of the package is the </span><a href="https://godoc.org/upspin.io/errors#Error" target="_blank"><span style="font-family: "trebuchet ms" , sans-serif;">Error</span></a><span style="font-family: "georgia" , "times new roman" , serif;"> type, the concrete representation of an Upspin error. It has several fields, any of which may be left unset:</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "trebuchet ms" , sans-serif;"> type Error struct {</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> Path upspin.PathName</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> User upspin.UserName</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> Op Op</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> Kind Kind</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> Err error</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> }</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The </span><span style="font-family: "trebuchet ms" , sans-serif;">Path</span><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><span style="font-family: "trebuchet ms" , sans-serif;">User</span><span style="font-family: "georgia" , "times new roman" , serif;"> fields denote the path and user affected by the operation. Note that these are both strings, but have distinct types in Upspin to clarify their usage and to allow the type system to catch certain classes of programming errors.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">The </span><span style="font-family: "trebuchet ms" , sans-serif;">Op</span><span style="font-family: "georgia" , "times new roman" , serif;"> field denotes the operation being performed. It is another string type and typically holds the name of the method or server function reporting the error: "</span><span style="font-family: "trebuchet ms" , sans-serif;">client.Lookup"</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="font-family: "trebuchet ms" , sans-serif;">"dir/server.Glob"</span><span style="font-family: "georgia" , "times new roman" , serif;">, and so on.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The </span><span style="font-family: "trebuchet ms" , sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;"> field classifies the error as one of a set of standard conditions (</span><span style="font-family: "trebuchet ms" , sans-serif;">Permission</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="font-family: "trebuchet ms" , sans-serif;">IO</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="font-family: "trebuchet ms" , sans-serif;">NotExist</span><span style="font-family: "georgia" , "times new roman" , serif;">, <a href="https://godoc.org/upspin.io/errors#Kind" target="_blank">and so on</a>). It makes it easy to see a concise description of what sort of error occurred, but also provides a hook for interfacing to other systems. For instance, </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/cmd/upspinfs" target="_blank">upspinfs</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> uses the </span><span style="font-family: "trebuchet ms" , sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;"> field as the key to translation from Upspin errors to Unix error constants such as </span><span style="font-family: "trebuchet ms" , sans-serif;">EPERM</span><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><span style="font-family: "trebuchet ms" , sans-serif;">EIO</span><span style="font-family: "georgia" , "times new roman" , serif;">.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The last field, </span><span style="font-family: "trebuchet ms" , sans-serif;">Err</span><span style="font-family: "georgia" , "times new roman" , serif;">, may hold another error value. Often this is an error from another system, such as a file system error from the </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://golang.org/pkg/os/" target="_blank">os</a></span><span style="font-family: "georgia" , "times new roman" , serif;"><span style="font-family: "georgia" , "times new roman" , serif;"> package or a network error from the </span><a href="https://golang.org/pkg/net/" target="_blank"><span style="font-family: "trebuchet ms" , sans-serif;">net</span></a><span style="font-family: "georgia" , "times new roman" , serif;"> package. It may also be another </span></span><span style="font-family: "trebuchet ms" , sans-serif;">upspin.io/errors.Error</span><span style="font-family: "georgia" , "times new roman" , serif;"> value, creating a kind of error trace that we will discuss later.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;"><b>Constructing an Error</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">To facilitate error construction, the package provides a function named </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/errors#E" target="_blank">E</a></span><span style="font-family: "georgia" , "times new roman" , serif;">, which is short and easy to type.</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> func E(args ...interface{}) error</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">As the <a href="https://godoc.org/upspin.io/errors#E" target="_blank">doc comment</a> for the function says, </span><span style="font-family: "trebuchet ms" , sans-serif;">E</span><span style="font-family: "georgia" , "times new roman" , serif;"> builds an error value from its arguments. The type of each argument determines its meaning. The idea is to look at the types of the arguments and assign each argument to the field of the corresponding type in the constructed </span><span style="font-family: "trebuchet ms" , sans-serif;">Error</span><span style="font-family: "georgia" , "times new roman" , serif;"> struct. There is an obvious correspondence: a </span><span style="font-family: "trebuchet ms" , sans-serif;">PathName</span><span style="font-family: "georgia" , "times new roman" , serif;"> goes to </span><span style="font-family: "trebuchet ms" , sans-serif;">Error.Path</span><span style="font-family: "georgia" , "times new roman" , serif;">, a </span><span style="font-family: "trebuchet ms" , sans-serif;">UserName</span><span style="font-family: "georgia" , "times new roman" , serif;"> to </span><span style="font-family: "trebuchet ms" , sans-serif;">Error.User</span><span style="font-family: "georgia" , "times new roman" , serif;">, and so on.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">Let's look at an example. In typical use, calls to </span><span style="font-family: "trebuchet ms" , sans-serif;">errors.E</span><span style="font-family: "georgia" , "times new roman" , serif;"> will arise multiple times within a method, so we define a constant, conventionally called </span><span style="font-family: "trebuchet ms" , sans-serif;">op</span><span style="font-family: "georgia" , "times new roman" , serif;">, that will be passed to all </span><span style="font-family: Trebuchet MS, sans-serif;">E</span><span style="font-family: "georgia" , "times new roman" , serif;"> calls within the method:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> func (s *Server) Delete(ref upspin.Reference) error {</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> const op errors.Op = "server.Delete"</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> ...</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Then through the method we use the constant to prefix each call (although the actual ordering of arguments is irrelevant, by convention </span><span style="font-family: "trebuchet ms" , sans-serif;">op</span><span style="font-family: "georgia" , "times new roman" , serif;"> goes first):</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "trebuchet ms" , sans-serif;"> if err := authorize(user); err != nil {</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> return errors.E(op, user, errors.Permission, err)</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> }</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">The </span><span style="font-family: "trebuchet ms" , sans-serif;">String</span><span style="font-family: "georgia" , "times new roman" , serif;"> method for </span><span style="font-family: "trebuchet ms" , sans-serif;">E</span><span style="font-family: "georgia" , "times new roman" , serif;"> will format this neatly:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> server.Delete: user ann@example.com: permission denied: user not authorized</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">If the errors nest to multiple levels, redundant fields are suppressed and the nesting is formatted with indentation:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> client.Lookup: ann@example.com/file: item does not exist:</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> dir/remote("upspin.example.net:443").Lookup:</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> dir/server.Lookup</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Notice that there are multiple operations mentioned in this error message (</span><span style="font-family: "trebuchet ms" , sans-serif;">client.Lookup</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="font-family: "trebuchet ms" , sans-serif;">dir/remote</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="font-family: "trebuchet ms" , sans-serif;">dir/server</span><span style="font-family: "georgia" , "times new roman" , serif;">). We'll discuss this multiplicity in a later section.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">As another example, sometimes the error is special and is most clearly described at the call site by a plain string. To make this work in the obvious way, the constructor promotes arguments of literal type </span><span style="font-family: Trebuchet MS, sans-serif;">string</span><span style="font-family: "georgia" , "times new roman" , serif;"> to a Go </span><span style="font-family: Trebuchet MS, sans-serif;">error</span><span style="font-family: "georgia" , "times new roman" , serif;"> type through a mechanism similar to the standard Go function </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://golang.org/pkg/errors/#New">errors.New</a><span id="goog_1425463653"></span><a href="https://www.blogger.com/"></a><span id="goog_1425463654"></span></span><span style="font-family: "georgia" , "times new roman" , serif;">. Thus one can write:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> errors.E(op, "unexpected failure")</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">or</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> errors.E(op, fmt.Sprintf("could not succeed after %d tries", nTries))</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">and have the string be assigned to the </span><span style="font-family: "trebuchet ms" , sans-serif;">Err</span><span style="font-family: "georgia" , "times new roman" , serif;"> field of the resulting </span><span style="font-family: "trebuchet ms" , sans-serif;">Err</span><span style="font-family: "georgia" , "times new roman" , serif;"> type. This is a natural and easy way to build special-case errors.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;"><b>Errors across the wire</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Upspin is a distributed system and so it is critical that communications between Upspin servers preserve the structure of errors. To accomplish this we made Upspin's RPCs aware of these error types, using the </span><span style="font-family: "trebuchet ms" , sans-serif;">errors</span><span style="font-family: "georgia" , "times new roman" , serif;"> package's </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/errors#MarshalError" target="_blank">MarshalError</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/errors#UnmarshalError" target="_blank">UnmarshalError</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> functions to transcode errors across a network connection. These functions make sure that a client will see all the details that the server provided when it constructed the error.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">Consider this error report:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> client.Lookup: ann@example.com/test/file: item does not exist:</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> dir/remote("dir.example.com:443").Lookup:</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> dir/server.Lookup:</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> store/remote("store.example.com:443").Get:</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> fetching https://storage.googleapis.com/bucket/C1AF...: 404 Not Found</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">This is represented by four nested </span><span style="font-family: "trebuchet ms" , sans-serif;">errors.E</span><span style="font-family: "georgia" , "times new roman" , serif;"> values.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Reading from the bottom up, the innermost is from the package </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="http://upspin.io/store/remotehttps://godoc.org/upspin.io/store/remote" target="_blank">upspin.io/store/remote</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> (responsible for taking to remote storage servers). The error indicates that there was a problem fetching an object from storage. That error is constructed with something like this, wrapping an underlying error from the cloud storage provider:</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "trebuchet ms" , sans-serif;"> const op errors.Op = `store/remote("store.example.com:443").Get`</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> var resp *http.Response</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> ...</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> return errors.E(op, errors.Sprintf("fetching %s: %s", url, resp.Status))</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The next error is from the directory server (package <a href="https://godoc.org/upspin.io/dir/server" target="_blank">upspin.io/dir/server</a>, our directory server reference implementation), which indicates that the directory server was trying to perform a </span><span style="font-family: "trebuchet ms" , sans-serif;">Lookup</span><span style="font-family: "georgia" , "times new roman" , serif;"> when the error occurred. That error is constructed like this:</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "trebuchet ms" , sans-serif;"> const op errors.Op = "dir/server.Lookup"</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> ...</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> return errors.E(op, pathName, errors.NotExist, err)</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">This is the first layer at which a </span><span style="font-family: Trebuchet MS, sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;"> (</span><span style="font-family: Trebuchet MS, sans-serif;">errors.NotExist</span><span style="font-family: "georgia" , "times new roman" , serif;">) is added.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The </span><span style="font-family: "trebuchet ms" , sans-serif;">Lookup</span><span style="font-family: "georgia" , "times new roman" , serif;"> error value is passed across the network (marshaled and unmarshaled along the way), and then the </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/dir/remote" target="_blank">upspin.io/dir/remote</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> package (responsible for talking to remote directory servers) wraps it with its own call to </span><span style="font-family: "trebuchet ms" , sans-serif;">errors.E</span><span style="font-family: "georgia" , "times new roman" , serif;">:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> const op errors.Op = "dir/remote.Lookup"</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> ...</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> return errors.E(op, pathName, err)</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">There is no </span><span style="font-family: "trebuchet ms" , sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;"> set in this call, so the inner </span><span style="font-family: "trebuchet ms" , sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;"> (</span><span style="font-family: "trebuchet ms" , sans-serif;">errors.NotExist</span><span style="font-family: "georgia" , "times new roman" , serif;">) is lifted up during the construction of this Error struct.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">Finally, the </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/client" target="_blank">upspin.io/client</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> package wraps the error once more:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> const op errors.Op = "client.Lookup"</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> ...</span><br />
<span style="font-family: "trebuchet ms" , sans-serif;"> return errors.E(op, pathName, err)</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Preserving the structure of the server's error permits the client to know programmatically that this is a "not exist" error and that the item in question is </span><span style="font-family: "trebuchet ms" , sans-serif;">"ann@example.com/file"</span><span style="font-family: "georgia" , "times new roman" , serif;">. The error's </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/errors#Error.Error" target="_blank">Error</a></span><span style="font-family: "georgia" , "times new roman" , serif;"> method can take advantage of this structure to suppress redundant fields. If the server error were merely an opaque string we would see the path name multiple times in the output.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The critical details (the </span><span style="font-family: "trebuchet ms" , sans-serif;">PathName</span><span style="font-family: "georgia" , "times new roman" , serif;"> and </span><span style="font-family: "trebuchet ms" , sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;">) are pulled to the top of the error so they are more prominent in the display. The hope is that when seen by a user the first line of the error is usually all that's needed; the details below that are more useful when further diagnosis is required.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Stepping back and looking at the error display as a unit, we can trace the path the error took from its creation back through various network-connected components to the client. The full picture might help the user but is sure to help the system implementer if the problem is unexpected or unusual.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;"><b>Users and implementers</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">There is a tension between making errors helpful and concise for the end user versus making them expansive and analytic for the implementer. Too often the implementer wins and the errors are overly verbose, to the point of including stack traces or other overwhelming detail.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">Upspin's errors are an attempt to serve both the users and the implementers. The reported errors are reasonably concise, concentrating on information the user should find helpful. But they also contain internal details such as method names an implementer might find diagnostic but not in a way that overwhelms the user. In practice we find that the tradeoff has worked well.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">In contrast, a stack trace-like error is worse in both respects. The user does not have the context to understand the stack trace, and an implementer shown a stack trace is denied the information that could be presented if the server-side error was passed to the client. This is why Upspin error nesting behaves as an <i>operational</i> trace, showing the path through the elements of the system, rather than as an <i>execution</i> trace, showing the path through the code. The distinction is vital.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">For those cases where stack traces would be helpful, we allow the </span><span style="font-family: Trebuchet MS, sans-serif;">errors</span><span style="font-family: "georgia" , "times new roman" , serif;"> package to be built with the </span><span style="font-family: "trebuchet ms" , sans-serif;">"debug"</span><span style="font-family: "georgia" , "times new roman" , serif;"> tag, which enables them. This works fine, but it's worth noting that we have almost never used this feature. Instead the default behavior of the package serves well enough that the overhead and ugliness of stack traces are obviated.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;"><b>Matching errors</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">An unexpected benefit of Upspin's custom error handling was the ease with which we could write error-dependent tests, as well as write error-sensitive code outside of tests. Two functions in the errors package enable these uses.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The first is a function, called </span><span style="font-family: "trebuchet ms" , sans-serif;"><a href="https://godoc.org/upspin.io/errors#Is" target="_blank">errors.Is</a></span><span style="font-family: "georgia" , "times new roman" , serif;">, that returns a boolean reporting whether the argument is of type </span><span style="font-family: "trebuchet ms" , sans-serif;">*errors.Error</span><span style="font-family: "georgia" , "times new roman" , serif;"> and, if so, that its </span><span style="font-family: "trebuchet ms" , sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;"> field has the specified value.</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> func Is(kind Kind, err error) bool</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">This function makes it straightforward for code to change behavior depending on the error condition, such as in the face of a permission error as opposed to a network error:</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "trebuchet ms" , sans-serif;"> if errors.Is(errors.Permission, err) { ... }</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The other function, </span><a href="https://godoc.org/upspin.io/errors#Match" target="_blank"><span style="font-family: "trebuchet ms" , sans-serif;">Match</span></a><span style="font-family: "georgia" , "times new roman" , serif;">, is useful in tests. It was created after we had been using the errors package for a while and found too many of our tests were sensitive to irrelevant details of the errors. For instance, a test might only need to check that there was a permission error opening a particular file, but was sensitive to the exact formatting of the error message.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">After fixing a number of brittle tests like this, we responded by writing a function to report whether the received error, err, matches an error template:</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "trebuchet ms" , sans-serif;"> func Match(template, err error) bool</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">The function checks whether the error is of type </span><span style="font-family: "trebuchet ms" , sans-serif;">*errors.Error</span><span style="font-family: "georgia" , "times new roman" , serif;">, and if so, whether the fields within equal those within the template. The key is that it checks <i>only</i> those fields that are non-zero in the template, ignoring the rest.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">For our example described above, one can write:</span><br />
<br />
<span style="font-family: "trebuchet ms" , sans-serif;"> if errors.Match(errors.E(errors.Permission, pathName), err) { … }</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">and be unaffected by whatever other properties the error has. We use </span><span style="font-family: "trebuchet ms" , sans-serif;">Match</span><span style="font-family: "georgia" , "times new roman" , serif;"> countless times throughout our tests; it has been a boon.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;"><b>Lessons</b></span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">There is a lot of discussion in the Go community about how to handle errors and it's important to realize that there is no single answer. No one package or approach can do what's needed for every program. As was pointed out <a href="https://blog.golang.org/errors-are-values" target="_blank">elsewhere</a>, errors are just values and can be programmed in different ways to suit different situations.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">The Upspin errors package has worked out well for us. We do not advocate that it is the right answer for another system, or even that the approach is right for anyone else. But the package worked well within Upspin and taught us some general lessons worth recording.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">The Upspin errors package is modest in size and scope. The original implementation was built in a few hours and the basic design has endured, with a few refinements, since then. A custom error package for another project should be just as easy to create. The specific needs of any given environment should be easy to apply. Don't be afraid to try; just think a bit first and be willing to experiment. What's out there now can surely be improved upon when the details of your own project are considered.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">We made sure the error constructor was both easy to use and easy to read. If it were not, programmers would resist using it.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">The behavior of the errors package is built in part upon the types intrinsic to the underlying system. This is a small but important point: No general errors package could do what ours does. It truly is a custom package.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Moreover, the use of types to discriminate arguments allowed error construction to be idiomatic and fluid. This was made possible by a combination of the existing types in the system (</span><span style="font-family: "trebuchet ms" , sans-serif;">PathName</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="font-family: "trebuchet ms" , sans-serif;">UserName</span><span style="font-family: "georgia" , "times new roman" , serif;">) and new ones created for the purpose (</span><span style="font-family: "trebuchet ms" , sans-serif;">Op</span><span style="font-family: "georgia" , "times new roman" , serif;">, </span><span style="font-family: "trebuchet ms" , sans-serif;">Kind</span><span style="font-family: "georgia" , "times new roman" , serif;">). Helper types made error construction clean, safe, and easy. It took a little more work—we had to create the types and use them everywhere, such as through the "</span><span style="font-family: "trebuchet ms" , sans-serif;">const op</span><span style="font-family: "georgia" , "times new roman" , serif;">" idiom—but the payoff was worthwhile.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">Finally, we would like to stress the lack of stack traces as part of the error model in Upspin. Instead, the errors package reports the sequence of events, often across the network, that resulted in a problem being delivered to the client. Carefully constructed errors that thread through the operations in the system can be more concise, more descriptive, and more helpful than a simple stack trace.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<span style="font-family: "georgia" , "times new roman" , serif;">Errors are for users, not just for programmers.</span><br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;"><i>by Rob Pike and Andrew Gerrand</i></span><br />
<div>
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span></div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-1950625669196290252017-10-26T13:00:00.000-07:002017-10-26T13:00:10.725-07:00The Upspin manifesto: On the ownership and sharing of data<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="font-family: "georgia" , "times new roman" , serif;">Here follows the original "manifesto" from late 2014 proposing the idea for what became <a href="https://upspin.io/" target="_blank">Upspin</a>. The text has been lightly edited to remove a couple of references to Google-internal systems, with no loss of meaning.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"></span><br /><span style="font-family: "georgia" , "times new roman" , serif;">
</span> <span style="font-family: "georgia" , "times new roman" , serif;">I'd like to thank Eduardo Pinheiro, Eric Grosse, Dave Presotto and Andrew Gerrand for helping me turn this into a working system, in retrospect remarkably close to the original vision.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br /></span>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://upspin.io/images/augie.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img alt="Augie" border="0" data-original-height="436" data-original-width="360" height="320" src="https://upspin.io/images/augie.jpg" title="" width="264" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-size: xx-small;">Augie image Copyright © 2017 Renee French</span></td></tr>
</tbody></table>
<br /><span style="font-family: "georgia" , "times new roman" , serif;">
</span> <br />
<h3>
<span style="font-family: "georgia" , "times new roman" , serif;"><b>Manifesto</b></span></h3>
<br />
<br />
<span style="font-family: "georgia" , "times new roman" , serif;">Outside our laptops, most of us today have no shared file system at work. (There was a time when we did, but it's long gone.) The world took away our /home folders and moved us to databases, which are not file systems. Thus I can no longer (at least not without clumsy hackery) make my true home directory be where my files are any more. Instead, I am expected to work on some local machine using some web app talking to some database or other external repository to do my actual work. This is mobile phone user interfaces brought to engineering workstations, which has its advantages but also some deep flaws. Most important is the philosophy it represents.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">You don't own your data any more. One argument is that companies own it, but from a strict user perspective, your "apps" own it. Each item you use in the modern mobile world is coupled to the program that manipulates it. Your Twitter, Facebook, or Google+ program is the only way to access the corresponding feed. Sometimes the boundary is softened within a company—photos in Google+ are available in other Google products—but that is the exception that proves the rule. <i>You</i> don't control your data, the programs do.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Yet there are many reasons to want to access data from multiple programs. That is, almost by definition, the Unix model. Unix's model is largely irrelevant today, but there are still legitimate ways to think about data that are made much too hard by today's way of working. It's not necessarily impossible to share data among programs (although it's often very difficult), but it's never <i>natural</i>. There are workarounds like plugin architectures and documented workflows but they just demonstrate that the fundamental idea—sharing data among programs—is not the way we work any more.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">This is backwards. It's a reversal of the old way we used to work, with a file system that all programs could access equally. The very notion of "download" and "upload" is plain stupid. Data should simply be available to any program with authenticated access rights. And of course for any person with those rights. Sharing between programs and people can be, technologically at least, the same problem, and a solved one.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">This document proposes a modern way to achieve the good properties of the old world: consistent access, understandable data flow, and easy sharing without workarounds. To do this, we go back to the old notion of a file system and make it uniform and global. The result should be a data space in which all people can use all their programs, sharing and collaborating at will in a consistent, intuitive way.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Not downloading, uploading, mailing, tarring, gzipping, plugging in and copying around. Just using. Conceptually: If I want to post a picture on Twitter, I just name the file that holds it. If I want to edit a picture on Twitter using Photoshop, I use the File>Open menu in Photoshop and name the file stored on Twitter, which is easy to discover or even know a priori. (There are security and access questions here, and we'll come back to those.)</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Working in a file system.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">I want my home directory to be where all my data is. Not just my local files, not just my source code, not just my photos, not just my mail. <i>All</i> my data. My "phone" should be able to access the same data as my laptop, which should be able to access the same data as the servers. (Ignore access control for the moment.) $HOME should be my home for everything: work, play, life; toy, phone, work, cluster.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">This was how things worked in the old single-machine days but we lost sight of that when networking became universally available. There were network file systems and some research systems used them to provide basically this model, but the arrival of consumer devices, portable computing, and then smartphones eroded the model until every device is its own fiefdom and every program manages its own data through networking. We have a network <i>connecting</i> devices instead of a network <i>composed</i> of devices.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The knowledge of how to achieve the old way still exists, and networks are fast and ubiquitous enough to restore the model. From a human point of view, the data is all we care about: my pictures, my mail, my documents. Put those into a globally addressable file system and I can see all my data with equal facility from any device I control. And then, when I want to share with another person, I can name the file (or files or directory) that holds the information I want to share, grant access, and the other person can access it.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The essence here is that the data (if it's in a single file) has one name that is globally usable to anyone who knows the name and has the permission to evaluate it. Those names might be long and clumsy, but simple name space techniques can make the data work smoothly using local aliasing so that I live in "my" world, you live in your world (also called "my" world from your machines), and the longer, globally unique names only arise when we share, which can be done with a trivial, transparent, easy to use file-system interface.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Note that the goal here is not a new file system to use alongside the existing world. Its purpose is to be the only file system to use. Obviously there will be underlying storage systems, but from the user's point of view all access is through this system. I edit a source file, compile it, find a problem, point a friend at it; she accesses <i>the same file</i>, not a copy, to help me understand it. (If she wants a copy, there's always cp!).</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">This is not a simple thing to do, but I believe it is possible. Here is how I see it being assembled. This discussion will be idealized and skate over a lot of hard stuff. That's OK; this is a vision, not a design document.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><b><br />
</b></span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Everyone has a name.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Each person is identified by a name. To make things simple here, let's just use an e-mail address. There may be a better idea, but this is sufficient for discussion. It is not a problem to have multiple names (addresses) in this model, since the sharing and access rights will treat the two names as distinct users with whatever sharing rights they choose to use.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Everyone has stable storage in the network.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Each person needs a way to make data accessible to the network, so the storage must live in the network. The easiest way to think of this is like the old network file systems, with per-user storage in the server farm. At a high level, it doesn't matter what that storage is or how it is structured, as long as it can be used to provide the storage layer for a file-system-like API.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Everyone's storage server has a name identified by the user's name.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The storage in the server farm is identified by the user's name.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Everyone has local storage, but it's just a cache.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">It's too expensive to send all file access to the servers, so the local device, whatever it is—laptop, desktop, phone, watch—caches what it needs and goes to the server as needed. Cache protocols are an important part of the implementation; for the point of this discussion, let's just say they can be designed to work well. That is a critical piece and I have ideas, but put that point aside for now.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The server always knows what devices have cached copies of the files on local storage. </span><br />
<span style="font-family: georgia, "times new roman", serif;"><br /></span>
<span style="font-family: georgia, "times new roman", serif;">The cache always knows what the associated server is for each directory file in its cache and maintains consistency within reasonable time boundaries.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The cache implements the API of a full file system. The user lives in this file system for all the user's own files. As the user moves between devices, caching protocols keep things working.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Everyone's cache can talk to multiple servers.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">A user may have multiple servers, perhaps from multiple providers. The same cache and therefore same file system API refers to them all equivalently. Similarly, if a user accesses a different user's files, the exact same protocol is used, and the result is cached in the same cache the same way. This is federation as architecture.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Every file has a globally unique name.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Every file is named by this triple: (host address, user name, file path). Access rights aside, any user can address any other user's file by evaluating the triple. The real access method will be nicer in practice, of course, but this is the gist.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Every file has a potentially unique ACL.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Although the user interface for access control needs to be very easy, the effect is that each file or directory has an access control list (ACL) that mediates all access to its contents. It will need to be very fine-grained with respect to each of users, files, and rights.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Every user has a local name space.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The cache/file-system layer contains functionality to bind things, typically directories, identified by such triples into locally nicer-to-use names. An obvious way to think about this is like an NFS mount point for /home, where the remote binding attaches to /home/XXX the component or components in the network that the local user wishes to identify by XXX. For example, Joe might establish /home/jane as a place to see all the (accessible to Joe) pieces of Jane's world. But it can be much finer-grained than that, to the level of pulling in a single file.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The NFS analogy only goes so far. First, the binding is a lazily-evaluated, multi-valued recipe, not a Unix-like mount. Also, the binding may itself be programmatic, so that there is an element of auto-discovery. Perhaps most important, one can ask any file in the cached local system what its triple is and get its unique name, so when a user wishes to share an item, the triple can be exposed and the remote user can use her locally-defined recipe to construct the renaming to make the item locally accessible. This is not as mysterious or as confusing in practice as it sounds; Plan 9 pretty much worked like this, although not as dynamically.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><b><br />
</b></span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Everyone's data becomes addressable.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Twitter gives you (or anyone you permit) access to your Twitter data by implementing the API, just as the regular, more file-like servers do. The same story applies to any entity that has data it wants to make usable. At some scaling point, it becomes wrong not to play.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Everyone's data is secure.</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">It remains to be figured out how to do that, I admit, but with a simple, coherent data model that should be achievable.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>Is this a product?</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">The protocols and some of the pieces, particularly what runs on local devices, should certainly be open source, as should a reference server implementation. Companies should be free to provide proprietary implementations to access their data, and should also be free to charge for hosting. A cloud provider could charge hosting fees for the service, perhaps with some free or very cheap tier that would satisfy the common user. There's money in this space.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;"><b>What is this again?</b></span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">What Google Drive should be. What Dropbox should be. What file systems can be. The way we unify our data access across companies, services, programs, and people. The way I want to live and work.</span><br />
<span style="font-family: "georgia" , "times new roman" , serif;"><br />
</span> <span style="font-family: "georgia" , "times new roman" , serif;">Never again should someone need to manually copy/upload/download/plugin/workflow/transfer data from one machine to another. </span></div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-10122834760065271332017-09-21T15:02:00.001-07:002017-09-21T15:48:28.668-07:00Go: Ten years and climbing<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-aGrvoIrHLeE/WcQu3Y2fE_I/AAAAAAAApsw/0lYHJ9InDUAtARMUhf0kBUKxCrEUkmrVgCLcBGAs/s1600/gophers10th.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="758" data-original-width="644" height="320" src="https://1.bp.blogspot.com/-aGrvoIrHLeE/WcQu3Y2fE_I/AAAAAAAApsw/0lYHJ9InDUAtARMUhf0kBUKxCrEUkmrVgCLcBGAs/s320/gophers10th.jpg" width="271" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: "times" , "times new roman" , serif; font-size: xx-small;">Drawing Copyright <span style="background-color: white; font-variant-ligatures: no-common-ligatures;">©2017 <a href="http://reneefrench.io/" target="_blank">Renee French</a></span></span></div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande Mono550'; color: #000000; background-color: #ffffff}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style>
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">This week marks the 10th anniversary of the creation of Go.</span></div>
<b id="docs-internal-guid-f05b57f6-a657-6f1c-a48d-0e1bc3931be0" style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The initial discussion was on the afternoon of Thursday, the 20th of September, 2007. That led to an organized meeting between Robert Griesemer, Rob Pike, and Ken Thompson at 2PM the next day in the conference room called Yaounde in Building 43 on Google's Mountain View campus. The name for the language arose on the 25th, several messages into the first mail thread about the design:</span><br />
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span><span style="background-color: transparent; font-family: "verdana"; font-size: x-small; vertical-align: baseline; white-space: pre-wrap;"> Subject: Re: prog lang discussion
From: Rob 'Commander' Pike
Date: Tue, Sep 25, 2007 at 3:12 PM
To: Robert Griesemer, Ken Thompson
i had a couple of thoughts on the drive home.
1. name
'go'. you can invent reasons for this name but it has nice properties.
it's short, easy to type. tools: goc, gol, goa. if there's an interactive
debugger/interpreter it could just be called 'go'. the suffix is .go
...</span><br />
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">(It's worth stating that the language is called Go; "golang" comes from the web site address (go.com was already a Disney web site) but is not the proper name of the language.)</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The Go project counts its birthday as November 10, 2009, the day it launched as open source, originally on code.google.com before migrating to GitHub a few years later. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">But for now let's date the language from its conception, two years earlier, which allows us to reach further back, take a longer view, and witness some of the earlier events in its history.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The first big surprise in Go's development was the receipt of this mail message:</span><br />
<span style="font-family: "verdana"; font-size: 14.6667px; white-space: pre-wrap;"><br /></span>
<span style="font-family: "verdana"; white-space: pre-wrap;"><span style="font-size: x-small;"> Subject: A gcc frontend for Go</span></span><br />
<span style="color: black; font-family: "verdana"; vertical-align: baseline;"><span style="white-space: pre-wrap;"><span style="font-size: x-small;"> From: Ian Lance Taylor
Date: Sat, Jun 7, 2008 at 7:06 PM
To: Robert Griesemer, Rob Pike, Ken Thompson
One of my office-mates pointed me at http://.../go_lang.html . It
seems like an interesting language, and I threw together a gcc
frontend for it. It's missing a lot of features, of course, but it
does compile the prime sieve code on the web page.</span></span><span style="font-size: 14.6667px; white-space: pre-wrap;">
</span>
</span><br />
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">The shocking yet delightful arrival of an ally (Ian) and a second compiler (gccgo) was not only encouraging, it was enabling. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Having a second implementation of the language was vital to the process of locking down the specification and libraries, helping guarantee the high portability that is part of Go's </span><a href="https://golang.org/doc/go1compat" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">promise</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Even though his office was not far away, none of us had even met Ian before that mail, but he has been a central player in the design and implementation of the language and its tools ever since.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Russ Cox joined the nascent Go team in 2008 as well, bringing his own bag of tricks. </span><span style="font-family: "verdana"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Russ discovered—that's the right word—that the generality of Go's methods meant that a function could have methods, leading to the <a href="https://golang.org/pkg/net/http/#HandlerFunc" target="_blank">http.HandlerFunc</a> idea, which was an unexpected result for all of us. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Russ promoted more general ideas too, like the the <a href="https://golang.org/pkg/io/#Reader" target="_blank">io.Reader</a> and <a href="https://golang.org/pkg/io/#Writer" target="_blank">io.Writer</a> interfaces, which informed the structure of all the I/O libraries.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Jini Kim, who was our product manager for the launch, recruited the security expert Adam Langley to help us get Go out the door. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Adam did a lot of things for us that are not widely known, including creating the original <a href="https://golang.org/">golang.org</a> web page and the <a href="https://build.golang.org/" target="_blank">build dashboard</a>, but of course his biggest contribution was in the cryptographic libraries. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">At first, they seemed disproportionate in both size and complexity, at least to some of us, but they enabled so much important networking and security software later that they become a crucial part of the Go story. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Network infrastructure companies like </span><a href="https://www.cloudflare.com/" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">Cloudflare</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;"> lean heavily on Adam's work in Go, and the internet is better for it. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">So is Go, and we thank him.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In fact a number of companies started to play with Go early on, particularly startups. </span><span style="color: black; font-family: "verdana"; font-size: 11pt; vertical-align: baseline; white-space: pre-wrap;">Some of those became powerhouses of cloud computing. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">One such startup, now called </span><a href="https://www.docker.com/" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">Docker</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">, used Go and catalyzed the container industry for computing, which then led to other efforts such as </span><a href="https://kubernetes.io/" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">Kubernetes</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Today it's fair to say that Go is the language of containers, another completely unexpected result.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Go's role in cloud computing is even bigger, though. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">In March of 2014 Donnie Berkholz, writing for </span><a href="https://redmonk.com/" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">RedMonk</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">, </span><a href="http://redmonk.com/dberkholz/2014/03/18/go-the-emerging-language-of-cloud-infrastructure/" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">claimed</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;"> that Go was "the emerging language of cloud infrastructure". </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Around the same time, Derek Collison of <a href="https://www.apcera.com/" target="_blank">Apcera</a> stated that Go was already the language of the cloud. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">That might not have been quite true then, but as the word "emerging" used by Berkholz implied, it was becoming true.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Today, Go </span><span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>is</i></span><span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"> the language of the cloud, and to think that a language only ten years old has come to dominate such a large and growing industry is the kind of success one can only dream of. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">And if you think "dominate" is too strong a word, take a look at the internet inside China. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">For a while, the huge usage of Go in China signaled to us by the </span><a href="https://trends.google.com/trends/explore?q=golang" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">Google trends graph</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;"> seemed some sort of mistake, but as anyone who has been to the Go conferences in China can attest, the measurements are real. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Go is huge in China.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">In short, ten years of travel with the language have brought us past many milestones. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">The most astonishing is at our current position: a </span><a href="https://research.swtch.com/gophercount" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">conservative estimate</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;"> </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">suggests there are at least half a million Go programmers. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">When the mail message naming Go was sent, the idea of there being half a million gophers would have sounded preposterous. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Yet here we are, and the number continues to grow.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Speaking of gophers, it's been fun to watch how <a href="http://reneefrench.io/" target="_blank">Renee French</a>'s idea for a mascot, the Go gopher, became not only a much loved creation but also a symbol for Go programmers everywhere. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">Many of the biggest Go conferences are called GopherCons as they gather together gophers from all over the world.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Gopher conferences are taking off. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">The </span><a href="https://www.youtube.com/playlist?list=PLE7tQUdRKcyb-k4TMNm2K59-sVlUJumw7" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">first one</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;"> was only three years ago, yet today there are many, all around the world, plus countless smaller local "</span><a href="https://www.meetup.com/topics/golang/" style="font-family: Verdana; font-size: 11pt; white-space: pre-wrap;" target="_blank">meetups</a><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">". </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">On any given day, there is more likely than not a group of gophers meeting somewhere in the world to share ideas.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">Looking back over ten years of Go design and development, it is astounding to reflect on the growth of the Go community. </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">The number of conferences and meetups, </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">the long and ever-increasing list of contributors to the Go project, </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">the profusion of open source repositories hosting Go code, </span><span style="font-family: "verdana"; font-size: 11pt; white-space: pre-wrap;">the number of companies using Go, some exclusively: these are all astonishing to contemplate.</span></div>
<b style="font-weight: normal;"><br /></b>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">For the three of us, Robert, Rob, and Ken, who just wanted to make our programming lives easier, it's incredibly gratifying to witness what our work has started.</span></div>
<br />
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;">What will the next ten years bring?</span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-style: normal; font-variant: normal; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><br /></span></div>
<div dir="ltr" style="line-height: 1.38; margin-bottom: 0pt; margin-top: 0pt;">
<span style="background-color: transparent; color: black; font-family: "verdana"; font-size: 11pt; font-weight: 400; text-decoration: none; vertical-align: baseline; white-space: pre-wrap;"><i>- Rob Pike, with Robert Griesemer and Ken Thompson</i></span></div>
<style type="text/css">
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande Mono550'; color: #000000; background-color: #ffffff}
p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Lucida Grande Mono550'; color: #000000; background-color: #ffffff; min-height: 16.0px}
span.s1 {font-variant-ligatures: no-common-ligatures}
</style>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-65710541159774072532017-02-25T09:52:00.001-08:002017-03-03T14:07:17.683-08:00The power of role models<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">I spent a few days a while back in a board meeting for a national astronomy organization and noticed a property of the population in that room: Out of about 40 people, about a third were women. And these were powerful women, too: professors, observatory directors and the like. Nor were they wallflowers. Their contributions to the meeting exceeded their proportion.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">In my long career, I had never before been in a room like that, and the difference in tone, conversation, respect, and professionalism was unlike any I have experienced. I can't prove it was the presence of women that made the difference - it could just be that astronomers are better people all around, a possibility I cannot really refute - but it seemed to me that the difference stemmed from the demographics.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">The meeting was one-third women, but of course in private conversation, when pressed, the women I spoke to complained that things weren't equal yet. We all have our reference points.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">But let's back up for a moment and think about the main point: In a room responsible for overseeing the budget and operation of major astronomical observatories, including things like the Hubble telescope, women played a major role. The contrast with computing is stark.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">It really got me thinking. At dinner I asked some of the women to speak to me about this, how astronomy became so (relatively) egalitarian. And one topic became clear: role models. Astronomy has a long history of women active in the field, going all the way back to Caroline Herschel in the early 19th century. Women have made huge contributions to the field. Dava Sobel just wrote a <a href="http://www.penguinrandomhouse.com/books/315726/the-glass-universe-by-dava-sobel/9780670016952/" target="_blank">book</a> about the women who laid the foundations for the discovery of the expansion of the universe. Just a couple of weeks ago, papers ran obituaries of <a href="https://www.nytimes.com/2016/12/27/science/vera-rubin-astronomist-who-made-the-case-for-dark-matter-dies-at-88.html" target="_blank">Vera Rubin</a>, the remarkable observational astronomer who discovered the evidence for dark matter. I could mention <a href="https://en.wikipedia.org/wiki/Jocelyn_Bell_Burnell" target="_blank">Jocelyn Bell</a>, whose discovery of pulsars got her advisor a Nobel (sic).</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">The most famous astronomer I met growing up was <a href="https://en.wikipedia.org/wiki/Helen_Sawyer_Hogg" target="_blank">Helen Hogg</a>, the (adopted) Canadian astronomer at David Dunlap Observatory outside Toronto, who also did a fair bit of what we now call outreach.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">The women at the meeting spoke of this, a history of women contributing, of role models to look up to, of proof that women can make major contributions to the field.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">What can computing learn from this?</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">It seems we're doing it wrong. The best way to improve the representation of women in the field is not to recruit them, important though that is, but to promote them. To create role models. To push them into positions of influence. Women leave computing in large numbers because they don't see a path up, or because the culture makes them unwelcome. More women excelling in the field, famous women, brilliant women, would be inspiring.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">Men have the power to help fix those things, but they also should have the courage to cede the stage to women more often, to fight the stupid bias that keeps women from excelling in the field. It may take proactive behavior, like choosing a women over a man when growing your team, just because, or promoting women more freely.</span><br />
<br style="-webkit-tap-highlight-color: transparent; background-color: #fefefe; color: rgba(0, 0, 0, 0.870588); font-family: Roboto, RobotoDraft, Helvetica, Arial, sans-serif; font-size: 14px; white-space: pre-wrap;" />
<span style="background-color: #fefefe; color: rgba(0 , 0 , 0 , 0.870588); font-family: "roboto" , "robotodraft" , "helvetica" , "arial" , sans-serif; font-size: 14px; white-space: pre-wrap;">But as I see it, without something being done to promote female role models, the way things are going computing will still be backwards a hundred years from now.</span>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-72081334303778242002014-08-03T14:55:00.001-07:002014-08-03T15:08:52.489-07:00PrintsTwo long-buried caches of photographs came to light last year. One was a stack of cellulose nitrate negatives made on the Scott Antarctic expedition almost a hundred years ago. Over time, they became stuck together into a moldy brick, but it was possible to tease the negatives apart and see what they revealed. You can view the images at the web site of the <a href="http://www.nzaht.org/AHT/antarctic-photos/" rel="nofollow" target="_blank">New Zealand Antarctic Heritage Trust</a>. The results show ragged edges and mold spots but, even beyond their historical importance, the photographs are evocative and in some cases very beautiful.<br />
<br />
The other cache contained images not quite so old and of less general interest but of personal importance. My mother moved from the house she had occupied for decades into a smaller apartment and while preparing to move she found the proverbial shoe box of old pictures in a closet. Some of the images are from my youth, some from hers, and some even from her parents'. One of the photographs, from 1931, shows my paternal great-grandparents. I never met my paternal grandparents, let alone great-grandparents, so this photograph touches something almost primordial for me. And some of the photographs in the box were even older.<br />
<br />
Due to the miracle of photography, we are able to see over a hundred years into the past. Of course this is not news; all of us have seen 19th century photographs by the pioneers of the medium. By the turn of the 20th century photography was so common that huge numbers of images, from the historical to the mundane, had been created. And sometimes we are lucky enough to chance upon forgotten images that open a window into a past that would otherwise fade from view.<br />
<br />
But such windows are becoming rare. A hundred years from now, there will be far fewer photo caches to find. Although the transition to digital photography has made photos almost unimaginably commonplace—one estimate puts the number of shutter activations at a trillion images worldwide per year—very few of those images become artifacts that can be left in a shoe box.<br />
<br />
We live in what has been named a <a href="http://en.wikipedia.org/wiki/Digital_dark_age" rel="nofollow" target="_blank">Digital Dark Age</a>. Because digital technology evolves so fast, we are rapidly losing the ability to understand yesterday's media. As file formats change, software becomes obsolete, and hardware becomes outmoded, old digital files become unreadable and unrecoverable.<br />
<br />
There are many examples of lost information, but here is an illustrative story of disaster narrowly averted. Early development of the Unix operating system, which became the software foundation for the Internet, was done in the late 1960s and early 1970s on Digital Equipment Corporation computers. Backups were made on a magnetic medium called a <a href="http://en.wikipedia.org/wiki/DECtape" rel="nofollow" target="_blank">DECtape</a>. By the mid 1970s, DECtape was obsolete and by the 1980s there were no remaining DECtape drives that could read the old backups. The scientists in the original Unix lab had kept a box of old backups under the raised floor of the computer room, but the tapes had spontaneously become unreadable because the device to read them no longer existed in the lab or anywhere else as far as anyone knew. And even if it did, no computer that could run the device was still powered on. Fortunately, around 1990 Paul Vixie and Keith Bostic, working for a different company, stumbled across an old junked DECtape drive and managed to get it up and running again by resurrecting an old computer to connect it to. They contacted the Unix research group and offered one last chance to recover the data on the backup tapes before the computer and DECtape drive were finally decommissioned. Time and resources were limited, but some of the key archival pieces of early Unix development were recovered through this combination of charity and a great deal of luck. This story has a happy ending, but not all digital archives survive. Far from it.<br />
<br />
The problem is that as technology advances, data needs to be curated. Files need to have their formats converted, and then transferred to new media. A backup disk in a box somewhere might be unreadable a few years from now. Its format may be obsolete, the software to read it might not run on current hardware, or the media might have physically decayed. NASA lost a large part of the data collected by the Viking Mars missions because the iron oxide fell off the tapes storing the data.<br />
<br />
Backups are important but they too are temporary, subject to the same problems as the data they attempt to protect. Backup software can become obsolete and media can fail. The same affliction that damaged the Viking tapes also wiped out my personal backup archive; I lost the only copy of my computer work from the 1970s. (It's worth noting my negatives and prints from the period survived.)<br />
<br />
It's not just tapes that go bad. Consider CDs and DVDs, media often used for backup. The disks, especially the writable kind use for backups, are very fragile, much more so than the mass-produced read-only kind used to store music and movies. Within a few years, especially in humid environments, the metal film can separate from the backing medium. Even if the backup medium survives, the formats used to store the backups might become obsolete. The software that reads the backups might not run on the next computer one buys. Today, CDs are already becoming relics; many computers today do not even come with a CD or DVD drive. What were once the gold standard for backup are already looking old-fashioned just a few years on. They will be antiquated and obscure a century from now.<br />
<br />
To summarize, digital information requires maintenance. It's not sufficient to make backups; the backups also need to be maintained, upgraded, transferred, and curated. Without conscientious care, the data of today will be lost forever in a few years. Even with care, it's possible through software or hardware changes to lose access forever. That shoebox of old backup CDs will be unreadable soon.<br />
<br />
Which brings us back to those old photo caches. They held negatives and prints, physical objects that stored images. They needed no attention, no curating, no updating. They sat untended and forgotten for decades, but through all that time faithfully held their information, waiting for a future discoverer. As a result, we can all see what the Scott Antarctic expedition saw, and I can see what my great-grandparents looked like.<br />
<br />
It is a sad irony that modern technology makes it unlikely that future generations will see the images made today.<br />
<br />
Ask yourself whether your great-grandchildren will be able to see your photographs. If the images exist only as a digital image file, the answer is almost certainly, "No". If, however, there are physical prints, the odds improve. Those digital images need to be made real to endure. Without a print, a digital photograph has no future.<br />
<br />
We live in a Digital Dark Age, but as individuals we can shine a little light. If you are one of the uncounted photographers who enjoy digital photography, keep in mind the fragility of data. When you have a digital image you care about, for whatever reason, artistic or sentimental, please make a print and put that print away. It will sit quietly in the dark, holding fast, never forgetting, ready to reveal itself to a grateful future generation.<br />
<div>
<br /></div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-44209402128976304002014-01-24T16:35:00.000-08:002014-02-24T08:59:32.220-08:00Self-referential functions and the design of optionsI've been trying on and off to find a nice way to deal with setting options in a <a href="http://golang.org/" target="_blank">Go</a> package I am writing. Options on a type, that is. The package is intricate and there will probably end up being dozens of options. There are many ways to do this kind of thing, but I wanted one that felt nice to use, didn't require too much API (or at least not too much for the user to absorb), and could grow as needed without bloat.<br />
<br />
I've tried most of the obvious ways: option structs, lots of methods, variant constructors, and more, and found them all unsatisfactory. After a bunch of trial versions over the past year or so, and a lot of conversations with other Gophers making suggestions, I've finally found one I like. You might like it too. Or you might not, but either way it does show an interesting use of self-referential functions.<br />
<br />
I hope I have your attention now.<br />
<br />
Let's start with a simple version. We'll refine it to get to the final version.<br />
<br />
First, we define an <span style="font-family: Trebuchet MS, sans-serif;">option</span> type. It is a function that takes one argument, the <span style="font-family: Trebuchet MS, sans-serif;">Foo</span> we are operating on.<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">type option func(*Foo)</span><br />
<br />
The idea is that an option is implemented as a function we call to set the state of that option. That may seem odd, but there's a method in the madness.<br />
<br />
Given the option type, we next define an <span style="font-family: Trebuchet MS, sans-serif;">Option</span> method on <span style="font-family: Trebuchet MS, sans-serif;">*Foo</span> that applies the options it's passed by calling them as functions. That method is defined in the same package, say <span style="font-family: Trebuchet MS, sans-serif;">pkg</span>, in which <span style="font-family: Trebuchet MS, sans-serif;">Foo</span> is defined.<br />
<br />
This is Go, so we can make the method variadic and set lots of options in a given call:<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">// Option sets the options specified.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">func (f *Foo) Option(opts ...option) {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">for _, opt := range opts {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">opt(f)</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<br />
Now to provide an option, we define in <span style="font-family: Trebuchet MS, sans-serif;">pkg</span> a function with the appropriate name and signature. Let's say we want to control verbosity by setting an integer value stored in a field of a <span style="font-family: Trebuchet MS, sans-serif;">Foo</span>. We provide the verbosity option by writing a function with the obvious name and have it return an <span style="font-family: Trebuchet MS, sans-serif;">option</span>, which means a closure; inside that closure we set the field:<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">// Verbosity sets Foo's verbosity level to v.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">func Verbosity(v int) option {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">return func(f *Foo) {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">f.verbosity = v</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<br />
Why return a closure instead of just doing the setting? Because we don't want the user to have to write the closure and we want the <span style="font-family: Trebuchet MS, sans-serif;">Option</span> method to be nice to use. (Plus there's more to come....)<br />
<br />
In the client of the package, we can set this option on a <span style="font-family: Trebuchet MS, sans-serif;">Foo</span> object by writing:<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">foo.Option(pkg.Verbosity(3))</span><br />
<br />
That's easy and probably good enough for most purposes, but for the package I'm writing, I want to be able to use the option mechanism to set temporary values, which means it would be nice if the <span style="font-family: Trebuchet MS, sans-serif;">Option</span> method could return the previous state. That's easy: just save it in an empty interface value that is returned by the <span style="font-family: Trebuchet MS, sans-serif;">Option</span> method and the underlying function type. That value flows through the code:<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">type option func(*Foo) interface{}</span><br />
<span style="font-family: Trebuchet MS, sans-serif;"><br /></span>
<span style="font-family: Trebuchet MS, sans-serif;">// Verbosity sets Foo's verbosity level to v.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">func Verbosity(v int) option {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">return func(f *Foo) interface{} {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">previous := f.verbosity</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">f.verbosity = v</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">return previous</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">// Option sets the options specified.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">// It returns the previous value of the last argument.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">func (f *Foo) Option(opts ...option) (previous interface{}) {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">for _, opt := range opts {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">previous = opt(f)</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">return previous</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<br />
The client can use this the same as before, but if the client also wants to restore a previous value, all that's needed is to save the return value from the first call, and then restore it.<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">prevVerbosity := foo.Option(pkg.Verbosity(3))</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">foo.DoSomeDebugging()</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">foo.Option(pkg.Verbosity(prevVerbosity.(int)))</span><br />
<br />
The type assertion in the restoring call to <span style="font-family: Trebuchet MS, sans-serif;">Option</span> is clumsy. We can do better if we push a little harder on our design.<br />
<br />
First, redefine an option to be a function that sets a value and returns <i>another option</i> to restore the previous value.<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">type option func(f *Foo) option</span><br />
<br />
This self-referential function definition is reminiscent of a <a href="http://www.youtube.com/watch?v=HxaD_trXwRE" target="_blank">state machine</a>. Here we're using it a little differently: it's a function that returns its <i>inverse</i>.<br />
<br />
Then change the return type (and meaning) of the <span style="font-family: Trebuchet MS, sans-serif;">Option</span> method of <span style="font-family: Trebuchet MS, sans-serif;">*Foo</span><span style="font-family: Times, Times New Roman, serif;"> to </span><span style="font-family: Trebuchet MS, sans-serif;">option</span><span style="font-family: Times, Times New Roman, serif;"> from </span><span style="font-family: Trebuchet MS, sans-serif;">interface{}</span><span style="font-family: Times, Times New Roman, serif;">:</span><br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">// Option sets the options specified.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">// It returns an option to restore the last arg's previous value.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">func (f *Foo) Option(opts ...option) (previous option) {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">for _, opt := range opts {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">previous = opt(f)</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">return previous</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<br />
The final piece is the implementation of the actual option functions. Their inner closure must now return an option, not an interface value, and that means it must return a closure to undo itself. But that's easy: it can just recur to prepare the closure to undo the original! It looks like this:<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">// Verbosity sets Foo's verbosity level to v.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">func Verbosity(v int) option {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">return func(f *Foo) option {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">previous := f.verbosity</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">f.verbosity = v</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">return Verbosity(previous)</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<br />
Note the last line of the inner closure changed from<br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">return previous</span><br />
to<br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: 'Trebuchet MS', sans-serif;">return Verbosity(previous)</span><br />
Instead of just returning the old value, it now calls the surrounding function (<span style="font-family: Trebuchet MS, sans-serif;">Verbosity</span>) to create the undo closure, and returns that <i>closure</i>.<br />
<br />
Now from the client's view this is all very nice:<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">prevVerbosity := foo.Option(pkg.Verbosity(3))</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">foo.DoSomeDebugging()</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">foo.Option(prevVerbosity)</span><br />
<br />
And finally we take it up one more level, using Go's <a href="http://blog.golang.org/defer-panic-and-recover" target="_blank">defer</a> mechanism to tidy it all up in the client:<br />
<br />
<span style="font-family: Trebuchet MS, sans-serif;">func DoSomethingVerbosely(foo *Foo, verbosity int) {</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">// Could combine the next two lines,</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">// with some loss of readability.</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">prev := foo.Option(pkg.Verbosity(verbosity))</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">defer foo.Option(prev)</span><br />
<span style="font-family: 'Trebuchet MS', sans-serif; white-space: pre;"> </span><span style="font-family: Trebuchet MS, sans-serif;">// ... do some stuff with foo under high verbosity.</span><br />
<span style="font-family: Trebuchet MS, sans-serif;">}</span><br />
<div>
<br /></div>
<div>
It's worth noting that since the "verbosity" returned is now a closure, not a verbosity value, the actual previous value is hidden. If you want that value you need a little more magic, but there's enough magic for now.</div>
<br />
The implementation of all this may seem like overkill but it's actually just a few lines for each option, and has great generality. Most important, it's really nice to use from the point of view of the package's client. I'm finally happy with the design. I'm also happy at the way this uses Go's closures to achieve its goals with grace.<br />
<br />robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-39434101922282570542013-05-01T08:57:00.001-07:002013-05-01T08:57:04.200-07:00Eisenbahnnet: Bohr's trip about spin<br />
The other day I was talking with a friend (yes, I have friends) about the way communication of ideas has changed. The Internet is the obvious advance, but what used to happen when an important new idea needed to be disseminated? As an example of how things used to be, I told him the story of Bohr's famous train trip.<br />
<br />
In 1925, two students at the University of Leiden, Sem Goudsmit and George Uhlenbeck, realized that the fourth electron quantum number could be explained if the electron had spin. This was a radical idea (a point particle spinning?), and coming from students was doubly suspect. Physicists throughout Europe were excited yet skeptical. When Bohr was planning a trip from Cophenhagen to Leiden for a conference, it seemed an excellent opportunity to talk to the students to help understand if they were right.<br />
<br />
In his book, Inward Bound, Abraham Païs narrates the story as told to him by Bohr twenty years later:<br />
<br />
<blockquote class="tr_bq">
Bohr's train to Leiden made a stop in Hamburg, where he was met by Pauli and Stern who had come to the station to ask him what he thought about spin. Bohr must have said that it was very very interesting (his favorite way of expressing that something was wrong), but he could not see how an electron moving in the electric field of the nucleus could experience the magnetic field necessary for producing fine structure. (As Uhlenbeck said later: 'I must say in retrospect that Sem and I in our euphoria had not really appreciated [this] basic difficulty.') On his arrival in Leiden, Bohr was met at the train by Ehrenfest and Einstein who asked him what he thought about spin. Bohr must have said that it was very very interesting but what about the magnetic field? Ehrenfest replied that Einstein had resolved that. The electron in its rest frame sees a rotating electric field; hence by elementary relativity it also sees a magnetic field. The net result is an effective spin-orbit coupling. Bohr was at once convinced. When told of the factor of two he expressed confidence that this problem would find a natural resolution. He urged Sem and George to write a more detailed note on their work. They did; Bohr added an approving comment.</blockquote>
<blockquote class="tr_bq">
After Leiden Bohr traveled to Goettingen. There he was met at the station by Heisenberg and Jordan who asked what he thought about spin. Bohr replied that it was a great advance and explained about the spin-orbit coupling. Heisenberg remarked that he had heard this remark before but that he could not remember who made it and when. ... On his way home the train stopped at Berlin where Bohr was met at the station by Pauli, who had made the trip from Hamburg for the sole purpose of asking Bohr what he now thought about spin. Bohr said it was a great advance, to which Pauli replied: 'eine Neue Kopenhagener Irrlehre' (a new Copenhagen heresy). After his return home Bohr wrote to Ehrenfest that he had become 'a prophet of the electron magnet gospel.'</blockquote>
<br />
Sneakernet indeed, or perhaps Eisenbahnnet. The idea of the great physicist carrying precious nuggets of wisdom across Europe is romantic and poignant. It also shows how Bohr's insight, and the insight of his brilliant colleagues, did the peer review in real time in two train trips. Bohr, Pauli, Stern, Ehrenfest, Einstein, Heisenberg, Jordan, Pauli: What a peer review it was!<br />
<br />
It is one of the greatest oversights of the Nobel committee that Goudsmit and Uhlenbeck were never rewarded. Their colleagues certainly understood the earth-shaking merit of their insight.<br />
<div>
<br /></div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-84625506247284099072012-09-22T15:55:00.001-07:002012-09-22T20:33:33.978-07:00Thank you Apple<br />
Some days, things just don't work out. Or don't work.<br />
<h4>
Earlier</h4>
I wanted to upgrade (their term, not mine) my iMac from Snow Leopard (10.6) to Lion (10.7). I even had the little USB stick version of the installer, to make it easy. But after spending some time attempting the installation, the Lion installer "app" failed, complaining about SMART errors on the disk.<br />
<br />
Disk Utility indeed reported there were SMART errors, and that the disk hardware needed to be replaced. An ugly start.<br />
<br />
The good news is that in some places, including where I live, Apple will do a house call for service, so I didn't have to haul the computer to an Apple store on public transit.<br />
<br />
Thank you Apple.<br />
<br />
I called them, scheduled the service for a few days later, and as instructed by Apple (I hardly needed prompting) prepped a backup using Time Machine.<br />
<br />
The day before the repairman was to come to give me a new disk, I made sure the system was fully backed up, for security reasons started a complete erasure of the bad disk (using Disk Utility in target mode from another machine, about which more later), and went to bed.<br />
<h4>
The day</h4>
When I got up, I checked that the disk had been erased and headed off to work. As I left the apartment, the ceiling lights in the entryway flickered and then went out: a new bulb was needed. On the way out of the building, I asked the doorman for a replacement bulb. He offered just to replace it for us. We have a good doorman.<br />
<br />
Once at work, things were normal until my cell phone rang about 2pm. It was the Apple repairman, Twinkletoes (some names and details have been changed), calling to tell me he'd be at my place within the hour. Actually, he wasn't an Apple employee, but a contractor working for Unisys, a name I hadn't heard in a long time. (Twinkletoes was a name I hadn't heard for a while either, but that's another story.) At least here, Apple uses Unisys contractors to do their house calls.<br />
<br />
So I headed home, arriving before Twinkletoes. At the front door, the doorman stopped me. He reported that the problem with the lights was not the bulb, but the wiring. He'd called in an electrician, who had found a problem in the breaker box and fixed it. Everything was good now.<br />
<br />
When I got up to the apartment, I found chaos: the cleaners were mid-job, with carpets rolled up, vacuum cleaners running, and general craziness. Not conducive to work. So I went back down to the lobby with my laptop and sat on the couch, surfing on the free WiFi from the café next door, and waited for Twinkletoes.<br />
<br />
Half an hour later, he arrived and we returned to the apartment. The cleaners were still there but the chaos level had dropped and it wasn't too hard to work around them. I saw what the inside of an iMac looks like as Twinkletoes swapped out the drive. By the time he was done, the cleaners had left and things had settled down.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-eWOKI4PjbFA/UF4_4v-DPEI/AAAAAAAACZQ/t69_q0Nkj1g/s1600/L1000753.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="300" src="http://3.bp.blogspot.com/-eWOKI4PjbFA/UF4_4v-DPEI/AAAAAAAACZQ/t69_q0Nkj1g/s400/L1000753.jpg" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">The innards of my 27" iMac</span></div>
<br />
<br />
I had assumed that the replacement drive would come with an installed operating system, but I assumed wrong. (When you assume, you put plum paste on your ass.) I had a Snow Leopard installation DVD, but I was worried: it had failed to work for me a few days earlier when I wanted to boot from it to run fsck on the broken drive. Twinkletoes noticed it had a scratch. I needed another way to boot the machine.<br />
<br />
It had surprised me when Lion came out that the installation was done by an "app", not as a bootable image. This is an unnecessary complication for those of us that need to maintain machines. Earlier, when updating a different machine, I had learned how painful this could be when the installation app destroyed the boot sector and I needed to reinstall Snow Leopard from DVD, and then upgrade <i>that</i> to a version of the system recent enough to run the Lion installer app. As will become apparent, had Lion come as a bootable image things might have gone more smoothly.<br />
<br />
Thank you Apple.<br />
<br />
[Note added in post: Several people have told me there's a bootable image inside the installer. I forgot to mention that I knew that, and there wasn't. For some reason, the version on the USB stick I have looks different from the downloaded one I checked out a day or two later, and even Twinkletoes couldn't figure out how to unpack it. Weird.]<br />
<br />
Twinkletoes had an OS image he was willing to let me copy, but I needed to make a bootable drive from it. I had no sufficiently large USB stick—you need a 4GB one you can wipe. However I did have a free, big enough CompactFlash card and a USB reader, so that should do, right? Twinkletoes was unsure but believed it would.<br />
<br />
Using my laptop, I used Disk Utility to create a bootable image on the CF card from Twinkletoes's disk image. We were ready.<br />
<br />
Plug in the machine, push down the Option key, power on.<br />
<br />
Nothing.<br />
<br />
Turn on the light.<br />
<br />
Nothing.<br />
<br />
No power.<br />
<br />
The cleaners must have tripped a breaker.<br />
<br />
I went to the breaker box and found that all the breakers looked OK. We now had a mystery, because the cleaners had had lights on and were using electric appliances—I saw a vacuum cleaner running—but now there was no power. Was the power off to the building? No: the lights still worked in the kitchen and the oven clock was lit. I called the doorman and asked him to get the electrician back as soon as possible and then, with a little portable lamp, went looking around the apartment for a working socket. I found one, again in the kitchen. The iMac was going to travel after all, if not as far as downtown.<br />
<br />
The machine was moved, plugged in, option-key-downed, and powered on. I selected the CF card to boot from, waited 15 minutes for the installation to come up, only to have the boot fail. CF cards don't work after all, although the diagnosis of failure is a bit tardy and uninformative.<br />
<br />
Thank you Apple.<br />
<br />
Next idea. My old laptop has FireWire so we could bring the disk up using target mode and then run the installer on the laptop to install Lion on the iMac.<br />
<br />
We did the target mode dance and connected to the newly installed drive, then ran Disk Utility on the laptop to format the drive. Things were starting to look better.<br />
<br />
Next, we put the Lion installer stick into the laptop, which was running a recent version of Snow Leopard.<br />
<br />
Failure again. This time the problem is that the laptop, all of about four years old, is too old to run Lion. It's got a Core Duo, not a Core 2 Duo, and Lion won't run on that hardware. Even though Lion doesn't need to run, only the Lion installer needs to run, the system refuses to help. My other laptop is new enough to run the installer, but it doesn't have FireWire so it can't do target mode.<br />
<br />
Thank you Apple. Your aggressive push to retire old technology hurts sometimes, you know? Actually, more than sometimes, but let's stay on topic.<br />
<br />
Twinkletoes has to leave—he's been on the job for several hours now—but graciously lends me a USB boot drive he has, asking me to return it by post when I'm done. I thank him profusely and send him away before he is drawn in any deeper.<br />
<br />
Using his boot drive, I was able to bring up the iMac and use the Lion installer stick to get the system to a clean install state. Finally, a computer, although of course all my personal data is over on the backup.<br />
<br />
When a new OS X installation comes up, it presents the option of "migrating" data from an existing system, including from a Time Machine backup. So I went for that option and connected the external drive with the Time Machine backup on it.<br />
<br />
The Migration Assistant presented a list of disks to migrate from. A list of one: the main drive in the machine. It didn't give me the option of using the Time Machine backup.<br />
<br />
Thank you Apple. You told me to save my machine this way but then I can't use this backup to recover.<br />
<br />
I called Apple on my cell phone (there's still no power in the room with the land line's wireless base station) and explained the situation. The sympathetic but ultimately unhelpful person on the phone said it should work (of course!) and that I should run Software Update and get everything up to the latest version. He reported that there were problems with the Migration Assistant in early versions of the Lion OS, and my copy of the installer was pretty early.<br />
<br />
I started the upgrade process, which would take a couple of hours, and took my laptop back down to the lobby for some free WiFi to kill time. But it's now evening, the café is closed, and there is no WiFi. Naturally.<br />
<br />
Back to the apartment, grab a book, return to the lobby to wait for the electrician.<br />
<br />
An hour or so later, the electrician arrived and we returned to the apartment to see what was wrong. It was easy to diagnose. He had made a mistake in the fix, in fact a mistake related to what was causing the original problem. The breaker box has a silly design that makes it too easy to break a connection when working in the box, and that's what had happened. So it was easy to fix and easy to verify that it was fixed, but also easy to understand why it had happened. No excuses, but problem solved and power was now restored.<br />
<br />
The computer was still upgrading but nearly done, so a few minutes later I got to try migrating again. Same result, naturally, and another call to Apple and this time little more than an apology. The unsatisfactory solution: do a clean installation and manually restore what's important from the Time Machine backup.<br />
<br />
Thank you Apple.<br />
<br />
It was fairly straightforward, if slow, to restore my personal files from the home directory on the backup, but the situation for installed software was dire. Restoring an installed program, either using the ludicrous Time Machine UI or copying the files by hand, is insufficient in most cases to bring back the program because you also need manifests and keys and receipts and whatnot. As a result, things such as iWork (Keynote etc.) and Aperture wouldn't run. I could copy every piece of data I could find but the apps refused to let me run them. Despite many attempts digging far too deep into the system, I could not get the right pieces back from the Time Machine backup. Worse, the failure modes were appalling: crashes, strange display states, inexplicable non-workiness. A frustating mess, but structured perfectly to belong on this day.<br />
<br />
For peculiar reasons I didn't have the installation disks for everything handy, so these (expensive!) programs were just gone, even though I had backed up everything as instructed.<br />
<br />
Thank you Apple.<br />
<br />
I did have some installation disks, so for instance I was able to restore Lightroom and Photoshop, but then of course I needed to wait for huge updates to download even though the data needed was already sitting on the backup drive.<br />
<br />
Back on the phone for the other stuff. Because I could prove that I had paid for the software, Apple agreed to send me fresh installation disks for everything of theirs but Aperture, but that would take time. In fact, it took almost a month for the iWork DVD to arrive, which is unacceptably long. I even needed to call twice to remind them before the disks were shipped.<br />
<br />
The Aperture story was more complicated. After a marathon debugging session I managed to get it to start but then it needed the install key to let me do anything. I didn't have the disk, so I didn't know the key. Now, Aperture is from part of the company called Pro Tools or something like that, and they have a different way of working. I needed to contact them separately to get Aperture back. It's important to understand I hadn't lost my digital images. They were backed up multiple times, including in the network, on the Time Machine backup, and also on an external drive using the separate "vault" mechanism that is one of the best features of Aperture.<br />
<br />
I reached the Aperture people on the phone and after a condensed version of the story convinced them I needed an install key (serial number) to run the version of Aperture I'd copied from the Time Machine backup. I was berated by the person on the phone: Time Machine is not suitable for backing up Aperture databases. (What? Your own company's backup solution doesn't know how to back up? Thank you Apple.) After a couple more rounds of abuse, I convinced the person on the phone that a) I was backing up my database as I should, using an Aperture vault and b) it wasn't the database that was the problem, but the program. I was again told that wasn't a suitable way to back up (again, What?), at which point I surrendered and just begged for an installation key, which was provided, and I could again run Aperture. This was the only time in the story where the people I was interacting with were not at least sympathetic to my situation. I guess Pro is a synonym for unfriendly.<br />
<br />
Thank you Apple.<br />
<br />
There's much more to the story. It took weeks to get everything working again properly. The complete failure of Time Machine to back up my computer's state properly was shocking to me. After this fiasco, I learned about the Lion Recovery App, which everyone who uses Macs should know about, but was not introduced until well after Lion rolled out with its preposterous not-bootable installation setup. The amount of data I already had on my backup disk but that needed to be copied from the net again was laughable. And there were total mysteries, like GMail hanging forever for the first day or so, a problem that may be unrelated or may just be the way life was this day.<br />
<br />
But, well after midnight, worn out, beat up, tired, but with electricity restored and a machine that had a little life in it again, I powered down, took the machine back to my office and started to get ready for bed. Rest was needed and I had had enough of technology for one day.<br />
<h4>
One more thing</h4>
Oh yes, one more thing. There's always one more thing in our technological world.<br />
<br />
I walked into the bathroom for my evening ablutions only to have the toilet seat come off completely in my hand.<br />
<br />
Just because you started it all, even for this,<br />
<br />
Thank you Apple.<br />
<div>
<br /></div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-82149303094109958062012-06-25T14:35:00.002-07:002021-01-01T17:07:50.475-08:00Less is exponentially more<br />
Here is the text of the talk I gave at the Go SF meeting in June, 2012.<br />
<br />
This is a personal talk. I do not speak for anyone else on the Go team here, although I want to acknowledge right up front that the team is what made and continues to make Go happen. I'd also like to thank the Go SF organizers for giving me the opportunity to talk to you.<br />
<br />
I was asked a few weeks ago, "What was the biggest surprise you encountered rolling out Go?" I knew the answer instantly: Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++.<br />
<br />
We—Ken, Robert and myself—were C++ programmers when we designed a new language to solve the problems that we thought needed to be solved for the kind of software we wrote. It seems almost paradoxical that other C++ programmers don't seem to care.<br />
<br />
I'd like to talk today about what prompted us to create Go, and why the result should not have surprised us like this. I promise this will be more about Go than about C++, and that if you don't know C++ you'll be able to follow along.<br />
<br />
The answer can be summarized like this: Do you think less is more, or less is less?<br />
<br />
Here is a metaphor, in the form of a true story. Bell Labs centers were originally assigned three-letter numbers: 111 for Physics Research, 127 for Computing Sciences Research, and so on. In the early 1980s a memo came around announcing that as our understanding of research had grown, it had become necessary to add another digit so we could better characterize our work. So our center became 1127. Ron Hardin joked, half-seriously, that if we really understood our world better, we could drop a digit and go down from 127 to just 27. Of course management didn't get the joke, nor were they expected to, but I think there's wisdom in it. Less can be more. The better you understand, the pithier you can be.<br />
<br />
Keep that idea in mind.<br />
<br />
Back around September 2007, I was doing some minor but central work on an enormous Google C++ program, one you've all interacted with, and my compilations were taking about 45 minutes on our huge distributed compile cluster. An announcement came around that there was going to be a talk presented by a couple of Google employees serving on the C++ standards committee. They were going to tell us what was coming in C++0x, as it was called at the time. (It's now known as C++11).<br />
<br />
In the span of an hour at that talk we heard about something like 35 new features that were being planned. In fact there were many more, but only 35 were described in the talk. Some of the features were minor, of course, but the ones in the talk were at least significant enough to call out. Some were very subtle and hard to understand, like rvalue references, while others are especially C++-like, such as variadic templates, and some others are just crazy, like user-defined literals.<br />
<br />
At this point I asked myself a question: Did the C++ committee really believe that was wrong with C++ was that it didn't have enough features? Surely, in a variant of Ron Hardin's joke, it would be a greater achievement to simplify the language rather than to add to it. Of course, that's ridiculous, but keep the idea in mind.<br />
<br />
Just a few months before that C++ talk I had given a talk myself, which you can see on <a href="https://www.youtube.com/watch?v=hB05UFqOtFA" target="_blank">YouTube</a>, about a toy concurrent language I had built way back in the 1980s. That language was called <a href="http://swtch.com/~rsc/thread/newsqueak.pdf">Newsqueak</a> and of course it is a precursor to Go.<br />
<br />
I gave that talk because there were ideas in Newsqueak that I missed in my work at Google and I had been thinking about them again. I was convinced they would make it easier to write server code and Google could really benefit from that.<br />
<br />
I actually tried and failed to find a way to bring the ideas to C++. It was too difficult to couple the concurrent operations with C++'s control structures, and in turn that made it too hard to see the real advantages. Plus C++ just made it all seem too cumbersome, although I admit I was never truly facile in the language. So I abandoned the idea.<br />
<br />
But the C++0x talk got me thinking again. One thing that really bothered me—and I think Ken and Robert as well—was the new C++ memory model with atomic types. It just felt wrong to put such a microscopically-defined set of details into an already over-burdened type system. It also seemed short-sighted, since it's likely that hardware will change significantly in the next decade and it would be unwise to couple the language too tightly to today's hardware.<br />
<br />
We returned to our offices after the talk. I started another compilation, turned my chair around to face Robert, and started asking pointed questions. Before the compilation was done, we'd roped Ken in and had decided to do something. We did not want to be writing in C++ forever, and we—me especially—wanted to have concurrency at my fingertips when writing Google code. We also wanted to address the problem of "programming in the large" head on, about which more later.<br />
<br />
We wrote on the white board a bunch of stuff that we wanted, desiderata if you will. We thought big, ignoring detailed syntax and semantics and focusing on the big picture.<br />
<br />
I still have a fascinating mail thread from that week. Here are a couple of excerpts:<br />
<br />
Robert: <i>Starting point: C, fix some obvious flaws, remove crud, add a few missing features.</i><br />
<br />
Rob: <i>name: 'go'. you can invent reasons for this name but it has nice properties. it's short, easy to type. tools: goc, gol, goa. if there's an interactive debugger/interpreter it could just be called 'go'. the suffix is .go.</i><br />
<br />
Robert: <i>Empty interfaces: interface {}. These are implemented by all interfaces, and thus this could take the place of void*.</i><br />
<br />
We didn't figure it all out right away. For instance, it took us over a year to figure out arrays and slices. But a significant amount of the flavor of the language emerged in that first couple of days.<br />
<br />
Notice that Robert said C was the starting point, not C++. I'm not certain but I believe he meant C proper, especially because Ken was there. But it's also true that, in the end, we didn't really start from C. We built from scratch, borrowing only minor things like operators and brace brackets and a few common keywords. (And of course we also borrowed ideas from other languages we knew.) In any case, I see now that we reacted to C++ by going back down to basics, breaking it all down and starting over. We weren't trying to design a better C++, or even a better C. It was to be a better language overall for the kind of software we cared about.<br />
<br />
In the end of course it came out quite different from either C or C++. More different even than many realize. I made a list of significant simplifications in Go over C and C++:<br />
<br />
<ul>
<li>regular syntax (don't need a symbol table to parse)</li>
<li>garbage collection (only)</li>
<li>no header files</li>
<li>explicit dependencies</li>
<li>no circular dependencies</li>
<li>constants are just numbers</li>
<li>int and int32 are distinct types</li>
<li>letter case sets visibility</li>
<li>methods for any type (no classes)</li>
<li>no subtype inheritance (no subclasses)</li>
<li>package-level initialization and well-defined order of initialization</li>
<li>files compiled together in a package</li>
<li>package-level globals presented in any order</li>
<li>no arithmetic conversions (constants help)</li>
<li>interfaces are implicit (no "implements" declaration)</li>
<li>embedding (no promotion to superclass)</li>
<li>methods are declared as functions (no special location)</li>
<li>methods are just functions</li>
<li>interfaces are just methods (no data)</li>
<li>methods match by name only (not by type)</li>
<li>no constructors or destructors</li>
<li>postincrement and postdecrement are statements, not expressions</li>
<li>no preincrement or predecrement</li>
<li>assignment is not an expression</li>
<li>evaluation order defined in assignment, function call (no "sequence point")</li>
<li>no pointer arithmetic</li>
<li>memory is always zeroed</li>
<li>legal to take address of local variable</li>
<li>no "this" in methods</li>
<li>segmented stacks</li>
<li>no const or other type annotations</li>
<li>no templates</li>
<li>no exceptions</li>
<li>builtin string, slice, map</li>
<li>array bounds checking</li>
</ul>
<br />
And yet, with that long list of simplifications and missing pieces, Go is, I believe, more expressive than C or C++. Less can be more.<br />
<br />
But you can't take out everything. You need building blocks such as an idea about how types behave, and syntax that works well in practice, and some ineffable thing that makes libraries interoperate well.<br />
<br />
We also added some things that were not in C or C++, like slices and maps, composite literals, expressions at the top level of the file (which is a huge thing that mostly goes unremarked), reflection, garbage collection, and so on. Concurrency, too, naturally.<br />
<br />
One thing that is conspicuously absent is of course a type hierarchy. Allow me to be rude about that for a minute.<br />
<br />
Early in the rollout of Go I was told by someone that he could not imagine working in a language without generic types. As I have reported elsewhere, I found that an odd remark.<br />
<br />
To be fair he was probably saying in his own way that he really liked what the STL does for him in C++. For the purpose of argument, though, let's take his claim at face value.<br />
<br />
What it says is that he finds writing containers like lists of ints and maps of strings an unbearable burden. I find that an odd claim. I spend very little of my programming time struggling with those issues, even in languages without generic types.<br />
<br />
But more important, what it says is that <i>types</i> are the way to lift that burden. <i>Types</i>. Not polymorphic functions or language primitives or helpers of other kinds, but <i>types</i>.<br />
<br />
That's the detail that sticks with me.<br />
<br />
Programmers who come to Go from C++ and Java miss the idea of programming with types, particularly inheritance and subclassing and all that. Perhaps I'm a philistine about types but I've never found that model particularly expressive.<br />
<br />
My late friend Alain Fournier once told me that he considered the lowest form of academic work to be taxonomy. And you know what? Type hierarchies are just taxonomy. You need to decide what piece goes in what box, every type's parent, whether A inherits from B or B from A. Is a sortable array an array that sorts or a sorter represented by an array? If you believe that types address all design issues you must make that decision.<br />
<br />
I believe that's a preposterous way to think about programming. What matters isn't the ancestor relations between things but what they can do for you.<br />
<br />
That, of course, is where interfaces come into Go. But they're part of a bigger picture, the true Go philosophy.<br />
<br />
If C++ and Java are about type hierarchies and the taxonomy of types, Go is about composition.<br />
<br />
Doug McIlroy, the eventual inventor of Unix pipes, wrote in 1964 (!):<br />
<blockquote class="tr_bq">
We should have some ways of coupling programs like garden hose--screw in another segment when it becomes necessary to massage data in another way. This is the way of IO also.</blockquote>
That is the way of Go also. Go takes that idea and pushes it very far. It is a language of composition and coupling.<br />
<br />
The obvious example is the way interfaces give us the composition of components. It doesn't matter what that thing is, if it implements method M I can just drop it in here.<br />
<br />
Another important example is how concurrency gives us the composition of independently executing computations.<br />
<br />
And there's even an unusual (and very simple) form of type composition: embedding.<br />
<br />
These compositional techniques are what give Go its flavor, which is profoundly different from the flavor of C++ or Java programs.<br />
<br />
===========<br />
<br />
There's an unrelated aspect of Go's design I'd like to touch upon: Go was designed to help write big programs, written and maintained by big teams.<br />
<br />
There's this idea about "programming in the large" and somehow C++ and Java own that domain. I believe that's just a historical accident, or perhaps an industrial accident. But the widely held belief is that it has something to do with object-oriented design.<br />
<br />
I don't buy that at all. Big software needs methodology to be sure, but not nearly as much as it needs strong dependency management and clean interface abstraction and superb documentation tools, none of which is served well by C++ (although Java does noticeably better).<br />
<br />
We don't know yet, because not enough software has been written in Go, but I'm confident Go will turn out to be a superb language for programming in the large. Time will tell.<br />
<br />
===========<br />
<br />
Now, to come back to the surprising question that opened my talk:<br />
<br />
Why does Go, a language designed from the ground up for what what C++ is used for, not attract more C++ programmers?<br />
<br />
Jokes aside, I think it's because Go and C++ are profoundly different philosophically.<br />
<br />
C++ is about having it all there at your fingertips. I found this quote on a C++11 FAQ:<br />
<blockquote class="tr_bq">
The range of abstractions that C++ can express elegantly, flexibly, and at zero costs compared to hand-crafted specialized code has greatly increased.</blockquote>
That way of thinking just isn't the way Go operates. Zero cost isn't a goal, at least not zero CPU cost. Go's claim is that minimizing programmer effort is a more important consideration.<br />
<br />
Go isn't all-encompassing. You don't get everything built in. You don't have precise control of every nuance of execution. For instance, you don't have RAII. Instead you get a garbage collector. You don't even get a memory-freeing function.<br />
<br />
What you're given is a set of powerful but easy to understand, easy to use building blocks from which you can assemble—compose—a solution to your problem. It might not end up quite as fast or as sophisticated or as ideologically motivated as the solution you'd write in some of those other languages, but it'll almost certainly be easier to write, easier to read, easier to understand, easier to maintain, and maybe safer.<br />
<br />
To put it another way, oversimplifying of course:<br />
<br />
Python and Ruby programmers come to Go because they don't have to surrender much expressiveness, but gain performance and get to play with concurrency.<br />
<br />
C++ programmers <i>don't</i> come to Go because they have fought hard to gain exquisite control of their programming domain, and don't want to surrender any of it. To them, software isn't just about getting the job done, it's about doing it a certain way.<br />
<br />
The issue, then, is that Go's success would contradict their world view.<br />
<br />
And we should have realized that from the beginning. People who are excited about C++11's new features are not going to care about a language that has so much less. Even if, in the end, it offers so much more.<br />
<br />
Thank you.<br />
<div>
<br /></div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-2041474998025852882012-04-03T22:22:00.005-07:002019-01-25T01:17:55.325-08:00The byte order fallacy<div>
<span style="font-family: Times, Times New Roman, serif;">Whenever I see code that asks what the native byte order is, it's almost certain the code is either wrong or misguided. And if the native byte order really does matter to the execution of the program, it's almost certain to be dealing with some external software that is either wrong or misguided. If your code contains </span><span class="Apple-style-span" style="font-family: Trebuchet MS, sans-serif;">#ifdef BIG_ENDIAN</span><span style="font-family: Times, Times New Roman, serif;"> or the equivalent, you need to unlearn about byte order.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">The byte order of the computer doesn't matter much at all except to compiler writers and the like, who fuss over allocation of bytes of memory mapped to register pieces. Chances are you're not a compiler writer, so the computer's byte order shouldn't matter to you one bit.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">Notice the phrase "computer's byte order". What <i>does</i> matter is the byte order of a peripheral or encoded data stream, but--and this is the key point--the byte order of the computer doing the processing is irrelevant to the processing of the data itself. If the data stream encodes values with byte order B, then the algorithm to decode the value on computer with byte order C should be about B, <i>not about the relationship between B and C</i>.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">Let's say your data stream has a little-endian-encoded 32-bit integer. Here's how to extract it (assuming unsigned bytes):</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;"> </span><span style="font-family: Trebuchet MS, sans-serif;">i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">If it's big-endian, here's how to extract it:</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;"> </span><span style="font-family: Trebuchet MS, sans-serif;">i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">Both these snippets work on any machine, independent of the machine's byte order, independent of alignment issues, independent of just about anything. They are totally portable, given unsigned bytes and 32-bit integers.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">What you might have expected to see for the little-endian case was something like</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Trebuchet MS, sans-serif;"> i = *((int*)data);</span><br />
<span style="font-family: Trebuchet MS, sans-serif;"> #ifdef BIG_ENDIAN</span><br />
<span style="font-family: Trebuchet MS, sans-serif;"> /* swap the bytes */</span><br />
<span style="font-family: Trebuchet MS, sans-serif;"><br /></span>
<span style="font-family: Trebuchet MS, sans-serif;"> i = ((i&0xFF)<<24) | (((i>>8)&0xFF)<<16) | (((i>>16)&0xFF)<<8) | (((i>>24)&0xFF)<<0);</span><br />
<span style="font-family: Trebuchet MS, sans-serif;"> </span><br />
<span style="font-family: Trebuchet MS, sans-serif;"> #endif</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;">or something similar. I've seen code like that many times. Why not do it that way? Well, for starters:</span></div>
<div>
<ol>
<li><span style="font-family: Times, Times New Roman, serif;">It's more code.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">It assumes integers are addressable at any byte offset; on some machines that's not true.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">It depends on integers being 32 bits long, or requires more <span class="Apple-style-span" style="font-family: 'trebuchet ms';">#ifdefs</span> to pick a 32-bit integer type.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">It may be a little faster on little-endian machines, but not much, and it's slower on big-endian machines.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">If you're using a little-endian machine when you write this, there's no way to test the big-endian code.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">It swaps the bytes, a sure sign of trouble (see below).</span></li>
</ol>
</div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">By contrast, my version of the code:</span></div>
<div>
<ol>
<li><span style="font-family: Times, Times New Roman, serif;">Is shorter.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">Does not depend on alignment issues.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">Computes a 32-bit integer value regardless of the local size of integers.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">Is equally fast regardless of local endianness, and fast enough (especially on modern processsors) anyway.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">Runs the same code on all computers: I can state with confidence that if it works on a little-endian machine it will work on a big-endian machine.</span></li>
<li><span style="font-family: Times, Times New Roman, serif;">Never "byte swaps".</span></li>
</ol>
</div>
<div>
<span style="font-family: Times, Times New Roman, serif;">In other words, it's simpler, cleaner, and utterly portable. There is no reason to ask about local byte order when about to interpret an externally provided byte stream.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">I've seen programs that end up swapping bytes two, three, even four times as layers of software grapple over byte order. In fact, byte-swapping is the surest indicator the programmer doesn't understand how byte order works.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">Why do people make the byte order mistake so often? I think it's because they've seen a lot of bad code that has convinced them byte order matters. "Here comes an encoded byte stream; time for an <span class="Apple-style-span" style="font-family: 'trebuchet ms';">#ifdef</span>." In fact, C may be part of the problem: in C it's easy to make byte order look like an issue. If instead you try to write byte-order-dependent code in a type-safe language, you'll find it's very hard. In a sense, byte order only bites you when you cheat.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">There's plenty of software that demonstrates the byte order fallacy is really a fallacy. The entire Plan 9 system ran, without architecture-dependent <span class="Apple-style-span" style="font-family: 'trebuchet ms';">#ifdefs</span> of any kind, on dozens of computers of different makes, models, and byte orders. I promise you, your computer's byte order doesn't matter even at the level of the operating system.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">And there's plenty of software that demonstrates how easily you can get it wrong. Here's one example. I don't know if it's still true, but some time back Adobe Photoshop screwed up byte order. Back then, Macs were big-endian and PCs, of course, were little-endian. If you wrote a Photoshop file on the Mac and read it back in, it worked. If you wrote it on a PC and tried to read it on a Mac, though, it wouldn't work unless back on the PC you checked a button that said you wanted the file to be readable on a Mac. (Why wouldn't you? Seriously, why wouldn't you?) Ironically, when you read a Mac-written file on a PC, it always worked, which demonstrates that someone at Adobe figured out something about byte order. But there would have been no problems transferring files between machines, and no need for a check box, if the people at Adobe wrote proper code to encode and decode their files, code that could have been identical between the platforms. I guarantee that to get this wrong took far more code than it would have taken to get it right. <span style="font-size: x-small;">[Note added in 2013: I'm told by folks at Adobe that the option was for TIFF files and only needed for third-party plugins. That doesn't explain why it was PC-only or necessary at all. Adobe might not be the right culprit but the issue was real.]</span></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">Just last week I was reviewing some test code that was checking byte order, and after some discussion it turned out that there was a byte-order-dependency bug in the code being tested. As is often the case, the existence of byte-order-checking was evidence of the presence of a bug. Once the bug was fixed, the test no longer cared about byte order.</span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div>
<span style="font-family: Times, Times New Roman, serif;">And neither should you, because byte order doesn't matter.</span></div>
<div>
<br /></div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-32876730473541247722011-12-31T18:15:00.000-08:002012-01-01T11:17:50.948-08:00Esmerelda's Imagination<div>An actress acquaintance of mine—let's call her Esmerelda—once said, "I can't imagine being anything except an actress." To which the retort was given, "You can't be much of an actress then, can you?"</div><div><br /></div><div>I was reminded of this exchange when someone said to me about Go, "I can't imagine programming in a language that doesn't have generics." My retort, unspoken this time, was, "You can't be much of a programmer, then, can you?"</div><div><br /></div><div>This is not an essay about generics (which are a fine thing and may arrive in Go one day, or may not) but about imagination, or at least what passes for imagination among computer programmers: complaint. A friend observed that the definitive modern pastime is to complain on line. For the complainers, it's fun, for the recipients of the complaint it can be dispiriting. As a recipient, I am pushing back—by complaining, of course.</div><div><br /></div><div>Not so long ago, a programmer was someone who programs, but that seems to be the last thing programmers do nowadays. Today, the definition of a programmer is someone who complains unless the problem being solved has already been solved and whose solution can be expressed in a single line of code. (From the point of view of a language designer, this reduces to a corollary of language success: every program must be reducible to single line of code or your language sucks. The lessons of APL have been lost.)</div><div><br /></div><div>A different, more liberal definition might be that a programmer is someone who approaches every problem exactly the same way and complains about the tools if the approach is unsuccessful.</div><div><br /></div><div>For the programmer population, the modern pastime demands that if one is required to program, or at least to think while programming, one blogs/tweets/rants instead. I have seen people write thousands of words of on-line vituperation that problem X requires a few extra keystrokes than it might otherwise, missing the irony that had they spent those words on programming, they could have solved the problem many times over with the saved keystrokes. But, of course, that would be programming.</div><div><br /></div><div>Two years ago Go went public. This year, Dart was announced. Both came from Google but from different teams with different goals; they have little in common. Yet I was struck by a property of the criticisms of Dart in the first few days: by doing a global substitution of "Go" for "Dart", many of the early complaints about Go would have fit right into the stream of Dart invective. It was unnecessary to try Go or Dart before commenting publicly on them; in fact, it was important not to (for one thing, trying them would require programming). The criticisms were loud and vociferous but irrelevant because they weren't about the languages at all. They were just a standard reaction to something new, empty of meaning, the result of a modern programmer's need to complain about everything different. Complaints are infinitely recyclable. ("I can't imagine programming in a language without XXX.") After all, they have a low quality standard: they need not be checked by a compiler.</div><div><br /></div><div>A while after Go launched, the criticisms changed tenor somewhat. Some people had actually tried it, but there were still many complainers, including the one quoted above. The problem now was that imagination had failed: Go is a language for writing Go programs, not Java programs or Haskell programs or any other language's programs. You need to think a different way to write good Go programs. But that takes time and effort, more than most will invest. So the usual story is to translate one program from another language into Go and see how it turns out. But translation misses idiom. A first attempt to write, for example, some Java construct in Go will likely fail, while a different Go-specific approach might succeed and illuminate. After 10 years of Java programming and 10 minutes of Go programming, any comparison of the language's capabilities is unlikely to generate insight, yet here come the results, because that's a modern programmer's job.</div><div><br /></div><div>It's not all bad, of course. Two years on, Go has lots of people who've spent the time to learn how it's meant to be used, and for many willing to invest such time the results have been worthwhile. It takes time and imagination and programming to learn how to use any language well, but it can be time well spent. The growing Go community has generated lots of great software and has given me hope, hope that there may still be actual programmers out there.</div><div><br /></div><div>However, I still see far too much ill-informed commentary about Go on the web, so for my own protection I will start 2012 with a resolution:</div><div><br /></div><div><i>I resolve to recognize that a complaint reveals more about the complainer than the complained-about. Authority is won not by rants but by experience and insight, which require practice and imagination. And maybe some programming.</i></div><div><br /></div>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-10911662949036815062011-09-18T15:19:00.000-07:002011-09-18T15:27:01.341-07:00User experience<div>[We open in a well-lit corporate conference room. A meeting has been running for a while. Lots has been accomplished but time is running out.]</div><div><br /></div><div>[The door opens and a tall, tow-headed twenty-something guy in glasses walks in, carrying a Mac Air and a folder.]</div><div><br /></div><div>Manager:</div><div><span class="Apple-style-span" style="white-space: pre;"> </span>Oh, here he is. This is Richard. I asked him to join us today. Glad he could make it. He's got some great user experience ideas.</div><div><br /></div><div>Richard:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Call me Dick.</div><div><br /></div><div>Manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Dick's done a lot of seminal UX work for us.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Hey, aren't you the guy who's arguing we shouldn't have search in e-books?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Absolutely. It's a lousy idea.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>What?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Books are the best UI ever created. They've been perfected over more than 500 years of development. We shouldn't mess with success.</div><div><br /></div><div>Product manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Well, this is a new age. We should be allowed to ...</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Books have never had search. If we add search, we'll just confuse the user.</div><div><br /></div><div>Product manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Oh, you're right. We don't want to do that.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>But e-books aren't physical books. They're not words on paper. They're just bits, information.</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Our users don't know that.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Yes they do! They don't want simple books, they want the possibilities that electronic books can bring. Do you know about information theory? Have you even heard of Claude Shannon?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Isn't he the chef at that new biodynamic tofu restaurant in North Beach?</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Uhh, yeah, OK. But look, you're treating books as a metaphor for your user interface. That's as lame as using a trash can to throw away files and folders. We can do so much more!</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>You misunderstand. Our goal is to make computers easier to use, not to make them more useful.</div><div><br /></div><div>Product manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Wow, that's good.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Wow.</div><div><br /></div><div>Manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Let's get back on track. Dick, you had some suggestions for us?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Yeah. I was thinking about the work we did with the Notes iPhone app. Using a font that looked like a felt marker was a big help for users.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Seriously?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Yes, it made users feel more comfortable about keeping notes on their phone. Having a font that looks like handwriting helps them forget there's a computer underneath.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>I see....</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Yes, so... I was thinking for the Address Book app for Lion, we should change the look to be like a...</div><div><br /></div><div>Manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Can you show us?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Yeah, sure. I have a mock-up here.</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>[Opens laptop, turns it to face the room.]</div><div><br /></div><div>Product manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>An address book! That's fantastic. Look at the detail! Leather, seams at the corners, a visible spine. This is awesome!</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>It's just a book. It's a throwback. What are you doing? Why does it need to look like a physical address book?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Because it <i>is</i> an address book!</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>No it's not, it's an app!</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>It's a book.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>You've made it one. This time it's not even a metaphor - it's literally a book. You're giving up on the possibility of doing more.</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>As I said, users don't care about functionality. They want comfort and familiarity. An Address Book app that looks like an address book will be welcome. Soothing.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>If they want a paper address book, they can buy one.</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Why would they do that if they have one on their desktop?</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Can they at least change the appearance? Is there a setting somewhere?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Oh, no. We know better than the user - otherwise why are we here? Settings are just confusing.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>I ... I really don't understand what's going on.</div><div><br /></div><div>Manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>That's OK, you don't have to, but I'd like to give you the action item to build it. End of the quarter OK?</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Uhhh, sure.</div><div><br /></div><div>Manager.</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Dick, do you have the requirements doc there?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Right here.</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>[Pushes the folder across the desk.]</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Can't you just mail it to me?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>It's right there.</div><div><br /></div><div>Engineer:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>I know, but... OK.</div><div><br /></div><div>Manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>That's a great start, Dick. What else do you have?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Well, actually, maybe this is the time to announce that I'm moving on. Today is my last day here.</div><div><br /></div><div>Manager, Product manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>[Unison] Oh no!</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Yeah, sorry about that. I've had an amazing time here changing the world but it's tiem for me to seek new challenges.</div><div><br /></div><div>Manager:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Do you have something in mind?</div><div><br /></div><div>Dick:</div><div><span class="Apple-style-span" style="white-space: pre; "> </span>Yes, I'm moving north. Microsoft has asked me to head a group there. They've got some amazing new ideas around paper clips.</div><div><br /></div><div>FADE</div><div><br /></div>robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.comtag:blogger.com,1999:blog-6983287.post-19822348570916601882011-08-22T19:36:00.000-07:002016-02-01T12:26:51.707-08:00Regular expressions in lexing and parsing<span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-family: Georgia, Times New Roman, serif; font-size: 13px;">Comments extracted from a code review. I've been asked to disseminate them more widely.</span><br />
<span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-family: Georgia, Times New Roman, serif; font-size: 13px;"><br /></span>
<div>
<span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-family: Georgia, Times New Roman, serif; font-size: 13px;">
</span></div>
<div>
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">I should say something about regular expressions in lexing and</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">parsing. Regular expressions are hard to write, hard to write well,</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">and can be expensive relative to other technologies. (Even when they</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">are implemented correctly in N*M time, they have significant</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">overheads, especially if they must capture the output.)</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">Lexers, on the other hand, are fairly easy to write correctly (if not</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">as compactly), and very easy to test. Consider finding alphanumeric</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">identifiers. It's not too hard to write the regexp (something like</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">"[a-ZA-Z_][a-ZA-Z_0-9]*"), but really not much harder to write as a</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">simple loop. The performance of the loop, though, will be much higher</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">and will involve much less code under the covers. A regular expression</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">library is a big thing. Using one to parse identifiers is like using a</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">Mack truck to go to the store for milk. </span></span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.952941); color: rgb(51 , 51 , 51); font-family: Georgia, 'Times New Roman', serif; font-size: 13px;">And when we want to adjust our lexer to admit other character types,</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.952941); color: rgb(51 , 51 , 51); font-family: Georgia, 'Times New Roman', serif; font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.952941); color: rgb(51 , 51 , 51); font-family: Georgia, 'Times New Roman', serif; font-size: 13px;">such as Unicode identifiers, and handle normalization, and so on, the</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.952941); color: rgb(51 , 51 , 51); font-family: Georgia, 'Times New Roman', serif; font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.952941); color: rgb(51 , 51 , 51); font-family: Georgia, 'Times New Roman', serif; font-size: 13px;">hand-written loop can cope easily but the regexp approach will break</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.952941); color: rgb(51 , 51 , 51); font-family: Georgia, 'Times New Roman', serif; font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.952941); color: rgb(51 , 51 , 51); font-family: Georgia, 'Times New Roman', serif; font-size: 13px;">down.</span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;"><br /></span></span>
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">A similar argument applies to parsing. Using regular expressions to</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">explore the parse state to find the way forward is expensive,</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">overkill, and error-prone. Standard lexing and parsing techniques are</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">so easy to write, so general, and so adaptable there's no reason to</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">use regular expressions. They also result in much faster, safer, and</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">compact implementations.</span></span><br />
<span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-family: Georgia, Times New Roman, serif; font-size: 13px;"><br /></span>
<div>
<span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-family: Georgia, Times New Roman, serif; font-size: 13px;">
</span></div>
<div>
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;"><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">Another way to look at it is that lexers and parsing are matching</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">statically-defined patterns, but regular expressions' strength is that</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">they provide a way to express patterns dynamically. They're great in</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">text editors and search tools, but when you know at compile time what</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">all the things are you're looking for, regular expressions bring far</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">
</span><span class="Apple-style-span" style="background-color: rgba(255, 255, 255, 0.949219);">more generality and flexibility than you need.</span></span></span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;"><br /></span></span>
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">Finally, on the point about writing well. Regular expressions are, in</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">my experience, widely misunderstood and abused. When I do code reviews</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">involving regular expressions, I fix up a far higher fraction of the</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">regular expressions in the code than I do regular statements. This is</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">a sign of misuse: most programmers (no finger pointing here, just</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">observing a generality) simply don't know what they are or how to use</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">them correctly.</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">Encouraging regular expressions as a panacea for all text processing</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">problems is not only lazy and poor engineering, it also reinforces</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">their use by people who shouldn't be using them at all.</span></span><br />
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;"><br /></span></span>
<span style="font-family: Georgia, Times New Roman, serif;"><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">So don't write lexers and parsers with regular expressions as the</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">starting point. Your code will be faster, cleaner, and much easier to</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: rgba(255 , 255 , 255 , 0.949219); color: rgb(51 , 51 , 51); font-size: 13px;">understand and to maintain.</span></span></div>
</div>
robhttp://www.blogger.com/profile/18259238879445421354noreply@blogger.com