aboutsummaryrefslogtreecommitdiff
path: root/docs/index.xml
diff options
context:
space:
mode:
Diffstat (limited to 'docs/index.xml')
-rw-r--r--docs/index.xml115
1 files changed, 115 insertions, 0 deletions
diff --git a/docs/index.xml b/docs/index.xml
index 628c111..003d4d6 100644
--- a/docs/index.xml
+++ b/docs/index.xml
@@ -12,6 +12,121 @@
12 <language>en-us</language> 12 <language>en-us</language>
13 <copyright>Creative Commons BY-NC-SA 4.0</copyright> 13 <copyright>Creative Commons BY-NC-SA 4.0</copyright>
14 <item> 14 <item>
15<title>Gripes With Go</title>
16<description>&lt;p&gt;You’ve read a lot of posts about the shortcomings of the Go programming language, so what’s one more.&lt;/p&gt;
17&lt;ol type="1"&gt;
18&lt;li&gt;&lt;a href="#lack-of-sum-types"&gt;Lack of sum types&lt;/a&gt;&lt;/li&gt;
19&lt;li&gt;&lt;a href="#type-assertions"&gt;Type assertions&lt;/a&gt;&lt;/li&gt;
20&lt;li&gt;&lt;a href="#date-and-time"&gt;Date and Time&lt;/a&gt;&lt;/li&gt;
21&lt;li&gt;&lt;a href="#statements-over-expressions"&gt;Statements over Expressions&lt;/a&gt;&lt;/li&gt;
22&lt;li&gt;&lt;a href="#erroring-out-on-unused-variables"&gt;Erroring out on unused variables&lt;/a&gt;&lt;/li&gt;
23&lt;li&gt;&lt;a href="#error-handling"&gt;Error handling&lt;/a&gt;&lt;/li&gt;
24&lt;/ol&gt;
25&lt;h3 id="lack-of-sum-types"&gt;Lack of Sum types&lt;/h3&gt;
26&lt;p&gt;A “Sum” type is a data type that can hold one of many states at a given time, similar to how a boolean can hold a true or a false, not too different from an &lt;code&gt;enum&lt;/code&gt; type in C. Go lacks &lt;code&gt;enum&lt;/code&gt; types unfortunately, and you are forced to resort to crafting your own substitute.&lt;/p&gt;
27&lt;p&gt;A type to represent gender for example:&lt;/p&gt;
28&lt;div class="sourceCode" id="cb1"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb1-1"&gt;&lt;a href="#cb1-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;type&lt;/span&gt; Gender &lt;span class="dt"&gt;int&lt;/span&gt;&lt;/span&gt;
29&lt;span id="cb1-2"&gt;&lt;a href="#cb1-2" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
30&lt;span id="cb1-3"&gt;&lt;a href="#cb1-3" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;const&lt;/span&gt; (&lt;/span&gt;
31&lt;span id="cb1-4"&gt;&lt;a href="#cb1-4" aria-hidden="true"&gt;&lt;/a&gt; Male Gender = &lt;span class="ot"&gt;iota&lt;/span&gt; &lt;span class="co"&gt;// assigns Male to 0&lt;/span&gt;&lt;/span&gt;
32&lt;span id="cb1-5"&gt;&lt;a href="#cb1-5" aria-hidden="true"&gt;&lt;/a&gt; Female &lt;span class="co"&gt;// assigns Female to 1&lt;/span&gt;&lt;/span&gt;
33&lt;span id="cb1-6"&gt;&lt;a href="#cb1-6" aria-hidden="true"&gt;&lt;/a&gt; Other &lt;span class="co"&gt;// assigns Other to 2&lt;/span&gt;&lt;/span&gt;
34&lt;span id="cb1-7"&gt;&lt;a href="#cb1-7" aria-hidden="true"&gt;&lt;/a&gt;)&lt;/span&gt;
35&lt;span id="cb1-8"&gt;&lt;a href="#cb1-8" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
36&lt;span id="cb1-9"&gt;&lt;a href="#cb1-9" aria-hidden="true"&gt;&lt;/a&gt;fmt.Println(&lt;span class="st"&gt;&amp;quot;My gender is &amp;quot;&lt;/span&gt;, Male)&lt;/span&gt;
37&lt;span id="cb1-10"&gt;&lt;a href="#cb1-10" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="co"&gt;// My gender is 0&lt;/span&gt;&lt;/span&gt;
38&lt;span id="cb1-11"&gt;&lt;a href="#cb1-11" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="co"&gt;// Oops! We have to implement String() for Gender ...&lt;/span&gt;&lt;/span&gt;
39&lt;span id="cb1-12"&gt;&lt;a href="#cb1-12" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
40&lt;span id="cb1-13"&gt;&lt;a href="#cb1-13" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;func&lt;/span&gt; (g Gender) String() &lt;span class="dt"&gt;string&lt;/span&gt; {&lt;/span&gt;
41&lt;span id="cb1-14"&gt;&lt;a href="#cb1-14" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;switch&lt;/span&gt; (g) {&lt;/span&gt;
42&lt;span id="cb1-15"&gt;&lt;a href="#cb1-15" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="dv"&gt;0&lt;/span&gt;: &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Male&amp;quot;&lt;/span&gt;&lt;/span&gt;
43&lt;span id="cb1-16"&gt;&lt;a href="#cb1-16" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;case&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt;: &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Female&amp;quot;&lt;/span&gt;&lt;/span&gt;
44&lt;span id="cb1-17"&gt;&lt;a href="#cb1-17" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;default&lt;/span&gt;: &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;Other&amp;quot;&lt;/span&gt;&lt;/span&gt;
45&lt;span id="cb1-18"&gt;&lt;a href="#cb1-18" aria-hidden="true"&gt;&lt;/a&gt; }&lt;/span&gt;
46&lt;span id="cb1-19"&gt;&lt;a href="#cb1-19" aria-hidden="true"&gt;&lt;/a&gt;}&lt;/span&gt;
47&lt;span id="cb1-20"&gt;&lt;a href="#cb1-20" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
48&lt;span id="cb1-21"&gt;&lt;a href="#cb1-21" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="co"&gt;// You can accidentally do stupid stuff like:&lt;/span&gt;&lt;/span&gt;
49&lt;span id="cb1-22"&gt;&lt;a href="#cb1-22" aria-hidden="true"&gt;&lt;/a&gt;gender := Male + &lt;span class="dv"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
50&lt;p&gt;The Haskell equivalent of the same:&lt;/p&gt;
51&lt;div class="sourceCode" id="cb2"&gt;&lt;pre class="sourceCode haskell"&gt;&lt;code class="sourceCode haskell"&gt;&lt;span id="cb2-1"&gt;&lt;a href="#cb2-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;data&lt;/span&gt; &lt;span class="dt"&gt;Gender&lt;/span&gt; &lt;span class="ot"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;Male&lt;/span&gt;&lt;/span&gt;
52&lt;span id="cb2-2"&gt;&lt;a href="#cb2-2" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Female&lt;/span&gt;&lt;/span&gt;
53&lt;span id="cb2-3"&gt;&lt;a href="#cb2-3" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="op"&gt;|&lt;/span&gt; &lt;span class="dt"&gt;Other&lt;/span&gt;&lt;/span&gt;
54&lt;span id="cb2-4"&gt;&lt;a href="#cb2-4" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;deriving&lt;/span&gt; (&lt;span class="dt"&gt;Show&lt;/span&gt;)&lt;/span&gt;
55&lt;span id="cb2-5"&gt;&lt;a href="#cb2-5" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
56&lt;span id="cb2-6"&gt;&lt;a href="#cb2-6" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="fu"&gt;print&lt;/span&gt; &lt;span class="op"&gt;$&lt;/span&gt; &lt;span class="st"&gt;&amp;quot;My gender is &amp;quot;&lt;/span&gt; &lt;span class="op"&gt;++&lt;/span&gt; (&lt;span class="fu"&gt;show&lt;/span&gt; &lt;span class="dt"&gt;Male&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
57&lt;h3 id="type-assertions"&gt;Type Assertions&lt;/h3&gt;
58&lt;p&gt;A downcast with an optional error check? What could go wrong?&lt;/p&gt;
59&lt;p&gt;Type assertions in Go allow you to do:&lt;/p&gt;
60&lt;div class="sourceCode" id="cb3"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb3-1"&gt;&lt;a href="#cb3-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;var&lt;/span&gt; x &lt;span class="kw"&gt;interface&lt;/span&gt;{} = &lt;span class="dv"&gt;7&lt;/span&gt;&lt;/span&gt;
61&lt;span id="cb3-2"&gt;&lt;a href="#cb3-2" aria-hidden="true"&gt;&lt;/a&gt;y, goodToGo := x.(&lt;span class="dt"&gt;int&lt;/span&gt;)&lt;/span&gt;
62&lt;span id="cb3-3"&gt;&lt;a href="#cb3-3" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;if&lt;/span&gt; goodToGo {&lt;/span&gt;
63&lt;span id="cb3-4"&gt;&lt;a href="#cb3-4" aria-hidden="true"&gt;&lt;/a&gt; fmt.Println(y)&lt;/span&gt;
64&lt;span id="cb3-5"&gt;&lt;a href="#cb3-5" aria-hidden="true"&gt;&lt;/a&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
65&lt;p&gt;The error check however is optional:&lt;/p&gt;
66&lt;div class="sourceCode" id="cb4"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb4-1"&gt;&lt;a href="#cb4-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;var&lt;/span&gt; x &lt;span class="kw"&gt;interface&lt;/span&gt;{} = &lt;span class="dv"&gt;7&lt;/span&gt;&lt;/span&gt;
67&lt;span id="cb4-2"&gt;&lt;a href="#cb4-2" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;var&lt;/span&gt; y := x.(&lt;span class="dt"&gt;float64&lt;/span&gt;)&lt;/span&gt;
68&lt;span id="cb4-3"&gt;&lt;a href="#cb4-3" aria-hidden="true"&gt;&lt;/a&gt;fmt.Println(y)&lt;/span&gt;
69&lt;span id="cb4-4"&gt;&lt;a href="#cb4-4" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="co"&gt;// results in a runtime error:&lt;/span&gt;&lt;/span&gt;
70&lt;span id="cb4-5"&gt;&lt;a href="#cb4-5" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="co"&gt;// panic: interface conversion: interface {} is int, not float64&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
71&lt;h3 id="date-and-time"&gt;Date and Time&lt;/h3&gt;
72&lt;p&gt;Anyone that has written Go previously, will probably already know what I am getting at here. For the uninitiated, parsing and formatting dates in Go requires a “layout”. This “layout” is based on magical reference date:&lt;/p&gt;
73&lt;pre&gt;&lt;code&gt;Mon Jan 2 15:04:05 MST 2006&lt;/code&gt;&lt;/pre&gt;
74&lt;p&gt;Which is the date produced when you write the first seven natural numbers like so:&lt;/p&gt;
75&lt;pre&gt;&lt;code&gt;01/02 03:04:05 &amp;#39;06 -0700&lt;/code&gt;&lt;/pre&gt;
76&lt;p&gt;Parsing a string in &lt;code&gt;YYYY-MM-DD&lt;/code&gt; format would look something like:&lt;/p&gt;
77&lt;div class="sourceCode" id="cb7"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb7-1"&gt;&lt;a href="#cb7-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;const&lt;/span&gt; layout = &lt;span class="st"&gt;&amp;quot;2006-01-02&amp;quot;&lt;/span&gt;&lt;/span&gt;
78&lt;span id="cb7-2"&gt;&lt;a href="#cb7-2" aria-hidden="true"&gt;&lt;/a&gt;time.Parse(layout, &lt;span class="st"&gt;&amp;quot;2020-08-01&amp;quot;&lt;/span&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
79&lt;p&gt;This so-called “intuitive” method of formatting dates doesn’t allow you to print &lt;code&gt;0000 hrs&lt;/code&gt; as &lt;code&gt;2400 hrs&lt;/code&gt;, it doesn’t allow you to omit the leading zero in 24 hour formats. It is rife with inconveniences, if only there were a &lt;a href="https://man7.org/linux/man-pages/man3/strftime.3.html"&gt;tried and tested&lt;/a&gt; date formatting convention …&lt;/p&gt;
80&lt;h3 id="statements-over-expressions"&gt;Statements over Expressions&lt;/h3&gt;
81&lt;p&gt;Statements have side effects, expressions return values. More often than not, expressions are easier to understand at a glance: evaluate the LHS and assign the same to the RHS.&lt;/p&gt;
82&lt;p&gt;Rust allows you to create local namespaces, and treats blocks (&lt;code&gt;{}&lt;/code&gt;) as expressions:&lt;/p&gt;
83&lt;div class="sourceCode" id="cb8"&gt;&lt;pre class="sourceCode rust"&gt;&lt;code class="sourceCode rust"&gt;&lt;span id="cb8-1"&gt;&lt;a href="#cb8-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;let&lt;/span&gt; twenty_seven &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
84&lt;span id="cb8-2"&gt;&lt;a href="#cb8-2" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;let&lt;/span&gt; three &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dv"&gt;1&lt;/span&gt; &lt;span class="op"&gt;+&lt;/span&gt; &lt;span class="dv"&gt;2&lt;/span&gt;&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
85&lt;span id="cb8-3"&gt;&lt;a href="#cb8-3" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;let&lt;/span&gt; nine &lt;span class="op"&gt;=&lt;/span&gt; three &lt;span class="op"&gt;*&lt;/span&gt; three&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
86&lt;span id="cb8-4"&gt;&lt;a href="#cb8-4" aria-hidden="true"&gt;&lt;/a&gt; nine &lt;span class="op"&gt;*&lt;/span&gt; three&lt;/span&gt;
87&lt;span id="cb8-5"&gt;&lt;a href="#cb8-5" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="op"&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
88&lt;p&gt;The Go equivalent of the same:&lt;/p&gt;
89&lt;div class="sourceCode" id="cb9"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb9-1"&gt;&lt;a href="#cb9-1" aria-hidden="true"&gt;&lt;/a&gt;twenty_seven := &lt;span class="ot"&gt;nil&lt;/span&gt;&lt;/span&gt;
90&lt;span id="cb9-2"&gt;&lt;a href="#cb9-2" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
91&lt;span id="cb9-3"&gt;&lt;a href="#cb9-3" aria-hidden="true"&gt;&lt;/a&gt;three := &lt;span class="dv"&gt;1&lt;/span&gt; + &lt;span class="dv"&gt;2&lt;/span&gt;&lt;/span&gt;
92&lt;span id="cb9-4"&gt;&lt;a href="#cb9-4" aria-hidden="true"&gt;&lt;/a&gt;nine := three * three&lt;/span&gt;
93&lt;span id="cb9-5"&gt;&lt;a href="#cb9-5" aria-hidden="true"&gt;&lt;/a&gt;twenty_seven = nine * three&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
94&lt;h3 id="erroring-out-on-unused-variables"&gt;Erroring out on unused variables&lt;/h3&gt;
95&lt;p&gt;Want to quickly prototype something? Go says no! In all seriousness, a warning would suffice, I don’t want to have to go back and comment each unused import out, only to come back and uncomment them a few seconds later.&lt;/p&gt;
96&lt;h3 id="error-handling"&gt;Error handling&lt;/h3&gt;
97&lt;div class="sourceCode" id="cb10"&gt;&lt;pre class="sourceCode go"&gt;&lt;code class="sourceCode go"&gt;&lt;span id="cb10-1"&gt;&lt;a href="#cb10-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;if&lt;/span&gt; err != &lt;span class="ot"&gt;nil&lt;/span&gt; { ... }&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
98&lt;p&gt;Need I say more? I will, for good measure:&lt;/p&gt;
99&lt;ol type="1"&gt;
100&lt;li&gt;Error handling is optional&lt;/li&gt;
101&lt;li&gt;Errors are propagated via a clunky &lt;code&gt;if&lt;/code&gt; + &lt;code&gt;return&lt;/code&gt; statement&lt;/li&gt;
102&lt;/ol&gt;
103&lt;p&gt;I prefer Haskell’s “Monadic” error handling, which is employed by Rust as well:&lt;/p&gt;
104&lt;div class="sourceCode" id="cb11"&gt;&lt;pre class="sourceCode rust"&gt;&lt;code class="sourceCode rust"&gt;&lt;span id="cb11-1"&gt;&lt;a href="#cb11-1" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="co"&gt;// 1. error handling is compulsory&lt;/span&gt;&lt;/span&gt;
105&lt;span id="cb11-2"&gt;&lt;a href="#cb11-2" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="co"&gt;// 2. errors are propagated with the `?` operator&lt;/span&gt;&lt;/span&gt;
106&lt;span id="cb11-3"&gt;&lt;a href="#cb11-3" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;fn&lt;/span&gt; foo() &lt;span class="op"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="dt"&gt;Result&lt;/span&gt;&lt;span class="op"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="op"&gt;,&lt;/span&gt; &lt;span class="pp"&gt;io::&lt;/span&gt;&lt;span class="bu"&gt;Error&lt;/span&gt;&lt;span class="op"&gt;&amp;gt;&lt;/span&gt; &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
107&lt;span id="cb11-4"&gt;&lt;a href="#cb11-4" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;let&lt;/span&gt; &lt;span class="kw"&gt;mut&lt;/span&gt; f &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="pp"&gt;File::&lt;/span&gt;open(&lt;span class="st"&gt;&amp;quot;foo.txt&amp;quot;&lt;/span&gt;)&lt;span class="op"&gt;?;&lt;/span&gt; &lt;span class="co"&gt;// return if error&lt;/span&gt;&lt;/span&gt;
108&lt;span id="cb11-5"&gt;&lt;a href="#cb11-5" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;let&lt;/span&gt; &lt;span class="kw"&gt;mut&lt;/span&gt; s &lt;span class="op"&gt;=&lt;/span&gt; &lt;span class="dt"&gt;String&lt;/span&gt;&lt;span class="pp"&gt;::&lt;/span&gt;new()&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
109&lt;span id="cb11-6"&gt;&lt;a href="#cb11-6" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
110&lt;span id="cb11-7"&gt;&lt;a href="#cb11-7" aria-hidden="true"&gt;&lt;/a&gt; f&lt;span class="op"&gt;.&lt;/span&gt;read_to_string(&lt;span class="op"&gt;&amp;amp;&lt;/span&gt;&lt;span class="kw"&gt;mut&lt;/span&gt; s)&lt;span class="op"&gt;?;&lt;/span&gt; &lt;span class="co"&gt;// return if error&lt;/span&gt;&lt;/span&gt;
111&lt;span id="cb11-8"&gt;&lt;a href="#cb11-8" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
112&lt;span id="cb11-9"&gt;&lt;a href="#cb11-9" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="cn"&gt;Ok&lt;/span&gt;(s) &lt;span class="co"&gt;// all good, return a string inside a `Result` context&lt;/span&gt;&lt;/span&gt;
113&lt;span id="cb11-10"&gt;&lt;a href="#cb11-10" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
114&lt;span id="cb11-11"&gt;&lt;a href="#cb11-11" aria-hidden="true"&gt;&lt;/a&gt;&lt;/span&gt;
115&lt;span id="cb11-12"&gt;&lt;a href="#cb11-12" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="kw"&gt;fn&lt;/span&gt; main() &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
116&lt;span id="cb11-13"&gt;&lt;a href="#cb11-13" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="co"&gt;// `contents` is an enum known as Result:&lt;/span&gt;&lt;/span&gt;
117&lt;span id="cb11-14"&gt;&lt;a href="#cb11-14" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;let&lt;/span&gt; contents &lt;span class="op"&gt;=&lt;/span&gt; foo()&lt;span class="op"&gt;;&lt;/span&gt;&lt;/span&gt;
118&lt;span id="cb11-15"&gt;&lt;a href="#cb11-15" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="kw"&gt;match&lt;/span&gt; contents &lt;span class="op"&gt;{&lt;/span&gt;&lt;/span&gt;
119&lt;span id="cb11-16"&gt;&lt;a href="#cb11-16" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="cn"&gt;Ok&lt;/span&gt;(c) &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pp"&gt;println!&lt;/span&gt;(c)&lt;span class="op"&gt;,&lt;/span&gt;&lt;/span&gt;
120&lt;span id="cb11-17"&gt;&lt;a href="#cb11-17" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="cn"&gt;Err&lt;/span&gt;(e) &lt;span class="op"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="pp"&gt;eprintln!&lt;/span&gt;(e)&lt;/span&gt;
121&lt;span id="cb11-18"&gt;&lt;a href="#cb11-18" aria-hidden="true"&gt;&lt;/a&gt; &lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;
122&lt;span id="cb11-19"&gt;&lt;a href="#cb11-19" aria-hidden="true"&gt;&lt;/a&gt;&lt;span class="op"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
123&lt;h3 id="conclusion"&gt;Conclusion&lt;/h3&gt;
124&lt;p&gt;I did not want to conclude without talking about stylistic choices, lack of metaprogramming, bizzare export rules, but, I am too busy converting my &lt;code&gt;interface{}&lt;/code&gt; types into actual generic code for Go v2.&lt;/p&gt;</description>
125<link>https://peppe.rs/posts/gripes_with_go/</link>
126<pubDate>Sat, 01 Aug 2020 11:55:00 +0000</pubDate>
127<guid>https://peppe.rs/posts/gripes_with_go/</guid>
128</item>
129<item>
15<title>Turing Complete Type Systems</title> 130<title>Turing Complete Type Systems</title>
16<description>&lt;p&gt;Rust’s type system is Turing complete:&lt;/p&gt; 131<description>&lt;p&gt;Rust’s type system is Turing complete:&lt;/p&gt;
17&lt;ul&gt; 132&lt;ul&gt;