+ Gripes With Go +
+You’ve read a lot of posts about the shortcomings of the Go programming language, so what’s one more.
+-
+
- Lack of sum types +
- Type assertions +
- Date and Time +
- Statements over Expressions +
- Erroring out on unused variables +
- Error handling +
Lack of Sum types
+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 enum
type in C. Go lacks enum
types unfortunately, and you are forced to resort to crafting your own substitute.
A type to represent gender for example:
+type Gender int
+
+const (
+iota // assigns Male to 0
+ Male Gender = // assigns Female to 1
+ Female // assigns Other to 2
+ Other
+ )
+"My gender is ", Male)
+ fmt.Println(// My gender is 0
+// Oops! We have to implement String() for Gender ...
+
+func (g Gender) String() string {
+switch (g) {
+ case 0: return "Male"
+ case 1: return "Female"
+ default: return "Other"
+
+ }
+ }
+// You can accidentally do stupid stuff like:
+1 gender := Male +
The Haskell equivalent of the same:
+data Gender = Male
+| Female
+ | Other
+ deriving (Show)
+
+print $ "My gender is " ++ (show Male)
Type Assertions
+A downcast with an optional error check? What could go wrong?
+Type assertions in Go allow you to do:
+var x interface{} = 7
+int)
+ y, goodToGo := x.(if goodToGo {
+
+ fmt.Println(y) }
The error check however is optional:
+var x interface{} = 7
+var y := x.(float64)
+
+ fmt.Println(y)// results in a runtime error:
+// panic: interface conversion: interface {} is int, not float64
Date and Time
+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:
+Mon Jan 2 15:04:05 MST 2006
+Which is the date produced when you write the first seven natural numbers like so:
+01/02 03:04:05 '06 -0700
+Parsing a string in YYYY-MM-DD
format would look something like:
const layout = "2006-01-02"
+"2020-08-01") time.Parse(layout,
This so-called “intuitive” method of formatting dates doesn’t allow you to print 0000 hrs
as 2400 hrs
, it doesn’t allow you to omit the leading zero in 24 hour formats. It is rife with inconveniences, if only there were a tried and tested date formatting convention …
Statements over Expressions
+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.
+Rust allows you to create local namespaces, and treats blocks ({}
) as expressions:
let twenty_seven = {
+let three = 1 + 2;
+ let nine = three * three;
+ * three
+ nine };
The Go equivalent of the same:
+nil
+ twenty_seven :=
+1 + 2
+ three :=
+ nine := three * three twenty_seven = nine * three
Erroring out on unused variables
+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.
+Error handling
+if err != nil { ... }
Need I say more? I will, for good measure:
+-
+
- Error handling is optional +
- Errors are propagated via a clunky
if
+return
statement
+
I prefer Haskell’s “Monadic” error handling, which is employed by Rust as well:
+// 1. error handling is compulsory
+// 2. errors are propagated with the `?` operator
+fn foo() -> Result<String, io::Error> {
+let mut f = File::open("foo.txt")?; // return if error
+ let mut s = String::new();
+
+.read_to_string(&mut s)?; // return if error
+ f
+Ok(s) // all good, return a string inside a `Result` context
+ }
+
+fn main() {
+// `contents` is an enum known as Result:
+ let contents = foo();
+ match contents {
+ Ok(c) => println!(c),
+ Err(e) => eprintln!(e)
+ }
+ }
Conclusion
+I did not want to conclude without talking about stylistic choices, lack of metaprogramming, bizzare export rules, but, I am too busy converting my interface{}
types into actual generic code for Go v2.
I'm Akshay, I go by nerd or nerdypepper on the internet.
++ I am a compsci undergrad, Rust programmer and an enthusiastic Vimmer. + I write open-source stuff to pass time. I also design fonts: scientifica, curie. +
+Send me a mail at nerdy@peppe.rs or a message at nerdypepper@irc.rizon.net.
+