Hello!

I am James Simas. Welcome to my blog. I write about tech and stuff I find interesting.

How to care for your Invisalign braces

I wore Invisalign braces from January of 2022 to early 2023. They require a lot of brushing and maintenance while wearing them. Here’s a few things I did along the way which made that easier. 1. Create brushing stations You’re going to brush and floss a lot. (Like a lot.) Anytime you eat or drink anything besides water you must remove the Invisalign trays, brush your teeth and trays, and then floss....

2024-04-14

Using git worktrees

Have you ever been developing on a feature branch and needed to look at a separate branch on the same repo? I have. When this happens, I normally do one of two things: git stash my changes and change branches This is annoying because it’s a lot of steps. I also have to remember which stash to pop when I come back to this branch. Stage all my changes and store them in a work-in-progress commit This is better than #1 but doesn’t let you view both branches simultaneously....

2024-03-27

How my digital life is backed up

Derek Sivers recently wrote a post explaining how he backups his computers. His post inspired me to improve my own backup strategy and also to write this post. My computer I only have two personal computers whose data I care about; my Macbook Pro and my wife’s Macbook Air. The strategies for backing these up are the same, so I’ll just talk about my computer. It has a lot of important things: files, videos, photos, personal code, and more....

2024-03-22

Running a subset of Go tests

It is often useful to run a subset of the tests in a Go project. You might do this because you only want to see test results for one package or to run tests faster. For these examples, assume your project is a Go module named examplemodule. It has the following structure: examplemodule |_ go.mod |_ go.sum |_ internal |_ foo | |_ foo.go | |_ foo_test.go |_ bar |_ bar....

2024-03-07

Max and min integer values in Golang

Today I needed to use the maximum unsigned 64-bit integer value possible in Golang. Here is a short program I wrote with some help from Stack Overflow to help me remember how to calculate these without any dependencies. package main import "fmt" const ( minUint32 = uint32(0) maxUint32 = ^uint32(0) minUint64 = uint64(0) maxUint64 = ^uint64(0) minInt32 = int32(-maxInt32 - 1) maxInt32 = int32(maxUint32 >> 1) minInt64 = int64(-maxInt64 - 1) maxInt64 = int64(maxUint64 >> 1) ) func details[numeric int32 | int64 | uint32 | uint64](name string, num numeric) { fmt....

2024-03-05

Using 'git commit --fixup'

I learned something new from Julia Evans today. Git has a --fixup argument when committing files which makes it easy to create fixup commits which can get automatically squashed when rebasing. This is fantastic! I’ve known about git commit --amend for years, but this allows you to fixup commits which are several commits back without manually moving a bunch of lines around while interactively rebasing… Let’s assume you have a repo which looks like shown below....

2024-02-20

Go build tags

Today I learned about Go build tags. Here’s some quick notes to help me remember how to use them. Assume you have directory like so: $ ls -1 extra.go go.mod main.go And main.go has contents: package main import "fmt" var numbers = []string{ "one", "two", } func main() { for _, number := range numbers { fmt.Println(number) } } And extra.go has contents: //go:build extrastuff package main func init() { numbers = append(numbers, "three", "four") } If you build without any tags, you get this:...

2024-01-03

Using gonew to easily create template repos

Now that I’ve been writing Golang for a while, when I start a new project, I typically know the sort of layout I’m looking for. I typically go for something like this: . ├── cmd │ └── demo │ └── main.go ├── go.mod ├── internal │ └── subpkg │ ├── subpkg.go │ └── subpkg_test.go └── LICENSE And often there are lots of ascillary files that go along with this, like Makefiles, CI/CD config files, Dockerfiles, docker-compose files, etc....

2023-12-14

Checking an error's type in Golang

I was not very familiar with checking an error’s type in Golang, so I spent a few minutes learning about it today. It turns out that it’s incredibly easy to do. Running the below code shows the output: 2009/11/10 23:00:00 got custom error: err1 package main import ( "errors" "log" ) var ( customErr = errors.New("err1") // create a error, identified by its var name ) // oops always returns our custom error....

2023-12-07

Benchmarking Unnecessary Allocations

I’ve also been thinking more about unnecessary allocations in my Go code and how to avoid them by pre-declaring the length of a slice up front. Normally, I’d write something like this: var s []int for _, val := otherSlice { s = append(s, val) } Since I don’t specify the size of s, if otherSlice is large, the array underlying s might not be large enough to hold all the values; then a new array will have to be allocated and (I presume) all existing values copied out of it one at a time to fill the new array....

2023-09-30