{"id":7758,"date":"2017-11-28T09:27:01","date_gmt":"2017-11-28T14:27:01","guid":{"rendered":"http:\/\/esr.ibiblio.org\/?p=7758"},"modified":"2017-12-02T12:39:48","modified_gmt":"2017-12-02T17:39:48","slug":"proposal-lets-backport-go-to-c","status":"publish","type":"post","link":"http:\/\/esr.ibiblio.org\/?p=7758","title":{"rendered":"Proposal &#8211; let&#8217;s backport Go := to C"},"content":{"rendered":"<p>The Go language was designed with the intention of replacing C and C++ over much of their ranges. While the large additions to Go &#8211; notably automatic memory allocation with garbage collection &#8211; attract attention, there is one small addition that does an impressive job of helping code be more concise while not being tied to any of the large ones.<\/p>\n<p>I refer to the := variant of assignment, which doesn&#8217;t seem to have a name of its own in the Go documentation but I will pronounce &#8220;definement&#8221;. It must have an unbound name on its left (receiving) side and an expression on the right (sending) side. The semantics are to declare the name as a new variable with the type of the right-hand expression, then assign it the value.<\/p>\n<p>Here&#8217;s the simplest possible example.  This<\/p>\n<pre LANG=\"C\">\r\nvoid foo(int i)\r\n{\r\n    int x;\r\n    x = bar(i);\r\n\r\n    \/* More code that operates on i and x *\/\r\n}\r\n<\/pre>\n<p>becomes this:<\/p>\n<pre LANG=\"C\">\r\nvoid foo(int i)\r\n{\r\n    x := bar(i)\r\n\r\n    \/* More code that operates on i and x *\/\r\n}\r\n<\/pre>\n<p>A way to think about definement is that it generates a variable declaration with an initialization. In modern C these can occur anywhere a conventional assignment can.<\/p>\n<p>Definement is a simple idea, but a remarkably productive one. It declutters code &#8211; scalar and struct local-variable declarations just vanish. This has two benefits; (1) it improves readability, and thus maintainability; and (2) it eliminates a class of silly errors due to multiple declarations falling out of sync &#8211; for example, when changing the return type of a function (such as bar() in the above example), you no longer gave to go back and tweak the declaration of every variable that receives a result from its callsites.<\/p>\n<p>Definement syntax also has the property that, if we were to implement it in C, it would break cleanly and obviously on any compiler that doesn&#8217;t support it. The sequence &#8220;:=&#8221; is not a legal token in current C.  In gcc you get a nice clean error message from trying to compile the definement:<\/p>\n<pre>\r\nfoo.c: In function \u2018foo\u2019:\r\nfoo.c:3:5: error: expected expression before \u2018=\u2019 token\r\n  x := i\r\n     ^\r\n<\/pre>\n<p>This makes it a low-risk extension to implement &#8211; there&#8217;s no possibility of<br \/>\nit breaking any existing code.<\/p>\n<p>It is worth noting that this will actually be slightly simpler to implement in C than it is in Go, because there are no untyped constants in C.<\/p>\n<p>I think there&#8217;s a relatively easy way to get this into C.<\/p>\n<p>First, write patches to implement it in both gcc and clang. This shouldn&#8217;t be difficult, as it can be implemented as a simple parser change and a minor transformation of the type-annotated AST &#8211; there are no implications for code generation at all.  I&#8217;d be surprised if it took a person familiar with those front ends more than three hours to do.<\/p>\n<p>Second, submit those patches simultanously, with the notes attached to each referencing the other one.<\/p>\n<p>Third, wait for minor compilers to catch up. Which they will pretty quickly, judging by the history of other pure-syntax enhancements such as dot syntax for structure initialization.<\/p>\n<p>Fourth, take it to the standards committees.<\/p>\n<p>OK, am I missing anything here?  Can any of my readers spot a difficulty I haven&#8217;t noticed?<\/p>\n<p>Will anyone who already knows these front ends volunteer to step up and do it?  I certainly could, but it would be more efficient for someone who&#8217;s already climbed the learning curve on those internals to do so. If it helps, I will cheerfully write tests and documentation.<\/p>\n<p>EDIT: No, we can&#8217;t backport C++ &#8220;auto&#8221; instead &#8211; it has a different and obscure meaning in C as a legacy from B (just declares a storage class, doesn&#8217;t do type propagation). Mind you I&#8217;ve never seen it actually used, but there&#8217;s still a nonzero risk of collision with old code.<\/p>\n<p>UPDATE, DECEMBER 2ND: I have been in touch with Ken Thompson.  He approves, raising two minor technical caveats about stack growth and name shadowing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The Go language was designed with the intention of replacing C and C++ over much of their ranges. While the large additions to Go &#8211; notably automatic memory allocation with garbage collection &#8211; attract attention, there is one small addition that does an impressive job of helping code be more concise while not being tied&hellip; <a class=\"more-link\" href=\"http:\/\/esr.ibiblio.org\/?p=7758\">Continue reading <span class=\"screen-reader-text\">Proposal &#8211; let&#8217;s backport Go := to C<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[13],"tags":[],"class_list":["post-7758","post","type-post","status-publish","format-standard","hentry","category-software","entry"],"_links":{"self":[{"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=\/wp\/v2\/posts\/7758","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7758"}],"version-history":[{"count":9,"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=\/wp\/v2\/posts\/7758\/revisions"}],"predecessor-version":[{"id":7782,"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=\/wp\/v2\/posts\/7758\/revisions\/7782"}],"wp:attachment":[{"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7758"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/esr.ibiblio.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}