Skip to content

Instantly share code, notes, and snippets.

@riandyrn
Created September 28, 2022 12:28
Show Gist options
  • Save riandyrn/1007568627196543736d26d5cd71c139 to your computer and use it in GitHub Desktop.
Save riandyrn/1007568627196543736d26d5cd71c139 to your computer and use it in GitHub Desktop.

Hello, Praveen

Thanks for the response!

Actually this article is about our unique experience in solving codebase maintainability issue as an organization by choosing Go rather than the feature of Go as programming language itself. This was why we are focusing more on the impact in our organization. 😃

Also the things that you mentioned are actually not issues for our organization. Here are the details:

  1. Error handling, it was good initially, but after writing err != nil for everything, I felt it's little annoying.

Yeah, I agree the error handling in Go could be annoying for some people sometimes. Based on my experience, they are usually people coming from NodeJS, PHP, & Java. 😃

However if we try to take look at broader perspective, returning error as a value could greatly help us in building more robust software. This is simply because we are made aware of that error and being "forced" to handle it.

This approach is very helpful especially if we are working with junior engineers. Consider a scenario when we want to call an HTTP endpoint.

In python we would write it like this:

import requests

if __name__ == '__main__':
    resp = requests.get("https://google.com")
    print(resp.text)

For most of junior engineers this code is already good enough. However for production, we know it isn't. It should be written at least in this way:

import requests

if __name__ == '__main__':
    try:
        resp = requests.get("https://google.com")
        print(resp.text)
    except BaseException:
        print("Oh no something wrong happened during the call!")

While in Go, the junior engineers usually will notice the error and handle it right away. For example:

package main

import (
	"fmt"

	"github.com/go-resty/resty/v2"
)

func main() {
	client := resty.New()
	resp, err := client.R().Get("https://google.com")
	if err != nil {
		fmt.Println("Oh no! Something wrong happened during http call!")
		return
	}
	fmt.Println(string(resp.Body()))
}
  1. Libraries. Golang haven't grown big yet. There were lot of libraries were unmaintained, which made hard to choose.

Hehe.., yeah, in some domains (e.g cryptography) Go libraries is still scarce. However in our organization use case, most of the time the Go standard library is already good enough. So usually we don't need extra library for that. 😃

This situation is different for Python & NodeJS though. Thus for creating production grade code, usually we must depend on external libraries (we are not only writing service in Go, but other languages as well such as Python & NodeJS).

  1. I personally felt I am writing a lot of code comparing to other languages. I have good experience in Python, but Golang makes codebase bigger.

Well yeah, compared to Python, of course Go codebase will be bigger. Go is statically typed language after all. 😅

Consider following code in Python:

class Sandwich:
    def __init__(self, name, price):
        self.name = name
        self.price = price


def printSandwich(sandwich):
    print(f"Name: {sandwich.name}")
    print(f"Price: {sandwich.price}")


if __name__ == '__main__':
    s = Sandwich("Subway 32", 1000)
    printSandwich(s)

When people read this code, he/she may be wondering what is the type of Sandwich.price? Is it integer or float?

But with Go we are always being forced to write down the parameter type, thus it provide more clarity for the reader. Like this:

package main

import (
	"fmt"
)

type Sandwich struct {
	Name  string
	Price float64
}

func printSandwich(s Sandwich) {
	fmt.Printf("Name: %v\n", s.Name)
	fmt.Printf("Price: %v\n", s.Price)
}

func main() {
	s := Sandwich{Name: "Subway 32", Price: 1000}
	printSandwich(s)
}

Our organization priority is clarity. So bigger or not, it doesn't concern us much. As long as the details is easy to be understood by our team, it is good for us.

@francipvb
Copy link

What about auto-documentation?

In python, .net and Node.JS we have various alternatives to this issue, but in golang I found that it is an unsolved issue.

@Jackysi
Copy link

Jackysi commented Oct 2, 2022

But with PHP, C#, Java, NodeJS, etc... You can handle global or per larger scope/chunk of code exceptions. In a lot of cases like example above (standard http library) you do not need to write a check at all. If you have one parent "catch" phrase you will capture this error automatically without writing extra line of code. While on Go it means for EVERY function call...

Very weird example but it sums up what I mean:

<?php

    set_error_handler(
            static function( $severity, $message, $file, $line ) {
                throw new ErrorException( $message, $severity, $severity, $file, $line );
            }
    );


    function loadWebSite( $url ): string {

        return file_get_contents( $url );

    }

    function saveInfo( $data ): void {

        file_put_contents( 'contents.html', $data );

    }


    try {

        $response = loadWebSite( 'https://google.com' );
        saveInfo( $response );

    } catch ( Exception|ErrorException $e ) {

        echo $e->getMessage();

    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment