sample_blogpost.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>research!rsc: My Go Resolutions for 2017</title>
  6. <link rel="alternate" type="application/atom+xml" title="research!rsc - Atom" href="http://research.swtch.com/feed.atom" />
  7. <link href='https://fonts.googleapis.com/css?family=Inconsolata:400,700' rel='stylesheet' type='text/css'>
  8. <script type="text/javascript" src="https://use.typekit.com/skm6yij.js"></script>
  9. <script type="text/javascript">try{Typekit.load();}catch(e){}</script>
  10. <style>
  11. body {
  12. padding: 0;
  13. margin: 0;
  14. font-size: 100%;
  15. }
  16. .header {
  17. height: 1.25em;
  18. background-color: #dff;
  19. margin: 0;
  20. padding: 0.1em 0.1em 0.2em;
  21. border-top: 1px solid black;
  22. border-bottom: 1px solid #8ff;
  23. }
  24. .header h3 {
  25. margin: 0;
  26. padding: 0 2em;
  27. display: inline-block;
  28. padding-right: 2em;
  29. font-style: italic;
  30. font-family: "adobe-text-pro" !important;
  31. font-size: 90%;
  32. }
  33. .rss {
  34. float: right;
  35. padding-top: 0.2em;
  36. padding-right: 2em;
  37. display: none;
  38. }
  39. .toc {
  40. margin-top: 2em;
  41. }
  42. .toc-title {
  43. font-family: "caflisch-script-pro";
  44. font-size: 300%;
  45. line-height: 50%;
  46. }
  47. .toc-subtitle {
  48. display: block;
  49. margin-bottom: 1em;
  50. font-size: 83%;
  51. }
  52. @media only screen and (max-width: 550px) { .toc-subtitle { display: none; } }
  53. .header h3 a {
  54. color: black;
  55. }
  56. .header h4 {
  57. margin: 0;
  58. padding: 0;
  59. display: inline-block;
  60. font-weight: normal;
  61. font-size: 83%;
  62. }
  63. @media only screen and (max-width: 550px) { .header h4 { display: none; } }
  64. .main {
  65. padding: 0 2em;
  66. }
  67. @media only screen and (max-width: 479px) { .article { font-size: 120%; } }
  68. .article h1 {
  69. text-align: center;
  70. }
  71. .article h1, .article h2, .article h3 {
  72. font-family: 'Myriad Pro';
  73. }
  74. .normal {
  75. font-size: medium;
  76. font-weight: normal;
  77. }
  78. .when {
  79. text-align: center;
  80. font-size: 100%;
  81. margin: 0;
  82. padding: 0;
  83. }
  84. .when p {
  85. margin: 0;
  86. padding: 0;
  87. }
  88. .article h2 {
  89. font-size: 100%;
  90. padding-top: 0.25em;
  91. }
  92. pre {
  93. margin-left: 4em;
  94. margin-right: 4em;
  95. }
  96. pre, code {
  97. font-family: 'Inconsolata', monospace;
  98. font-size: 100%;
  99. }
  100. .footer {
  101. margin-top: 10px;
  102. font-size: 83%;
  103. font-family: sans-serif;
  104. }
  105. .comments {
  106. margin-top: 2em;
  107. background-color: #ffe;
  108. border-top: 1px solid #aa4;
  109. border-left: 1px solid #aa4;
  110. border-right: 1px solid #aa4;
  111. }
  112. .comments-header {
  113. padding: 0 5px 0 5px;
  114. }
  115. .comments-header p {
  116. padding: 0;
  117. margin: 3px 0 0 0;
  118. }
  119. .comments-body {
  120. padding: 5px 5px 5px 5px;
  121. }
  122. #plus-comments {
  123. border-bottom: 1px dotted #ccc;
  124. }
  125. .plus-comment {
  126. width: 100%;
  127. font-size: 14px;
  128. border-top: 1px dotted #ccc;
  129. }
  130. .me {
  131. background-color: #eec;
  132. }
  133. .plus-comment ul {
  134. margin: 0;
  135. padding: 0;
  136. list-style: none;
  137. width: 100%;
  138. display: inline-block;
  139. }
  140. .comment-when {
  141. color:#999;
  142. width:auto;
  143. padding:0 5px;
  144. }
  145. .old {
  146. font-size: 83%;
  147. }
  148. .plus-comment ul li {
  149. display: inline-block;
  150. vertical-align: top;
  151. margin-top: 5px;
  152. margin-bottom: 5px;
  153. padding: 0;
  154. }
  155. .plus-icon {
  156. width: 45px;
  157. }
  158. .plus-img {
  159. float: left;
  160. margin: 4px 4px 4px 4px;
  161. width: 32px;
  162. height: 32px;
  163. }
  164. .plus-comment p {
  165. margin: 0;
  166. padding: 0;
  167. }
  168. .plus-clear {
  169. clear: left;
  170. }
  171. .toc-when {
  172. font-size: 83%;
  173. color: #ccc;
  174. }
  175. .toc {
  176. list-style: none;
  177. }
  178. .toc li {
  179. margin-bottom: 0.5em;
  180. }
  181. .toc-head {
  182. margin-bottom: 1em !important;
  183. font-size: 117%;
  184. }
  185. .toc-summary {
  186. margin-left: 2em;
  187. }
  188. .favorite {
  189. font-weight: bold;
  190. }
  191. .article p {
  192. line-height: 144%;
  193. }
  194. sup, sub {
  195. vertical-align: baseline;
  196. position: relative;
  197. font-size: 83%;
  198. }
  199. sup {
  200. bottom: 1ex;
  201. }
  202. sub {
  203. top: 0.8ex;
  204. }
  205. .main {
  206. position: relative;
  207. margin: 0 auto;
  208. padding: 0;
  209. width: 900px;
  210. }
  211. @media only screen and (min-width: 768px) and (max-width: 959px) { .main { width: 708px; } }
  212. @media only screen and (min-width: 640px) and (max-width: 767px) { .main { width: 580px; } }
  213. @media only screen and (min-width: 480px) and (max-width: 639px) { .main { width: 420px; } }
  214. @media only screen and (max-width: 479px) { .main { width: 300px; } }
  215. </style>
  216. </head>
  217. <body>
  218. <div class="header">
  219. <h3><a href="/">research!rsc</a></h3>
  220. <h4>Thoughts and links about programming,
  221. by <a href="https://swtch.com/~rsc/" rel="author">Russ Cox</a> </h4>
  222. <a class="rss" href="/feed.atom"><img src="/feed-icon-14x14.png" /></a>
  223. </div>
  224. <div class="main">
  225. <div class="article">
  226. <h1>My Go Resolutions for 2017
  227. <div class="normal">
  228. <div class="when">
  229. Posted on Wednesday, January 18, 2017.
  230. </div>
  231. </div>
  232. </h1>
  233. <p class=lp>’Tis the season for resolutions,
  234. and I thought it would make sense to write a little
  235. about what I hope to work on this year as far as Go is concerned.</p>
  236. <p class=pp>My goal every year is to <em>help Go developers</em>.
  237. I want to make sure that the work we do on the Go team
  238. has a significant, positive impact on Go developers.
  239. That may sound obvious, but there are a variety of common ways to fail to achieve that:
  240. for example, spending too much time cleaning up or optimizing code that doesn’t need it;
  241. responding only to the most common or recent complaints or requests;
  242. or focusing too much on short-term improvements.
  243. It’s important to step back and make sure we’re focusing
  244. our development work where it does the most good.</p>
  245. <p class=pp>This post outlines a few of my own major focuses for this year.
  246. This is only my personal list, not the Go team’s list.</p>
  247. <p class=pp>One reason for posting this is to gather feedback.
  248. If these spark any ideas or suggestions of your own,
  249. please feel free to comment below or on the linked GitHub issues.</p>
  250. <p class=pp>Another reason is to make clear that I’m aware of these issues as important.
  251. I think too often people interpret lack of action by the Go team
  252. as a signal that we think everything is perfect, when instead
  253. there is simply other, higher priority work to do first.</p>
  254. <h2><a name="alias"></a>Type aliases</h2>
  255. <p class=lp>There is a recurring problem with moving types
  256. from one package to another during large codebase refactorings.
  257. We tried to solve it last year with <a href="https://golang.org/issue/16339">general aliases</a>,
  258. which didn’t work for at least two reasons: we didn’t explain the change well enough,
  259. and we didn’t deliver it on time, so it wasn’t ready for Go 1.8.
  260. Learning from that experience,
  261. I <a href="https://www.youtube.com/watch?v=h6Cw9iCDVcU">gave a talk</a>
  262. and <a href="https://talks.golang.org/2016/refactor.article">wrote an article</a>
  263. about the underlying problem,
  264. and that started a <a href="https://golang.org/issue/18130">productive discussion</a>
  265. on the Go issue tracker about the solution space.
  266. It looks like more limited <a href="https://golang.org/design/18130-type-alias">type aliases</a>
  267. are the right next step.
  268. I want to make sure those land smoothly in Go 1.9. <a href="https://golang.org/issue/18130">#18130</a>.</p>
  269. <h2><a name="package"></a>Package management</h2>
  270. <p class=lp>I designed the Go support for downloading published packages
  271. (“goinstall”, which became “go get”) in February 2010.
  272. A lot has happened since then.
  273. In particular, other language ecosystems have really raised the bar
  274. for what people expect from package management,
  275. and the open source world has mostly agreed on
  276. <a href="http://semver.org/">semantic versioning</a>, which provides a useful base
  277. for inferring version compatibility.
  278. Go needs to do better here, and a group of contributors have been
  279. <a href="https://blog.gopheracademy.com/advent-2016/saga-go-dependency-management/">working on a solution</a>.
  280. I want to make sure these ideas are integrated well
  281. into the standard Go toolchain and to make package management
  282. a reason that people love Go.</p>
  283. <h2><a name="build"></a>Build improvements</h2>
  284. <p class=lp>There are a handful of shortcomings in the design of
  285. the go command’s build system that are overdue to be fixed.
  286. Here are three representative examples that I intend to
  287. address with a bit of a redesign of the internals of the go command.</p>
  288. <p class=pp>Builds can be too slow,
  289. because the go command doesn’t cache build results as aggressively as it should.
  290. Many people don’t realize that <code>go</code> <code>install</code> saves its work while <code>go</code> <code>build</code> does not,
  291. and then they run repeated <code>go</code> <code>build</code> commands that are slow
  292. because the later builds do more work than they should need to.
  293. The same for repeated <code>go</code> <code>test</code> without <code>go</code> <code>test</code> <code>-i</code> when dependencies are modified.
  294. All builds should be as incremental as possible.
  295. <a href="https://golang.org/issue/4719">#4719</a>.</p>
  296. <p class=pp>Test results should be cached too:
  297. if none of the inputs to a test have changed,
  298. then usually there is no need to rerun the test.
  299. This will make it very cheap to run “all tests” when little or nothing has changed.
  300. <a href="https://golang.org/issue/11193">#11193</a>.</p>
  301. <p class=pp>Work outside GOPATH should be supported nearly as well
  302. as work inside GOPATH.
  303. In particular, it should be possible to <code>git</code> <code>clone</code> a repo,
  304. <code>cd</code> into it, and run <code>go</code> commands and have them work fine.
  305. Package management only makes that more important:
  306. you’ll need to be able to work on different versions of a package (say, v1 and v2)
  307. without having entirely separate GOPATHs for them.
  308. <a href="https://golang.org/issue/17271">#17271</a>.</p>
  309. <h2><a name="corpus"></a>Code corpus</h2>
  310. <p class=lp>I think it helped to have concrete examples from real projects
  311. in the talk and article I prepared about codebase refactoring (see <a href="#alias">above</a>).
  312. We&rsquo;ve also defined that <a href="https://golang.org/src/cmd/vet/README">additions to vet</a>
  313. must target problems that happen frequently in real programs.
  314. I&rsquo;d like to see that kind of analysis of actual practice—examining
  315. the effects on and possible improvements to real programs—become a
  316. standard way we discuss and evaluate changes to Go.</p>
  317. <p class=pp>Right now there&rsquo;s not an agreed-upon representative corpus of code to use for
  318. those analyses: everyone must first create their own, which is too much work.
  319. I&rsquo;d like to put together a single, self-contained Git repo people can check out that
  320. contains our official baseline corpus for those analyses.
  321. A possible starting point could be the top 100 Go language repos
  322. on GitHub by stars or forks or both.</p>
  323. <h2><a name="vet"></a>Automatic vet</h2>
  324. <p class=lp>The Go distribution ships with this powerful tool,
  325. <a href="https://golang.org/cmd/vet/"><code>go</code> <code>vet</code></a>,
  326. that points out correctness bugs.
  327. We have a high bar for checks, so that when vet speaks, you should listen.
  328. But everyone has to remember to run it.
  329. It would be better if you didn’t have to remember.
  330. In particular, I think we could probably run vet
  331. in parallel with the final compile and link of the test binary
  332. during <code>go</code> <code>test</code> without slowing the compile-edit-test cycle at all.
  333. If we can do that, and if we limit the enabled vet checks to a subset
  334. that is essentially 100% accurate,
  335. we can make passing vet a precondition for running a test at all.
  336. Then developers don’t need to remember to run <code>go</code> <code>vet</code>.
  337. They run <code>go</code> <code>test</code>,
  338. and once in a while vet speaks up with something important
  339. and avoids a debugging session.
  340. <a href="https://golang.org/issue/18084">#18084</a>,
  341. <a href="https://golang.org/issue/18085">#18085</a>.</p>
  342. <h2><a name="error"></a>Errors &amp; best practices</h2>
  343. <p class=lp>Part of the intended contract for error reporting in Go is that functions
  344. include relevant available context, including the operation being attempted
  345. (such as the function name and its arguments).
  346. For example, this program:</p>
  347. <pre><code>err := os.Remove(&quot;/tmp/nonexist&quot;)
  348. fmt.Println(err)
  349. </code></pre>
  350. <p class=lp>prints this output:</p>
  351. <pre><code>remove /tmp/nonexist: no such file or directory
  352. </code></pre>
  353. <p class=lp>Not enough Go code adds context like <code>os.Remove</code> does. Too much code does only</p>
  354. <pre><code>if err != nil {
  355. return err
  356. }
  357. </code></pre>
  358. <p class=lp>all the way up the call stack,
  359. discarding useful context that should be reported
  360. (like <code>remove</code> <code>/tmp/nonexist:</code> above).
  361. I would like to try to understand whether our expectations
  362. for including context are wrong, or if there is something
  363. we can do to make it easier to write code that returns better errors.</p>
  364. <p class=pp>There are also various discussions in the community about
  365. agreed-upon interfaces for stripping error context.
  366. I would like to try to understand when that makes sense and
  367. whether we should adopt an official recommendation.</p>
  368. <h2><a name="context"></a>Context &amp; best practices</h2>
  369. <p class=lp>We added the new <a href="https://golang.org/pkg/context/">context package</a>
  370. in Go 1.7 for holding request-scoped information like
  371. <a href="https://blog.golang.org/context">timeouts, cancellation state, and credentials</a>.
  372. An individual context is immutable (like an individual string or int):
  373. it is only possible to derive a new, updated context and
  374. pass that context explicitly further down the call stack or
  375. (less commonly) back up to the caller.
  376. The context is now carried through APIs such as
  377. <a href="https://golang.org/pkg/database/sql">database/sql</a>
  378. and
  379. <a href="https://golang.org/pkg/net/http">net/http</a>,
  380. mainly so that those can stop processing a request when the caller
  381. is no longer interested in the result.
  382. Timeout information is appropriate to carry in a context,
  383. but—to use a <a href="https://golang.org/issue/18284">real example we removed</a>—database options
  384. are not, because they are unlikely to apply equally well to all possible
  385. database operations carried out during a request.
  386. What about the current clock source, or logging sink?
  387. Is either of those appropriate to store in a context?
  388. I would like to try to understand and characterize the
  389. criteria for what is and is not an appropriate use of context.</p>
  390. <h2><a name="memory"></a>Memory model</h2>
  391. <p class=lp>Go’s <a href="https://golang.org/ref/mem">memory model</a> is intentionally low-key,
  392. making few promises to users, compared to other languages.
  393. In fact it starts by discouraging people from reading the rest of the document.
  394. At the same time, it demands more of the compiler than other languages:
  395. in particular, a race on an integer value is not sufficient license
  396. for your program to misbehave in arbitrary ways.
  397. But there are some complete gaps, in particular no mention of
  398. the <a href="https://golang.org/pkg/sync/atomic/">sync/atomic package</a>.
  399. I think the core compiler and runtime developers all agree
  400. that the behavior of those atomics should be roughly the same as
  401. C++ seqcst atomics or Java volatiles,
  402. but we still need to write that down carefully in the memory model,
  403. and probably also in a long blog post.
  404. <a href="https://golang.org/issue/5045">#5045</a>,
  405. <a href="https://golang.org/issue/7948">#7948</a>,
  406. <a href="https://golang.org/issue/9442">#9442</a>.</p>
  407. <h2><a name="immutability"></a>Immutability</h2>
  408. <p class=lp>The <a href="https://golang.org/doc/articles/race_detector.html">race detector</a>
  409. is one of Go’s most loved features.
  410. But not having races would be even better.
  411. I would love it if there were some reasonable way to integrate
  412. <a href="https://www.google.com/search?q=%22reference+immutability%22">reference immutability</a> into Go,
  413. so that programmers can make clear, checked assertions about what can and cannot
  414. be written and thereby eliminate certain races at compile time.
  415. Go already has one immutable type, <code>string</code>; it would
  416. be nice to retroactively define that
  417. <code>string</code> is a named type (or type alias) for <code>immutable</code> <code>[]byte</code>.
  418. I don’t think that will happen this year,
  419. but I’d like to understand the solution space better.
  420. Javari, Midori, Pony, and Rust have all staked out interesting points
  421. in the solution space, and there are plenty of research papers
  422. beyond those.</p>
  423. <p class=pp>In the long-term, if we could statically eliminate the possibility of races,
  424. that would eliminate the need for most of the memory model.
  425. That may well be an impossible dream,
  426. but again I’d like to understand the solution space better.</p>
  427. <h2><a name="generics"></a>Generics</h2>
  428. <p class=lp>Nothing sparks more <a href="https://research.swtch.com/dogma">heated arguments</a>
  429. among Go and non-Go developers than the question of whether Go should
  430. have support for generics (or how many years ago that should have happened).
  431. I don’t believe the Go team has ever said “Go does not need generics.”
  432. What we <em>have</em> said is that there are higher-priority issues facing Go.
  433. For example, I believe that better support for package management
  434. would have a much larger immediate positive impact on most Go developers
  435. than adding generics.
  436. But we do certainly understand that for a certain subset of Go use cases,
  437. the lack of parametric polymorphism is a significant hindrance.</p>
  438. <p class=pp>Personally, I would like to be able to write general channel-processing
  439. functions like:</p>
  440. <pre><code>// Join makes all messages received on the input channels
  441. // available for receiving from the returned channel.
  442. func Join(inputs ...&lt;-chan T) &lt;-chan T
  443. // Dup duplicates messages received on c to both c1 and c2.
  444. func Dup(c &lt;-chan T) (c1, c2 &lt;-chan T)
  445. </code></pre>
  446. <p class=lp>I would also like to be able to write
  447. Go support for high-level data processing abstractions,
  448. analogous to
  449. <a href="https://research.google.com/pubs/archive/35650.pdf">FlumeJava</a> or
  450. C#’s <a href="https://en.wikipedia.org/wiki/Language_Integrated_Query">LINQ</a>,
  451. in a way that catches type errors at compile time instead of at run time.
  452. There are also any number of data structures or generic algorithms
  453. that might be written,
  454. but I personally find these broader applications more compelling.</p>
  455. <p class=pp>We’ve <a href="https://research.swtch.com/generic">struggled</a> off and on
  456. <a href="https://golang.org/design/15292-generics">for years</a>
  457. to find the right way to add generics to Go.
  458. At least a few of the past proposals got hung up on trying to design
  459. something that provided both general parametric polymorphism
  460. (like <code>chan</code> <code>T</code>) and also a unification of <code>string</code> and <code>[]byte</code>.
  461. If the latter is handled by parameterization over immutability,
  462. as described in the previous section, then maybe that simplifies
  463. the demands on a design for generics.</p>
  464. <p class=pp>When I first started thinking about generics for Go in 2008,
  465. the main examples to learn from were C#, Java, Haskell, and ML.
  466. None of the approaches in those languages seemed like a
  467. perfect fit for Go.
  468. Today, there are newer attempts to learn from as well,
  469. including Dart, Midori, Rust, and Swift.</p>
  470. <p class=pp>It’s been a few years since we ventured out and explored the design space.
  471. It is probably time to look around again,
  472. especially in light of the insight about mutability and
  473. the additional examples set by newer languages.
  474. I don’t think generics will happen this year,
  475. but I’d like to be able to say I understand the solution space better.</p>
  476. </div>
  477. <div id="disqus_thread"></div>
  478. <script>
  479. var disqus_config = function () {
  480. this.page.url = "https://research.swtch.com/go2017";
  481. this.page.identifier = "blog/go2017";
  482. };
  483. (function() {
  484. var d = document, s = d.createElement('script');
  485. s.src = '//swtch.disqus.com/embed.js';
  486. s.setAttribute('data-timestamp', +new Date());
  487. (d.head || d.body).appendChild(s);
  488. })();
  489. </script>
  490. <noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
  491. </div>
  492. </div>
  493. <script type="text/javascript">
  494. var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
  495. document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
  496. </script>
  497. <script type="text/javascript">
  498. var pageTracker = _gat._getTracker("UA-3319603-2");
  499. pageTracker._initData();
  500. pageTracker._trackPageview();
  501. </script>
  502. </body>
  503. </html>