Tales of a Software Craftsman

POST CATEGORY
:Uncategorized

So here it goes again, I have started another new blog / site – http://polyglot.ninja/ – I am planning to create programming related contents there. Mostly learning guides, tutorials and who knows, may be some video tutorials too?

Why did I start another site? Well, for one I love that domain. Also being a Polyglot developer by heart, I feel the need to make the term “polyglot” more familiar among developers. I would also like to convey the idea that learning multiple programming languages is very important. It does make us better developers if we learn new ideas and concepts from other languages.

I hope to continue writing there. If you are interested, you can subscribe to the mailing list (I have the same list, so subscribing here would also get you updates from that site). I will keep you posted of the new contents I create there 🙂

Update: The result returned from the StackExchange is slightly outdated. So it might not display the latest reputation or other profile changes and thus slightly affecting the ranking.

Update: Because the large list was affecting the site performance, I have moved it to Github Gist.

This post uses the StackExchange Data Explorer to query the StackOverflow users and grab their data. The Python script to query and parse the data is attached below the ranking. So let’s wait no further and meet the top 500 people on SO from Bangladesh:

One of the first thing beginners wonder in the Go userland is how to organize a project. Go expects to have a global workspace. A go workspace contains 3 directories: “src”, “pkg” and “bin”. The src directory contains the source codes for all your projects and their dependencies. When you try to import a package, go compiler will try to locate it under this “src” directory. The “pkg” directory is used to build cross OS packages out of your source code. Yes, you can build single compiled binaries for other platforms directly from your current OS. That is one of the awesome features of Golang. Finally, the “bin” directory holds all the executable binaries. When you’re building a command line app or trying to install one from 3rd parties using the “go install” command, the binary is placed in here. I have the central Go Workspace in ~/Projects/golang.

Go expects the path of the go workspace as the $GOPATH environment variable. So I added this to my ZSH profile:

My $GOPATH is set to ~/Projects/golang:

Shell

1

export GOPATH=~/Projects/golang

Now that we have a workspace, how do we lay out individual projects? We can choose any structure we like. As long as Go can find required packages in the workspace’s src directory tree, it will be okay. However, since we all love to push our codes to some code hosting service, we will try to match our project structure with our VCS url structure. How? Well, first, we know that Go has a fantastic tool – “go get” – it can download source codes from an array of VCS and install them for us. How does it work? When I type: “go get github.com/masnun/go-project”, it understands that it’s a git project. It would create the reflecting directory structure inside the “src” directory of the workspace so that we can import the project as “import github.com/masnun/go-project” in our local projects. So it’s better if we keep our own projects in a similar pattern whether we publish them or not in the future.

I created a directory named “github.com” under “src” and then created “masnun” under that. Now my projects would reside in: ~/Projects/golang/src/github.com/masnun directory. My newly created project path would be something like: ~/Projects/golang/src/github.com/masnun/go-project-name. I can now treat ~/Projects/golang/src/github.com/masnun directory as my personal workspace. So, I added these to my .zshrc for convenience:

Shell

1

export GOWORKSPACE=$GOPATH/src/github.com/masnun

After I have this mirrored up, I can actually do:

Shell

1

2

3

4

5

6

7

8

9

cd$GOWORKSPACE

take my_project

# Create the project files

# Commit and Push to Github

go build

# Or

go install

Then I added a handy alias to emulate Python’s virtualenvwrapper’s “workon” command:

Shell

1

aliasgowork='cd $GOWORKSPACE'

So I can now just do:

Shell

1

2

3

4

5

gowork

take new_project

# .......

# .......

I also added the ~/Projects/golang/bin (aka $GOPATH/bin) to my system path so that I can use the commands installed from “go install” or “go get”.

Shell

1

export PATH=$GOPATH/bin:$PATH

How do you organize your Go projects? What tools/techniques do you use in day to day Golang hacking?

The use case is simple – I have one row (I mean document). I need to make multiple copies of it. Say, I am building a blog app and I need to quickly generate a few posts on the database. Scripting is one way to do it, but if I need to do this only once, automation is a waste of time.

Thanks to mongodb’s shell and JS-like APIs. This is actually simple.

Connect to mongodb:

Shell

1

mongo

Select the database:

Shell

1

useblog

Find an entry on the “posts” collection:

JavaScript

1

x=db.posts.findOne()

Now let’s change the “_id”:

JavaScript

1

x._id=newObjectId()

X is now a whole new object/document (since we changed the “_id”). We can alter other fields as well. Let’s store it:

JavaScript

1

db.posts.insert(x)

You just copied one document into a new document. Cool?

The command line mongo client has readline and history support. So you can actually use the up arrow to repeat the commands quite easily.

I use the top notch IDEs for development but that is not geeky enough. So, ignoring my previous failed attempts, I am going to give the text editor one more try. Apparently, this blog post would be more like self documentation, mostly notes and hints to self. If anyone else also gets benefited, that’d be an added bonus.

Ever needed a custom string type to add your own methods or tweak certain behavior? In languages like Ruby or Javascript, you can directly modify built in types. In other languages, we usually create custom objects to wrap around a default type and then extend that object with necessary methods or attributes.

A sample example in Python would look like:

Python

1

2

3

4

5

6

7

8

9

10

classMyString(object):

def__init__(self,val):

self.val=val

defprint_len(self):

print"Length: "+str(len(self.val))

name=MyString("masnun")

name.print_len()

In Go, we would define a new type based on an existing type. Then define methods on the newly defined type. It allows us to easily create new types based on existing types and then customize to suit our needs. The same example in Go would look like:

This post is dedicated to the awesome concept of “Goroutines” in Go. A “Goroutine” (Go Routine?) is a lightweight thread implementation that executes asynchronously with the main process. To define a goroutine, we use the “go” keyword before a function call. Instead of a regular blocking call, the function is then executed asynchronously.

Let’s jump into a quick demonstration. We shall write a program that creates multiple threads, each thread sleeping for a random period of time. For us, the mere mortals, we shall politely ask the threads to print some information so that we can tell when they go to sleep and when they wake up!

Go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

packagemain

import(

"fmt"

"math/rand"

"time"

)

funcmain(){

// let's create 5 goroutines using for loop

fori:=0;i<5;i++{

// the go keyword makes it a goroutine, making the function

// execute asynchronously instead of a blocking call

// we are using anonymous function for simple

// demonstration

gofunc(num int){

// let's seed the random number generator

rand.Seed(time.Now().UnixNano())

// create a random number for sleeping

sleepDuration:=rand.Intn(20)

// let's print a message before sleeping

fmt.Printf("[%d]: Sleeping for %d milisecs \n",num,sleepDuration)

// ZzzzZzzZZZzzzz!!

time.Sleep(time.Duration(sleepDuration)*time.Millisecond)

// Good morning, World!

fmt.Printf("[%d]: Woke up! \n",num)

}(i)

}

// delay the main process so that others can print to the terminal

varinput string

fmt.Scanln(&input)

}

The blocking call (from the main process) always executes first. The Scanln() call waits for user input thus allowing the async functions to print their information on the terminal. If we don’t wait, the main process will finish execution and the program will quit. Since the other functions are async, we shall never see their outputs. So we wait and wait for their messages! 🙂

Sample output?

1

2

3

4

5

6

7

8

9

10

11

12

Lighthouse:~/Codes/go

$go run main.go

[0]:Sleeping for3milisecs

[1]:Sleeping for18milisecs

[2]:Sleeping for2milisecs

[3]:Sleeping for16milisecs

[4]:Sleeping for9milisecs

[2]:Woke up!

[0]:Woke up!

[4]:Woke up!

[3]:Woke up!

[1]:Woke up!

It’s simple, right? In some languages, you have to subclass a built in class and then define specific methods to direct the behavior/actions. In Go, you just define a function and prepend “go” before making the function call. Good thing, you can use anonymous functions and invoke them immediately as well.

For communication between these goroutines, we can use “Channels”. Hope to write another blog post on using channels soon.

It’s been a while I am looking at Go. The language is nice, feels like a mixture of Python and C with huge performance gains and some innovative language features. In this post, I would try to quickly focus on the basics of “Go”. I hope I shall write more on the language in the coming days.

Installation

If you happen to have the same OS as mine, that is OSX, I highly recommend installing Go using Homebrew. It’s just a matter of one line –

Shell

1

brew install go

Once it’s installed, you can display useful information with this command –

Shell

1

brew info go

If you are on Windows, Linux or any other OS, please follow a suitable instruction set from the documentation.

Running Go Programs

How does a first program look on Go? Let’s see –

Go

1

2

3

4

packagemain

funcmain(){

print("Hello World! \n")

}

A Go file must define a function named main if you want to run it. We can define a function in go using “func” keyword.

Running it –

Shell

1

go run main.go

You can directly run a Go file by using the “go run” command. This comes in handy for debugging, if you want to build a compiled binary, use “go build”.

Shell

1

2

3

4

5

6

7

8

9

10

Lighthouse:~/Codes/go

$go build main.go

Lighthouse:~/Codes/go

$ls

main main.go

Lighthouse:~/Codes/go

$./main

Hello World!

Variables, Constants and Printing

First, how do we define variables in Go? It’s simple –

Go

1

varvariableName variableType="default value"

In Go, we can import packages using the “import” keyword. The package “fmt” has a nice function named “Println” which is more or less Go equivalent to System.out.println() in Java. Let’s see a code sample –

Go

1

2

3

4

5

6

7

8

9

10

11

12

13

packagemain

import"fmt"

funcmain(){

//var variableName variableType = "default value"

varname string="masnun"

varage int=23

fmt.Println(name);

fmt.Println(age);

}

If you are initializing a variable, you can optionally skip the variable data type. Go can infer that from the initialization.

There is a shorthand format for declaring and initializing a value quickly –

Go

1

name:="masnun"

It will create a var type string and assign the value “masnun” at the same time.

To create a constant, we just replace “var” with “const”. Example:

Go

1

constsstring="constant"

Looping

In Go, we use “for” for all types of looping. Check out –

While Loop:

Go

1

2

3

4

5

6

7

8

9

10

11

packagemain

import"fmt"

funcmain(){

i:=1

fori<=10{

fmt.Println(i)

i=i+1

}

}

Generic For Loop:

Go

1

2

3

4

5

6

7

8

9

packagemain

import"fmt"

funcmain(){

fori:=1;i<=10;i++{

fmt.Println(i)

}

}

We can do common “foreach” loops combining “for” with “range”. We shall see them in the next section.

Arrays, Slices and Maps

Arrays:

If you are any programmer at all, I probably don’t need to tell you about arrays. Defining arrays in Go is easy.

The syntax is –

Go

1

2

3

4

5

vararrayName[size]type

// Example: an array of 5 integers

varnumbers[5]int

We can reference the indexes just like in any other language. We can even declare and initialize an array on the same line. Take a look at the example:

Go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

packagemain

import"fmt"

funcmain(){

varnumbers[5]int

numbers[1]=2

fmt.Println(numbers)

varinitNumbers=[5]int{1,2,3,4,5}

fmt.Println(initNumbers)

}

Slices:

Slices are like arrays but not fixed size. However, the type must remain the same. I mean you can’t add a string type to an integer slice.

We use the make() function to create a slice. In fact, in Go, make() can create a lot of stuff for me. We shall soon find out. For now, let’s see how we can use a Slice.

Go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

packagemain

import"fmt"

funcmain(){

strSlice:=make([]string,1)// we make a slice & initialize with one item

strSlice=append(strSlice,"hello")

strSlice=append(strSlice,"world")

fmt.Println(strSlice)

}

Maps:

Maps are what we call “Hashes”, “Dictionaries” or “Associative Arrays” in misc other languages. Maps are in reality key value pairs. We use make() to create maps of certain types. Example follows –

Go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

packagemain

import"fmt"

funcmain(){

ages:=make(map[string]int)// create a map with string keys and integer values

ages["voldemort"]=50

ages["thedoctor"]=1200

fmt.Println(ages)

}

Iteration with Range

“range” allows us to iterate over a number of data structures. range gives us the key and value in each iteration. It works quite like the “enumerate” function in some languages (eg. Python). Let’s see how we can iterate over common data structures:

Go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

packagemain

import"fmt"

funcmain(){

// Arrays

nums:=[5]int{1,2,3,4,5}

forindex,value:=rangenums{

fmt.Println(index,": ",value)

}

// Maps

emails:=make(map[string]string)

emails["gmail"]="masnun [at] gmail.com"

emails["work"]="masnun [at] team.okdo.it"

forkey,value:=rangeemails{

fmt.Println(key,": ",value)

}

}

That’s all for Part – 1. In my next blog post, I shall try to cover “If/Else” with “Structs, Functions & Methods”.