Below you will find pages that utilize the taxonomy term “Go”
October 17, 2021
Interpreter in Go - 4
In Chapter 1.3 of [Ball’s Writing an Interpreter in Go][1], we encounter one design decision of his Monkey programming language. Here, the lexer has a NextToken() method that looks like this:
func (l *Lexer) NextToken() token.Token { var tok token.Token switch l.ch { // [...] default: if isLetter(l.ch) { tok.Literal = l.readIdentifier() return tok } else { tok = newToken(token.ILLEGAL, l.ch) } } // [...] } This means the lexer itself does not do backtracking.
read moreAugust 22, 2021
Interpreter in Go - 3
A lexer takes the source code, a sequence of characters, and group them into tokens. e.g., it makes the first decision on how to process the strings 100-10, -100-10, and -100--100 into groups. I’m going to call this grouping “tokenization” even though I may be misusing the term.
Tokenizing source code is hard. How should -100--100 be tokenized? Should it be a literal -100 followed by the minus token, followed by another -100?
read moreJuly 29, 2021
Interpreter in Go - 2
Writing an Interpreter In Go by Thorsten Ball will be my personal introduction to writing an interpreter. I’ve never taken a comp sci class before, so I know nothing about compilers. On a lark, I decided to explore this area now, nearly 20 years after I started to learn computer programming.
If you are interested in this book as well, you might might the AST Explorer a useful companion.
I was told as some point in the past, that compilation can be broken down into four stages:
read moreJuly 27, 2021
Interpreter in Go - 1
It happened. At the recommendation of https://twitter.com/dgryski, I bought Writing an Interpreter In Go. This will be my next hobby project. It’ll be interesting to see if I ever finish it.
read moreApril 18, 2021
Posts Of The Week 2021-04-15
Lots of small things today.
History “Those who cannot remember the past are condemned to repeat it”. I love reading about how software came to be the way they are today.
Before we can talk about where generics are going, we first have to talk about where they are, and how they got there.
https://cr.openjdk.java.net/~briangoetz/erasure.html
Go Errors Error handling is still jacked in Go 1.16. That is, the formatting change is still not present.
read moreApril 3, 2021
Workflow Orchestration - Part 3 (How do I use this?)
In this part of the series, we’ll write some hands-on Temporal code and run it. Let’s start with our requirements:
You need to transmit a data packet. You can choose from multiple Route Providers to do this. Transmission takes time – you will be notified on a callback URL when the packet is delivered. Delivery may fail – either because the acknowledgement was not sent or arrived late (because Internet).
read moreApril 1, 2021
Posts Of The Week 2021-04-01
I spent a couple of hours evaluating 3rd party libraries. What have I learned? For me, there’s one clear winner in a small field of candidates.
Presently, these are the top hits for “golang gauge counter timer”.
https://pkg.go.dev/github.com/go-kit/kit/metrics https://pkg.go.dev/github.com/facebookgo/metrics https://github.com/uber-go/tally The first result is go-kit. Go-kit isn’t a metrics library. Rather, it bills itself as a “framework for building microservices.” Its metrics package is simply a set of interfaces.
read moreMarch 24, 2021
Posts Of The Week 2021-03-25
Go does not allow cyclic imports. A solution is to create a “shared” package to hold interfaces that related packages all reference. This, for some reason, reminds of me join tables in SQL.
Here is an example of a typical Go project. Packages toward the bottom, e.g., “common/persistence”, allow different packages to work with each other without introducing cyclic dependencies. For this project, “log” can be referenced by “config”, but cannot use “config” to conifgure itself.
read moreMarch 8, 2021
Posts Of The Week 2021-03-11
Oldie but goodie. Go concurrency patterns
https://drive.google.com/file/d/1nPdvhB0PutEJzdCq5ms6UI58dp50fcAN/view
read moreNovember 23, 2020
Go: Pointer vs Value
In A Tour of Go, it states “Go has pointers. A pointer holds the memory address of a value.” When you design your data structure in Go, you have to decide between using a pointer or not. There’s no clear rule of thumb for it.
I had been reading the Go source code to AWS’s client library for DynamoDB. For a while, I had been annoying with their API design, which looks like this:
read moreAugust 1, 2020
Go io/fs Design (Part I)
As usual, LWN has a good write up on what’s going on in the Go community. This week’s discussion in on the new io/fs package. The Go team decided to use a Reddit thread to host the conversation about this draft design. LWN points out that posters raised the following concerns:
We added status logging by wrapping http.ResponseWriter, and now HTTP/2 push doesn’t work anymore, because our wrapper hides the Push method from the handlers downstream.
read moreJuly 26, 2020
Localstack S3 and Go
I spent too much time Saturday getting the Go S3 SDK to work with LocalStack.. It turns out that if you are using LocalStack, you need to explicitly configure the following properties:
sess, err := session.NewSession(aws.NewConfig(). WithEndpoint(endpoint). WithRegion(region). WithS3ForcePathStyle(true)) The requirements for Endpoint and Region are obvious. If S3ForcePathStyle is not specified, then LocalStack will fail.
data, err := svc.GetObject(&s3.GetObjectInput{ Bucket: &bucket, Key: &cfgKey, }) What is path-style? In May 2019, Amazon deprecated path-based access model for S3 objects.
read moreMay 26, 2020
Gomock Tutorial
I’ve been using mock/Gomock to write tests in my personal project. When you’re building something in a new language, it is hard to prioritize learning every tool in your toolchain. For me, I’ve been writing custom and suboptimal code for Gomock because of a nifty but undocumented API call .Do.
In many cases, I wan to match subsets of a complex object while ignoring irrelevant parts. e.g., verify a function is invoked with a list of User objects, but only verifying the email addresses.
read moreMay 17, 2020
Go Project Organization
Here’s a rough layout of how I organize my Go project. Some parts are situational and some parts are essential. I’ll go over both in this blog.
A rough layout:
+ basedir +-- go.mod (module jcheng.org) +-- hello (empty) +-- log/ +-- utils/ +-- config/ +-- models/ +-- repositories/ +-- services/ +-- cmd/ +-- hello_app/ +--/cmd/ +-- speak/ +-- email/ +-- sms/ The basedir Situational.
I have my (personal) projects in a monorepo.
read moreFebruary 19, 2020
Mocking in Go Part 2
In a previous post, I talked about Gomock. I want to spend a bit more time on it.
As I’ve mentioned, setting up Gomock requires
Download mockgen go get github.com/golang/mock/mockgen@latest Edit your go.mod module jcheng.org go 1.13 require ( github.com/golang/mock v1.4.0 ) Add the go:generate incantation to your code //go:generate mockgen -source $GOFILE -destination mock_$GOFILE -package $GOPACKAGE package pastself import ( "time" ) ... Use mocks in your test case.
read moreFebruary 19, 2020
Few Annoying Things about Go
As promised, a few thoughts about Go that is annoying.
No Generics Code generation is tightly coupled with the tool chain. When I need to use code generation, i.e., enums and mocks, the use case can be solved with generics instead.
No lambda syntax Scala has a lambda syntax to make it easy to work with anonymous function objects
val numbers = Seq(1, 5, 2, 100) val doubled = numbers.map( n => n * 2 ) Java has a similar syntax
read moreFebruary 14, 2020
Mocking in Go
Today I want to talk a little about the testify and gomock packages and doing mocks in Go.
Mocking is essential when writing code that depends on external services, e.g., microservices, message brokers, and datastores. For many people, this means web applications: My system has business rules and talks to multiple services. How do I test the business rules without setting up all the services locally?
Some people argue that mocks create a false sense of test coverage and introduce blind spots.
read moreFebruary 8, 2020
Why I like Go
I have a few side projects, published and unpublished. By trade, I’ve come to programming as a Java programmer. I started coding directly against the Servlet API and have coded using Enterprise Java Beans, Play Framework, Spring Framework, and even some Scala. Lately, I’ve been coding mainly in Go with some Python.
Go is a really nice programming language. Some people like it for its simplicity. I want to offer a different take on why you should learn and use Go for your own projects.
read moreJanuary 4, 2020
Viper Examples
Viper is a configuration library fo Go. It has been my go to library for configs. Some of the best features of Viper are:
Ability to unmarshal subsets of a configuration file into a Go struct Ability to override contents of a configuration file using OS environment variables Here’s a brief example that demonstrates both features:
Assume you have a configuration file at $HOME/server.toml
resolve_dns = true http_keep_alive = 5 [example_com] doc_root = "/var/www/example_com" allow_files = "*.
read moreNovember 29, 2019
Go1 13 Errors
For me, Go 1.13 arrived with anticipation of better error handling. Presently, the second Google search result for Go 1.13 error hanlding is an article that refers to the “xerrors” package. One feature of the xerrors package is that it produced errors with a stack trace showing where the error came from. The addition to Go 1.13, however, did not include this particular feature, and left me spending frustrating hours trying to debug the loss of stack trace after switching from xerrors to the standard library.
read moreAugust 19, 2019
Own Your Data
I previously wrote about owning my own data. An important part of data ownership is backing up your data. I use S3 as my long term data store. It is pretty easy to set this up using Terraform.
S3
Provisioning a S3 bucket is simply a single Terraform resource:
resource "aws_s3_bucket" "repo_archive_log" {
acl = "log-delivery-write"
bucket = "example-bucket"
tags = {
Name = "example"
TTL = "persistent"
ManagedBy = "Terraform"
}
}