Gil Amran

@gilamran

Introduction to Go for JavaScript developer

Banner by Marina Rudinsky

Shifting from JavaScript to Go, I’ve encountered a few “whaaat?!” moments that eventually became “haaa, ok!” moments. To put it more eloquently, if you’re a JavaScript/TypeScript developer and thinking about trying Go, this article is for you.

Working at Orbs, a blockchain for consumer apps, I’ve taken part in contributing to the reference implementation in TypeScript — I’ve implemented a consensus algorithm from scratch. Recently, we’ve started working on the reference implementation in Go language. My task is to port the consensus algorithm to Go — you can see the converted code in progress here.

Similarities

  • Like JavaScript, Go uses Garbage Collector. You don’t have to do any memory allocation/disposal.
  • Functions play a big part of your day to day development.
  • Variables and functions have scope.
  • You can use closure in functions.
  • After all, it’s a very simple language, and like JavaScript you define variables, structures, functions and do your for loops and if statements. I’d say that Go is something between C and JavaScript

(Big) Differences

There are many other differences in addition to the following list, but I have found that these are the most interesting for developers that come from JavaScript background.

  • Go is statically typed, and will detect type errors on compilation
  • I know that Garbage Collector was in the “Similarities” above, but in Go there’s a big difference: GC is amazingly FAST. No lags!
  • JavaScript is based on one main thread that runs your code (The event-loop) and several other threads that do external IO. While in Go, concurrency is king! Get ready. It is not easy to grasp at first, but once you get it, you’ll have great power in your hands. (The world is progressing to more and more cores)
  • It is so fun to write JavaScript and just run it. JavaScript is interpreted, and code is compiled just before it runs, but who really does that? Today, the JavaScript tool-chain involves many code analysis tools and even compilation like Babel or TypeScript. As mentioned above, Go is compiled.
  • Go is using pointers. Yes! Pointers. BUT WAIT! Don’t stop reading.
    In order to be able to do GC properly and avoid reading/writing out of memory, Go pointers do not allow any arithmetics on pointers. You can’t do p++ on a pointer to move it to the next item in an array, like you would do in C. But you do have all the other benefits of pointers (References)
  • Go is faster than JavaScript! Depending on what you measure, it can even be x10 times faster
  • Go is better suited for the server, while JavaScript is, well, everywhere

“Whaaat!? Haaa, ok”

One key thing you should understand is that Go is very opinionated. For example regarding syntax, in Go you MUST put the { in your if statement at the same line. Not doing so will result in a compilation error!

No OOP

Go is structured in a way that classes, inheritance, and polymorphism are not possible (or at least very difficult). What started as “I don’t like that!” became “Hmmm, maybe that’s even better!” when I understood that Go is pushing you to use composition instead of inheritance.

Shortcuts

In Go, there are many shortcuts. It almost feels as though anything that can be written in Go with fewer characters.

// The long way
var age Int = 42
// The short way
age := 42

This makes your learning curve steeper, but if you stick with Go, you’ll (probably) eventually like it.

Map/Reduce

Go is typed, but no generics. This means that you don’t have the lodash-like map/reduce functions. This “Whaaat” did not end with “haa ok”…
It is planned for future versions of Go.

Packages

When I first installed Go and wanted to create a project, I thought that I’d create a folder and put all my code there, build it, and run…nope. This is not how Go usually operates. All your projects should be under the same global src folder, under a folder unique to your project, usually your Github path (for example: ~/go/src/github.com/gilamran/PBFT-Typescript)

There are many issues with this approach like the dependencies of your project being under the same src folder and versions becoming a big issue.

Golang does support vendor folder (Similar to node_modules in JavaScript), but it will fetch the master branch…

There are many attempts to solve this, but know that currently dependencies in Go can be painful.

Tests

Golang loves tests, so much so that when the compiler detects test files (by file name _test.go), it will automatically exclude the test code when you build.

Syntax

Before you dive in, let me give you a short preview of how we do things:

Basic rules

  • Lines don’t end with a semicolon.
  • Last item in an array must have the , after the value.
var arr = [3]int{
1,
2,
3,
}
  • { of if is at the same line
  • public/private is defined by whether the first letter of the name is capitalized or not, respectively.
var ThisIsPublic = "You can access this variable from outside"
var privateValue = "Accessible only inside the current package"

Basic types

// common types
var num int = 5
var pi float32 = 3.14
var name string = "Gil"
var isActive bool = true

// without initialisation
var num int // value is 0
var pi float32 // value is 0
var name string // value is ""
var isActive bool // value is false
var person Person // value is nil

// one liner
var one, two, three bool
var a, b, c = true, "Hi", 0.5 // you got the point

// short version with inference
num := 5 // `var` is omitted, and type is inffered

Loops

// you should be familiar with this
for i := 0; i < 100; i++ {
sum += i
}
// while
for sum < 1000 {
sum += sum
}
// infinite loop
for {
}

Flow control

/// yep, no parenthesis
if age < 18 {
return true
} else {
return false
}
// switch no need to add `break`
switch state {
case "ACTIVE" :
deactivate()
case "INACTIVE":
activate()
default:
fmt.Printf("Unknown state")
}

Functions

// simple function
func add(a int, b int) int {
return a + b
}
// multiple return values
func swap(a, b int) (int, int) {
return b, a
}
// named return values
func namedResult(input int) (output int) {
output = 0
.
.
.
output = 42
.
.
.
return
}

Of course, this is the just tip of the iceberg. There are many other advanced things like channels, structs, and interfaces, but I’ll leave those for a future post.

Conclusion

Go is very interesting, very fast, and has an amazing GC. It really shines when talking about concurrency and it is very opinionated about how you write code. On the down side, the package management is not spectacular, and the lack of Generics is a bit annoying.

So, if you want to do something for the server, and you want it to work very fast, Go is a good choice.

Topics of interest

More Related Stories