DEV Community

Cover image for Golang for JavaScript developers - Part 1
Deepu K Sasidharan
Deepu K Sasidharan

Posted on • Edited on • Originally published at deepu.tech

Golang for JavaScript developers - Part 1

Originally published at deepu.tech.

If you are a JavaScript developer thinking about learning another programming language, then Golang is a great choice. It is simple, has a lot of momentum, very performant and has some similarities to JavaScript.

Edit: Someone asked me in the comments that why should a JS developer choose Go among all the available options. In my opinion, JS is not a perfect language and hence learning few other languages will greatly benefit a JS developer to use JS more pragmatically and would help to cement her/his knowledge of fundamental programming concepts better. There are of course many options out there like Rust, Go, Haskel, Kotlin and so on, but I think Go is a great place to start as its one of the simplest among all the available options and has wide adoption. My second choice would be Kotlin or Rust.

This post is not a comparison of the languages or is stating that they are very similar. Its a guide for JavaScript developers to grasp Golang quickly. There are many aspects of Go that are entirely different from JavaScript we will touch upon that as well.

Things that are more similar

There are many things in Go which are quite similar to concepts in JavaScript. Most are not the same but similar. let us get them out of our way first. In the first part of this series, we will see how they are similar and note any key differences as well.

Functions

The most similar feature in JS and Go are the functions.

Similarities

  • Functions are first-class citizens.
  • Functions can be assigned to variables.
  • Functions can be passed as arguments to other functions and can be returned from functions.
  • Functions can be nested.
  • Functions can be curried(partial functions).
  • Functions can memorize its surrounding context thus creating closures.
  • Functions can be named or anonymous. Anonymous functions can be immediately invoked(IIFE)

JavaScript

// A normal function with access to `this`
function standardFunction(arg1, arg2) {
  return `${arg1}:${arg2}`;
}

// A function assigned to a variable
const assignedFunction1 = standardFunction;

// An arrow function assigned to a variable
const assignedArrowFunction = (arg1, arg2) => {
  return `${arg1}:${arg2}`;
};

// A higher-order-function that accepts functions as argument and returns a function
function functionAsArgumentAndReturn(addFn, arg1, arg2) {
  const out = addFn(arg1, arg2);
  // This returns a closure
  return function (numArg) {
    return out + numArg;
  };
}

const out = functionAsArgumentAndReturn(
  (a, b) => {
    return a + b;
  },
  5,
  10
)(10);
// returns 25

// Nested functions
function nested() {
  console.log("outer fn");
  function nested2() {
    console.log("inner fn");
    const arrow = () => {
      console.log("inner arrow");
    };
    arrow();
  }
  nested2();
}

nested(); // prints:
// outer fn
// inner fn
// inner arrow

// this is a higher-order-function that returns a function
function add(x) {
  // A function is returned here as closure
  // variable x is obtained from the outer scope of this method and memorized in the closure
  return (y) => x + y;
}

// we are currying the add method to create more variations
var add10 = add(10);
var add20 = add(20);
var add30 = add(30);

console.log(add10(5)); // 15
console.log(add20(5)); // 25
console.log(add30(5)); // 35

// An anonymous function invoked immediately(IIFE)
(function () {
  console.log("anonymous fn");
})();
// prints: anonymous fn
Enter fullscreen mode Exit fullscreen mode

Go

// A normal function, this cannot be nested
func standardFunction(arg1 string, arg2 string) string {
    return fmt.Sprintf("%s:%s", arg1, arg2)
}

func main() {

    // A function assigned to a variable
    var assignedFunction1 = standardFunction

    // An anonymous function assigned to a variable and nested
    var assignedFunction2 = func(arg1 string, arg2 string) string {
        return fmt.Sprintf("%s:%s", arg1, arg2)
    }

    // A higher-order-function that accepts functions as argument and returns a function
    var functionAsArgumentAndReturn = func(addFn func(int, int) int, arg1 int, arg2 int) func(int) int {
        var out = addFn(arg1, arg2)
        // This returns a closure
        return func(numArg int) int {
            return out + numArg
        }
    }

    var out = functionAsArgumentAndReturn(
        func(a, b int) int {
            return a + b
        },
        5,
        10,
    )(10)
    fmt.Println(out) // prints 25

    // Nested anonymous functions
    var nested = func() {
        fmt.Println("outer fn")
        var nested2 = func() {
            fmt.Println("inner fn")
            var nested3 = func() {
                fmt.Println("inner arrow")
            }
            nested3()
        }
        nested2()
    }

    nested() // prints:
    // outer fn
    // inner fn
    // inner arrow

    // this is a higher-order-function that returns a function
    var add = func(x int) func(y int) int {
        // A function is returned here as closure
        // variable x is obtained from the outer scope of this method and memorized in the closure
        return func(y int) int {
            return x + y
        }
    }

    // we are currying the add method to create more variations
    var add10 = add(10)
    var add20 = add(20)
    var add30 = add(30)

    fmt.Println(add10(5)) // 15
    fmt.Println(add20(5)) // 25
    fmt.Println(add30(5)) // 35

    // An anonymous function invoked immediately(IIFE)
    (func() {
        fmt.Println("anonymous fn")
    })()
    // prints: anonymous fn

    assignedFunction1("a", "b")
    assignedFunction2("a", "b")
}

Enter fullscreen mode Exit fullscreen mode

Differences

  • JavaScript Functions have two forms; regular functions, and arrow functions whereas in Go there is normal functions and interface functions. Normal Go functions do not have a this and hence are more similar to arrow functions whereas interface functions have something similar to a this and hence closer to normal functions in JavaScript. Go doesn't have the concept of a global this.

JavaScript

function normalFnOutsideClass() {
  console.log(`I still can access global this: ${this}`);
}

const arrowFnOutsideClass = () => {
  console.log(`I don't have any this`);
};

class SomeClass {
  name = "Foo";
  normalFnInsideClass = function () {
    console.log(`I can access the callee as this: ${this.name}`);
  };
  arrowFnInsideClass = () => {
    console.log(`I can access the class reference as this: ${this.name}`);
  };
}

new SomeClass().normalFnInsideClass();
new SomeClass().arrowFnInsideClass();
Enter fullscreen mode Exit fullscreen mode

Go

type SomeStruct struct {
    name string
}

func (this *SomeStruct) normalFnInsideStruct() {
    // you can name the variable this or anything else
    fmt.Printf("I can access the struct reference as this\n: %s", this.name)
}

func main() {

    var normalFnOutsideStruct = func() {
        fmt.Println("I can access variables in my scope")
    }
    normalFnOutsideStruct()

    var structVal = SomeStruct{"Foo"}
    structVal.normalFnInsideStruct()
}
Enter fullscreen mode Exit fullscreen mode
  • JavaScript functions are the same as any other value type and hence can even hold additional attributes which is not possible in Go.
  • Go functions can have implicit named returns.
  • Only anonymous functions can be nested in Go.
  • Go functions can return multiple values, whereas in JavaScript you can return only one value. However, in JS you can work around that by using destructuring so you can do similar looking functions in both

JavaScript

function holdMyBeer() {
  return ["John", 2];
}

let [a, b] = holdMyBeer();
console.log(`Hey ${a}, hold my ${b} beer\n`);
Enter fullscreen mode Exit fullscreen mode

Go

func holdMyBeer() (string, int64) {
    return "John", 2
}

func main() {
    a, b := holdMyBeer()
    fmt.Printf("Hey %s, hold my %d beer\n", a, b)
}
Enter fullscreen mode Exit fullscreen mode

Scope

The scope is the context in which a variable is valid, this decides where a variable can be used and both JS and Go has many similarities here

Similarities

  • Both have function Scope and Functions can memorize their surrounding scope.
  • Both have block scope.
  • Both have a global scope.

Differences

  • Go doesn't have the concept of this which is a tricky concept in JavaScript. IMO this makes things much simpler in Go.
  • Variables in the same scope cannot be re-declared in Go. Go var is closer to let keyword in JS.

Flow control

Flow control in Golang is quite similar but simpler than JavaScript in many aspects.

Similarities

  • for loops are very similar in both.
  • while loops are very similar, though Go uses the same for keyword.
  • forEach is also similar in functionality but the syntax is quite different.
  • You can break/continue from a loop. You can use labels to do so as well.
  • if/else syntax is quite similar, Go version is a bit more powerful

JavaScript

// For loop
for (let i = 0; i < 10; i++) {
  console.log(i);
}

// While loop
let i = 0;
while (i < 10) {
  console.log(i);
  i++;
}

// Do while

let j = 0;
do {
  j += 1;
  console.log(j);
} while (j < 5);

// ForEach loop
["John", "Sam", "Ram", "Sabi", "Deepu"].forEach((v, i) => {
  console.log(`${v} at index ${i}`);
});

// for of loop
for (let i of ["John", "Sam", "Ram", "Sabi", "Deepu"]) {
  console.log(i);
}

// For in loop
const obj = {
  a: "aVal",
  b: "bVal",
};

for (let i in obj) {
  console.log(obj[i]);
}
Enter fullscreen mode Exit fullscreen mode

Go

func main() {
    // For loop
    for i := 0; i < 10; i++ {
        fmt.Println(i)
    }

    // While loop
    i := 0
    for i < 10 {
        fmt.Println(i)
        i++
    }

    // Do while
    j := 0
    for {
        j += 1
        fmt.Println(j)
        if j == 5 {
            break
        }
    }

    // ForEach and for of loop
    for i, v := range []string{"John", "Sam", "Ram", "Sabi", "Deepu"} {
        fmt.Printf("%v at index %d\n", v, i)
    }

    // For in loop
    var obj = map[string]string{
        "a": "aVal",
        "b": "bVal",
    }

    for i, v := range obj {
        fmt.Printf("%v at index %s\n", v, i)
    }
}

Enter fullscreen mode Exit fullscreen mode

Differences

  • There is no ternary operator in Go.
  • switch statement syntax is similar but Go defaults to break and JS defaults to fall through. In Go, you can use the fallthrough keyword for that functionality while in JS, we have the break keyword.
  • JS has many more ways of iterations, like while, forEach, for in & for of loops and so on which are not available in Go though most of them can be achieved using the for syntax.
  • if/else can have an init assignment in Go. In the below code the assignment for val has scope only within the if and else blocks and not outside of it. This is not possible in JS.

Go

if val := getVal(); val < 10 {
    return val
} else {
    return val + 1
}
Enter fullscreen mode Exit fullscreen mode

Memory management

Memory management is also quite similar except for details in both JS and Go.

Similarities

  • Both are garbage collected at runtime.
  • Both have heap and stack memory which means the same in both.

Differences

  • Go has pointers that are exposed to users while their memory management is abstracted away whereas in JavaScript pointers are abstracted away completely and you only work with values and references.
  • Go uses a concurrent tricolor mark-and-sweep algorithm with a focus on latency whereas JS engines normally implement different algorithms with Mark-Sweep being a very popular choice. V8 engine, for example, uses both Mark-Sweep and a Scavenge algorithm.

Misc

  • Commenting is same in both, with // and /* */
  • Both JS and Go supports importing other modules, though the behavior is not the same
  • SetTimeout is similar in both. setTimeout(somefunction, 3*1000) vs time.AfterFunc(3*time.Second, somefunction).
  • Both have a spread operator console.log(...array) vs fmt.Println(array...). Go spread works only on interface arrays/slices though.
  • Both have rest operator for method arguments ...nums vs nums ...int.

Conclusion

In this part, we saw concepts that are similar in both languages. In the next part of the series, we will see things that are more different between JS and Go. There are more things in the next part, that are different, than this, but please also note that some differences are quite subtle so it would be easy to digest for a JavaScript developer.

In the next chapter we will see:

  • Types & Variables
  • Error handling
  • Mutability
  • Composition instead of inheritance
  • Concurrency
  • Compilation
  • Paradigm

References:


If you like this article, please leave a like or a comment.

You can follow me on Twitter and LinkedIn.


Cover image photo created using images from norfolkjs (designed by Lookmai Rattana) and juststickers

Top comments (18)

Collapse
 
marcellothearcane profile image
marcellothearcane
if val := getVal(); val < 10 {
    return val
} else {
    return val + 1
}

This is not possible in JS

What does it do?

Collapse
 
vinceramces profile image
Vince Ramces Oliveros

the variable is scoped to the if statement. Thus, it is much more readable. might be that the getVal() function would be like this.

func getVal() int{
    // return any number
    return 0
}

compare to javascript

// given by the example. the `val` is mutable
let val = getVal()
if(val < 10){
   return val
}
else{
  return val + 1
}
Collapse
 
nmhillusion profile image
nmhillusion

in golang,
after if block, variable val continues existing? Or it just exists in the if block?

Thread Thread
 
vinceramces profile image
Vince Ramces Oliveros

val is no longer accessible after the if statement. the variable is scoped to the if block

Collapse
 
deepu105 profile image
Deepu K Sasidharan

Thanks

Collapse
 
deepu105 profile image
Deepu K Sasidharan

Sorry, I should have explained it better. I'll update the post

Collapse
 
bradtaniguchi profile image
Brad

Awesome article, the only thing I feel like is missing the reason why a JavaScript developer should learn GoLang over other languages. 🤔

Collapse
 
freedom profile image
Freedom

A good reason for me, to port a backend Nodejs to a single Go binary, I can run without any dependencies or installation e.g. virtual machine/runtime, this help to reduce security vulnerabilities and improve reliability.

Collapse
 
deepu105 profile image
Deepu K Sasidharan

Well, IMO there is no strong reasons to specifically learn Go except that it is easier to start with. But IMO JS is not a perfect language and hence JS developers would greatly benefit by learning a few other languages which will help to make them more pragmatic. It helped me for sure.

Collapse
 
erebos-manannan profile image
Erebos Manannán

Golang has a massive number of benefits over many other languages. However, "a JavaScript developer" is too vague a concept to list any specific benefits to them.

Some significant benefits:

  • Quick compilation time
  • Good ecosystem with lots of well made libraries
  • Widespread standardization and tooling for e.g. automatic code formatting and static analysis
  • Compiles easy to distribute binaries without external dependencies
  • Cross-compilation is easy in most cases (I believe as long as you don't link to C code), so you can just set up one build pipeline and loop through a number of GOOS and GOARCH variables and get the build results easily
  • Concurrency is incredibly well handled in Golang - no need to worry about threads and other such things manually, but it's easy to control when things are executed in parallel and to communicate between "goroutines"
Collapse
 
bradtaniguchi profile image
Brad

I've learned a bit of Go and I agree it is a clear straight forward language, which makes it easy to learn, very similar to Python in those regards.

Collapse
 
hchev001 profile image
Hamilton Chevez

When and what will part 2 be about, released?

Collapse
 
deepu105 profile image
Deepu K Sasidharan

I mentioned what is covered in part 2 at the end of this post. I'll still need to finish up a few topics there but you can expect it start of next week

Collapse
 
deepu105 profile image
Deepu K Sasidharan
Collapse
 
k_penguin_sato profile image
K-Sato

go Go!!

Collapse
 
deepu105 profile image
Deepu K Sasidharan
Collapse
 
qinlinsen profile image
秦林森

NICE

Collapse
 
dscamargo profile image
Douglas Simon Camargo

I'm JS developer and learning Golang.
Your articles (part1 and part2) help me a lot to understand how to golang works :) Thank you.